]> www.infradead.org Git - users/willy/xarray.git/commitdiff
cxl: Convert contexts_idr to XArray
authorMatthew Wilcox <willy@infradead.org>
Tue, 12 Feb 2019 21:11:40 +0000 (16:11 -0500)
committerMatthew Wilcox (Oracle) <willy@infradead.org>
Fri, 9 Aug 2019 01:38:16 +0000 (21:38 -0400)
Signed-off-by: Matthew Wilcox <willy@infradead.org>
drivers/misc/cxl/context.c
drivers/misc/cxl/cxl.h
drivers/misc/cxl/guest.c
drivers/misc/cxl/main.c
drivers/misc/cxl/native.c
drivers/misc/cxl/pci.c
drivers/misc/cxl/sysfs.c

index aed9c445d1e2c4d905ae71415b3037a811483a82..11c648a265afac8c0ff419c5604dfaee0f9d4101 100644 (file)
@@ -12,8 +12,8 @@
 #include <linux/mm.h>
 #include <linux/debugfs.h>
 #include <linux/slab.h>
-#include <linux/idr.h>
 #include <linux/sched/mm.h>
+#include <linux/xarray.h>
 #include <linux/mmu_context.h>
 #include <asm/cputable.h>
 #include <asm/current.h>
@@ -72,11 +72,11 @@ int cxl_context_init(struct cxl_context *ctx, struct cxl_afu *afu, bool master)
        INIT_LIST_HEAD(&ctx->irq_names);
 
        /*
-        * When we have to destroy all contexts in cxl_context_detach_all() we
-        * end up with afu_release_irqs() called from inside a
-        * idr_for_each_entry(). Hence we need to make sure that anything
-        * dereferenced from this IDR is ok before we allocate the IDR here.
-        * This clears out the IRQ ranges to ensure this.
+        * When we have to destroy all contexts in cxl_context_detach_all()
+        * we end up with afu_release_irqs() called from inside a
+        * xa_for_each loop. Hence we need to make sure that anything
+        * dereferenced from this context is ok before we store it in the
+        * array.  This clears out the IRQ ranges to ensure this.
         */
        for (i = 0; i < CXL_IRQ_RANGES; i++)
                ctx->irqs.range[i] = 0;
@@ -85,20 +85,14 @@ int cxl_context_init(struct cxl_context *ctx, struct cxl_afu *afu, bool master)
 
        ctx->status = OPENED;
 
-       /*
-        * Allocating IDR! We better make sure everything's setup that
-        * dereferences from it.
-        */
+       /* Prevent resets and mode changes */
        mutex_lock(&afu->contexts_lock);
-       idr_preload(GFP_KERNEL);
-       i = idr_alloc(&ctx->afu->contexts_idr, ctx, 0,
-                     ctx->afu->num_procs, GFP_NOWAIT);
-       idr_preload_end();
+       i = xa_alloc(&ctx->afu->contexts, &ctx->pe, ctx,
+                       XA_LIMIT(0, ctx->afu->num_procs), GFP_KERNEL);
        mutex_unlock(&afu->contexts_lock);
        if (i < 0)
                return i;
 
