From: Matthew Wilcox Date: Tue, 12 Feb 2019 21:11:40 +0000 (-0500) Subject: cxl: Convert contexts_idr to XArray X-Git-Url: https://www.infradead.org/git/?a=commitdiff_plain;h=6e4e89704a1022fa3e551f64b406711d60801fcf;p=users%2Fwilly%2Fxarray.git cxl: Convert contexts_idr to XArray Signed-off-by: Matthew Wilcox --- diff --git a/drivers/misc/cxl/context.c b/drivers/misc/cxl/context.c index aed9c445d1e2..11c648a265af 100644 --- a/drivers/misc/cxl/context.c +++ b/drivers/misc/cxl/context.c @@ -12,8 +12,8 @@ #include #include #include -#include #include +#include #include #include #include @@ -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); } diff --git a/drivers/misc/cxl/cxl.h b/drivers/misc/cxl/cxl.h index 5dc0f6093f9d..b66c61801a3a 100644 --- a/drivers/misc/cxl/cxl.h +++ b/drivers/misc/cxl/cxl.h @@ -15,6 +15,7 @@ #include #include #include +#include #include #include #include @@ -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; diff --git a/drivers/misc/cxl/guest.c b/drivers/misc/cxl/guest.c index 186308f1f8eb..47d5511eb3db 100644 --- a/drivers/misc/cxl/guest.c +++ b/drivers/misc/cxl/guest.c @@ -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); } diff --git a/drivers/misc/cxl/main.c b/drivers/misc/cxl/main.c index 482a2c1b340a..5fddec36b945 100644 --- a/drivers/misc/cxl/main.c +++ b/drivers/misc/cxl/main.c @@ -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); diff --git a/drivers/misc/cxl/native.c b/drivers/misc/cxl/native.c index 1a7f22836041..bd22c6b02857 100644 --- a/drivers/misc/cxl/native.c +++ b/drivers/misc/cxl/native.c @@ -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); diff --git a/drivers/misc/cxl/pci.c b/drivers/misc/cxl/pci.c index 25a9dd9c0c1b..74597685db8a 100644 --- a/drivers/misc/cxl/pci.c +++ b/drivers/misc/cxl/pci.c @@ -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); diff --git a/drivers/misc/cxl/sysfs.c b/drivers/misc/cxl/sysfs.c index f0263d1a1fdf..6bea1abad436 100644 --- a/drivers/misc/cxl/sysfs.c +++ b/drivers/misc/cxl/sysfs.c @@ -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))