diff mbox series

[29/32] ucma: Convert multicast_idr to XArray

Message ID 20190221002107.22625-30-willy@infradead.org (mailing list archive)
State Accepted
Headers show
Series Convert the Infiniband subsystem to XArray | expand

Commit Message

Matthew Wilcox Feb. 21, 2019, 12:21 a.m. UTC
Signed-off-by: Matthew Wilcox <willy@infradead.org>
---
 drivers/infiniband/core/ucma.c | 26 +++++++++-----------------
 1 file changed, 9 insertions(+), 17 deletions(-)

Comments

Jason Gunthorpe Feb. 21, 2019, 6:58 p.m. UTC | #1
On Wed, Feb 20, 2019 at 04:21:04PM -0800, Matthew Wilcox wrote:
> Signed-off-by: Matthew Wilcox <willy@infradead.org>
>  drivers/infiniband/core/ucma.c | 26 +++++++++-----------------
>  1 file changed, 9 insertions(+), 17 deletions(-)
> 
> diff --git a/drivers/infiniband/core/ucma.c b/drivers/infiniband/core/ucma.c
> index 01d68ed46c1b..9a30068d4c1d 100644
> +++ b/drivers/infiniband/core/ucma.c
> @@ -124,7 +124,7 @@ struct ucma_event {
>  
>  static DEFINE_MUTEX(mut);
>  static DEFINE_IDR(ctx_idr);
> -static DEFINE_IDR(multicast_idr);
> +static DEFINE_XARRAY_ALLOC(multicast_table);
>  
>  static const struct file_operations ucma_fops;
>  
> @@ -238,10 +238,7 @@ static struct ucma_multicast* ucma_alloc_multicast(struct ucma_context *ctx)
>  	if (!mc)
>  		return NULL;
>  
> -	mutex_lock(&mut);
> -	mc->id = idr_alloc(&multicast_idr, NULL, 0, 0, GFP_KERNEL);
> -	mutex_unlock(&mut);
> -	if (mc->id < 0)
> +	if (xa_alloc(&multicast_table, &mc->id, NULL, xa_limit_32b, GFP_KERNEL))
>  		goto error;
>  
>  	mc->ctx = ctx;
> @@ -540,7 +537,7 @@ static void ucma_cleanup_multicast(struct ucma_context *ctx)
>  	mutex_lock(&mut);
>  	list_for_each_entry_safe(mc, tmp, &ctx->mc_list, list) {
>  		list_del(&mc->list);
> -		idr_remove(&multicast_idr, mc->id);
> +		xa_erase(&multicast_table, mc->id);
>  		kfree(mc);
>  	}
>  	mutex_unlock(&mut);
> @@ -1425,9 +1422,7 @@ static ssize_t ucma_process_join(struct ucma_file *file,
>  		goto err3;
>  	}
>  
> -	mutex_lock(&mut);
> -	idr_replace(&multicast_idr, mc, mc->id);
> -	mutex_unlock(&mut);
> +	xa_store(&multicast_table, mc->id, mc, 0);
>  
>  	mutex_unlock(&file->mut);
>  	ucma_put_ctx(ctx);
> @@ -1437,9 +1432,7 @@ static ssize_t ucma_process_join(struct ucma_file *file,
>  	rdma_leave_multicast(ctx->cm_id, (struct sockaddr *) &mc->addr);
>  	ucma_cleanup_mc_events(mc);
>  err2:
> -	mutex_lock(&mut);
> -	idr_remove(&multicast_idr, mc->id);
> -	mutex_unlock(&mut);
> +	xa_erase(&multicast_table, mc->id);

IMHO this is a lot clearer written as xa_release(), as it is only
undoing the store of XA_ZERO_ENTRY and that is why we don't need
locking.

> @@ -1501,8 +1494,8 @@ static ssize_t ucma_leave_multicast(struct ucma_file *file,
>  	if (copy_from_user(&cmd, inbuf, sizeof(cmd)))
>  		return -EFAULT;
>  
> -	mutex_lock(&mut);
> -	mc = idr_find(&multicast_idr, cmd.id);

This can run concurrently with ucma_cleanup_multicast, so I don't
think the mut lock can be eliminated here.

Jason
Jason Gunthorpe June 7, 2019, 7:42 p.m. UTC | #2
On Wed, Feb 20, 2019 at 04:21:04PM -0800, Matthew Wilcox wrote:
> Signed-off-by: Matthew Wilcox <willy@infradead.org>
> ---
>  drivers/infiniband/core/ucma.c | 26 +++++++++-----------------
>  1 file changed, 9 insertions(+), 17 deletions(-)

Applied to for-next, but I added these two hunks:

--- a/drivers/infiniband/core/ucma.c
+++ b/drivers/infiniband/core/ucma.c
@@ -104,7 +104,7 @@ struct ucma_context {
 
 struct ucma_multicast {
        struct ucma_context     *ctx;
-       int                     id;
+       u32                     id;
        int                     events_reported;
 
        u64                     uid;
@@ -234,10 +234,10 @@ static struct ucma_multicast* ucma_alloc_multicast(struct ucma_context *ctx)
        if (!mc)
                return NULL;
 
+       mc->ctx = ctx;
        if (xa_alloc(&multicast_table, &mc->id, NULL, xa_limit_32b, GFP_KERNEL))
                goto error;
 
-       mc->ctx = ctx;
        list_add_tail(&mc->list, &ctx->mc_list);
        return mc;

Thanks,
Jason
diff mbox series

Patch

diff --git a/drivers/infiniband/core/ucma.c b/drivers/infiniband/core/ucma.c
index 01d68ed46c1b..9a30068d4c1d 100644
--- a/drivers/infiniband/core/ucma.c
+++ b/drivers/infiniband/core/ucma.c
@@ -124,7 +124,7 @@  struct ucma_event {
 
 static DEFINE_MUTEX(mut);
 static DEFINE_IDR(ctx_idr);
-static DEFINE_IDR(multicast_idr);
+static DEFINE_XARRAY_ALLOC(multicast_table);
 
 static const struct file_operations ucma_fops;
 
@@ -238,10 +238,7 @@  static struct ucma_multicast* ucma_alloc_multicast(struct ucma_context *ctx)
 	if (!mc)
 		return NULL;
 
-	mutex_lock(&mut);
-	mc->id = idr_alloc(&multicast_idr, NULL, 0, 0, GFP_KERNEL);
-	mutex_unlock(&mut);
-	if (mc->id < 0)
+	if (xa_alloc(&multicast_table, &mc->id, NULL, xa_limit_32b, GFP_KERNEL))
 		goto error;
 
 	mc->ctx = ctx;
@@ -540,7 +537,7 @@  static void ucma_cleanup_multicast(struct ucma_context *ctx)
 	mutex_lock(&mut);
 	list_for_each_entry_safe(mc, tmp, &ctx->mc_list, list) {
 		list_del(&mc->list);
-		idr_remove(&multicast_idr, mc->id);
+		xa_erase(&multicast_table, mc->id);
 		kfree(mc);
 	}
 	mutex_unlock(&mut);
@@ -1425,9 +1422,7 @@  static ssize_t ucma_process_join(struct ucma_file *file,
 		goto err3;
 	}
 
-	mutex_lock(&mut);
-	idr_replace(&multicast_idr, mc, mc->id);
-	mutex_unlock(&mut);
+	xa_store(&multicast_table, mc->id, mc, 0);
 
 	mutex_unlock(&file->mut);
 	ucma_put_ctx(ctx);
@@ -1437,9 +1432,7 @@  static ssize_t ucma_process_join(struct ucma_file *file,
 	rdma_leave_multicast(ctx->cm_id, (struct sockaddr *) &mc->addr);
 	ucma_cleanup_mc_events(mc);
 err2:
-	mutex_lock(&mut);
-	idr_remove(&multicast_idr, mc->id);
-	mutex_unlock(&mut);
+	xa_erase(&multicast_table, mc->id);
 	list_del(&mc->list);
 	kfree(mc);
 err1:
@@ -1501,8 +1494,8 @@  static ssize_t ucma_leave_multicast(struct ucma_file *file,
 	if (copy_from_user(&cmd, inbuf, sizeof(cmd)))
 		return -EFAULT;
 
-	mutex_lock(&mut);
-	mc = idr_find(&multicast_idr, cmd.id);
+	xa_lock(&multicast_table);
+	mc = xa_load(&multicast_table, cmd.id);
 	if (!mc)
 		mc = ERR_PTR(-ENOENT);
 	else if (mc->ctx->file != file)
@@ -1510,8 +1503,8 @@  static ssize_t ucma_leave_multicast(struct ucma_file *file,
 	else if (!atomic_inc_not_zero(&mc->ctx->ref))
 		mc = ERR_PTR(-ENXIO);
 	else
-		idr_remove(&multicast_idr, mc->id);
-	mutex_unlock(&mut);
+		__xa_erase(&multicast_table, mc->id);
+	xa_unlock(&multicast_table);
 
 	if (IS_ERR(mc)) {
 		ret = PTR_ERR(mc);
@@ -1840,7 +1833,6 @@  static void __exit ucma_cleanup(void)
 	device_remove_file(ucma_misc.this_device, &dev_attr_abi_version);
 	misc_deregister(&ucma_misc);
 	idr_destroy(&ctx_idr);
-	idr_destroy(&multicast_idr);
 }
 
 module_init(ucma_init);