aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/infiniband/hw/mlx5/mr.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/infiniband/hw/mlx5/mr.c')
-rw-r--r--drivers/infiniband/hw/mlx5/mr.c167
1 files changed, 122 insertions, 45 deletions
diff --git a/drivers/infiniband/hw/mlx5/mr.c b/drivers/infiniband/hw/mlx5/mr.c
index 3453580b1eb2..039c3e40fcb4 100644
--- a/drivers/infiniband/hw/mlx5/mr.c
+++ b/drivers/infiniband/hw/mlx5/mr.c
@@ -35,11 +35,12 @@
35#include <linux/random.h> 35#include <linux/random.h>
36#include <linux/debugfs.h> 36#include <linux/debugfs.h>
37#include <linux/export.h> 37#include <linux/export.h>
38#include <linux/delay.h>
38#include <rdma/ib_umem.h> 39#include <rdma/ib_umem.h>
39#include "mlx5_ib.h" 40#include "mlx5_ib.h"
40 41
41enum { 42enum {
42 DEF_CACHE_SIZE = 10, 43 MAX_PENDING_REG_MR = 8,
43}; 44};
44 45
45enum { 46enum {
@@ -63,6 +64,51 @@ static int order2idx(struct mlx5_ib_dev *dev, int order)
63 return order - cache->ent[0].order; 64 return order - cache->ent[0].order;
64} 65}
65 66
67static void reg_mr_callback(int status, void *context)
68{
69 struct mlx5_ib_mr *mr = context;
70 struct mlx5_ib_dev *dev = mr->dev;
71 struct mlx5_mr_cache *cache = &dev->cache;
72 int c = order2idx(dev, mr->order);
73 struct mlx5_cache_ent *ent = &cache->ent[c];
74 u8 key;
75 unsigned long flags;
76
77 spin_lock_irqsave(&ent->lock, flags);
78 ent->pending--;
79 spin_unlock_irqrestore(&ent->lock, flags);
80 if (status) {
81 mlx5_ib_warn(dev, "async reg mr failed. status %d\n", status);
82 kfree(mr);
83 dev->fill_delay = 1;
84 mod_timer(&dev->delay_timer, jiffies + HZ);
85 return;
86 }
87
88 if (mr->out.hdr.status) {
89 mlx5_ib_warn(dev, "failed - status %d, syndorme 0x%x\n",
90 mr->out.hdr.status,
91 be32_to_cpu(mr->out.hdr.syndrome));
92 kfree(mr);
93 dev->fill_delay = 1;
94 mod_timer(&dev->delay_timer, jiffies + HZ);
95 return;
96 }
97
98 spin_lock_irqsave(&dev->mdev.priv.mkey_lock, flags);
99 key = dev->mdev.priv.mkey_key++;
100 spin_unlock_irqrestore(&dev->mdev.priv.mkey_lock, flags);
101 mr->mmr.key = mlx5_idx_to_mkey(be32_to_cpu(mr->out.mkey) & 0xffffff) | key;
102
103 cache->last_add = jiffies;
104
105 spin_lock_irqsave(&ent->lock, flags);
106 list_add_tail(&mr->list, &ent->head);
107 ent->cur++;
108 ent->size++;
109 spin_unlock_irqrestore(&ent->lock, flags);
110}
111
66static int add_keys(struct mlx5_ib_dev *dev, int c, int num) 112static int add_keys(struct mlx5_ib_dev *dev, int c, int num)
67{ 113{
68 struct mlx5_mr_cache *cache = &dev->cache; 114 struct mlx5_mr_cache *cache = &dev->cache;
@@ -78,36 +124,39 @@ static int add_keys(struct mlx5_ib_dev *dev, int c, int num)
78 return -ENOMEM; 124 return -ENOMEM;
79 125
80 for (i = 0; i < num; i++) { 126 for (i = 0; i < num; i++) {
127 if (ent->pending >= MAX_PENDING_REG_MR) {
128 err = -EAGAIN;
129 break;
130 }
131
81 mr = kzalloc(sizeof(*mr), GFP_KERNEL); 132 mr = kzalloc(sizeof(*mr), GFP_KERNEL);
82 if (!mr) { 133 if (!mr) {
83 err = -ENOMEM; 134 err = -ENOMEM;
84 goto out; 135 break;
85 } 136 }
86 mr->order = ent->order; 137 mr->order = ent->order;
87 mr->umred = 1; 138 mr->umred = 1;
139 mr->dev = dev;
88 in->seg.status = 1 << 6; 140 in->seg.status = 1 << 6;
89 in->seg.xlt_oct_size = cpu_to_be32((npages + 1) / 2); 141 in->seg.xlt_oct_size = cpu_to_be32((npages + 1) / 2);
90 in->seg.qpn_mkey7_0 = cpu_to_be32(0xffffff << 8); 142 in->seg.qpn_mkey7_0 = cpu_to_be32(0xffffff << 8);
91 in->seg.flags = MLX5_ACCESS_MODE_MTT | MLX5_PERM_UMR_EN; 143 in->seg.flags = MLX5_ACCESS_MODE_MTT | MLX5_PERM_UMR_EN;
92 in->seg.log2_page_size = 12; 144 in->seg.log2_page_size = 12;
93 145
146 spin_lock_irq(&ent->lock);
147 ent->pending++;
148 spin_unlock_irq(&ent->lock);
149 mr->start = jiffies;
94 err = mlx5_core_create_mkey(&dev->mdev, &mr->mmr, in, 150 err = mlx5_core_create_mkey(&dev->mdev, &mr->mmr, in,
95 sizeof(*in)); 151 sizeof(*in), reg_mr_callback,
152 mr, &mr->out);
96 if (err) { 153 if (err) {
97 mlx5_ib_warn(dev, "create mkey failed %d\n", err); 154 mlx5_ib_warn(dev, "create mkey failed %d\n", err);
98 kfree(mr); 155 kfree(mr);
99 goto out; 156 break;
100 } 157 }
101 cache->last_add = jiffies;
102
103 spin_lock(&ent->lock);
104 list_add_tail(&mr->list, &ent->head);
105 ent->cur++;
106 ent->size++;
107 spin_unlock(&ent->lock);
108 } 158 }
109 159
110out:
111 kfree(in); 160 kfree(in);
112 return err; 161 return err;
113} 162}
@@ -121,16 +170,16 @@ static void remove_keys(struct mlx5_ib_dev *dev, int c, int num)
121 int i; 170 int i;
122 171
123 for (i = 0; i < num; i++) { 172 for (i = 0; i < num; i++) {
124 spin_lock(&ent->lock); 173 spin_lock_irq(&ent->lock);
125 if (list_empty(&ent->head)) { 174 if (list_empty(&ent->head)) {
126 spin_unlock(&ent->lock); 175 spin_unlock_irq(&ent->lock);
127 return; 176 return;
128 } 177 }
129 mr = list_first_entry(&ent->head, struct mlx5_ib_mr, list); 178 mr = list_first_entry(&ent->head, struct mlx5_ib_mr, list);
130 list_del(&mr->list); 179 list_del(&mr->list);
131 ent->cur--; 180 ent->cur--;
132 ent->size--; 181 ent->size--;
133 spin_unlock(&ent->lock); 182 spin_unlock_irq(&ent->lock);
134 err = mlx5_core_destroy_mkey(&dev->mdev, &mr->mmr); 183 err = mlx5_core_destroy_mkey(&dev->mdev, &mr->mmr);
135 if (err) 184 if (err)
136 mlx5_ib_warn(dev, "failed destroy mkey\n"); 185 mlx5_ib_warn(dev, "failed destroy mkey\n");
@@ -162,9 +211,13 @@ static ssize_t size_write(struct file *filp, const char __user *buf,
162 return -EINVAL; 211 return -EINVAL;
163 212
164 if (var > ent->size) { 213 if (var > ent->size) {
165 err = add_keys(dev, c, var - ent->size); 214 do {
166 if (err) 215 err = add_keys(dev, c, var - ent->size);
167 return err; 216 if (err && err != -EAGAIN)
217 return err;
218
219 usleep_range(3000, 5000);
220 } while (err);
168 } else if (var < ent->size) { 221 } else if (var < ent->size) {
169 remove_keys(dev, c, ent->size - var); 222 remove_keys(dev, c, ent->size - var);
170 } 223 }
@@ -280,23 +333,37 @@ static void __cache_work_func(struct mlx5_cache_ent *ent)
280 struct mlx5_ib_dev *dev = ent->dev; 333 struct mlx5_ib_dev *dev = ent->dev;
281 struct mlx5_mr_cache *cache = &dev->cache; 334 struct mlx5_mr_cache *cache = &dev->cache;
282 int i = order2idx(dev, ent->order); 335 int i = order2idx(dev, ent->order);
336 int err;
283 337
284 if (cache->stopped) 338 if (cache->stopped)
285 return; 339 return;
286 340
287 ent = &dev->cache.ent[i]; 341 ent = &dev->cache.ent[i];
288 if (ent->cur < 2 * ent->limit) { 342 if (ent->cur < 2 * ent->limit && !dev->fill_delay) {
289 add_keys(dev, i, 1); 343 err = add_keys(dev, i, 1);
290 if (ent->cur < 2 * ent->limit) 344 if (ent->cur < 2 * ent->limit) {
291 queue_work(cache->wq, &ent->work); 345 if (err == -EAGAIN) {
346 mlx5_ib_dbg(dev, "returned eagain, order %d\n",
347 i + 2);
348 queue_delayed_work(cache->wq, &ent->dwork,
349 msecs_to_jiffies(3));
350 } else if (err) {
351 mlx5_ib_warn(dev, "command failed order %d, err %d\n",
352 i + 2, err);
353 queue_delayed_work(cache->wq, &ent->dwork,
354 msecs_to_jiffies(1000));
355 } else {
356 queue_work(cache->wq, &ent->work);
357 }
358 }
292 } else if (ent->cur > 2 * ent->limit) { 359 } else if (ent->cur > 2 * ent->limit) {
293 if (!someone_adding(cache) && 360 if (!someone_adding(cache) &&
294 time_after(jiffies, cache->last_add + 60 * HZ)) { 361 time_after(jiffies, cache->last_add + 300 * HZ)) {
295 remove_keys(dev, i, 1); 362 remove_keys(dev, i, 1);
296 if (ent->cur > ent->limit) 363 if (ent->cur > ent->limit)
297 queue_work(cache->wq, &ent->work); 364 queue_work(cache->wq, &ent->work);
298 } else { 365 } else {
299 queue_delayed_work(cache->wq, &ent->dwork, 60 * HZ); 366 queue_delayed_work(cache->wq, &ent->dwork, 300 * HZ);
300 } 367 }
301 } 368 }
302} 369}
@@ -336,18 +403,18 @@ static struct mlx5_ib_mr *alloc_cached_mr(struct mlx5_ib_dev *dev, int order)
336 403
337 mlx5_ib_dbg(dev, "order %d, cache index %d\n", ent->order, i); 404 mlx5_ib_dbg(dev, "order %d, cache index %d\n", ent->order, i);
338 405
339 spin_lock(&ent->lock); 406 spin_lock_irq(&ent->lock);
340 if (!list_empty(&ent->head)) { 407 if (!list_empty(&ent->head)) {
341 mr = list_first_entry(&ent->head, struct mlx5_ib_mr, 408 mr = list_first_entry(&ent->head, struct mlx5_ib_mr,
342 list); 409 list);
343 list_del(&mr->list); 410 list_del(&mr->list);
344 ent->cur--; 411 ent->cur--;
345 spin_unlock(&ent->lock); 412 spin_unlock_irq(&ent->lock);
346 if (ent->cur < ent->limit) 413 if (ent->cur < ent->limit)
347 queue_work(cache->wq, &ent->work); 414 queue_work(cache->wq, &ent->work);
348 break; 415 break;
349 } 416 }
350 spin_unlock(&ent->lock); 417 spin_unlock_irq(&ent->lock);
351 418
352 queue_work(cache->wq, &ent->work); 419 queue_work(cache->wq, &ent->work);
353 420
@@ -374,12 +441,12 @@ static void free_cached_mr(struct mlx5_ib_dev *dev, struct mlx5_ib_mr *mr)
374 return; 441 return;
375 } 442 }
376 ent = &cache->ent[c]; 443 ent = &cache->ent[c];
377 spin_lock(&ent->lock); 444 spin_lock_irq(&ent->lock);
378 list_add_tail(&mr->list, &ent->head); 445 list_add_tail(&mr->list, &ent->head);
379 ent->cur++; 446 ent->cur++;
380 if (ent->cur > 2 * ent->limit) 447 if (ent->cur > 2 * ent->limit)
381 shrink = 1; 448 shrink = 1;
382 spin_unlock(&ent->lock); 449 spin_unlock_irq(&ent->lock);
383 450
384 if (shrink) 451 if (shrink)
385 queue_work(cache->wq, &ent->work); 452 queue_work(cache->wq, &ent->work);
@@ -394,16 +461,16 @@ static void clean_keys(struct mlx5_ib_dev *dev, int c)
394 461
395 cancel_delayed_work(&ent->dwork); 462 cancel_delayed_work(&ent->dwork);
396 while (1) { 463 while (1) {
397 spin_lock(&ent->lock); 464 spin_lock_irq(&ent->lock);
398 if (list_empty(&ent->head)) { 465 if (list_empty(&ent->head)) {
399 spin_unlock(&ent->lock); 466 spin_unlock_irq(&ent->lock);
400 return; 467 return;
401 } 468 }
402 mr = list_first_entry(&ent->head, struct mlx5_ib_mr, list); 469 mr = list_first_entry(&ent->head, struct mlx5_ib_mr, list);
403 list_del(&mr->list); 470 list_del(&mr->list);
404 ent->cur--; 471 ent->cur--;
405 ent->size--; 472 ent->size--;
406 spin_unlock(&ent->lock); 473 spin_unlock_irq(&ent->lock);
407 err = mlx5_core_destroy_mkey(&dev->mdev, &mr->mmr); 474 err = mlx5_core_destroy_mkey(&dev->mdev, &mr->mmr);
408 if (err) 475 if (err)
409 mlx5_ib_warn(dev, "failed destroy mkey\n"); 476 mlx5_ib_warn(dev, "failed destroy mkey\n");
@@ -464,12 +531,18 @@ static void mlx5_mr_cache_debugfs_cleanup(struct mlx5_ib_dev *dev)
464 debugfs_remove_recursive(dev->cache.root); 531 debugfs_remove_recursive(dev->cache.root);
465} 532}
466 533
534static void delay_time_func(unsigned long ctx)
535{
536 struct mlx5_ib_dev *dev = (struct mlx5_ib_dev *)ctx;
537
538 dev->fill_delay = 0;
539}
540
467int mlx5_mr_cache_init(struct mlx5_ib_dev *dev) 541int mlx5_mr_cache_init(struct mlx5_ib_dev *dev)
468{ 542{
469 struct mlx5_mr_cache *cache = &dev->cache; 543 struct mlx5_mr_cache *cache = &dev->cache;
470 struct mlx5_cache_ent *ent; 544 struct mlx5_cache_ent *ent;
471 int limit; 545 int limit;
472 int size;
473 int err; 546 int err;
474 int i; 547 int i;
475 548
@@ -479,6 +552,7 @@ int mlx5_mr_cache_init(struct mlx5_ib_dev *dev)
479 return -ENOMEM; 552 return -ENOMEM;
480 } 553 }
481 554
555 setup_timer(&dev->delay_timer, delay_time_func, (unsigned long)dev);
482 for (i = 0; i < MAX_MR_CACHE_ENTRIES; i++) { 556 for (i = 0; i < MAX_MR_CACHE_ENTRIES; i++) {
483 INIT_LIST_HEAD(&cache->ent[i].head); 557 INIT_LIST_HEAD(&cache->ent[i].head);
484 spin_lock_init(&cache->ent[i].lock); 558 spin_lock_init(&cache->ent[i].lock);
@@ -489,13 +563,11 @@ int mlx5_mr_cache_init(struct mlx5_ib_dev *dev)
489 ent->order = i + 2; 563 ent->order = i + 2;
490 ent->dev = dev; 564 ent->dev = dev;
491 565
492 if (dev->mdev.profile->mask & MLX5_PROF_MASK_MR_CACHE) { 566 if (dev->mdev.profile->mask & MLX5_PROF_MASK_MR_CACHE)
493 size = dev->mdev.profile->mr_cache[i].size;
494 limit = dev->mdev.profile->mr_cache[i].limit; 567 limit = dev->mdev.profile->mr_cache[i].limit;
495 } else { 568 else
496 size = DEF_CACHE_SIZE;
497 limit = 0; 569 limit = 0;
498 } 570
499 INIT_WORK(&ent->work, cache_work_func); 571 INIT_WORK(&ent->work, cache_work_func);
500 INIT_DELAYED_WORK(&ent->dwork, delayed_cache_work_func); 572 INIT_DELAYED_WORK(&ent->dwork, delayed_cache_work_func);
501 ent->limit = limit; 573 ent->limit = limit;
@@ -522,6 +594,7 @@ int mlx5_mr_cache_cleanup(struct mlx5_ib_dev *dev)
522 clean_keys(dev, i); 594 clean_keys(dev, i);
523 595
524 destroy_workqueue(dev->cache.wq); 596 destroy_workqueue(dev->cache.wq);
597 del_timer_sync(&dev->delay_timer);
525 598
526 return 0; 599 return 0;
527} 600}
@@ -551,7 +624,8 @@ struct ib_mr *mlx5_ib_get_dma_mr(struct ib_pd *pd, int acc)
551 seg->qpn_mkey7_0 = cpu_to_be32(0xffffff << 8); 624 seg->qpn_mkey7_0 = cpu_to_be32(0xffffff << 8);
552 seg->start_addr = 0; 625 seg->start_addr = 0;
553 626
554 err = mlx5_core_create_mkey(mdev, &mr->mmr, in, sizeof(*in)); 627 err = mlx5_core_create_mkey(mdev, &mr->mmr, in, sizeof(*in), NULL, NULL,
628 NULL);
555 if (err) 629 if (err)
556 goto err_in; 630 goto err_in;
557 631
@@ -660,14 +734,14 @@ static struct mlx5_ib_mr *reg_umr(struct ib_pd *pd, struct ib_umem *umem,
660 int err; 734 int err;
661 int i; 735 int i;
662 736
663 for (i = 0; i < 10; i++) { 737 for (i = 0; i < 1; i++) {
664 mr = alloc_cached_mr(dev, order); 738 mr = alloc_cached_mr(dev, order);
665 if (mr) 739 if (mr)
666 break; 740 break;
667 741
668 err = add_keys(dev, order2idx(dev, order), 1); 742 err = add_keys(dev, order2idx(dev, order), 1);
669 if (err) { 743 if (err && err != -EAGAIN) {
670 mlx5_ib_warn(dev, "add_keys failed\n"); 744 mlx5_ib_warn(dev, "add_keys failed, err %d\n", err);
671 break; 745 break;
672 } 746 }
673 } 747 }
@@ -759,8 +833,10 @@ static struct mlx5_ib_mr *reg_create(struct ib_pd *pd, u64 virt_addr,
759 in->seg.xlt_oct_size = cpu_to_be32(get_octo_len(virt_addr, length, 1 << page_shift)); 833 in->seg.xlt_oct_size = cpu_to_be32(get_octo_len(virt_addr, length, 1 << page_shift));
760 in->seg.log2_page_size = page_shift; 834 in->seg.log2_page_size = page_shift;
761 in->seg.qpn_mkey7_0 = cpu_to_be32(0xffffff << 8); 835 in->seg.qpn_mkey7_0 = cpu_to_be32(0xffffff << 8);
762 in->xlat_oct_act_size = cpu_to_be32(get_octo_len(virt_addr, length, 1 << page_shift)); 836 in->xlat_oct_act_size = cpu_to_be32(get_octo_len(virt_addr, length,
763 err = mlx5_core_create_mkey(&dev->mdev, &mr->mmr, in, inlen); 837 1 << page_shift));
838 err = mlx5_core_create_mkey(&dev->mdev, &mr->mmr, in, inlen, NULL,
839 NULL, NULL);
764 if (err) { 840 if (err) {
765 mlx5_ib_warn(dev, "create mkey failed\n"); 841 mlx5_ib_warn(dev, "create mkey failed\n");
766 goto err_2; 842 goto err_2;
@@ -944,7 +1020,8 @@ struct ib_mr *mlx5_ib_alloc_fast_reg_mr(struct ib_pd *pd,
944 * TBD not needed - issue 197292 */ 1020 * TBD not needed - issue 197292 */
945 in->seg.log2_page_size = PAGE_SHIFT; 1021 in->seg.log2_page_size = PAGE_SHIFT;
946 1022
947 err = mlx5_core_create_mkey(&dev->mdev, &mr->mmr, in, sizeof(*in)); 1023 err = mlx5_core_create_mkey(&dev->mdev, &mr->mmr, in, sizeof(*in), NULL,
1024 NULL, NULL);
948 kfree(in); 1025 kfree(in);
949 if (err) 1026 if (err)
950 goto err_free; 1027 goto err_free;