171d10453SEric Joyner /* SPDX-License-Identifier: BSD-3-Clause */ 2*015f8cc5SEric Joyner /* Copyright (c) 2024, Intel Corporation 371d10453SEric Joyner * All rights reserved. 471d10453SEric Joyner * 571d10453SEric Joyner * Redistribution and use in source and binary forms, with or without 671d10453SEric Joyner * modification, are permitted provided that the following conditions are met: 771d10453SEric Joyner * 871d10453SEric Joyner * 1. Redistributions of source code must retain the above copyright notice, 971d10453SEric Joyner * this list of conditions and the following disclaimer. 1071d10453SEric Joyner * 1171d10453SEric Joyner * 2. Redistributions in binary form must reproduce the above copyright 1271d10453SEric Joyner * notice, this list of conditions and the following disclaimer in the 1371d10453SEric Joyner * documentation and/or other materials provided with the distribution. 1471d10453SEric Joyner * 1571d10453SEric Joyner * 3. Neither the name of the Intel Corporation nor the names of its 1671d10453SEric Joyner * contributors may be used to endorse or promote products derived from 1771d10453SEric Joyner * this software without specific prior written permission. 1871d10453SEric Joyner * 1971d10453SEric Joyner * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 2071d10453SEric Joyner * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 2171d10453SEric Joyner * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 2271d10453SEric Joyner * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 2371d10453SEric Joyner * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 2471d10453SEric Joyner * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 2571d10453SEric Joyner * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 2671d10453SEric Joyner * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 2771d10453SEric Joyner * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 2871d10453SEric Joyner * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 2971d10453SEric Joyner * POSSIBILITY OF SUCH DAMAGE. 3071d10453SEric Joyner */ 3171d10453SEric Joyner 3271d10453SEric Joyner /** 3371d10453SEric Joyner * @file ice_resmgr.c 3471d10453SEric Joyner * @brief Resource allocation manager 3571d10453SEric Joyner * 3671d10453SEric Joyner * Manage device resource allocations for a PF, including assigning queues to 3771d10453SEric Joyner * VSIs, or managing interrupt allocations across the PF. 3871d10453SEric Joyner * 3971d10453SEric Joyner * It can handle contiguous and scattered resource allocations, and upon 4071d10453SEric Joyner * assigning them, will fill in the mapping array with a map of 4171d10453SEric Joyner * resource IDs to PF-space resource indices. 4271d10453SEric Joyner */ 4371d10453SEric Joyner 4471d10453SEric Joyner #include "ice_resmgr.h" 4571d10453SEric Joyner 4671d10453SEric Joyner /** 4771d10453SEric Joyner * @var M_ICE_RESMGR 4871d10453SEric Joyner * @brief PF resource manager allocation type 4971d10453SEric Joyner * 5071d10453SEric Joyner * malloc(9) allocation type used by the resource manager code. 5171d10453SEric Joyner */ 5271d10453SEric Joyner MALLOC_DEFINE(M_ICE_RESMGR, "ice-resmgr", "Intel(R) 100Gb Network Driver resmgr allocations"); 5371d10453SEric Joyner 5471d10453SEric Joyner /* 5571d10453SEric Joyner * Public resource manager allocation functions 5671d10453SEric Joyner */ 5771d10453SEric Joyner 5871d10453SEric Joyner /** 5971d10453SEric Joyner * ice_resmgr_init - Initialize a resource manager structure 6071d10453SEric Joyner * @resmgr: structure to track the resource manager state 6171d10453SEric Joyner * @num_res: the maximum number of resources it can assign 6271d10453SEric Joyner * 6371d10453SEric Joyner * Initialize the state of a resource manager structure, allocating space to 6471d10453SEric Joyner * assign up to the requested number of resources. Uses bit strings to track 6571d10453SEric Joyner * which resources have been assigned. This type of resmgr is intended to be 6671d10453SEric Joyner * used for tracking LAN queue assignments between VSIs. 6771d10453SEric Joyner */ 6871d10453SEric Joyner int 6971d10453SEric Joyner ice_resmgr_init(struct ice_resmgr *resmgr, u16 num_res) 7071d10453SEric Joyner { 7171d10453SEric Joyner resmgr->resources = bit_alloc(num_res, M_ICE_RESMGR, M_NOWAIT); 7271d10453SEric Joyner if (resmgr->resources == NULL) 7371d10453SEric Joyner return (ENOMEM); 7471d10453SEric Joyner 7571d10453SEric Joyner resmgr->num_res = num_res; 7671d10453SEric Joyner resmgr->contig_only = false; 7771d10453SEric Joyner return (0); 7871d10453SEric Joyner } 7971d10453SEric Joyner 8071d10453SEric Joyner /** 8171d10453SEric Joyner * ice_resmgr_init_contig_only - Initialize a resource manager structure 8271d10453SEric Joyner * @resmgr: structure to track the resource manager state 8371d10453SEric Joyner * @num_res: the maximum number of resources it can assign 8471d10453SEric Joyner * 8571d10453SEric Joyner * Functions similarly to ice_resmgr_init(), but the resulting resmgr structure 8671d10453SEric Joyner * will only allow contiguous allocations. This type of resmgr is intended to 8771d10453SEric Joyner * be used with tracking device MSI-X interrupt allocations. 8871d10453SEric Joyner */ 8971d10453SEric Joyner int 9071d10453SEric Joyner ice_resmgr_init_contig_only(struct ice_resmgr *resmgr, u16 num_res) 9171d10453SEric Joyner { 9271d10453SEric Joyner int error; 9371d10453SEric Joyner 9471d10453SEric Joyner error = ice_resmgr_init(resmgr, num_res); 9571d10453SEric Joyner if (error) 9671d10453SEric Joyner return (error); 9771d10453SEric Joyner 9871d10453SEric Joyner resmgr->contig_only = true; 9971d10453SEric Joyner return (0); 10071d10453SEric Joyner } 10171d10453SEric Joyner 10271d10453SEric Joyner /** 10371d10453SEric Joyner * ice_resmgr_destroy - Deallocate memory associated with a resource manager 10471d10453SEric Joyner * @resmgr: resource manager structure 10571d10453SEric Joyner * 10671d10453SEric Joyner * De-allocates the bit string associated with this resource manager. It is 10771d10453SEric Joyner * expected that this function will not be called until all of the assigned 10871d10453SEric Joyner * resources have been released. 10971d10453SEric Joyner */ 11071d10453SEric Joyner void 11171d10453SEric Joyner ice_resmgr_destroy(struct ice_resmgr *resmgr) 11271d10453SEric Joyner { 11371d10453SEric Joyner if (resmgr->resources != NULL) { 11471d10453SEric Joyner #ifdef INVARIANTS 11571d10453SEric Joyner int set; 11671d10453SEric Joyner 11771d10453SEric Joyner bit_count(resmgr->resources, 0, resmgr->num_res, &set); 11871d10453SEric Joyner MPASS(set == 0); 11971d10453SEric Joyner #endif 12071d10453SEric Joyner 12171d10453SEric Joyner free(resmgr->resources, M_ICE_RESMGR); 12271d10453SEric Joyner resmgr->resources = NULL; 12371d10453SEric Joyner } 12471d10453SEric Joyner resmgr->num_res = 0; 12571d10453SEric Joyner } 12671d10453SEric Joyner 12771d10453SEric Joyner /* 12871d10453SEric Joyner * Resource allocation functions 12971d10453SEric Joyner */ 13071d10453SEric Joyner 13171d10453SEric Joyner /** 13271d10453SEric Joyner * ice_resmgr_assign_contiguous - Assign contiguous mapping of resources 13371d10453SEric Joyner * @resmgr: resource manager structure 13471d10453SEric Joyner * @idx: memory to store mapping, at least num_res wide 13571d10453SEric Joyner * @num_res: the number of resources to assign 13671d10453SEric Joyner * 13771d10453SEric Joyner * Assign num_res number of contiguous resources into the idx mapping. On 13871d10453SEric Joyner * success, idx will be updated to map each index to a PF resource. 13971d10453SEric Joyner * 14071d10453SEric Joyner * This function guarantees that the resource mapping will be contiguous, and 14171d10453SEric Joyner * will fail if that is not possible. 14271d10453SEric Joyner */ 14371d10453SEric Joyner int 14471d10453SEric Joyner ice_resmgr_assign_contiguous(struct ice_resmgr *resmgr, u16 *idx, u16 num_res) 14571d10453SEric Joyner { 14671d10453SEric Joyner int start, i; 14771d10453SEric Joyner 14871d10453SEric Joyner bit_ffc_area(resmgr->resources, resmgr->num_res, num_res, &start); 14971d10453SEric Joyner if (start < 0) 15071d10453SEric Joyner return (ENOSPC); 15171d10453SEric Joyner 15271d10453SEric Joyner /* Set each bit and update the index array */ 15371d10453SEric Joyner for (i = 0; i < num_res; i++) { 15471d10453SEric Joyner bit_set(resmgr->resources, start + i); 15571d10453SEric Joyner idx[i] = start + i; 15671d10453SEric Joyner } 15771d10453SEric Joyner 15871d10453SEric Joyner return (0); 15971d10453SEric Joyner } 16071d10453SEric Joyner 16171d10453SEric Joyner /** 16271d10453SEric Joyner * ice_resmgr_assign_scattered - Assign possibly scattered resources 16371d10453SEric Joyner * @resmgr: the resource manager structure 16471d10453SEric Joyner * @idx: memory to store associated resource mapping, at least num_res wide 16571d10453SEric Joyner * @num_res: the number of resources to assign 16671d10453SEric Joyner * 16771d10453SEric Joyner * Assign num_res number of resources into the idx_mapping. On success, idx 16871d10453SEric Joyner * will be updated to map each index to a PF-space resource. 16971d10453SEric Joyner * 17071d10453SEric Joyner * Queues may be allocated non-contiguously, and this function requires that 17171d10453SEric Joyner * num_res be less than the ICE_MAX_SCATTERED_QUEUES due to hardware 17271d10453SEric Joyner * limitations on scattered queue assignment. 17371d10453SEric Joyner */ 17471d10453SEric Joyner int 17571d10453SEric Joyner ice_resmgr_assign_scattered(struct ice_resmgr *resmgr, u16 *idx, u16 num_res) 17671d10453SEric Joyner { 17771d10453SEric Joyner int index = 0, i; 17871d10453SEric Joyner 17971d10453SEric Joyner /* Scattered allocations won't work if they weren't allowed at resmgr 18071d10453SEric Joyner * creation time. 18171d10453SEric Joyner */ 18271d10453SEric Joyner if (resmgr->contig_only) 18371d10453SEric Joyner return (EPERM); 18471d10453SEric Joyner 18571d10453SEric Joyner /* Hardware can only support a limited total of scattered queues for 18671d10453SEric Joyner * a single VSI 18771d10453SEric Joyner */ 18871d10453SEric Joyner if (num_res > ICE_MAX_SCATTERED_QUEUES) 18971d10453SEric Joyner return (EOPNOTSUPP); 19071d10453SEric Joyner 19171d10453SEric Joyner for (i = 0; i < num_res; i++) { 19271d10453SEric Joyner bit_ffc_at(resmgr->resources, index, resmgr->num_res, &index); 19371d10453SEric Joyner if (index < 0) 19471d10453SEric Joyner goto err_no_space; 19571d10453SEric Joyner 19671d10453SEric Joyner bit_set(resmgr->resources, index); 19771d10453SEric Joyner idx[i] = index; 19871d10453SEric Joyner } 19971d10453SEric Joyner return (0); 20071d10453SEric Joyner 20171d10453SEric Joyner err_no_space: 20271d10453SEric Joyner /* Release any resources we did assign up to this point. */ 20371d10453SEric Joyner ice_resmgr_release_map(resmgr, idx, i); 20471d10453SEric Joyner return (ENOSPC); 20571d10453SEric Joyner } 20671d10453SEric Joyner 20771d10453SEric Joyner /** 20871d10453SEric Joyner * ice_resmgr_release_map - Release previously assigned resource mapping 20971d10453SEric Joyner * @resmgr: the resource manager structure 21071d10453SEric Joyner * @idx: previously assigned resource mapping 21171d10453SEric Joyner * @num_res: number of resources in the mapping 21271d10453SEric Joyner * 21371d10453SEric Joyner * Clears the assignment of each resource in the provided resource index. Updates 21471d10453SEric Joyner * the idx to indicate that each of the virtual indexes have invalid resource 21571d10453SEric Joyner * mappings by assigning them to ICE_INVALID_RES_IDX. 21671d10453SEric Joyner */ 21771d10453SEric Joyner void 21871d10453SEric Joyner ice_resmgr_release_map(struct ice_resmgr *resmgr, u16 *idx, u16 num_res) 21971d10453SEric Joyner { 22071d10453SEric Joyner int i; 22171d10453SEric Joyner 22271d10453SEric Joyner for (i = 0; i < num_res; i++) { 22371d10453SEric Joyner if (idx[i] < resmgr->num_res) 22471d10453SEric Joyner bit_clear(resmgr->resources, idx[i]); 22571d10453SEric Joyner idx[i] = ICE_INVALID_RES_IDX; 22671d10453SEric Joyner } 22771d10453SEric Joyner } 228