OSDN Git Service

qib: Convert qib_unit_table to XArray
authorMatthew Wilcox <willy@infradead.org>
Thu, 21 Feb 2019 00:21:00 +0000 (16:21 -0800)
committerJason Gunthorpe <jgg@mellanox.com>
Mon, 1 Apr 2019 16:31:35 +0000 (13:31 -0300)
Also remove qib_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/qib/qib.h
drivers/infiniband/hw/qib/qib_driver.c
drivers/infiniband/hw/qib/qib_fs.c
drivers/infiniband/hw/qib/qib_iba7322.c
drivers/infiniband/hw/qib/qib_init.c

index 83d2349..432d6d0 100644 (file)
@@ -52,6 +52,7 @@
 #include <linux/kref.h>
 #include <linux/sched.h>
 #include <linux/kthread.h>
+#include <linux/xarray.h>
 #include <rdma/ib_hdrs.h>
 #include <rdma/rdma_vt.h>
 
@@ -1105,8 +1106,7 @@ struct qib_filedata {
        int rec_cpu_num; /* for cpu affinity; -1 if none */
 };
 
-extern struct list_head qib_dev_list;
-extern spinlock_t qib_devs_lock;
+extern struct xarray qib_dev_table;
 extern struct qib_devdata *qib_lookup(int unit);
 extern u32 qib_cpulist_count;
 extern unsigned long *qib_cpulist;
index 3117cc5..92eeea5 100644 (file)
@@ -49,8 +49,6 @@
  */
 const char ib_qib_version[] = QIB_DRIVER_VERSION "\n";
 
-DEFINE_SPINLOCK(qib_devs_lock);
-LIST_HEAD(qib_dev_list);
 DEFINE_MUTEX(qib_mutex);       /* general driver use */
 
 unsigned qib_ibmtu;
@@ -96,11 +94,11 @@ int qib_count_active_units(void)
 {
        struct qib_devdata *dd;
        struct qib_pportdata *ppd;
-       unsigned long flags;
+       unsigned long index, flags;
        int pidx, nunits_active = 0;
 
-       spin_lock_irqsave(&qib_devs_lock, flags);
-       list_for_each_entry(dd, &qib_dev_list, list) {
+       xa_lock_irqsave(&qib_dev_table, flags);
+       xa_for_each(&qib_dev_table, index, dd) {
                if (!(dd->flags & QIB_PRESENT) || !dd->kregbase)
                        continue;
                for (pidx = 0; pidx < dd->num_pports; ++pidx) {
@@ -112,7 +110,7 @@ int qib_count_active_units(void)
                        }
                }
        }
-       spin_unlock_irqrestore(&qib_devs_lock, flags);
+       xa_unlock_irqrestore(&qib_dev_table, flags);
        return nunits_active;
 }
 
