OSDN Git Service

hfi1: Convert hfi1_unit_table to XArray
authorMatthew Wilcox <willy@infradead.org>
Fri, 8 Feb 2019 20:41:29 +0000 (15:41 -0500)
committerJason Gunthorpe <jgg@mellanox.com>
Mon, 1 Apr 2019 16:27:35 +0000 (13:27 -0300)
Also remove hfi1_devs_list.

Signed-off-by: Matthew Wilcox <willy@infradead.org>
Reviewed-by: Dennis Dalessandro <dennis.dalessandro@intel.com>
Signed-off-by: Jason Gunthorpe <jgg@mellanox.com>
drivers/infiniband/hw/hfi1/chip.c
drivers/infiniband/hw/hfi1/debugfs.c
drivers/infiniband/hw/hfi1/driver.c
drivers/infiniband/hw/hfi1/hfi.h
drivers/infiniband/hw/hfi1/init.c
drivers/infiniband/hw/hfi1/verbs.c

index 612f041..6150567 100644 (file)
@@ -14654,8 +14654,8 @@ void hfi1_start_cleanup(struct hfi1_devdata *dd)
  */
 static int init_asic_data(struct hfi1_devdata *dd)
 {
-       unsigned long flags;
-       struct hfi1_devdata *tmp, *peer = NULL;
+       unsigned long index;
+       struct hfi1_devdata *peer;
        struct hfi1_asic_data *asic_data;
        int ret = 0;
 
@@ -14664,14 +14664,12 @@ static int init_asic_data(struct hfi1_devdata *dd)
        if (!asic_data)
                return -ENOMEM;
 
-       spin_lock_irqsave(&hfi1_devs_lock, flags);
+       xa_lock_irq(&hfi1_dev_table);
        /* Find our peer device */
-       list_for_each_entry(tmp, &hfi1_dev_list, list) {
-               if ((HFI_BASE_GUID(dd) == HFI_BASE_GUID(tmp)) &&
-                   dd->unit != tmp->unit) {
-                       peer = tmp;
+       xa_for_each(&hfi1_dev_table, index, peer) {
+               if ((HFI_BASE_GUID(dd) == HFI_BASE_GUID(peer)) &&
+                   dd->unit != peer->unit)
                        break;
-               }
        }
 
        if (peer) {
@@ -14683,7 +14681,7 @@ static int init_asic_data(struct hfi1_devdata *dd)
                mutex_init(&dd->asic_data->asic_resource_mutex);
        }
        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 */
        if (!peer)
index 427ba0c..057bb82 100644 (file)
@@ -1302,15 +1302,15 @@ static void _driver_stats_seq_stop(struct seq_file *s, void *v)
 
 static u64 hfi1_sps_ints(void)
 {
-       unsigned long flags;
+       unsigned long index, flags;
        struct hfi1_devdata *dd;
        u64 sps_ints = 0;
 
-       spin_lock_irqsave(&hfi1_devs_lock, flags);
-       list_for_each_entry(dd, &hfi1_dev_list, list) {
+       xa_lock_irqsave(&hfi1_dev_table, flags);
+       xa_for_each(&hfi1_dev_table, index, dd) {
                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;
 }
 
index 2a9d291..867b4e1 100644 (file)
@@ -72,8 +72,6 @@
  */
 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 */
 
 unsigned int hfi1_max_mtu = HFI1_DEFAULT_MAX_MTU;
@@ -175,11 +173,11 @@ int hfi1_count_active_units(void)
 {
        struct hfi1_devdata *dd;
        struct hfi1_pportdata *ppd;
-       unsigned long flags;
+       unsigned long index, flags;
        int pidx, nunits_active = 0;
 
-       spin_lock_irqsave(&hfi1_devs_lock, flags);
-       list_for_each_entry(dd, &hfi1_dev_list, list) {
+       xa_lock_irqsave(&hfi1_dev_table, flags);
+       xa_for_each(&hfi1_dev_table, index, dd) {
                if (!(dd->flags & HFI1_PRESENT) || !dd->kregbase1)
                        continue;
                for (pidx = 0; pidx < dd->num_pports; ++pidx) {
@@ -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;
 }
 
index aafd8c3..b458c21 100644 (file)
@@ -64,6 +64,7 @@
 #include <linux/kthread.h>
 #include <linux/i2c.h>
 #include <linux/i2c-algo-bit.h>
+#include <linux/xarray.h>
 #include <rdma/ib_hdrs.h>
 #include <rdma/opa_addr.h>
 #include <linux/rhashtable.h>
@@ -1040,7 +1041,6 @@ struct sdma_vl_map;
 typedef int (*send_routine)(struct rvt_qp *, struct hfi1_pkt_state *, u64);
 struct hfi1_devdata {
        struct hfi1_ibdev verbs_dev;     /* must be first */
-       struct list_head list;
        /* pointers to related structs for this device */
        /* pci access data structure */
        struct pci_dev *pcidev;
@@ -1425,8 +1425,7 @@ struct hfi1_filedata {
        struct mm_struct *mm;
 };
 
-extern struct list_head hfi1_dev_list;
-extern spinlock_t hfi1_devs_lock;
+extern struct xarray hfi1_dev_table;
 struct hfi1_devdata *hfi1_lookup(int unit);
 
 static inline unsigned long uctxt_offset(struct hfi1_ctxtdata *uctxt)
index 3c33961..e4c2ae4 100644 (file)
@@ -49,7 +49,7 @@
 #include <linux/netdevice.h>
 #include <linux/vmalloc.h>
 #include <linux/delay.h>
-#include <linux/idr.h>
+#include <linux/xarray.h>
 #include <linux/module.h>
 #include <linux/printk.h>
 #include <linux/hrtimer.h>
@@ -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 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,
                             struct hfi1_pportdata *ppd)
@@ -1018,21 +1018,9 @@ done:
        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 *dd;
-       unsigned long flags;
-
-       spin_lock_irqsave(&hfi1_devs_lock, flags);
-       dd = __hfi1_lookup(unit);
-       spin_unlock_irqrestore(&hfi1_devs_lock, flags);
-
-       return dd;
+       return xa_load(&hfi1_dev_table, unit);
 }
 
 /*
@@ -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,
  * 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)
 {
@@ -1236,13 +1224,10 @@ static void hfi1_clean_devdata(struct hfi1_devdata *dd)
        struct hfi1_asic_data *ad;
        unsigned long flags;
 
-       spin_lock_irqsave(&hfi1_devs_lock, flags);
-       if (!list_empty(&dd->list)) {
-               idr_remove(&hfi1_unit_table, dd->unit);
-               list_del_init(&dd->list);
-       }
+       xa_lock_irqsave(&hfi1_dev_table, flags);
+       __xa_erase(&hfi1_dev_table, dd->unit);
        ad = release_asic_data(dd);
-       spin_unlock_irqrestore(&hfi1_devs_lock, flags);
+       xa_unlock_irqrestore(&hfi1_dev_table, flags);
 
        finalize_asic_data(dd, ad);
        free_platform_config(dd);
@@ -1286,13 +1271,10 @@ void hfi1_free_devdata(struct hfi1_devdata *dd)
  * Must be done via verbs allocator, because the verbs cleanup process
  * both does cleanup and free of the data structure.
  * "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,
                                               size_t extra)
 {
-       unsigned long flags;
        struct hfi1_devdata *dd;
        int ret, nports;
 
@@ -1307,21 +1289,10 @@ static struct hfi1_devdata *hfi1_alloc_devdata(struct pci_dev *pdev,
        dd->pport = (struct hfi1_pportdata *)(dd + 1);
        dd->pcidev = pdev;
        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;
 
-       spin_unlock_irqrestore(&hfi1_devs_lock, flags);
-       idr_preload_end();
-
+       ret = xa_alloc_irq(&hfi1_dev_table, &dd->unit, dd, xa_limit_32b,
+                       GFP_KERNEL);
        if (ret < 0) {
                dev_err(&pdev->dev,
                        "Could not allocate unit ID: error %d\n", -ret);
@@ -1522,8 +1493,6 @@ static int __init hfi1_mod_init(void)
         * These must be called before the driver is registered with
         * the PCI subsystem.
         */
-       idr_init(&hfi1_unit_table);
-
        hfi1_dbg_init();
        ret = pci_register_driver(&hfi1_pci_driver);
        if (ret < 0) {
@@ -1534,7 +1503,6 @@ static int __init hfi1_mod_init(void)
 
 bail_dev:
        hfi1_dbg_exit();
-       idr_destroy(&hfi1_unit_table);
        dev_cleanup();
 bail:
        return ret;
@@ -1552,7 +1520,7 @@ static void __exit hfi1_mod_cleanup(void)
        node_affinity_destroy_all();
        hfi1_dbg_exit();
 
-       idr_destroy(&hfi1_unit_table);
+       WARN_ON(!xa_empty(&hfi1_dev_table));
        dispose_firmware();     /* asymmetric with obtain_firmware() */
        dev_cleanup();
 }
index b73ab7c..1eb4105 100644 (file)
@@ -1740,15 +1740,15 @@ static struct rdma_hw_stats *alloc_hw_stats(struct ib_device *ibdev,
 
 static u64 hfi1_sps_ints(void)
 {
-       unsigned long flags;
+       unsigned long index, flags;
        struct hfi1_devdata *dd;
        u64 sps_ints = 0;
 
-       spin_lock_irqsave(&hfi1_devs_lock, flags);
-       list_for_each_entry(dd, &hfi1_dev_list, list) {
+       xa_lock_irqsave(&hfi1_dev_table, flags);
+       xa_for_each(&hfi1_dev_table, index, dd) {
                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;
 }