case MLX5_CQE_SIG_ERR:
                sig_err_cqe = (struct mlx5_sig_err_cqe *)cqe64;
 
-               read_lock(&dev->mdev->priv.mkey_table.lock);
-               mmkey = __mlx5_mr_lookup(dev->mdev,
-                                        mlx5_base_mkey(be32_to_cpu(sig_err_cqe->mkey)));
+               xa_lock(&dev->mdev->priv.mkey_table);
+               mmkey = xa_load(&dev->mdev->priv.mkey_table,
+                               mlx5_base_mkey(be32_to_cpu(sig_err_cqe->mkey)));
                mr = to_mibmr(mmkey);
                get_sig_err_item(sig_err_cqe, &mr->sig->err_item);
                mr->sig->sig_err_exists = true;
                             mr->sig->err_item.expected,
                             mr->sig->err_item.actual);
 
-               read_unlock(&dev->mdev->priv.mkey_table.lock);
+               xa_unlock(&dev->mdev->priv.mkey_table);
                goto repoll;
        }
 
 
                                     struct mlx5_ib_dev *dev,
                                     void *in, void *out)
 {
-       struct mlx5_mkey_table *table = &dev->mdev->priv.mkey_table;
        struct mlx5_ib_devx_mr *devx_mr = &obj->devx_mr;
-       unsigned long flags;
        struct mlx5_core_mkey *mkey;
        void *mkc;
        u8 key;
-       int err;
 
        mkey = &devx_mr->mmkey;
        mkc = MLX5_ADDR_OF(create_mkey_in, in, memory_key_mkey_entry);
        mkey->pd = MLX5_GET(mkc, mkc, pd);
        devx_mr->ndescs = MLX5_GET(mkc, mkc, translations_octword_size);
 
-       write_lock_irqsave(&table->lock, flags);
-       err = radix_tree_insert(&table->tree, mlx5_base_mkey(mkey->key),
-                               mkey);
-       write_unlock_irqrestore(&table->lock, flags);
-       return err;
+       return xa_err(xa_store(&dev->mdev->priv.mkey_table,
+                              mlx5_base_mkey(mkey->key), mkey, GFP_KERNEL));
 }
 
 static int devx_handle_mkey_create(struct mlx5_ib_dev *dev,
  */
 static void devx_cleanup_mkey(struct devx_obj *obj)
 {
-       struct mlx5_mkey_table *table = &obj->mdev->priv.mkey_table;
-       unsigned long flags;
-
-       write_lock_irqsave(&table->lock, flags);
-       radix_tree_delete(&table->tree, mlx5_base_mkey(obj->devx_mr.mmkey.key));
-       write_unlock_irqrestore(&table->lock, flags);
+       xa_erase(&obj->mdev->priv.mkey_table,
+                mlx5_base_mkey(obj->devx_mr.mmkey.key));
 }
 
 static int devx_obj_cleanup(struct ib_uobject *uobject,
 
        struct mlx5_cache_ent *ent = &cache->ent[c];
        u8 key;
        unsigned long flags;
-       struct mlx5_mkey_table *table = &dev->mdev->priv.mkey_table;
+       struct xarray *mkeys = &dev->mdev->priv.mkey_table;
        int err;
 
        spin_lock_irqsave(&ent->lock, flags);
        ent->size++;
        spin_unlock_irqrestore(&ent->lock, flags);
 
-       write_lock_irqsave(&table->lock, flags);
-       err = radix_tree_insert(&table->tree, mlx5_base_mkey(mr->mmkey.key),
-                               &mr->mmkey);
+       xa_lock_irqsave(mkeys, flags);
+       err = xa_err(__xa_store(mkeys, mlx5_base_mkey(mr->mmkey.key),
+                               &mr->mmkey, GFP_ATOMIC));
+       xa_unlock_irqrestore(mkeys, flags);
        if (err)
                pr_err("Error inserting to mkey tree. 0x%x\n", -err);
-       write_unlock_irqrestore(&table->lock, flags);
 
        if (!completion_done(&ent->compl))
                complete(&ent->compl);
 
        bcnt -= *bytes_committed;
 
 next_mr:
-       mmkey = __mlx5_mr_lookup(dev->mdev, mlx5_base_mkey(key));
+       mmkey = xa_load(&dev->mdev->priv.mkey_table, mlx5_base_mkey(key));
        if (!mkey_is_eq(mmkey, key)) {
                mlx5_ib_dbg(dev, "failed to find mkey %x\n", key);
                ret = -EFAULT;
                struct mlx5_core_mkey *mmkey;
                struct mlx5_ib_mr *mr;
 
-               mmkey = __mlx5_mr_lookup(dev->mdev,
-                                        mlx5_base_mkey(sg_list[i].lkey));
+               mmkey = xa_load(&dev->mdev->priv.mkey_table,
+                               mlx5_base_mkey(sg_list[i].lkey));
                mr = container_of(mmkey, struct mlx5_ib_mr, mmkey);
                atomic_dec(&mr->num_pending_prefetch);
        }
                struct mlx5_core_mkey *mmkey;
                struct mlx5_ib_mr *mr;
 
-               mmkey = __mlx5_mr_lookup(dev->mdev,
-                                        mlx5_base_mkey(sg_list[i].lkey));
+               mmkey = xa_load(&dev->mdev->priv.mkey_table,
+                               mlx5_base_mkey(sg_list[i].lkey));
                if (!mmkey || mmkey->key != sg_list[i].lkey) {
                        ret = false;
                        break;
 
 
 void mlx5_init_mkey_table(struct mlx5_core_dev *dev)
 {
-       struct mlx5_mkey_table *table = &dev->priv.mkey_table;
-
-       memset(table, 0, sizeof(*table));
-       rwlock_init(&table->lock);
-       INIT_RADIX_TREE(&table->tree, GFP_ATOMIC);
+       xa_init_flags(&dev->priv.mkey_table, XA_FLAGS_LOCK_IRQ);
 }
 
 void mlx5_cleanup_mkey_table(struct mlx5_core_dev *dev)
 {
+       WARN_ON(!xa_empty(&dev->priv.mkey_table));
 }
 
 int mlx5_core_create_mkey_cb(struct mlx5_core_dev *dev,
                             mlx5_async_cbk_t callback,
                             struct mlx5_async_work *context)
 {
-       struct mlx5_mkey_table *table = &dev->priv.mkey_table;
        u32 lout[MLX5_ST_SZ_DW(create_mkey_out)] = {0};
+       struct xarray *mkeys = &dev->priv.mkey_table;
        u32 mkey_index;
        void *mkc;
        int err;
        mlx5_core_dbg(dev, "out 0x%x, key 0x%x, mkey 0x%x\n",
                      mkey_index, key, mkey->key);
 
-       /* connect to mkey tree */
-       write_lock_irq(&table->lock);
-       err = radix_tree_insert(&table->tree, mlx5_base_mkey(mkey->key), mkey);
-       write_unlock_irq(&table->lock);
+       err = xa_err(xa_store_irq(mkeys, mlx5_base_mkey(mkey->key), mkey,
+                                 GFP_KERNEL));
        if (err) {
-               mlx5_core_warn(dev, "failed radix tree insert of mkey 0x%x, %d\n",
+               mlx5_core_warn(dev, "failed xarray insert of mkey 0x%x, %d\n",
                               mlx5_base_mkey(mkey->key), err);
                mlx5_core_destroy_mkey(dev, mkey);
        }
 int mlx5_core_destroy_mkey(struct mlx5_core_dev *dev,
                           struct mlx5_core_mkey *mkey)
 {
-       struct mlx5_mkey_table *table = &dev->priv.mkey_table;
        u32 out[MLX5_ST_SZ_DW(destroy_mkey_out)] = {0};
        u32 in[MLX5_ST_SZ_DW(destroy_mkey_in)]   = {0};
+       struct xarray *mkeys = &dev->priv.mkey_table;
        struct mlx5_core_mkey *deleted_mkey;
        unsigned long flags;
 
-       write_lock_irqsave(&table->lock, flags);
-       deleted_mkey = radix_tree_delete(&table->tree, mlx5_base_mkey(mkey->key));
-       write_unlock_irqrestore(&table->lock, flags);
+       xa_lock_irqsave(mkeys, flags);
+       deleted_mkey = __xa_erase(mkeys, mlx5_base_mkey(mkey->key));
+       xa_unlock_irqrestore(mkeys, flags);
        if (!deleted_mkey) {
-               mlx5_core_dbg(dev, "failed radix tree delete of mkey 0x%x\n",
+               mlx5_core_dbg(dev, "failed xarray delete of mkey 0x%x\n",
                              mlx5_base_mkey(mkey->key));
                return -ENOENT;
        }
 
 #include <linux/semaphore.h>
 #include <linux/slab.h>
 #include <linux/vmalloc.h>
-#include <linux/radix-tree.h>
+#include <linux/xarray.h>
 #include <linux/workqueue.h>
 #include <linux/mempool.h>
 #include <linux/interrupt.h>
        struct radix_tree_root  tree;
 };
 
-struct mlx5_mkey_table {
-       /* protect radix tree
-        */
-       rwlock_t                lock;
-       struct radix_tree_root  tree;
-};
-
 struct mlx5_vf_context {
        int     enabled;
        u64     port_guid;
        struct dentry          *cmdif_debugfs;
        /* end: qp staff */
 
-       /* start: mkey staff */
-       struct mlx5_mkey_table  mkey_table;
-       /* end: mkey staff */
+       struct xarray           mkey_table;
 
        /* start: alloc staff */
        /* protect buffer alocation according to numa node */
 
        return radix_tree_lookup(&dev->priv.qp_table.tree, qpn);
 }
 
-static inline struct mlx5_core_mkey *__mlx5_mr_lookup(struct mlx5_core_dev *dev, u32 key)
-{
-       return radix_tree_lookup(&dev->priv.mkey_table.tree, key);
-}
-
 int mlx5_core_create_dct(struct mlx5_core_dev *dev,
                         struct mlx5_core_dct *qp,
                         u32 *in, int inlen,