aboutsummaryrefslogtreecommitdiff
path: root/sys/dev/ice/ice_resmgr.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/dev/ice/ice_resmgr.c')
-rw-r--r--sys/dev/ice/ice_resmgr.c227
1 files changed, 227 insertions, 0 deletions
diff --git a/sys/dev/ice/ice_resmgr.c b/sys/dev/ice/ice_resmgr.c
new file mode 100644
index 000000000000..824b986fff57
--- /dev/null
+++ b/sys/dev/ice/ice_resmgr.c
@@ -0,0 +1,227 @@
+/* SPDX-License-Identifier: BSD-3-Clause */
+/* Copyright (c) 2024, Intel Corporation
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the Intel Corporation nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/**
+ * @file ice_resmgr.c
+ * @brief Resource allocation manager
+ *
+ * Manage device resource allocations for a PF, including assigning queues to
+ * VSIs, or managing interrupt allocations across the PF.
+ *
+ * It can handle contiguous and scattered resource allocations, and upon
+ * assigning them, will fill in the mapping array with a map of
+ * resource IDs to PF-space resource indices.
+ */
+
+#include "ice_resmgr.h"
+
+/**
+ * @var M_ICE_RESMGR
+ * @brief PF resource manager allocation type
+ *
+ * malloc(9) allocation type used by the resource manager code.
+ */
+MALLOC_DEFINE(M_ICE_RESMGR, "ice-resmgr", "Intel(R) 100Gb Network Driver resmgr allocations");
+
+/*
+ * Public resource manager allocation functions
+ */
+
+/**
+ * ice_resmgr_init - Initialize a resource manager structure
+ * @resmgr: structure to track the resource manager state
+ * @num_res: the maximum number of resources it can assign
+ *
+ * Initialize the state of a resource manager structure, allocating space to
+ * assign up to the requested number of resources. Uses bit strings to track
+ * which resources have been assigned. This type of resmgr is intended to be
+ * used for tracking LAN queue assignments between VSIs.
+ */
+int
+ice_resmgr_init(struct ice_resmgr *resmgr, u16 num_res)
+{
+ resmgr->resources = bit_alloc(num_res, M_ICE_RESMGR, M_NOWAIT);
+ if (resmgr->resources == NULL)
+ return (ENOMEM);
+
+ resmgr->num_res = num_res;
+ resmgr->contig_only = false;
+ return (0);
+}
+
+/**
+ * ice_resmgr_init_contig_only - Initialize a resource manager structure
+ * @resmgr: structure to track the resource manager state
+ * @num_res: the maximum number of resources it can assign
+ *
+ * Functions similarly to ice_resmgr_init(), but the resulting resmgr structure
+ * will only allow contiguous allocations. This type of resmgr is intended to
+ * be used with tracking device MSI-X interrupt allocations.
+ */
+int
+ice_resmgr_init_contig_only(struct ice_resmgr *resmgr, u16 num_res)
+{
+ int error;
+
+ error = ice_resmgr_init(resmgr, num_res);
+ if (error)
+ return (error);
+
+ resmgr->contig_only = true;
+ return (0);
+}
+
+/**
+ * ice_resmgr_destroy - Deallocate memory associated with a resource manager
+ * @resmgr: resource manager structure
+ *
+ * De-allocates the bit string associated with this resource manager. It is
+ * expected that this function will not be called until all of the assigned
+ * resources have been released.
+ */
+void
+ice_resmgr_destroy(struct ice_resmgr *resmgr)
+{
+ if (resmgr->resources != NULL) {
+#ifdef INVARIANTS
+ int set;
+
+ bit_count(resmgr->resources, 0, resmgr->num_res, &set);
+ MPASS(set == 0);
+#endif
+
+ free(resmgr->resources, M_ICE_RESMGR);
+ resmgr->resources = NULL;
+ }
+ resmgr->num_res = 0;
+}
+
+/*
+ * Resource allocation functions
+ */
+
+/**
+ * ice_resmgr_assign_contiguous - Assign contiguous mapping of resources
+ * @resmgr: resource manager structure
+ * @idx: memory to store mapping, at least num_res wide
+ * @num_res: the number of resources to assign
+ *
+ * Assign num_res number of contiguous resources into the idx mapping. On
+ * success, idx will be updated to map each index to a PF resource.
+ *
+ * This function guarantees that the resource mapping will be contiguous, and
+ * will fail if that is not possible.
+ */
+int
+ice_resmgr_assign_contiguous(struct ice_resmgr *resmgr, u16 *idx, u16 num_res)
+{
+ int start, i;
+
+ bit_ffc_area(resmgr->resources, resmgr->num_res, num_res, &start);
+ if (start < 0)
+ return (ENOSPC);
+
+ /* Set each bit and update the index array */
+ for (i = 0; i < num_res; i++) {
+ bit_set(resmgr->resources, start + i);
+ idx[i] = start + i;
+ }
+
+ return (0);
+}
+
+/**
+ * ice_resmgr_assign_scattered - Assign possibly scattered resources
+ * @resmgr: the resource manager structure
+ * @idx: memory to store associated resource mapping, at least num_res wide
+ * @num_res: the number of resources to assign
+ *
+ * Assign num_res number of resources into the idx_mapping. On success, idx
+ * will be updated to map each index to a PF-space resource.
+ *
+ * Queues may be allocated non-contiguously, and this function requires that
+ * num_res be less than the ICE_MAX_SCATTERED_QUEUES due to hardware
+ * limitations on scattered queue assignment.
+ */
+int
+ice_resmgr_assign_scattered(struct ice_resmgr *resmgr, u16 *idx, u16 num_res)
+{
+ int index = 0, i;
+
+ /* Scattered allocations won't work if they weren't allowed at resmgr
+ * creation time.
+ */
+ if (resmgr->contig_only)
+ return (EPERM);
+
+ /* Hardware can only support a limited total of scattered queues for
+ * a single VSI
+ */
+ if (num_res > ICE_MAX_SCATTERED_QUEUES)
+ return (EOPNOTSUPP);
+
+ for (i = 0; i < num_res; i++) {
+ bit_ffc_at(resmgr->resources, index, resmgr->num_res, &index);
+ if (index < 0)
+ goto err_no_space;
+
+ bit_set(resmgr->resources, index);
+ idx[i] = index;
+ }
+ return (0);
+
+err_no_space:
+ /* Release any resources we did assign up to this point. */
+ ice_resmgr_release_map(resmgr, idx, i);
+ return (ENOSPC);
+}
+
+/**
+ * ice_resmgr_release_map - Release previously assigned resource mapping
+ * @resmgr: the resource manager structure
+ * @idx: previously assigned resource mapping
+ * @num_res: number of resources in the mapping
+ *
+ * Clears the assignment of each resource in the provided resource index. Updates
+ * the idx to indicate that each of the virtual indexes have invalid resource
+ * mappings by assigning them to ICE_INVALID_RES_IDX.
+ */
+void
+ice_resmgr_release_map(struct ice_resmgr *resmgr, u16 *idx, u16 num_res)
+{
+ int i;
+
+ for (i = 0; i < num_res; i++) {
+ if (idx[i] < resmgr->num_res)
+ bit_clear(resmgr->resources, idx[i]);
+ idx[i] = ICE_INVALID_RES_IDX;
+ }
+}