Skip to content

Commit 0093cb1

Browse files
pkitszelkuba-moo
authored andcommitted
ice: use DSN instead of PCI BDF for ice_adapter index
Use Device Serial Number instead of PCI bus/device/function for the index of struct ice_adapter. Functions on the same physical device should point to the very same ice_adapter instance, but with two PFs, when at least one of them is PCI-e passed-through to a VM, it is no longer the case - PFs will get seemingly random PCI BDF values, and thus indices, what finally leds to each of them being on their own instance of ice_adapter. That causes them to don't attempt any synchronization of the PTP HW clock usage, or any other future resources. DSN works nicely in place of the index, as it is "immutable" in terms of virtualization. Fixes: 0e2bddf ("ice: add ice_adapter for shared data across PFs on the same NIC") Suggested-by: Jacob Keller <[email protected]> Suggested-by: Jakub Kicinski <[email protected]> Suggested-by: Jiri Pirko <[email protected]> Reviewed-by: Aleksandr Loktionov <[email protected]> Signed-off-by: Przemek Kitszel <[email protected]> Reviewed-by: Simon Horman <[email protected]> Tested-by: Rinitha S <[email protected]> (A Contingent worker at Intel) Signed-off-by: Tony Nguyen <[email protected]> Reviewed-by: Jiri Pirko <[email protected]> Link: https://patch.msgid.link/[email protected] Signed-off-by: Jakub Kicinski <[email protected]>
1 parent e8716b5 commit 0093cb1

File tree

2 files changed

+22
-31
lines changed

2 files changed

+22
-31
lines changed

drivers/net/ethernet/intel/ice/ice_adapter.c

Lines changed: 18 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
// SPDX-License-Identifier: GPL-2.0-only
22
// SPDX-FileCopyrightText: Copyright Red Hat
33

4-
#include <linux/bitfield.h>
54
#include <linux/cleanup.h>
65
#include <linux/mutex.h>
76
#include <linux/pci.h>
@@ -14,39 +13,24 @@
1413
static DEFINE_XARRAY(ice_adapters);
1514
static DEFINE_MUTEX(ice_adapters_mutex);
1615

17-
/* PCI bus number is 8 bits. Slot is 5 bits. Domain can have the rest. */
18-
#define INDEX_FIELD_DOMAIN GENMASK(BITS_PER_LONG - 1, 13)
19-
#define INDEX_FIELD_DEV GENMASK(31, 16)
20-
#define INDEX_FIELD_BUS GENMASK(12, 5)
21-
#define INDEX_FIELD_SLOT GENMASK(4, 0)
22-
23-
static unsigned long ice_adapter_index(const struct pci_dev *pdev)
16+
static unsigned long ice_adapter_index(u64 dsn)
2417
{
25-
unsigned int domain = pci_domain_nr(pdev->bus);
26-
27-
WARN_ON(domain > FIELD_MAX(INDEX_FIELD_DOMAIN));
28-
29-
switch (pdev->device) {
30-
case ICE_DEV_ID_E825C_BACKPLANE:
31-
case ICE_DEV_ID_E825C_QSFP:
32-
case ICE_DEV_ID_E825C_SFP:
33-
case ICE_DEV_ID_E825C_SGMII:
34-
return FIELD_PREP(INDEX_FIELD_DEV, pdev->device);
35-
default:
36-
return FIELD_PREP(INDEX_FIELD_DOMAIN, domain) |
37-
FIELD_PREP(INDEX_FIELD_BUS, pdev->bus->number) |
38-
FIELD_PREP(INDEX_FIELD_SLOT, PCI_SLOT(pdev->devfn));
39-
}
18+
#if BITS_PER_LONG == 64
19+
return dsn;
20+
#else
21+
return (u32)dsn ^ (u32)(dsn >> 32);
22+
#endif
4023
}
4124

42-
static struct ice_adapter *ice_adapter_new(void)
25+
static struct ice_adapter *ice_adapter_new(u64 dsn)
4326
{
4427
struct ice_adapter *adapter;
4528

4629
adapter = kzalloc(sizeof(*adapter), GFP_KERNEL);
4730
if (!adapter)
4831
return NULL;
4932

33+
adapter->device_serial_number = dsn;
5034
spin_lock_init(&adapter->ptp_gltsyn_time_lock);
5135
refcount_set(&adapter->refcount, 1);
5236

@@ -77,23 +61,26 @@ static void ice_adapter_free(struct ice_adapter *adapter)
7761
* Return: Pointer to ice_adapter on success.
7862
* ERR_PTR() on error. -ENOMEM is the only possible error.
7963
*/
80-
struct ice_adapter *ice_adapter_get(const struct pci_dev *pdev)
64+
struct ice_adapter *ice_adapter_get(struct pci_dev *pdev)
8165
{
82-
unsigned long index = ice_adapter_index(pdev);
66+
u64 dsn = pci_get_dsn(pdev);
8367
struct ice_adapter *adapter;
68+
unsigned long index;
8469
int err;
8570

71+
index = ice_adapter_index(dsn);
8672
scoped_guard(mutex, &ice_adapters_mutex) {
8773
err = xa_insert(&ice_adapters, index, NULL, GFP_KERNEL);
8874
if (err == -EBUSY) {
8975
adapter = xa_load(&ice_adapters, index);
9076
refcount_inc(&adapter->refcount);
77+
WARN_ON_ONCE(adapter->device_serial_number != dsn);
9178
return adapter;
9279
}
9380
if (err)
9481
return ERR_PTR(err);
9582

96-
adapter = ice_adapter_new();
83+
adapter = ice_adapter_new(dsn);
9784
if (!adapter)
9885
return ERR_PTR(-ENOMEM);
9986
xa_store(&ice_adapters, index, adapter, GFP_KERNEL);
@@ -110,11 +97,13 @@ struct ice_adapter *ice_adapter_get(const struct pci_dev *pdev)
11097
*
11198
* Context: Process, may sleep.
11299
*/
113-
void ice_adapter_put(const struct pci_dev *pdev)
100+
void ice_adapter_put(struct pci_dev *pdev)
114101
{
115-
unsigned long index = ice_adapter_index(pdev);
102+
u64 dsn = pci_get_dsn(pdev);
116103
struct ice_adapter *adapter;
104+
unsigned long index;
117105

106+
index = ice_adapter_index(dsn);
118107
scoped_guard(mutex, &ice_adapters_mutex) {
119108
adapter = xa_load(&ice_adapters, index);
120109
if (WARN_ON(!adapter))

drivers/net/ethernet/intel/ice/ice_adapter.h

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ struct ice_port_list {
3232
* @refcount: Reference count. struct ice_pf objects hold the references.
3333
* @ctrl_pf: Control PF of the adapter
3434
* @ports: Ports list
35+
* @device_serial_number: DSN cached for collision detection on 32bit systems
3536
*/
3637
struct ice_adapter {
3738
refcount_t refcount;
@@ -40,9 +41,10 @@ struct ice_adapter {
4041

4142
struct ice_pf *ctrl_pf;
4243
struct ice_port_list ports;
44+
u64 device_serial_number;
4345
};
4446

45-
struct ice_adapter *ice_adapter_get(const struct pci_dev *pdev);
46-
void ice_adapter_put(const struct pci_dev *pdev);
47+
struct ice_adapter *ice_adapter_get(struct pci_dev *pdev);
48+
void ice_adapter_put(struct pci_dev *pdev);
4749

4850
#endif /* _ICE_ADAPTER_H */

0 commit comments

Comments
 (0)