History

net/mlx5: Convert mkey_table to XArray

The lock protecting the data structure does not need to be an rwlock. The only read access to the lock is in an error path, and if that's limiting your scalability, you have bigger performance problems. Eliminate mlx5_mkey_table in favour of using the xarray directly. reg_mr_callback must use GFP_ATOMIC for allocating XArray nodes as it may be called in interrupt context. This also fixes a minor bug where SRCU locking was being used on the radix tree read side, when RCU was needed too.

Matthew Wilcox committed 7 years ago

Commit 792c4e91 parent 82b11f07 files · +31 −60Browse files

Unified · Split

7 files
  1. drivers/infiniband/hw/mlx5/cq.c +4 −4
  2. drivers/infiniband/hw/mlx5/devx.c +4 −14
  3. drivers/infiniband/hw/mlx5/mr.c +5 −5
  4. drivers/infiniband/hw/mlx5/odp.c +5 −5
  5. drivers/net/ethernet/mellanox/mlx5/core/mr.c +11 −16
  6. include/linux/mlx5/driver.h +2 −11
  7. include/linux/mlx5/qp.h +0 −5
drivers/infiniband/hw/mlx5/cq.c+4−4
@@ -522,9 +522,9 @@ repoll: · 521 unmodified lines
522522 case MLX5_CQE_SIG_ERR:
523523 sig_err_cqe = (struct mlx5_sig_err_cqe *)cqe64;
524524
525− read_lock(&dev->mdev->priv.mkey_table.lock);
526− mmkey = __mlx5_mr_lookup(dev->mdev,
527− mlx5_base_mkey(be32_to_cpu(sig_err_cqe->mkey)));
525+ xa_lock(&dev->mdev->priv.mkey_table);
526+ mmkey = xa_load(&dev->mdev->priv.mkey_table,
527+ mlx5_base_mkey(be32_to_cpu(sig_err_cqe->mkey)));
528528 mr = to_mibmr(mmkey);
529529 get_sig_err_item(sig_err_cqe, &mr->sig->err_item);
530530 mr->sig->sig_err_exists = true;
@@ -537,7 +537,7 @@ repoll: · 6 unmodified lines
537537 mr->sig->err_item.expected,
538538 mr->sig->err_item.actual);
539539
540− read_unlock(&dev->mdev->priv.mkey_table.lock);
540+ xa_unlock(&dev->mdev->priv.mkey_table);
541541 goto repoll;
542542 }
543543
drivers/infiniband/hw/mlx5/devx.c+4−14
@@ -1043,13 +1043,10 @@ static int devx_handle_mkey_indirect(struct devx_obj *obj, · 1042 unmodified lines
10431043 struct mlx5_ib_dev *dev,
10441044 void *in, void *out)
10451045 {
1046− struct mlx5_mkey_table *table = &dev->mdev->priv.mkey_table;
10471046 struct mlx5_ib_devx_mr *devx_mr = &obj->devx_mr;
1048− unsigned long flags;
10491047 struct mlx5_core_mkey *mkey;
10501048 void *mkc;
10511049 u8 key;
1052− int err;
10531050
10541051 mkey = &devx_mr->mmkey;
10551052 mkc = MLX5_ADDR_OF(create_mkey_in, in, memory_key_mkey_entry);
@@ -1062,11 +1059,8 @@ static int devx_handle_mkey_indirect(struct devx_obj *obj, · 6 unmodified lines
10621059 mkey->pd = MLX5_GET(mkc, mkc, pd);
10631060 devx_mr->ndescs = MLX5_GET(mkc, mkc, translations_octword_size);
10641061
1065− write_lock_irqsave(&table->lock, flags);
1066− err = radix_tree_insert(&table->tree, mlx5_base_mkey(mkey->key),
1067− mkey);
1068− write_unlock_irqrestore(&table->lock, flags);
1069− return err;
1062+ return xa_err(xa_store(&dev->mdev->priv.mkey_table,
1063+ mlx5_base_mkey(mkey->key), mkey, GFP_KERNEL));
10701064 }
10711065
10721066 static int devx_handle_mkey_create(struct mlx5_ib_dev *dev,
@@ -1117,12 +1111,8 @@ static void devx_free_indirect_mkey(struct rcu_head *rcu) · 44 unmodified lines
11171111 */
11181112 static void devx_cleanup_mkey(struct devx_obj *obj)
11191113 {
1120− struct mlx5_mkey_table *table = &obj->mdev->priv.mkey_table;
1121− unsigned long flags;
1122−
1123− write_lock_irqsave(&table->lock, flags);
1124− radix_tree_delete(&table->tree, mlx5_base_mkey(obj->devx_mr.mmkey.key));
1125− write_unlock_irqrestore(&table->lock, flags);
1114+ xa_erase(&obj->mdev->priv.mkey_table,
1115+ mlx5_base_mkey(obj->devx_mr.mmkey.key));
11261116 }
11271117
11281118 static int devx_obj_cleanup(struct ib_uobject *uobject,
drivers/infiniband/hw/mlx5/mr.c+5−5
@@ -130,7 +130,7 @@ static void reg_mr_callback(int status, struct mlx5_async_work *context) · 129 unmodified lines
130130 struct mlx5_cache_ent *ent = &cache->ent[c];
131131 u8 key;
132132 unsigned long flags;
133− struct mlx5_mkey_table *table = &dev->mdev->priv.mkey_table;
133+ struct xarray *mkeys = &dev->mdev->priv.mkey_table;
134134 int err;
135135
136136 spin_lock_irqsave(&ent->lock, flags);
@@ -158,12 +158,12 @@ static void reg_mr_callback(int status, struct mlx5_async_work *context) · 21 unmodified lines
158158 ent->size++;
159159 spin_unlock_irqrestore(&ent->lock, flags);
160160
161− write_lock_irqsave(&table->lock, flags);
162− err = radix_tree_insert(&table->tree, mlx5_base_mkey(mr->mmkey.key),
163− &mr->mmkey);
161+ xa_lock_irqsave(mkeys, flags);
162+ err = xa_err(__xa_store(mkeys, mlx5_base_mkey(mr->mmkey.key),
163+ &mr->mmkey, GFP_ATOMIC));
164+ xa_unlock_irqrestore(mkeys, flags);
164165 if (err)
165166 pr_err("Error inserting to mkey tree. 0x%x\n", -err);
166− write_unlock_irqrestore(&table->lock, flags);
167167
168168 if (!completion_done(&ent->compl))
169169 complete(&ent->compl);
drivers/infiniband/hw/mlx5/odp.c+5−5
@@ -768,7 +768,7 @@ static int pagefault_single_data_segment(struct mlx5_ib_dev *dev, · 767 unmodified lines
768768 bcnt -= *bytes_committed;
769769
770770 next_mr:
771− mmkey = __mlx5_mr_lookup(dev->mdev, mlx5_base_mkey(key));
771+ mmkey = xa_load(&dev->mdev->priv.mkey_table, mlx5_base_mkey(key));
772772 if (!mkey_is_eq(mmkey, key)) {
773773 mlx5_ib_dbg(dev, "failed to find mkey %x\n", key);
774774 ret = -EFAULT;
@@ -1686,8 +1686,8 @@ static void num_pending_prefetch_dec(struct mlx5_ib_dev *dev, · 911 unmodified lines
16861686 struct mlx5_core_mkey *mmkey;
16871687 struct mlx5_ib_mr *mr;
16881688
1689− mmkey = __mlx5_mr_lookup(dev->mdev,
1690− mlx5_base_mkey(sg_list[i].lkey));
1689+ mmkey = xa_load(&dev->mdev->priv.mkey_table,
1690+ mlx5_base_mkey(sg_list[i].lkey));
16911691 mr = container_of(mmkey, struct mlx5_ib_mr, mmkey);
16921692 atomic_dec(&mr->num_pending_prefetch);
16931693 }
@@ -1706,8 +1706,8 @@ static bool num_pending_prefetch_inc(struct ib_pd *pd, · 12 unmodified lines
17061706 struct mlx5_core_mkey *mmkey;
17071707 struct mlx5_ib_mr *mr;
17081708
1709− mmkey = __mlx5_mr_lookup(dev->mdev,
1710− mlx5_base_mkey(sg_list[i].lkey));
1709+ mmkey = xa_load(&dev->mdev->priv.mkey_table,
1710+ mlx5_base_mkey(sg_list[i].lkey));
17111711 if (!mmkey || mmkey->key != sg_list[i].lkey) {
17121712 ret = false;
17131713 break;
drivers/net/ethernet/mellanox/mlx5/core/mr.c+11−16
@@ -38,15 +38,12 @@ · 37 unmodified lines
3838
3939 void mlx5_init_mkey_table(struct mlx5_core_dev *dev)
4040 {
41− struct mlx5_mkey_table *table = &dev->priv.mkey_table;
42−
43− memset(table, 0, sizeof(*table));
44− rwlock_init(&table->lock);
45− INIT_RADIX_TREE(&table->tree, GFP_ATOMIC);
41+ xa_init_flags(&dev->priv.mkey_table, XA_FLAGS_LOCK_IRQ);
4642 }
4743
4844 void mlx5_cleanup_mkey_table(struct mlx5_core_dev *dev)
4945 {
46+ WARN_ON(!xa_empty(&dev->priv.mkey_table));
5047 }
5148
5249 int mlx5_core_create_mkey_cb(struct mlx5_core_dev *dev,
@@ -56,8 +53,8 @@ int mlx5_core_create_mkey_cb(struct mlx5_core_dev *dev, · 3 unmodified lines
5653 mlx5_async_cbk_t callback,
5754 struct mlx5_async_work *context)
5855 {
59− struct mlx5_mkey_table *table = &dev->priv.mkey_table;
6056 u32 lout[MLX5_ST_SZ_DW(create_mkey_out)] = {0};
57+ struct xarray *mkeys = &dev->priv.mkey_table;
6158 u32 mkey_index;
6259 void *mkc;
6360 int err;
@@ -88,12 +85,10 @@ int mlx5_core_create_mkey_cb(struct mlx5_core_dev *dev, · 24 unmodified lines
8885 mlx5_core_dbg(dev, "out 0x%x, key 0x%x, mkey 0x%x\n",
8986 mkey_index, key, mkey->key);
9087
91− /* connect to mkey tree */
92− write_lock_irq(&table->lock);
93− err = radix_tree_insert(&table->tree, mlx5_base_mkey(mkey->key), mkey);
94− write_unlock_irq(&table->lock);
88+ err = xa_err(xa_store_irq(mkeys, mlx5_base_mkey(mkey->key), mkey,
89+ GFP_KERNEL));
9590 if (err) {
96− mlx5_core_warn(dev, "failed radix tree insert of mkey 0x%x, %d\n",
91+ mlx5_core_warn(dev, "failed xarray insert of mkey 0x%x, %d\n",
9792 mlx5_base_mkey(mkey->key), err);
9893 mlx5_core_destroy_mkey(dev, mkey);
9994 }
@@ -114,17 +109,17 @@ EXPORT_SYMBOL(mlx5_core_create_mkey); · 14 unmodified lines
114109 int mlx5_core_destroy_mkey(struct mlx5_core_dev *dev,
115110 struct mlx5_core_mkey *mkey)
116111 {
117− struct mlx5_mkey_table *table = &dev->priv.mkey_table;
118112 u32 out[MLX5_ST_SZ_DW(destroy_mkey_out)] = {0};
119113 u32 in[MLX5_ST_SZ_DW(destroy_mkey_in)] = {0};
114+ struct xarray *mkeys = &dev->priv.mkey_table;
120115 struct mlx5_core_mkey *deleted_mkey;
121116 unsigned long flags;
122117
123− write_lock_irqsave(&table->lock, flags);
124− deleted_mkey = radix_tree_delete(&table->tree, mlx5_base_mkey(mkey->key));
125− write_unlock_irqrestore(&table->lock, flags);
118+ xa_lock_irqsave(mkeys, flags);
119+ deleted_mkey = __xa_erase(mkeys, mlx5_base_mkey(mkey->key));
120+ xa_unlock_irqrestore(mkeys, flags);
126121 if (!deleted_mkey) {
127− mlx5_core_dbg(dev, "failed radix tree delete of mkey 0x%x\n",
122+ mlx5_core_dbg(dev, "failed xarray delete of mkey 0x%x\n",
128123 mlx5_base_mkey(mkey->key));
129124 return -ENOENT;
130125 }
include/linux/mlx5/driver.h+2−11
@@ -41,7 +41,7 @@ · 40 unmodified lines
4141 #include <linux/semaphore.h>
4242 #include <linux/slab.h>
4343 #include <linux/vmalloc.h>
44−#include <linux/radix-tree.h>
44+#include <linux/xarray.h>
4545 #include <linux/workqueue.h>
4646 #include <linux/mempool.h>
4747 #include <linux/interrupt.h>
@@ -452,13 +452,6 @@ struct mlx5_qp_table { · 404 unmodified lines
452452 struct radix_tree_root tree;
453453 };
454454
455−struct mlx5_mkey_table {
456− /* protect radix tree
457− */
458− rwlock_t lock;
459− struct radix_tree_root tree;
460−};
461−
462455 struct mlx5_vf_context {
463456 int enabled;
464457 u64 port_guid;
@@ -546,9 +539,7 @@ struct mlx5_priv { · 81 unmodified lines
546539 struct dentry *cmdif_debugfs;
547540 /* end: qp staff */
548541
549− /* start: mkey staff */
550− struct mlx5_mkey_table mkey_table;
551− /* end: mkey staff */
542+ struct xarray mkey_table;
552543
553544 /* start: alloc staff */
554545 /* protect buffer alocation according to numa node */
include/linux/mlx5/qp.h+0−5
@@ -551,11 +551,6 @@ static inline struct mlx5_core_qp *__mlx5_qp_lookup(struct mlx5_core_dev *dev, u · 550 unmodified lines
551551 return radix_tree_lookup(&dev->priv.qp_table.tree, qpn);
552552 }
553553
554−static inline struct mlx5_core_mkey *__mlx5_mr_lookup(struct mlx5_core_dev *dev, u32 key)
555−{
556− return radix_tree_lookup(&dev->priv.mkey_table.tree, key);
557−}
558−
559554 int mlx5_core_create_dct(struct mlx5_core_dev *dev,
560555 struct mlx5_core_dct *qp,
561556 u32 *in, int inlen,

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t