#include <linux/file.h>
 #include <linux/mount.h>
 #include <linux/cdev.h>
-#include <linux/idr.h>
+#include <linux/xarray.h>
 #include <linux/mutex.h>
 #include <linux/slab.h>
 
        .remove = ib_ucm_remove_one
 };
 
-static DEFINE_MUTEX(ctx_id_mutex);
-static DEFINE_IDR(ctx_id_table);
+static DEFINE_XARRAY_ALLOC(ctx_id_table);
 static DECLARE_BITMAP(dev_map, IB_UCM_MAX_DEVICES);
 
 static struct ib_ucm_context *ib_ucm_ctx_get(struct ib_ucm_file *file, int id)
 {
        struct ib_ucm_context *ctx;
 
-       mutex_lock(&ctx_id_mutex);
-       ctx = idr_find(&ctx_id_table, id);
+       xa_lock(&ctx_id_table);
+       ctx = xa_load(&ctx_id_table, id);
        if (!ctx)
                ctx = ERR_PTR(-ENOENT);
        else if (ctx->file != file)
                ctx = ERR_PTR(-EINVAL);
        else
                atomic_inc(&ctx->ref);
-       mutex_unlock(&ctx_id_mutex);
+       xa_unlock(&ctx_id_table);
 
        return ctx;
 }
        ctx->file = file;
        INIT_LIST_HEAD(&ctx->events);
 
-       mutex_lock(&ctx_id_mutex);
-       ctx->id = idr_alloc(&ctx_id_table, ctx, 0, 0, GFP_KERNEL);
-       mutex_unlock(&ctx_id_mutex);
-       if (ctx->id < 0)
+       if (xa_alloc(&ctx_id_table, &ctx->id, ctx, xa_limit_32b, GFP_KERNEL))
                goto error;
 
        list_add_tail(&ctx->file_list, &file->ctxs);
 err2:
        ib_destroy_cm_id(ctx->cm_id);
 err1:
-       mutex_lock(&ctx_id_mutex);
-       idr_remove(&ctx_id_table, ctx->id);
-       mutex_unlock(&ctx_id_mutex);
+       xa_erase(&ctx_id_table, ctx->id);
        kfree(ctx);
        return result;
 }
        if (copy_from_user(&cmd, inbuf, sizeof(cmd)))
                return -EFAULT;
 
-       mutex_lock(&ctx_id_mutex);
-       ctx = idr_find(&ctx_id_table, cmd.id);
+       xa_lock(&ctx_id_table);
+       ctx = xa_load(&ctx_id_table, cmd.id);
        if (!ctx)
                ctx = ERR_PTR(-ENOENT);
        else if (ctx->file != file)
                ctx = ERR_PTR(-EINVAL);
        else
-               idr_remove(&ctx_id_table, ctx->id);
-       mutex_unlock(&ctx_id_mutex);
+               __xa_erase(&ctx_id_table, ctx->id);
+       xa_unlock(&ctx_id_table);
 
        if (IS_ERR(ctx))
                return PTR_ERR(ctx);
                                 struct ib_ucm_context, file_list);
                mutex_unlock(&file->file_mutex);
 
-               mutex_lock(&ctx_id_mutex);
-               idr_remove(&ctx_id_table, ctx->id);
-               mutex_unlock(&ctx_id_mutex);
-
+               xa_erase(&ctx_id_table, ctx->id);
                ib_destroy_cm_id(ctx->cm_id);
                ib_ucm_cleanup_events(ctx);
                kfree(ctx);
        class_remove_file(&cm_class, &class_attr_abi_version.attr);
        unregister_chrdev_region(IB_UCM_BASE_DEV, IB_UCM_NUM_FIXED_MINOR);
        unregister_chrdev_region(dynamic_ucm_dev, IB_UCM_NUM_DYNAMIC_MINOR);
-       idr_destroy(&ctx_id_table);
+       WARN_ON(!xa_empty(&ctx_id_table));
 }
 
 module_init(ib_ucm_init);