@@ -125,13 +123,12 @@ int qib_count_units(int *npresentp, int *nupp)
 {
        int nunits = 0, npresent = 0, nup = 0;
        struct qib_devdata *dd;
-       unsigned long flags;
+       unsigned long index, flags;
        int pidx;
        struct qib_pportdata *ppd;
 
-       spin_lock_irqsave(&qib_devs_lock, flags);
-
-       list_for_each_entry(dd, &qib_dev_list, list) {
+       xa_lock_irqsave(&qib_dev_table, flags);
+       xa_for_each(&qib_dev_table, index, dd) {
                nunits++;
                if ((dd->flags & QIB_PRESENT) && dd->kregbase)
                        npresent++;
@@ -142,8 +139,7 @@ int qib_count_units(int *npresentp, int *nupp)
                                nup++;
                }
        }
-
-       spin_unlock_irqrestore(&qib_devs_lock, flags);
+       xa_unlock_irqrestore(&qib_dev_table, flags);
 
        if (npresentp)
                *npresentp = npresent;
index 1d940a2..ceb42d9 100644 (file)
@@ -508,8 +508,8 @@ bail:
  */
 static int qibfs_fill_super(struct super_block *sb, void *data, int silent)
 {
-       struct qib_devdata *dd, *tmp;
-       unsigned long flags;
+       struct qib_devdata *dd;
+       unsigned long index;
        int ret;
 
        static const struct tree_descr files[] = {
@@ -524,18 +524,12 @@ static int qibfs_fill_super(struct super_block *sb, void *data, int silent)
                goto bail;
        }
 
-       spin_lock_irqsave(&qib_devs_lock, flags);
-
-       list_for_each_entry_safe(dd, tmp, &qib_dev_list, list) {
-               spin_unlock_irqrestore(&qib_devs_lock, flags);
+       xa_for_each(&qib_dev_table, index, dd) {
                ret = add_cntr_files(sb, dd);
                if (ret)
                        goto bail;
-               spin_lock_irqsave(&qib_devs_lock, flags);
        }
 
-       spin_unlock_irqrestore(&qib_devs_lock, flags);
-
 bail:
        return ret;
 }
index 17d6b24..5f4aa36 100644 (file)
@@ -6140,7 +6140,7 @@ static void set_no_qsfp_atten(struct qib_devdata *dd, int change)
 static int setup_txselect(const char *str, const struct kernel_param *kp)
 {
        struct qib_devdata *dd;
-       unsigned long val;
+       unsigned long index, val;
        char *n;
 
        if (strlen(str) >= ARRAY_SIZE(txselect_list)) {
@@ -6156,7 +6156,7 @@ static int setup_txselect(const char *str, const struct kernel_param *kp)
        }
        strncpy(txselect_list, str, ARRAY_SIZE(txselect_list) - 1);
 
-       list_for_each_entry(dd, &qib_dev_list, list)
+       xa_for_each(&qib_dev_table, index, dd)
                if (dd->deviceid == PCI_DEVICE_ID_QLOGIC_IB_7322)
                        set_no_qsfp_atten(dd, 1);
        return 0;
index 9fd6990..d4fd8a6 100644 (file)
@@ -36,7 +36,6 @@
 #include <linux/netdevice.h>
 #include <linux/vmalloc.h>
 #include <linux/delay.h>
-#include <linux/idr.h>
 #include <linux/module.h>
 #include <linux/printk.h>
 #ifdef CONFIG_INFINIBAND_QIB_DCA
@@ -95,7 +94,7 @@ MODULE_PARM_DESC(cc_table_size, "Congestion control table entries 0 (CCA disable
 
 static void verify_interrupt(struct timer_list *);
 
-static struct idr qib_unit_table;
+DEFINE_XARRAY_FLAGS(qib_dev_table, XA_FLAGS_ALLOC | XA_FLAGS_LOCK_IRQ);
 u32 qib_cpulist_count;
 unsigned long *qib_cpulist;
 
@@ -785,21 +784,9 @@ void __attribute__((weak)) qib_disable_wc(struct qib_devdata *dd)
 {
 }
 
-static inline struct qib_devdata *__qib_lookup(int unit)
-{
-       return idr_find(&qib_unit_table, unit);
-}
-
 struct qib_devdata *qib_lookup(int unit)
 {
-       struct qib_devdata *dd;
-       unsigned long flags;
-
-       spin_lock_irqsave(&qib_devs_lock, flags);
-       dd = __qib_lookup(unit);
-       spin_unlock_irqrestore(&qib_devs_lock, flags);
-
-       return dd;
+       return xa_load(&qib_dev_table, unit);
 }
 
 /*
@@ -1046,10 +1033,9 @@ void qib_free_devdata(struct qib_devdata *dd)
 {
        unsigned long flags;
 
-       spin_lock_irqsave(&qib_devs_lock, flags);
-       idr_remove(&qib_unit_table, dd->unit);
-       list_del(&dd->list);
-       spin_unlock_irqrestore(&qib_devs_lock, flags);
+       xa_lock_irqsave(&qib_dev_table, flags);
+       __xa_erase(&qib_dev_table, dd->unit);
+       xa_unlock_irqrestore(&qib_dev_table, flags);
 
 #ifdef CONFIG_DEBUG_FS
        qib_dbg_ibdev_exit(&dd->verbs_dev);
@@ -1070,15 +1056,15 @@ u64 qib_int_counter(struct qib_devdata *dd)
 
 u64 qib_sps_ints(void)
 {
-       unsigned long flags;
+       unsigned long index, flags;
        struct qib_devdata *dd;
        u64 sps_ints = 0;
 
-       spin_lock_irqsave(&qib_devs_lock, flags);
-       list_for_each_entry(dd, &qib_dev_list, list) {
+       xa_lock_irqsave(&qib_dev_table, flags);
+       xa_for_each(&qib_dev_table, index, dd) {
                sps_ints += qib_int_counter(dd);
        }
-       spin_unlock_irqrestore(&qib_devs_lock, flags);
+       xa_unlock_irqrestore(&qib_dev_table, flags);
        return sps_ints;
 }
 
@@ -1087,12 +1073,9 @@ u64 qib_sps_ints(void)
  * 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.
  */
 struct qib_devdata *qib_alloc_devdata(struct pci_dev *pdev, size_t extra)
 {
-       unsigned long flags;
        struct qib_devdata *dd;
        int ret, nports;
 
@@ -1103,20 +1086,8 @@ struct qib_devdata *qib_alloc_devdata(struct pci_dev *pdev, size_t extra)
        if (!dd)
                return ERR_PTR(-ENOMEM);
 
-       INIT_LIST_HEAD(&dd->list);
-
-       idr_preload(GFP_KERNEL);
-       spin_lock_irqsave(&qib_devs_lock, flags);
-
-       ret = idr_alloc(&qib_unit_table, dd, 0, 0, GFP_NOWAIT);
-       if (ret >= 0) {
-               dd->unit = ret;
-               list_add(&dd->list, &qib_dev_list);
-       }
-
-       spin_unlock_irqrestore(&qib_devs_lock, flags);
-       idr_preload_end();
-
+       ret = xa_alloc_irq(&qib_dev_table, &dd->unit, dd, xa_limit_32b,
+                       GFP_KERNEL);
        if (ret < 0) {
                qib_early_err(&pdev->dev,
                              "Could not allocate unit ID: error %d\n", -ret);
@@ -1255,8 +1226,6 @@ static int __init qib_ib_init(void)
         * These must be called before the driver is registered with
         * the PCI subsystem.
         */
-       idr_init(&qib_unit_table);
-
 #ifdef CONFIG_INFINIBAND_QIB_DCA
        dca_register_notify(&dca_notifier);
 #endif
@@ -1281,7 +1250,6 @@ bail_dev:
 #ifdef CONFIG_DEBUG_FS
        qib_dbg_exit();
 #endif
-       idr_destroy(&qib_unit_table);
        qib_dev_cleanup();
 bail:
        return ret;
@@ -1313,7 +1281,7 @@ static void __exit qib_ib_cleanup(void)
        qib_cpulist_count = 0;
        kfree(qib_cpulist);
 
-       idr_destroy(&qib_unit_table);
+       WARN_ON(!xa_empty(&qib_dev_table));
        qib_dev_cleanup();
 }