Commit 03b92789 authored by Matthew Wilcox's avatar Matthew Wilcox Committed by Jason Gunthorpe

hfi1: Convert hfi1_unit_table to XArray

Also remove hfi1_devs_list.
Signed-off-by: default avatarMatthew Wilcox <willy@infradead.org>
Reviewed-by: default avatarDennis Dalessandro <dennis.dalessandro@intel.com>
Signed-off-by: default avatarJason Gunthorpe <jgg@mellanox.com>
parent d3243da8
...@@ -14654,8 +14654,8 @@ void hfi1_start_cleanup(struct hfi1_devdata *dd) ...@@ -14654,8 +14654,8 @@ void hfi1_start_cleanup(struct hfi1_devdata *dd)
*/ */
static int init_asic_data(struct hfi1_devdata *dd) static int init_asic_data(struct hfi1_devdata *dd)
{ {
unsigned long flags; unsigned long index;
struct hfi1_devdata *tmp, *peer = NULL; struct hfi1_devdata *peer;
struct hfi1_asic_data *asic_data; struct hfi1_asic_data *asic_data;
int ret = 0; int ret = 0;
...@@ -14664,15 +14664,13 @@ static int init_asic_data(struct hfi1_devdata *dd) ...@@ -14664,15 +14664,13 @@ static int init_asic_data(struct hfi1_devdata *dd)
if (!asic_data) if (!asic_data)
return -ENOMEM; return -ENOMEM;
spin_lock_irqsave(&hfi1_devs_lock, flags); xa_lock_irq(&hfi1_dev_table);
/* Find our peer device */ /* Find our peer device */
list_for_each_entry(tmp, &hfi1_dev_list, list) { xa_for_each(&hfi1_dev_table, index, peer) {
if ((HFI_BASE_GUID(dd) == HFI_BASE_GUID(tmp)) && if ((HFI_BASE_GUID(dd) == HFI_BASE_GUID(peer)) &&
dd->unit != tmp->unit) { dd->unit != peer->unit)
peer = tmp;
break; break;
} }
}
if (peer) { if (peer) {
/* use already allocated structure */ /* use already allocated structure */
...@@ -14683,7 +14681,7 @@ static int init_asic_data(struct hfi1_devdata *dd) ...@@ -14683,7 +14681,7 @@ static int init_asic_data(struct hfi1_devdata *dd)
mutex_init(&dd->asic_data->asic_resource_mutex); mutex_init(&dd->asic_data->asic_resource_mutex);
} }
dd->asic_data->dds[dd->hfi1_id] = dd; /* self back-pointer */ dd->asic_data->dds[dd->hfi1_id] = dd; /* self back-pointer */
spin_unlock_irqrestore(&hfi1_devs_lock, flags); xa_unlock_irq(&hfi1_dev_table);
/* first one through - set up i2c devices */ /* first one through - set up i2c devices */
if (!peer) if (!peer)
......
...@@ -1302,15 +1302,15 @@ static void _driver_stats_seq_stop(struct seq_file *s, void *v) ...@@ -1302,15 +1302,15 @@ static void _driver_stats_seq_stop(struct seq_file *s, void *v)
static u64 hfi1_sps_ints(void) static u64 hfi1_sps_ints(void)
{ {
unsigned long flags; unsigned long index, flags;
struct hfi1_devdata *dd; struct hfi1_devdata *dd;
u64 sps_ints = 0; u64 sps_ints = 0;
spin_lock_irqsave(&hfi1_devs_lock, flags); xa_lock_irqsave(&hfi1_dev_table, flags);
list_for_each_entry(dd, &hfi1_dev_list, list) { xa_for_each(&hfi1_dev_table, index, dd) {
sps_ints += get_all_cpu_total(dd->int_counter); sps_ints += get_all_cpu_total(dd->int_counter);
} }
spin_unlock_irqrestore(&hfi1_devs_lock, flags); xa_unlock_irqrestore(&hfi1_dev_table, flags);
return sps_ints; return sps_ints;
} }
......
...@@ -72,8 +72,6 @@ ...@@ -72,8 +72,6 @@
*/ */
const char ib_hfi1_version[] = HFI1_DRIVER_VERSION "\n"; const char ib_hfi1_version[] = HFI1_DRIVER_VERSION "\n";
DEFINE_SPINLOCK(hfi1_devs_lock);
LIST_HEAD(hfi1_dev_list);
DEFINE_MUTEX(hfi1_mutex); /* general driver use */ DEFINE_MUTEX(hfi1_mutex); /* general driver use */
unsigned int hfi1_max_mtu = HFI1_DEFAULT_MAX_MTU; unsigned int hfi1_max_mtu = HFI1_DEFAULT_MAX_MTU;
...@@ -175,11 +173,11 @@ int hfi1_count_active_units(void) ...@@ -175,11 +173,11 @@ int hfi1_count_active_units(void)
{ {
struct hfi1_devdata *dd; struct hfi1_devdata *dd;
struct hfi1_pportdata *ppd; struct hfi1_pportdata *ppd;
unsigned long flags; unsigned long index, flags;
int pidx, nunits_active = 0; int pidx, nunits_active = 0;
spin_lock_irqsave(&hfi1_devs_lock, flags); xa_lock_irqsave(&hfi1_dev_table, flags);
list_for_each_entry(dd, &hfi1_dev_list, list) { xa_for_each(&hfi1_dev_table, index, dd) {
if (!(dd->flags & HFI1_PRESENT) || !dd->kregbase1) if (!(dd->flags & HFI1_PRESENT) || !dd->kregbase1)
continue; continue;
for (pidx = 0; pidx < dd->num_pports; ++pidx) { for (pidx = 0; pidx < dd->num_pports; ++pidx) {
...@@ -190,7 +188,7 @@ int hfi1_count_active_units(void) ...@@ -190,7 +188,7 @@ int hfi1_count_active_units(void)
} }
} }
} }
spin_unlock_irqrestore(&hfi1_devs_lock, flags); xa_unlock_irqrestore(&hfi1_dev_table, flags);
return nunits_active; return nunits_active;
} }
......
...@@ -64,6 +64,7 @@ ...@@ -64,6 +64,7 @@
#include <linux/kthread.h> #include <linux/kthread.h>
#include <linux/i2c.h> #include <linux/i2c.h>
#include <linux/i2c-algo-bit.h> #include <linux/i2c-algo-bit.h>
#include <linux/xarray.h>
#include <rdma/ib_hdrs.h> #include <rdma/ib_hdrs.h>
#include <rdma/opa_addr.h> #include <rdma/opa_addr.h>
#include <linux/rhashtable.h> #include <linux/rhashtable.h>
...@@ -1040,7 +1041,6 @@ struct sdma_vl_map; ...@@ -1040,7 +1041,6 @@ struct sdma_vl_map;
typedef int (*send_routine)(struct rvt_qp *, struct hfi1_pkt_state *, u64); typedef int (*send_routine)(struct rvt_qp *, struct hfi1_pkt_state *, u64);
struct hfi1_devdata { struct hfi1_devdata {
struct hfi1_ibdev verbs_dev; /* must be first */ struct hfi1_ibdev verbs_dev; /* must be first */
struct list_head list;
/* pointers to related structs for this device */ /* pointers to related structs for this device */
/* pci access data structure */ /* pci access data structure */
struct pci_dev *pcidev; struct pci_dev *pcidev;
...@@ -1425,8 +1425,7 @@ struct hfi1_filedata { ...@@ -1425,8 +1425,7 @@ struct hfi1_filedata {
struct mm_struct *mm; struct mm_struct *mm;
}; };
extern struct list_head hfi1_dev_list; extern struct xarray hfi1_dev_table;
extern spinlock_t hfi1_devs_lock;
struct hfi1_devdata *hfi1_lookup(int unit); struct hfi1_devdata *hfi1_lookup(int unit);
static inline unsigned long uctxt_offset(struct hfi1_ctxtdata *uctxt) static inline unsigned long uctxt_offset(struct hfi1_ctxtdata *uctxt)
......
...@@ -49,7 +49,7 @@ ...@@ -49,7 +49,7 @@
#include <linux/netdevice.h> #include <linux/netdevice.h>
#include <linux/vmalloc.h> #include <linux/vmalloc.h>
#include <linux/delay.h> #include <linux/delay.h>
#include <linux/idr.h> #include <linux/xarray.h>
#include <linux/module.h> #include <linux/module.h>
#include <linux/printk.h> #include <linux/printk.h>
#include <linux/hrtimer.h> #include <linux/hrtimer.h>
...@@ -124,7 +124,7 @@ MODULE_PARM_DESC(user_credit_return_threshold, "Credit return threshold for user ...@@ -124,7 +124,7 @@ MODULE_PARM_DESC(user_credit_return_threshold, "Credit return threshold for user
static inline u64 encode_rcv_header_entry_size(u16 size); static inline u64 encode_rcv_header_entry_size(u16 size);
static struct idr hfi1_unit_table; DEFINE_XARRAY_FLAGS(hfi1_dev_table, XA_FLAGS_ALLOC | XA_FLAGS_LOCK_IRQ);
static int hfi1_create_kctxt(struct hfi1_devdata *dd, static int hfi1_create_kctxt(struct hfi1_devdata *dd,
struct hfi1_pportdata *ppd) struct hfi1_pportdata *ppd)
...@@ -1018,21 +1018,9 @@ int hfi1_init(struct hfi1_devdata *dd, int reinit) ...@@ -1018,21 +1018,9 @@ int hfi1_init(struct hfi1_devdata *dd, int reinit)
return ret; return ret;
} }
static inline struct hfi1_devdata *__hfi1_lookup(int unit)
{
return idr_find(&hfi1_unit_table, unit);
}
struct hfi1_devdata *hfi1_lookup(int unit) struct hfi1_devdata *hfi1_lookup(int unit)
{ {
struct hfi1_devdata *dd; return xa_load(&hfi1_dev_table, unit);
unsigned long flags;
spin_lock_irqsave(&hfi1_devs_lock, flags);
dd = __hfi1_lookup(unit);
spin_unlock_irqrestore(&hfi1_devs_lock, flags);
return dd;
} }
/* /*
...@@ -1200,7 +1188,7 @@ void hfi1_free_ctxtdata(struct hfi1_devdata *dd, struct hfi1_ctxtdata *rcd) ...@@ -1200,7 +1188,7 @@ void hfi1_free_ctxtdata(struct hfi1_devdata *dd, struct hfi1_ctxtdata *rcd)
/* /*
* Release our hold on the shared asic data. If we are the last one, * Release our hold on the shared asic data. If we are the last one,
* return the structure to be finalized outside the lock. Must be * return the structure to be finalized outside the lock. Must be
* holding hfi1_devs_lock. * holding hfi1_dev_table lock.
*/ */
static struct hfi1_asic_data *release_asic_data(struct hfi1_devdata *dd) static struct hfi1_asic_data *release_asic_data(struct hfi1_devdata *dd)
{ {
...@@ -1236,13 +1224,10 @@ static void hfi1_clean_devdata(struct hfi1_devdata *dd) ...@@ -1236,13 +1224,10 @@ static void hfi1_clean_devdata(struct hfi1_devdata *dd)
struct hfi1_asic_data *ad; struct hfi1_asic_data *ad;
unsigned long flags; unsigned long flags;
spin_lock_irqsave(&hfi1_devs_lock, flags); xa_lock_irqsave(&hfi1_dev_table, flags);
if (!list_empty(&dd->list)) { __xa_erase(&hfi1_dev_table, dd->unit);
idr_remove(&hfi1_unit_table, dd->unit);
list_del_init(&dd->list);
}
ad = release_asic_data(dd); ad = release_asic_data(dd);
spin_unlock_irqrestore(&hfi1_devs_lock, flags); xa_unlock_irqrestore(&hfi1_dev_table, flags);
finalize_asic_data(dd, ad); finalize_asic_data(dd, ad);
free_platform_config(dd); free_platform_config(dd);
...@@ -1286,13 +1271,10 @@ void hfi1_free_devdata(struct hfi1_devdata *dd) ...@@ -1286,13 +1271,10 @@ void hfi1_free_devdata(struct hfi1_devdata *dd)
* Must be done via verbs allocator, because the verbs cleanup process * Must be done via verbs allocator, because the verbs cleanup process
* both does cleanup and free of the data structure. * both does cleanup and free of the data structure.
* "extra" is for chip-specific data. * "extra" is for chip-specific data.
*
* Use the idr mechanism to get a unit number for this unit.
*/ */
static struct hfi1_devdata *hfi1_alloc_devdata(struct pci_dev *pdev, static struct hfi1_devdata *hfi1_alloc_devdata(struct pci_dev *pdev,
size_t extra) size_t extra)
{ {
unsigned long flags;
struct hfi1_devdata *dd; struct hfi1_devdata *dd;
int ret, nports; int ret, nports;
...@@ -1307,21 +1289,10 @@ static struct hfi1_devdata *hfi1_alloc_devdata(struct pci_dev *pdev, ...@@ -1307,21 +1289,10 @@ static struct hfi1_devdata *hfi1_alloc_devdata(struct pci_dev *pdev,
dd->pport = (struct hfi1_pportdata *)(dd + 1); dd->pport = (struct hfi1_pportdata *)(dd + 1);
dd->pcidev = pdev; dd->pcidev = pdev;
pci_set_drvdata(pdev, dd); pci_set_drvdata(pdev, dd);
INIT_LIST_HEAD(&dd->list);
idr_preload(GFP_KERNEL);
spin_lock_irqsave(&hfi1_devs_lock, flags);
ret = idr_alloc(&hfi1_unit_table, dd, 0, 0, GFP_NOWAIT);
if (ret >= 0) {
dd->unit = ret;
list_add(&dd->list, &hfi1_dev_list);
}
dd->node = NUMA_NO_NODE; dd->node = NUMA_NO_NODE;
spin_unlock_irqrestore(&hfi1_devs_lock, flags); ret = xa_alloc_irq(&hfi1_dev_table, &dd->unit, dd, xa_limit_32b,
idr_preload_end(); GFP_KERNEL);
if (ret < 0) { if (ret < 0) {
dev_err(&pdev->dev, dev_err(&pdev->dev,
"Could not allocate unit ID: error %d\n", -ret); "Could not allocate unit ID: error %d\n", -ret);
...@@ -1522,8 +1493,6 @@ static int __init hfi1_mod_init(void) ...@@ -1522,8 +1493,6 @@ static int __init hfi1_mod_init(void)
* These must be called before the driver is registered with * These must be called before the driver is registered with
* the PCI subsystem. * the PCI subsystem.
*/ */
idr_init(&hfi1_unit_table);
hfi1_dbg_init(); hfi1_dbg_init();
ret = pci_register_driver(&hfi1_pci_driver); ret = pci_register_driver(&hfi1_pci_driver);
if (ret < 0) { if (ret < 0) {
...@@ -1534,7 +1503,6 @@ static int __init hfi1_mod_init(void) ...@@ -1534,7 +1503,6 @@ static int __init hfi1_mod_init(void)
bail_dev: bail_dev:
hfi1_dbg_exit(); hfi1_dbg_exit();
idr_destroy(&hfi1_unit_table);
dev_cleanup(); dev_cleanup();
bail: bail:
return ret; return ret;
...@@ -1552,7 +1520,7 @@ static void __exit hfi1_mod_cleanup(void) ...@@ -1552,7 +1520,7 @@ static void __exit hfi1_mod_cleanup(void)
node_affinity_destroy_all(); node_affinity_destroy_all();
hfi1_dbg_exit(); hfi1_dbg_exit();
idr_destroy(&hfi1_unit_table); WARN_ON(!xa_empty(&hfi1_dev_table));
dispose_firmware(); /* asymmetric with obtain_firmware() */ dispose_firmware(); /* asymmetric with obtain_firmware() */
dev_cleanup(); dev_cleanup();
} }
......
...@@ -1740,15 +1740,15 @@ static struct rdma_hw_stats *alloc_hw_stats(struct ib_device *ibdev, ...@@ -1740,15 +1740,15 @@ static struct rdma_hw_stats *alloc_hw_stats(struct ib_device *ibdev,
static u64 hfi1_sps_ints(void) static u64 hfi1_sps_ints(void)
{ {
unsigned long flags; unsigned long index, flags;
struct hfi1_devdata *dd; struct hfi1_devdata *dd;
u64 sps_ints = 0; u64 sps_ints = 0;
spin_lock_irqsave(&hfi1_devs_lock, flags); xa_lock_irqsave(&hfi1_dev_table, flags);
list_for_each_entry(dd, &hfi1_dev_list, list) { xa_for_each(&hfi1_dev_table, index, dd) {
sps_ints += get_all_cpu_total(dd->int_counter); sps_ints += get_all_cpu_total(dd->int_counter);
} }
spin_unlock_irqrestore(&hfi1_devs_lock, flags); xa_unlock_irqrestore(&hfi1_dev_table, flags);
return sps_ints; return sps_ints;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment