[patch 2/2] ice: Fix wrong dsn read in ice_adapter_put

From: Cyrill Gorcunov

Date: Fri May 22 2026 - 10:50:30 EST


When registering an adapter instance, we read the PCI configuration
space to fetch the DSN and generate an adapter index for lookups.

However, if the adapter has been physically unplugged, the PCI space
is no longer accessible. Reading it returns a zero value, which results
in either an incorrect adapter instance being put or the proper instance
not being put at all. To fix this, we will use the previously known
index instead.

Signed-off-by: Cyrill Gorcunov <gorcunov@xxxxxxxxx>
---
drivers/net/ethernet/intel/ice/ice_adapter.c | 17 ++++++++++++-----
1 file changed, 12 insertions(+), 5 deletions(-)

Index: linux-tip.git/drivers/net/ethernet/intel/ice/ice_adapter.c
===================================================================
--- linux-tip.git.orig/drivers/net/ethernet/intel/ice/ice_adapter.c
+++ linux-tip.git/drivers/net/ethernet/intel/ice/ice_adapter.c
@@ -40,10 +40,8 @@ static u64 ice_adapter_index(struct pci_
}
}

-static unsigned long ice_adapter_xa_index(struct pci_dev *pdev)
+static unsigned long xa_index_mangle(u64 index)
{
- u64 index = ice_adapter_index(pdev);
-
#if BITS_PER_LONG == 64
return index;
#else
@@ -51,6 +49,11 @@ static unsigned long ice_adapter_xa_inde
#endif
}

+static unsigned long ice_adapter_xa_index(struct pci_dev *pdev)
+{
+ return xa_index_mangle(ice_adapter_index(pdev));
+}
+
static struct ice_adapter *ice_adapter_new(struct pci_dev *pdev)
{
struct ice_adapter *adapter;
@@ -130,13 +133,17 @@ struct ice_adapter *ice_adapter_get(stru
*/
void ice_adapter_put(struct pci_dev *pdev)
{
+ const struct ice_pf *pf = pci_get_drvdata(pdev);
struct ice_adapter *adapter;
unsigned long index;

- index = ice_adapter_xa_index(pdev);
+ if (WARN_ON(!pf->adapter))
+ return;
+
scoped_guard(mutex, &ice_adapters_mutex) {
+ index = xa_index_mangle(pf->adapter->index);
adapter = xa_load(&ice_adapters, index);
- if (WARN_ON(!adapter))
+ if (WARN_ON(!adapter || adapter != pf->adapter))
return;
if (!refcount_dec_and_test(&adapter->refcount))
return;