| From 80dd118b04fa3f6752ec77106942c9b78cfc7b70 Mon Sep 17 00:00:00 2001 |
| From: Sasha Levin <sashal@kernel.org> |
| Date: Tue, 3 Dec 2024 07:58:14 +0100 |
| Subject: ice: treat dyn_allowed only as suggestion |
| |
| From: Michal Swiatkowski <michal.swiatkowski@linux.intel.com> |
| |
| [ Upstream commit a8c2d3932c1106af2764cc6869b29bcf3cb5bc47 ] |
| |
| It can be needed to have some MSI-X allocated as static and rest as |
| dynamic. For example on PF VSI. We want to always have minimum one MSI-X |
| on it, because of that it is allocated as a static one, rest can be |
| dynamic if it is supported. |
| |
| Change the ice_get_irq_res() to allow using static entries if they are |
| free even if caller wants dynamic one. |
| |
| Adjust limit values to the new approach. Min and max in limit means the |
| values that are valid, so decrease max and num_static by one. |
| |
| Set vsi::irq_dyn_alloc if dynamic allocation is supported. |
| |
| Reviewed-by: Jacob Keller <jacob.e.keller@intel.com> |
| Reviewed-by: Wojciech Drewek <wojciech.drewek@intel.com> |
| Tested-by: Pucha Himasekhar Reddy <himasekharx.reddy.pucha@intel.com> |
| Signed-off-by: Michal Swiatkowski <michal.swiatkowski@linux.intel.com> |
| Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com> |
| Signed-off-by: Sasha Levin <sashal@kernel.org> |
| --- |
| drivers/net/ethernet/intel/ice/ice_irq.c | 25 ++++++++++++------------ |
| drivers/net/ethernet/intel/ice/ice_lib.c | 2 ++ |
| 2 files changed, 15 insertions(+), 12 deletions(-) |
| |
| diff --git a/drivers/net/ethernet/intel/ice/ice_irq.c b/drivers/net/ethernet/intel/ice/ice_irq.c |
| index ad82ff7d19957..09f9c7ba52795 100644 |
| --- a/drivers/net/ethernet/intel/ice/ice_irq.c |
| +++ b/drivers/net/ethernet/intel/ice/ice_irq.c |
| @@ -45,7 +45,7 @@ static void ice_free_irq_res(struct ice_pf *pf, u16 index) |
| /** |
| * ice_get_irq_res - get an interrupt resource |
| * @pf: board private structure |
| - * @dyn_only: force entry to be dynamically allocated |
| + * @dyn_allowed: allow entry to be dynamically allocated |
| * |
| * Allocate new irq entry in the free slot of the tracker. Since xarray |
| * is used, always allocate new entry at the lowest possible index. Set |
| @@ -53,11 +53,12 @@ static void ice_free_irq_res(struct ice_pf *pf, u16 index) |
| * |
| * Returns allocated irq entry or NULL on failure. |
| */ |
| -static struct ice_irq_entry *ice_get_irq_res(struct ice_pf *pf, bool dyn_only) |
| +static struct ice_irq_entry *ice_get_irq_res(struct ice_pf *pf, |
| + bool dyn_allowed) |
| { |
| - struct xa_limit limit = { .max = pf->irq_tracker.num_entries, |
| + struct xa_limit limit = { .max = pf->irq_tracker.num_entries - 1, |
| .min = 0 }; |
| - unsigned int num_static = pf->irq_tracker.num_static; |
| + unsigned int num_static = pf->irq_tracker.num_static - 1; |
| struct ice_irq_entry *entry; |
| unsigned int index; |
| int ret; |
| @@ -66,9 +67,9 @@ static struct ice_irq_entry *ice_get_irq_res(struct ice_pf *pf, bool dyn_only) |
| if (!entry) |
| return NULL; |
| |
| - /* skip preallocated entries if the caller says so */ |
| - if (dyn_only) |
| - limit.min = num_static; |
| + /* only already allocated if the caller says so */ |
| + if (!dyn_allowed) |
| + limit.max = num_static; |
| |
| ret = xa_alloc(&pf->irq_tracker.entries, &index, entry, limit, |
| GFP_KERNEL); |
| @@ -78,7 +79,7 @@ static struct ice_irq_entry *ice_get_irq_res(struct ice_pf *pf, bool dyn_only) |
| entry = NULL; |
| } else { |
| entry->index = index; |
| - entry->dynamic = index >= num_static; |
| + entry->dynamic = index > num_static; |
| } |
| |
| return entry; |
| @@ -272,7 +273,7 @@ int ice_init_interrupt_scheme(struct ice_pf *pf) |
| /** |
| * ice_alloc_irq - Allocate new interrupt vector |
| * @pf: board private structure |
| - * @dyn_only: force dynamic allocation of the interrupt |
| + * @dyn_allowed: allow dynamic allocation of the interrupt |
| * |
| * Allocate new interrupt vector for a given owner id. |
| * return struct msi_map with interrupt details and track |
| @@ -285,20 +286,20 @@ int ice_init_interrupt_scheme(struct ice_pf *pf) |
| * interrupt will be allocated with pci_msix_alloc_irq_at. |
| * |
| * Some callers may only support dynamically allocated interrupts. |
| - * This is indicated with dyn_only flag. |
| + * This is indicated with dyn_allowed flag. |
| * |
| * On failure, return map with negative .index. The caller |
| * is expected to check returned map index. |
| * |
| */ |
| -struct msi_map ice_alloc_irq(struct ice_pf *pf, bool dyn_only) |
| +struct msi_map ice_alloc_irq(struct ice_pf *pf, bool dyn_allowed) |
| { |
| int sriov_base_vector = pf->sriov_base_vector; |
| struct msi_map map = { .index = -ENOENT }; |
| struct device *dev = ice_pf_to_dev(pf); |
| struct ice_irq_entry *entry; |
| |
| - entry = ice_get_irq_res(pf, dyn_only); |
| + entry = ice_get_irq_res(pf, dyn_allowed); |
| if (!entry) |
| return map; |
| |
| diff --git a/drivers/net/ethernet/intel/ice/ice_lib.c b/drivers/net/ethernet/intel/ice/ice_lib.c |
| index e0785e820d601..021ed7451bb9f 100644 |
| --- a/drivers/net/ethernet/intel/ice/ice_lib.c |
| +++ b/drivers/net/ethernet/intel/ice/ice_lib.c |
| @@ -567,6 +567,8 @@ ice_vsi_alloc_def(struct ice_vsi *vsi, struct ice_channel *ch) |
| return -ENOMEM; |
| } |
| |
| + vsi->irq_dyn_alloc = pci_msix_can_alloc_dyn(vsi->back->pdev); |
| + |
| switch (vsi->type) { |
| case ICE_VSI_PF: |
| case ICE_VSI_SF: |
| -- |
| 2.39.5 |
| |