-       ctx->pe = i;
        if (cpu_has_feature(CPU_FTR_HVMODE)) {
                ctx->elem = &ctx->afu->native->spa[i];
                ctx->external_pe = ctx->pe;
@@ -297,13 +291,12 @@ void cxl_context_detach(struct cxl_context *ctx)
 void cxl_context_detach_all(struct cxl_afu *afu)
 {
        struct cxl_context *ctx;
-       int tmp;
+       unsigned long index;
 
-       mutex_lock(&afu->contexts_lock);
-       idr_for_each_entry(&afu->contexts_idr, ctx, tmp) {
+       xa_for_each(&afu->contexts, index, ctx) {
                /*
-                * Anything done in here needs to be setup before the IDR is
-                * created and torn down after the IDR removed
+                * Anything done in here needs to be setup before the context
+                * is added to the array and torn down after it is removed
                 */
                cxl_context_detach(ctx);
 
@@ -318,7 +311,6 @@ void cxl_context_detach_all(struct cxl_afu *afu)
                        unmap_mapping_range(ctx->mapping, 0, 0, 1);
                mutex_unlock(&ctx->mapping_lock);
        }
-       mutex_unlock(&afu->contexts_lock);
 }
 
 static void reclaim_ctx(struct rcu_head *rcu)
@@ -343,9 +335,7 @@ void cxl_context_free(struct cxl_context *ctx)
 {
        if (ctx->kernelapi && ctx->mapping)
                cxl_release_mapping(ctx);
-       mutex_lock(&ctx->afu->contexts_lock);
-       idr_remove(&ctx->afu->contexts_idr, ctx->pe);
-       mutex_unlock(&ctx->afu->contexts_lock);
+       xa_erase(&ctx->afu->contexts, ctx->pe);
        call_rcu(&ctx->rcu, reclaim_ctx);
 }
 
index 5dc0f6093f9d92aa267c1f733cc39c848900c3f2..b66c61801a3a865c555cc5b75777ab519b6afa5e 100644 (file)
@@ -15,6 +15,7 @@
 #include <linux/io.h>
 #include <linux/pci.h>
 #include <linux/fs.h>
+#include <linux/xarray.h>
 #include <asm/cputable.h>
 #include <asm/mmu.h>
 #include <asm/reg.h>
@@ -487,7 +488,7 @@ struct cxl_afu {
        struct device dev;
        struct cdev afu_cdev_s, afu_cdev_m, afu_cdev_d;
        struct device *chardev_s, *chardev_m, *chardev_d;
-       struct idr contexts_idr;
+       struct xarray contexts;
        struct dentry *debugfs;
        struct mutex contexts_lock;
        spinlock_t afu_cntl_lock;
index 186308f1f8eba38ba09a8d511114b8ee0e845d78..47d5511eb3dbe8f745b6cca985fdd4c7741934df 100644 (file)
@@ -659,8 +659,6 @@ static void guest_release_afu(struct device *dev)
 
        pr_devel("%s\n", __func__);
 
-       idr_destroy(&afu->contexts_idr);
-
        kfree(afu->guest);
        kfree(afu);
 }
index 482a2c1b340a037fa774b5cdd31862bc192a03b6..5fddec36b945af30262b09435d59d23f78f05245 100644 (file)
@@ -76,7 +76,8 @@ static inline void cxl_slbia_core(struct mm_struct *mm)
        struct cxl *adapter;
        struct cxl_afu *afu;
        struct cxl_context *ctx;
-       int card, slice, id;
+       unsigned long index;
+       int card, slice;
 
        pr_devel("%s called\n", __func__);
 
@@ -88,10 +89,8 @@ static inline void cxl_slbia_core(struct mm_struct *mm)
                        afu = adapter->afu[slice];
                        if (!afu || !afu->enabled)
                                continue;
-                       rcu_read_lock();
-                       idr_for_each_entry(&afu->contexts_idr, ctx, id)
+                       xa_for_each(&afu->contexts, index, ctx)
                                _cxl_slbia(ctx, mm);
-                       rcu_read_unlock();
                }
                spin_unlock(&adapter->afu_list_lock);
        }
@@ -250,7 +249,7 @@ struct cxl_afu *cxl_alloc_afu(struct cxl *adapter, int slice)
        afu->dev.parent = &adapter->dev;
        afu->dev.release = cxl_ops->release_afu;
        afu->slice = slice;
-       idr_init(&afu->contexts_idr);
+       xa_init_flags(&afu->contexts, XA_FLAGS_ALLOC);
        mutex_init(&afu->contexts_lock);
        spin_lock_init(&afu->afu_cntl_lock);
        atomic_set(&afu->configured_state, -1);
index 1a7f228360416de9e72ee024dc6dd76f42ab35bd..bd22c6b02857a5c76e91b2fad4cde7b3f3855389 100644 (file)
@@ -1195,7 +1195,7 @@ static irqreturn_t native_irq_multiplexed(int irq, void *data)
        }
 
        rcu_read_lock();
-       ctx = idr_find(&afu->contexts_idr, ph);
+       ctx = xa_load(&afu->contexts, ph);
        if (ctx) {
                if (afu->adapter->native->sl_ops->handle_interrupt)
                        ret = afu->adapter->native->sl_ops->handle_interrupt(irq, ctx, &irq_info);
index 25a9dd9c0c1b5ad6b52bb3b3c262e126066ff9a7..74597685db8a6f99a5fe0ba6010a51ddee7cc6e9 100644 (file)
@@ -831,7 +831,6 @@ void cxl_pci_release_afu(struct device *dev)
 
        pr_devel("%s\n", __func__);
 
-       idr_destroy(&afu->contexts_idr);
        cxl_release_spa(afu);
 
        kfree(afu->native);
index f0263d1a1fdf270facb6c30b3403395d95cb635d..6bea1abad436580318ee95e441a0ae2735715ef9 100644 (file)
@@ -253,7 +253,7 @@ static ssize_t reset_store_afu(struct device *device,
 
        /* Not safe to reset if it is currently in use */
        mutex_lock(&afu->contexts_lock);
-       if (!idr_is_empty(&afu->contexts_idr)) {
+       if (!xa_empty(&afu->contexts)) {
                rc = -EBUSY;
                goto err;
        }
@@ -393,7 +393,7 @@ static ssize_t mode_store(struct device *device, struct device_attribute *attr,
 
        /* can't change this if we have a user */
        mutex_lock(&afu->contexts_lock);
-       if (!idr_is_empty(&afu->contexts_idr))
+       if (!xa_empty(&afu->contexts))
                goto err;
 
        if (!strncmp(buf, "dedicated_process", 17))