IB/mlx5: Add mlx5_ib_update_mtt to update page tables after creation
[linux-2.6-block.git] / drivers / infiniband / hw / mlx5 / mr.c
CommitLineData
e126ba97
EC
1/*
2 * Copyright (c) 2013, Mellanox Technologies inc. All rights reserved.
3 *
4 * This software is available to you under a choice of one of two
5 * licenses. You may choose to be licensed under the terms of the GNU
6 * General Public License (GPL) Version 2, available from the file
7 * COPYING in the main directory of this source tree, or the
8 * OpenIB.org BSD license below:
9 *
10 * Redistribution and use in source and binary forms, with or
11 * without modification, are permitted provided that the following
12 * conditions are met:
13 *
14 * - Redistributions of source code must retain the above
15 * copyright notice, this list of conditions and the following
16 * disclaimer.
17 *
18 * - Redistributions in binary form must reproduce the above
19 * copyright notice, this list of conditions and the following
20 * disclaimer in the documentation and/or other materials
21 * provided with the distribution.
22 *
23 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
24 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
25 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
26 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
27 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
28 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
29 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
30 * SOFTWARE.
31 */
32
33
34#include <linux/kref.h>
35#include <linux/random.h>
36#include <linux/debugfs.h>
37#include <linux/export.h>
746b5583 38#include <linux/delay.h>
e126ba97 39#include <rdma/ib_umem.h>
968e78dd 40#include <rdma/ib_verbs.h>
e126ba97
EC
41#include "mlx5_ib.h"
42
43enum {
746b5583 44 MAX_PENDING_REG_MR = 8,
e126ba97
EC
45};
46
832a6b06
HE
47#define MLX5_UMR_ALIGN 2048
48#ifdef CONFIG_INFINIBAND_ON_DEMAND_PAGING
49static __be64 mlx5_ib_update_mtt_emergency_buffer[
50 MLX5_UMR_MTT_MIN_CHUNK_SIZE/sizeof(__be64)]
51 __aligned(MLX5_UMR_ALIGN);
52static DEFINE_MUTEX(mlx5_ib_update_mtt_emergency_buffer_mutex);
53#endif
fe45f827 54
e126ba97
EC
55static int order2idx(struct mlx5_ib_dev *dev, int order)
56{
57 struct mlx5_mr_cache *cache = &dev->cache;
58
59 if (order < cache->ent[0].order)
60 return 0;
61 else
62 return order - cache->ent[0].order;
63}
64
746b5583
EC
65static void reg_mr_callback(int status, void *context)
66{
67 struct mlx5_ib_mr *mr = context;
68 struct mlx5_ib_dev *dev = mr->dev;
69 struct mlx5_mr_cache *cache = &dev->cache;
70 int c = order2idx(dev, mr->order);
71 struct mlx5_cache_ent *ent = &cache->ent[c];
72 u8 key;
746b5583 73 unsigned long flags;
9603b61d 74 struct mlx5_mr_table *table = &dev->mdev->priv.mr_table;
8605933a 75 int err;
746b5583 76
746b5583
EC
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
9603b61d
JM
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);
746b5583
EC
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);
8605933a
HE
110
111 write_lock_irqsave(&table->lock, flags);
112 err = radix_tree_insert(&table->tree, mlx5_base_mkey(mr->mmr.key),
113 &mr->mmr);
114 if (err)
115 pr_err("Error inserting to mr tree. 0x%x\n", -err);
116 write_unlock_irqrestore(&table->lock, flags);
746b5583
EC
117}
118
e126ba97
EC
119static int add_keys(struct mlx5_ib_dev *dev, int c, int num)
120{
e126ba97
EC
121 struct mlx5_mr_cache *cache = &dev->cache;
122 struct mlx5_cache_ent *ent = &cache->ent[c];
123 struct mlx5_create_mkey_mbox_in *in;
124 struct mlx5_ib_mr *mr;
125 int npages = 1 << ent->order;
e126ba97
EC
126 int err = 0;
127 int i;
128
129 in = kzalloc(sizeof(*in), GFP_KERNEL);
130 if (!in)
131 return -ENOMEM;
132
133 for (i = 0; i < num; i++) {
746b5583
EC
134 if (ent->pending >= MAX_PENDING_REG_MR) {
135 err = -EAGAIN;
136 break;
137 }
138
e126ba97
EC
139 mr = kzalloc(sizeof(*mr), GFP_KERNEL);
140 if (!mr) {
141 err = -ENOMEM;
746b5583 142 break;
e126ba97
EC
143 }
144 mr->order = ent->order;
145 mr->umred = 1;
746b5583 146 mr->dev = dev;
968e78dd 147 in->seg.status = MLX5_MKEY_STATUS_FREE;
e126ba97
EC
148 in->seg.xlt_oct_size = cpu_to_be32((npages + 1) / 2);
149 in->seg.qpn_mkey7_0 = cpu_to_be32(0xffffff << 8);
150 in->seg.flags = MLX5_ACCESS_MODE_MTT | MLX5_PERM_UMR_EN;
151 in->seg.log2_page_size = 12;
152
746b5583
EC
153 spin_lock_irq(&ent->lock);
154 ent->pending++;
155 spin_unlock_irq(&ent->lock);
9603b61d 156 err = mlx5_core_create_mkey(dev->mdev, &mr->mmr, in,
746b5583
EC
157 sizeof(*in), reg_mr_callback,
158 mr, &mr->out);
e126ba97 159 if (err) {
d14e7110
EC
160 spin_lock_irq(&ent->lock);
161 ent->pending--;
162 spin_unlock_irq(&ent->lock);
e126ba97 163 mlx5_ib_warn(dev, "create mkey failed %d\n", err);
e126ba97 164 kfree(mr);
746b5583 165 break;
e126ba97 166 }
e126ba97
EC
167 }
168
e126ba97
EC
169 kfree(in);
170 return err;
171}
172
173static void remove_keys(struct mlx5_ib_dev *dev, int c, int num)
174{
e126ba97
EC
175 struct mlx5_mr_cache *cache = &dev->cache;
176 struct mlx5_cache_ent *ent = &cache->ent[c];
177 struct mlx5_ib_mr *mr;
e126ba97
EC
178 int err;
179 int i;
180
181 for (i = 0; i < num; i++) {
746b5583 182 spin_lock_irq(&ent->lock);
e126ba97 183 if (list_empty(&ent->head)) {
746b5583 184 spin_unlock_irq(&ent->lock);
e126ba97
EC
185 return;
186 }
187 mr = list_first_entry(&ent->head, struct mlx5_ib_mr, list);
188 list_del(&mr->list);
189 ent->cur--;
190 ent->size--;
746b5583 191 spin_unlock_irq(&ent->lock);
9603b61d 192 err = mlx5_core_destroy_mkey(dev->mdev, &mr->mmr);
203099fd 193 if (err)
e126ba97 194 mlx5_ib_warn(dev, "failed destroy mkey\n");
203099fd 195 else
e126ba97 196 kfree(mr);
e126ba97
EC
197 }
198}
199
200static ssize_t size_write(struct file *filp, const char __user *buf,
201 size_t count, loff_t *pos)
202{
203 struct mlx5_cache_ent *ent = filp->private_data;
204 struct mlx5_ib_dev *dev = ent->dev;
205 char lbuf[20];
206 u32 var;
207 int err;
208 int c;
209
210 if (copy_from_user(lbuf, buf, sizeof(lbuf)))
5e631a03 211 return -EFAULT;
e126ba97
EC
212
213 c = order2idx(dev, ent->order);
214 lbuf[sizeof(lbuf) - 1] = 0;
215
216 if (sscanf(lbuf, "%u", &var) != 1)
217 return -EINVAL;
218
219 if (var < ent->limit)
220 return -EINVAL;
221
222 if (var > ent->size) {
746b5583
EC
223 do {
224 err = add_keys(dev, c, var - ent->size);
225 if (err && err != -EAGAIN)
226 return err;
227
228 usleep_range(3000, 5000);
229 } while (err);
e126ba97
EC
230 } else if (var < ent->size) {
231 remove_keys(dev, c, ent->size - var);
232 }
233
234 return count;
235}
236
237static ssize_t size_read(struct file *filp, char __user *buf, size_t count,
238 loff_t *pos)
239{
240 struct mlx5_cache_ent *ent = filp->private_data;
241 char lbuf[20];
242 int err;
243
244 if (*pos)
245 return 0;
246
247 err = snprintf(lbuf, sizeof(lbuf), "%d\n", ent->size);
248 if (err < 0)
249 return err;
250
251 if (copy_to_user(buf, lbuf, err))
5e631a03 252 return -EFAULT;
e126ba97
EC
253
254 *pos += err;
255
256 return err;
257}
258
259static const struct file_operations size_fops = {
260 .owner = THIS_MODULE,
261 .open = simple_open,
262 .write = size_write,
263 .read = size_read,
264};
265
266static ssize_t limit_write(struct file *filp, const char __user *buf,
267 size_t count, loff_t *pos)
268{
269 struct mlx5_cache_ent *ent = filp->private_data;
270 struct mlx5_ib_dev *dev = ent->dev;
271 char lbuf[20];
272 u32 var;
273 int err;
274 int c;
275
276 if (copy_from_user(lbuf, buf, sizeof(lbuf)))
5e631a03 277 return -EFAULT;
e126ba97
EC
278
279 c = order2idx(dev, ent->order);
280 lbuf[sizeof(lbuf) - 1] = 0;
281
282 if (sscanf(lbuf, "%u", &var) != 1)
283 return -EINVAL;
284
285 if (var > ent->size)
286 return -EINVAL;
287
288 ent->limit = var;
289
290 if (ent->cur < ent->limit) {
291 err = add_keys(dev, c, 2 * ent->limit - ent->cur);
292 if (err)
293 return err;
294 }
295
296 return count;
297}
298
299static ssize_t limit_read(struct file *filp, char __user *buf, size_t count,
300 loff_t *pos)
301{
302 struct mlx5_cache_ent *ent = filp->private_data;
303 char lbuf[20];
304 int err;
305
306 if (*pos)
307 return 0;
308
309 err = snprintf(lbuf, sizeof(lbuf), "%d\n", ent->limit);
310 if (err < 0)
311 return err;
312
313 if (copy_to_user(buf, lbuf, err))
5e631a03 314 return -EFAULT;
e126ba97
EC
315
316 *pos += err;
317
318 return err;
319}
320
321static const struct file_operations limit_fops = {
322 .owner = THIS_MODULE,
323 .open = simple_open,
324 .write = limit_write,
325 .read = limit_read,
326};
327
328static int someone_adding(struct mlx5_mr_cache *cache)
329{
330 int i;
331
332 for (i = 0; i < MAX_MR_CACHE_ENTRIES; i++) {
333 if (cache->ent[i].cur < cache->ent[i].limit)
334 return 1;
335 }
336
337 return 0;
338}
339
340static void __cache_work_func(struct mlx5_cache_ent *ent)
341{
342 struct mlx5_ib_dev *dev = ent->dev;
343 struct mlx5_mr_cache *cache = &dev->cache;
344 int i = order2idx(dev, ent->order);
746b5583 345 int err;
e126ba97
EC
346
347 if (cache->stopped)
348 return;
349
350 ent = &dev->cache.ent[i];
746b5583
EC
351 if (ent->cur < 2 * ent->limit && !dev->fill_delay) {
352 err = add_keys(dev, i, 1);
353 if (ent->cur < 2 * ent->limit) {
354 if (err == -EAGAIN) {
355 mlx5_ib_dbg(dev, "returned eagain, order %d\n",
356 i + 2);
357 queue_delayed_work(cache->wq, &ent->dwork,
358 msecs_to_jiffies(3));
359 } else if (err) {
360 mlx5_ib_warn(dev, "command failed order %d, err %d\n",
361 i + 2, err);
362 queue_delayed_work(cache->wq, &ent->dwork,
363 msecs_to_jiffies(1000));
364 } else {
365 queue_work(cache->wq, &ent->work);
366 }
367 }
e126ba97
EC
368 } else if (ent->cur > 2 * ent->limit) {
369 if (!someone_adding(cache) &&
746b5583 370 time_after(jiffies, cache->last_add + 300 * HZ)) {
e126ba97
EC
371 remove_keys(dev, i, 1);
372 if (ent->cur > ent->limit)
373 queue_work(cache->wq, &ent->work);
374 } else {
746b5583 375 queue_delayed_work(cache->wq, &ent->dwork, 300 * HZ);
e126ba97
EC
376 }
377 }
378}
379
380static void delayed_cache_work_func(struct work_struct *work)
381{
382 struct mlx5_cache_ent *ent;
383
384 ent = container_of(work, struct mlx5_cache_ent, dwork.work);
385 __cache_work_func(ent);
386}
387
388static void cache_work_func(struct work_struct *work)
389{
390 struct mlx5_cache_ent *ent;
391
392 ent = container_of(work, struct mlx5_cache_ent, work);
393 __cache_work_func(ent);
394}
395
396static struct mlx5_ib_mr *alloc_cached_mr(struct mlx5_ib_dev *dev, int order)
397{
398 struct mlx5_mr_cache *cache = &dev->cache;
399 struct mlx5_ib_mr *mr = NULL;
400 struct mlx5_cache_ent *ent;
401 int c;
402 int i;
403
404 c = order2idx(dev, order);
405 if (c < 0 || c >= MAX_MR_CACHE_ENTRIES) {
406 mlx5_ib_warn(dev, "order %d, cache index %d\n", order, c);
407 return NULL;
408 }
409
410 for (i = c; i < MAX_MR_CACHE_ENTRIES; i++) {
411 ent = &cache->ent[i];
412
413 mlx5_ib_dbg(dev, "order %d, cache index %d\n", ent->order, i);
414
746b5583 415 spin_lock_irq(&ent->lock);
e126ba97
EC
416 if (!list_empty(&ent->head)) {
417 mr = list_first_entry(&ent->head, struct mlx5_ib_mr,
418 list);
419 list_del(&mr->list);
420 ent->cur--;
746b5583 421 spin_unlock_irq(&ent->lock);
e126ba97
EC
422 if (ent->cur < ent->limit)
423 queue_work(cache->wq, &ent->work);
424 break;
425 }
746b5583 426 spin_unlock_irq(&ent->lock);
e126ba97
EC
427
428 queue_work(cache->wq, &ent->work);
429
430 if (mr)
431 break;
432 }
433
434 if (!mr)
435 cache->ent[c].miss++;
436
437 return mr;
438}
439
440static void free_cached_mr(struct mlx5_ib_dev *dev, struct mlx5_ib_mr *mr)
441{
442 struct mlx5_mr_cache *cache = &dev->cache;
443 struct mlx5_cache_ent *ent;
444 int shrink = 0;
445 int c;
446
447 c = order2idx(dev, mr->order);
448 if (c < 0 || c >= MAX_MR_CACHE_ENTRIES) {
449 mlx5_ib_warn(dev, "order %d, cache index %d\n", mr->order, c);
450 return;
451 }
452 ent = &cache->ent[c];
746b5583 453 spin_lock_irq(&ent->lock);
e126ba97
EC
454 list_add_tail(&mr->list, &ent->head);
455 ent->cur++;
456 if (ent->cur > 2 * ent->limit)
457 shrink = 1;
746b5583 458 spin_unlock_irq(&ent->lock);
e126ba97
EC
459
460 if (shrink)
461 queue_work(cache->wq, &ent->work);
462}
463
464static void clean_keys(struct mlx5_ib_dev *dev, int c)
465{
e126ba97
EC
466 struct mlx5_mr_cache *cache = &dev->cache;
467 struct mlx5_cache_ent *ent = &cache->ent[c];
468 struct mlx5_ib_mr *mr;
e126ba97
EC
469 int err;
470
3c461911 471 cancel_delayed_work(&ent->dwork);
e126ba97 472 while (1) {
746b5583 473 spin_lock_irq(&ent->lock);
e126ba97 474 if (list_empty(&ent->head)) {
746b5583 475 spin_unlock_irq(&ent->lock);
e126ba97
EC
476 return;
477 }
478 mr = list_first_entry(&ent->head, struct mlx5_ib_mr, list);
479 list_del(&mr->list);
480 ent->cur--;
481 ent->size--;
746b5583 482 spin_unlock_irq(&ent->lock);
9603b61d 483 err = mlx5_core_destroy_mkey(dev->mdev, &mr->mmr);
203099fd 484 if (err)
e126ba97 485 mlx5_ib_warn(dev, "failed destroy mkey\n");
203099fd 486 else
e126ba97 487 kfree(mr);
e126ba97
EC
488 }
489}
490
491static int mlx5_mr_cache_debugfs_init(struct mlx5_ib_dev *dev)
492{
493 struct mlx5_mr_cache *cache = &dev->cache;
494 struct mlx5_cache_ent *ent;
495 int i;
496
497 if (!mlx5_debugfs_root)
498 return 0;
499
9603b61d 500 cache->root = debugfs_create_dir("mr_cache", dev->mdev->priv.dbg_root);
e126ba97
EC
501 if (!cache->root)
502 return -ENOMEM;
503
504 for (i = 0; i < MAX_MR_CACHE_ENTRIES; i++) {
505 ent = &cache->ent[i];
506 sprintf(ent->name, "%d", ent->order);
507 ent->dir = debugfs_create_dir(ent->name, cache->root);
508 if (!ent->dir)
509 return -ENOMEM;
510
511 ent->fsize = debugfs_create_file("size", 0600, ent->dir, ent,
512 &size_fops);
513 if (!ent->fsize)
514 return -ENOMEM;
515
516 ent->flimit = debugfs_create_file("limit", 0600, ent->dir, ent,
517 &limit_fops);
518 if (!ent->flimit)
519 return -ENOMEM;
520
521 ent->fcur = debugfs_create_u32("cur", 0400, ent->dir,
522 &ent->cur);
523 if (!ent->fcur)
524 return -ENOMEM;
525
526 ent->fmiss = debugfs_create_u32("miss", 0600, ent->dir,
527 &ent->miss);
528 if (!ent->fmiss)
529 return -ENOMEM;
530 }
531
532 return 0;
533}
534
535static void mlx5_mr_cache_debugfs_cleanup(struct mlx5_ib_dev *dev)
536{
537 if (!mlx5_debugfs_root)
538 return;
539
540 debugfs_remove_recursive(dev->cache.root);
541}
542
746b5583
EC
543static void delay_time_func(unsigned long ctx)
544{
545 struct mlx5_ib_dev *dev = (struct mlx5_ib_dev *)ctx;
546
547 dev->fill_delay = 0;
548}
549
e126ba97
EC
550int mlx5_mr_cache_init(struct mlx5_ib_dev *dev)
551{
552 struct mlx5_mr_cache *cache = &dev->cache;
553 struct mlx5_cache_ent *ent;
554 int limit;
e126ba97
EC
555 int err;
556 int i;
557
558 cache->wq = create_singlethread_workqueue("mkey_cache");
559 if (!cache->wq) {
560 mlx5_ib_warn(dev, "failed to create work queue\n");
561 return -ENOMEM;
562 }
563
746b5583 564 setup_timer(&dev->delay_timer, delay_time_func, (unsigned long)dev);
e126ba97
EC
565 for (i = 0; i < MAX_MR_CACHE_ENTRIES; i++) {
566 INIT_LIST_HEAD(&cache->ent[i].head);
567 spin_lock_init(&cache->ent[i].lock);
568
569 ent = &cache->ent[i];
570 INIT_LIST_HEAD(&ent->head);
571 spin_lock_init(&ent->lock);
572 ent->order = i + 2;
573 ent->dev = dev;
574
9603b61d
JM
575 if (dev->mdev->profile->mask & MLX5_PROF_MASK_MR_CACHE)
576 limit = dev->mdev->profile->mr_cache[i].limit;
2d036fad 577 else
e126ba97 578 limit = 0;
2d036fad 579
e126ba97
EC
580 INIT_WORK(&ent->work, cache_work_func);
581 INIT_DELAYED_WORK(&ent->dwork, delayed_cache_work_func);
582 ent->limit = limit;
583 queue_work(cache->wq, &ent->work);
584 }
585
586 err = mlx5_mr_cache_debugfs_init(dev);
587 if (err)
588 mlx5_ib_warn(dev, "cache debugfs failure\n");
589
590 return 0;
591}
592
593int mlx5_mr_cache_cleanup(struct mlx5_ib_dev *dev)
594{
595 int i;
596
597 dev->cache.stopped = 1;
3c461911 598 flush_workqueue(dev->cache.wq);
e126ba97
EC
599
600 mlx5_mr_cache_debugfs_cleanup(dev);
601
602 for (i = 0; i < MAX_MR_CACHE_ENTRIES; i++)
603 clean_keys(dev, i);
604
3c461911 605 destroy_workqueue(dev->cache.wq);
746b5583 606 del_timer_sync(&dev->delay_timer);
3c461911 607
e126ba97
EC
608 return 0;
609}
610
611struct ib_mr *mlx5_ib_get_dma_mr(struct ib_pd *pd, int acc)
612{
613 struct mlx5_ib_dev *dev = to_mdev(pd->device);
9603b61d 614 struct mlx5_core_dev *mdev = dev->mdev;
e126ba97
EC
615 struct mlx5_create_mkey_mbox_in *in;
616 struct mlx5_mkey_seg *seg;
617 struct mlx5_ib_mr *mr;
618 int err;
619
620 mr = kzalloc(sizeof(*mr), GFP_KERNEL);
621 if (!mr)
622 return ERR_PTR(-ENOMEM);
623
624 in = kzalloc(sizeof(*in), GFP_KERNEL);
625 if (!in) {
626 err = -ENOMEM;
627 goto err_free;
628 }
629
630 seg = &in->seg;
631 seg->flags = convert_access(acc) | MLX5_ACCESS_MODE_PA;
632 seg->flags_pd = cpu_to_be32(to_mpd(pd)->pdn | MLX5_MKEY_LEN64);
633 seg->qpn_mkey7_0 = cpu_to_be32(0xffffff << 8);
634 seg->start_addr = 0;
635
746b5583
EC
636 err = mlx5_core_create_mkey(mdev, &mr->mmr, in, sizeof(*in), NULL, NULL,
637 NULL);
e126ba97
EC
638 if (err)
639 goto err_in;
640
641 kfree(in);
642 mr->ibmr.lkey = mr->mmr.key;
643 mr->ibmr.rkey = mr->mmr.key;
644 mr->umem = NULL;
645
646 return &mr->ibmr;
647
648err_in:
649 kfree(in);
650
651err_free:
652 kfree(mr);
653
654 return ERR_PTR(err);
655}
656
657static int get_octo_len(u64 addr, u64 len, int page_size)
658{
659 u64 offset;
660 int npages;
661
662 offset = addr & (page_size - 1);
663 npages = ALIGN(len + offset, page_size) >> ilog2(page_size);
664 return (npages + 1) / 2;
665}
666
667static int use_umr(int order)
668{
cc149f75 669 return order <= MLX5_MAX_UMR_SHIFT;
e126ba97
EC
670}
671
672static void prep_umr_reg_wqe(struct ib_pd *pd, struct ib_send_wr *wr,
673 struct ib_sge *sg, u64 dma, int n, u32 key,
674 int page_shift, u64 virt_addr, u64 len,
675 int access_flags)
676{
677 struct mlx5_ib_dev *dev = to_mdev(pd->device);
678 struct ib_mr *mr = dev->umrc.mr;
968e78dd 679 struct mlx5_umr_wr *umrwr = (struct mlx5_umr_wr *)&wr->wr.fast_reg;
e126ba97
EC
680
681 sg->addr = dma;
682 sg->length = ALIGN(sizeof(u64) * n, 64);
683 sg->lkey = mr->lkey;
684
685 wr->next = NULL;
686 wr->send_flags = 0;
687 wr->sg_list = sg;
688 if (n)
689 wr->num_sge = 1;
690 else
691 wr->num_sge = 0;
692
693 wr->opcode = MLX5_IB_WR_UMR;
968e78dd
HE
694
695 umrwr->npages = n;
696 umrwr->page_shift = page_shift;
697 umrwr->mkey = key;
698 umrwr->target.virt_addr = virt_addr;
699 umrwr->length = len;
700 umrwr->access_flags = access_flags;
701 umrwr->pd = pd;
e126ba97
EC
702}
703
704static void prep_umr_unreg_wqe(struct mlx5_ib_dev *dev,
705 struct ib_send_wr *wr, u32 key)
706{
968e78dd
HE
707 struct mlx5_umr_wr *umrwr = (struct mlx5_umr_wr *)&wr->wr.fast_reg;
708
709 wr->send_flags = MLX5_IB_SEND_UMR_UNREG | MLX5_IB_SEND_UMR_FAIL_IF_FREE;
e126ba97 710 wr->opcode = MLX5_IB_WR_UMR;
968e78dd 711 umrwr->mkey = key;
e126ba97
EC
712}
713
714void mlx5_umr_cq_handler(struct ib_cq *cq, void *cq_context)
715{
a74d2416 716 struct mlx5_ib_umr_context *context;
e126ba97
EC
717 struct ib_wc wc;
718 int err;
719
720 while (1) {
721 err = ib_poll_cq(cq, 1, &wc);
722 if (err < 0) {
723 pr_warn("poll cq error %d\n", err);
724 return;
725 }
726 if (err == 0)
727 break;
728
6c9b5d9b 729 context = (struct mlx5_ib_umr_context *) (unsigned long) wc.wr_id;
a74d2416
SR
730 context->status = wc.status;
731 complete(&context->done);
e126ba97
EC
732 }
733 ib_req_notify_cq(cq, IB_CQ_NEXT_COMP);
734}
735
736static struct mlx5_ib_mr *reg_umr(struct ib_pd *pd, struct ib_umem *umem,
737 u64 virt_addr, u64 len, int npages,
738 int page_shift, int order, int access_flags)
739{
740 struct mlx5_ib_dev *dev = to_mdev(pd->device);
203099fd 741 struct device *ddev = dev->ib_dev.dma_device;
e126ba97 742 struct umr_common *umrc = &dev->umrc;
a74d2416 743 struct mlx5_ib_umr_context umr_context;
e126ba97
EC
744 struct ib_send_wr wr, *bad;
745 struct mlx5_ib_mr *mr;
746 struct ib_sge sg;
cc149f75 747 int size;
21af2c3e 748 __be64 *mr_pas;
cc149f75 749 __be64 *pas;
21af2c3e 750 dma_addr_t dma;
096f7e72 751 int err = 0;
e126ba97
EC
752 int i;
753
746b5583 754 for (i = 0; i < 1; i++) {
e126ba97
EC
755 mr = alloc_cached_mr(dev, order);
756 if (mr)
757 break;
758
759 err = add_keys(dev, order2idx(dev, order), 1);
746b5583
EC
760 if (err && err != -EAGAIN) {
761 mlx5_ib_warn(dev, "add_keys failed, err %d\n", err);
e126ba97
EC
762 break;
763 }
764 }
765
766 if (!mr)
767 return ERR_PTR(-EAGAIN);
768
cc149f75
HE
769 /* UMR copies MTTs in units of MLX5_UMR_MTT_ALIGNMENT bytes.
770 * To avoid copying garbage after the pas array, we allocate
771 * a little more. */
772 size = ALIGN(sizeof(u64) * npages, MLX5_UMR_MTT_ALIGNMENT);
21af2c3e
HE
773 mr_pas = kmalloc(size + MLX5_UMR_ALIGN - 1, GFP_KERNEL);
774 if (!mr_pas) {
203099fd 775 err = -ENOMEM;
096f7e72 776 goto free_mr;
203099fd 777 }
54313907 778
cc149f75
HE
779 pas = PTR_ALIGN(mr_pas, MLX5_UMR_ALIGN);
780 mlx5_ib_populate_pas(dev, umem, page_shift, pas, MLX5_IB_MTT_PRESENT);
781 /* Clear padding after the actual pages. */
782 memset(pas + npages, 0, size - npages * sizeof(u64));
54313907 783
cc149f75 784 dma = dma_map_single(ddev, pas, size, DMA_TO_DEVICE);
21af2c3e 785 if (dma_mapping_error(ddev, dma)) {
203099fd 786 err = -ENOMEM;
096f7e72 787 goto free_pas;
203099fd
EC
788 }
789
e126ba97 790 memset(&wr, 0, sizeof(wr));
a74d2416 791 wr.wr_id = (u64)(unsigned long)&umr_context;
21af2c3e
HE
792 prep_umr_reg_wqe(pd, &wr, &sg, dma, npages, mr->mmr.key, page_shift,
793 virt_addr, len, access_flags);
e126ba97 794
a74d2416 795 mlx5_ib_init_umr_context(&umr_context);
e126ba97 796 down(&umrc->sem);
e126ba97
EC
797 err = ib_post_send(umrc->qp, &wr, &bad);
798 if (err) {
799 mlx5_ib_warn(dev, "post send failed, err %d\n", err);
096f7e72 800 goto unmap_dma;
a74d2416
SR
801 } else {
802 wait_for_completion(&umr_context.done);
803 if (umr_context.status != IB_WC_SUCCESS) {
804 mlx5_ib_warn(dev, "reg umr failed\n");
805 err = -EFAULT;
806 }
096f7e72 807 }
e126ba97 808
b475598a
HE
809 mr->mmr.iova = virt_addr;
810 mr->mmr.size = len;
811 mr->mmr.pd = to_mpd(pd)->pdn;
812
096f7e72
HE
813unmap_dma:
814 up(&umrc->sem);
21af2c3e 815 dma_unmap_single(ddev, dma, size, DMA_TO_DEVICE);
096f7e72
HE
816
817free_pas:
21af2c3e 818 kfree(mr_pas);
203099fd 819
096f7e72
HE
820free_mr:
821 if (err) {
822 free_cached_mr(dev, mr);
823 return ERR_PTR(err);
e126ba97
EC
824 }
825
826 return mr;
e126ba97
EC
827}
828
832a6b06
HE
829#ifdef CONFIG_INFINIBAND_ON_DEMAND_PAGING
830int mlx5_ib_update_mtt(struct mlx5_ib_mr *mr, u64 start_page_index, int npages,
831 int zap)
832{
833 struct mlx5_ib_dev *dev = mr->dev;
834 struct device *ddev = dev->ib_dev.dma_device;
835 struct umr_common *umrc = &dev->umrc;
836 struct mlx5_ib_umr_context umr_context;
837 struct ib_umem *umem = mr->umem;
838 int size;
839 __be64 *pas;
840 dma_addr_t dma;
841 struct ib_send_wr wr, *bad;
842 struct mlx5_umr_wr *umrwr = (struct mlx5_umr_wr *)&wr.wr.fast_reg;
843 struct ib_sge sg;
844 int err = 0;
845 const int page_index_alignment = MLX5_UMR_MTT_ALIGNMENT / sizeof(u64);
846 const int page_index_mask = page_index_alignment - 1;
847 size_t pages_mapped = 0;
848 size_t pages_to_map = 0;
849 size_t pages_iter = 0;
850 int use_emergency_buf = 0;
851
852 /* UMR copies MTTs in units of MLX5_UMR_MTT_ALIGNMENT bytes,
853 * so we need to align the offset and length accordingly */
854 if (start_page_index & page_index_mask) {
855 npages += start_page_index & page_index_mask;
856 start_page_index &= ~page_index_mask;
857 }
858
859 pages_to_map = ALIGN(npages, page_index_alignment);
860
861 if (start_page_index + pages_to_map > MLX5_MAX_UMR_PAGES)
862 return -EINVAL;
863
864 size = sizeof(u64) * pages_to_map;
865 size = min_t(int, PAGE_SIZE, size);
866 /* We allocate with GFP_ATOMIC to avoid recursion into page-reclaim
867 * code, when we are called from an invalidation. The pas buffer must
868 * be 2k-aligned for Connect-IB. */
869 pas = (__be64 *)get_zeroed_page(GFP_ATOMIC);
870 if (!pas) {
871 mlx5_ib_warn(dev, "unable to allocate memory during MTT update, falling back to slower chunked mechanism.\n");
872 pas = mlx5_ib_update_mtt_emergency_buffer;
873 size = MLX5_UMR_MTT_MIN_CHUNK_SIZE;
874 use_emergency_buf = 1;
875 mutex_lock(&mlx5_ib_update_mtt_emergency_buffer_mutex);
876 memset(pas, 0, size);
877 }
878 pages_iter = size / sizeof(u64);
879 dma = dma_map_single(ddev, pas, size, DMA_TO_DEVICE);
880 if (dma_mapping_error(ddev, dma)) {
881 mlx5_ib_err(dev, "unable to map DMA during MTT update.\n");
882 err = -ENOMEM;
883 goto free_pas;
884 }
885
886 for (pages_mapped = 0;
887 pages_mapped < pages_to_map && !err;
888 pages_mapped += pages_iter, start_page_index += pages_iter) {
889 dma_sync_single_for_cpu(ddev, dma, size, DMA_TO_DEVICE);
890
891 npages = min_t(size_t,
892 pages_iter,
893 ib_umem_num_pages(umem) - start_page_index);
894
895 if (!zap) {
896 __mlx5_ib_populate_pas(dev, umem, PAGE_SHIFT,
897 start_page_index, npages, pas,
898 MLX5_IB_MTT_PRESENT);
899 /* Clear padding after the pages brought from the
900 * umem. */
901 memset(pas + npages, 0, size - npages * sizeof(u64));
902 }
903
904 dma_sync_single_for_device(ddev, dma, size, DMA_TO_DEVICE);
905
906 memset(&wr, 0, sizeof(wr));
907 wr.wr_id = (u64)(unsigned long)&umr_context;
908
909 sg.addr = dma;
910 sg.length = ALIGN(npages * sizeof(u64),
911 MLX5_UMR_MTT_ALIGNMENT);
912 sg.lkey = dev->umrc.mr->lkey;
913
914 wr.send_flags = MLX5_IB_SEND_UMR_FAIL_IF_FREE |
915 MLX5_IB_SEND_UMR_UPDATE_MTT;
916 wr.sg_list = &sg;
917 wr.num_sge = 1;
918 wr.opcode = MLX5_IB_WR_UMR;
919 umrwr->npages = sg.length / sizeof(u64);
920 umrwr->page_shift = PAGE_SHIFT;
921 umrwr->mkey = mr->mmr.key;
922 umrwr->target.offset = start_page_index;
923
924 mlx5_ib_init_umr_context(&umr_context);
925 down(&umrc->sem);
926 err = ib_post_send(umrc->qp, &wr, &bad);
927 if (err) {
928 mlx5_ib_err(dev, "UMR post send failed, err %d\n", err);
929 } else {
930 wait_for_completion(&umr_context.done);
931 if (umr_context.status != IB_WC_SUCCESS) {
932 mlx5_ib_err(dev, "UMR completion failed, code %d\n",
933 umr_context.status);
934 err = -EFAULT;
935 }
936 }
937 up(&umrc->sem);
938 }
939 dma_unmap_single(ddev, dma, size, DMA_TO_DEVICE);
940
941free_pas:
942 if (!use_emergency_buf)
943 free_page((unsigned long)pas);
944 else
945 mutex_unlock(&mlx5_ib_update_mtt_emergency_buffer_mutex);
946
947 return err;
948}
949#endif
950
e126ba97
EC
951static struct mlx5_ib_mr *reg_create(struct ib_pd *pd, u64 virt_addr,
952 u64 length, struct ib_umem *umem,
953 int npages, int page_shift,
954 int access_flags)
955{
956 struct mlx5_ib_dev *dev = to_mdev(pd->device);
957 struct mlx5_create_mkey_mbox_in *in;
958 struct mlx5_ib_mr *mr;
959 int inlen;
960 int err;
cc149f75
HE
961 bool pg_cap = !!(dev->mdev->caps.gen.flags &
962 MLX5_DEV_CAP_FLAG_ON_DMND_PG);
e126ba97
EC
963
964 mr = kzalloc(sizeof(*mr), GFP_KERNEL);
965 if (!mr)
966 return ERR_PTR(-ENOMEM);
967
968 inlen = sizeof(*in) + sizeof(*in->pas) * ((npages + 1) / 2) * 2;
969 in = mlx5_vzalloc(inlen);
970 if (!in) {
971 err = -ENOMEM;
972 goto err_1;
973 }
cc149f75
HE
974 mlx5_ib_populate_pas(dev, umem, page_shift, in->pas,
975 pg_cap ? MLX5_IB_MTT_PRESENT : 0);
e126ba97 976
cc149f75
HE
977 /* The MLX5_MKEY_INBOX_PG_ACCESS bit allows setting the access flags
978 * in the page list submitted with the command. */
979 in->flags = pg_cap ? cpu_to_be32(MLX5_MKEY_INBOX_PG_ACCESS) : 0;
e126ba97
EC
980 in->seg.flags = convert_access(access_flags) |
981 MLX5_ACCESS_MODE_MTT;
982 in->seg.flags_pd = cpu_to_be32(to_mpd(pd)->pdn);
983 in->seg.start_addr = cpu_to_be64(virt_addr);
984 in->seg.len = cpu_to_be64(length);
985 in->seg.bsfs_octo_size = 0;
986 in->seg.xlt_oct_size = cpu_to_be32(get_octo_len(virt_addr, length, 1 << page_shift));
987 in->seg.log2_page_size = page_shift;
988 in->seg.qpn_mkey7_0 = cpu_to_be32(0xffffff << 8);
746b5583
EC
989 in->xlat_oct_act_size = cpu_to_be32(get_octo_len(virt_addr, length,
990 1 << page_shift));
9603b61d 991 err = mlx5_core_create_mkey(dev->mdev, &mr->mmr, in, inlen, NULL,
746b5583 992 NULL, NULL);
e126ba97
EC
993 if (err) {
994 mlx5_ib_warn(dev, "create mkey failed\n");
995 goto err_2;
996 }
997 mr->umem = umem;
479163f4 998 kvfree(in);
e126ba97
EC
999
1000 mlx5_ib_dbg(dev, "mkey = 0x%x\n", mr->mmr.key);
1001
1002 return mr;
1003
1004err_2:
479163f4 1005 kvfree(in);
e126ba97
EC
1006
1007err_1:
1008 kfree(mr);
1009
1010 return ERR_PTR(err);
1011}
1012
1013struct ib_mr *mlx5_ib_reg_user_mr(struct ib_pd *pd, u64 start, u64 length,
1014 u64 virt_addr, int access_flags,
1015 struct ib_udata *udata)
1016{
1017 struct mlx5_ib_dev *dev = to_mdev(pd->device);
1018 struct mlx5_ib_mr *mr = NULL;
1019 struct ib_umem *umem;
1020 int page_shift;
1021 int npages;
1022 int ncont;
1023 int order;
1024 int err;
1025
900a6d79
EC
1026 mlx5_ib_dbg(dev, "start 0x%llx, virt_addr 0x%llx, length 0x%llx, access_flags 0x%x\n",
1027 start, virt_addr, length, access_flags);
e126ba97
EC
1028 umem = ib_umem_get(pd->uobject->context, start, length, access_flags,
1029 0);
1030 if (IS_ERR(umem)) {
900a6d79 1031 mlx5_ib_dbg(dev, "umem get failed (%ld)\n", PTR_ERR(umem));
e126ba97
EC
1032 return (void *)umem;
1033 }
1034
1035 mlx5_ib_cont_pages(umem, start, &npages, &page_shift, &ncont, &order);
1036 if (!npages) {
1037 mlx5_ib_warn(dev, "avoid zero region\n");
1038 err = -EINVAL;
1039 goto error;
1040 }
1041
1042 mlx5_ib_dbg(dev, "npages %d, ncont %d, order %d, page_shift %d\n",
1043 npages, ncont, order, page_shift);
1044
1045 if (use_umr(order)) {
1046 mr = reg_umr(pd, umem, virt_addr, length, ncont, page_shift,
1047 order, access_flags);
1048 if (PTR_ERR(mr) == -EAGAIN) {
1049 mlx5_ib_dbg(dev, "cache empty for order %d", order);
1050 mr = NULL;
1051 }
1052 }
1053
1054 if (!mr)
1055 mr = reg_create(pd, virt_addr, length, umem, ncont, page_shift,
1056 access_flags);
1057
1058 if (IS_ERR(mr)) {
1059 err = PTR_ERR(mr);
1060 goto error;
1061 }
1062
1063 mlx5_ib_dbg(dev, "mkey 0x%x\n", mr->mmr.key);
1064
1065 mr->umem = umem;
1066 mr->npages = npages;
1067 spin_lock(&dev->mr_lock);
9603b61d 1068 dev->mdev->priv.reg_pages += npages;
e126ba97
EC
1069 spin_unlock(&dev->mr_lock);
1070 mr->ibmr.lkey = mr->mmr.key;
1071 mr->ibmr.rkey = mr->mmr.key;
1072
1073 return &mr->ibmr;
1074
1075error:
1076 ib_umem_release(umem);
1077 return ERR_PTR(err);
1078}
1079
1080static int unreg_umr(struct mlx5_ib_dev *dev, struct mlx5_ib_mr *mr)
1081{
1082 struct umr_common *umrc = &dev->umrc;
a74d2416 1083 struct mlx5_ib_umr_context umr_context;
e126ba97
EC
1084 struct ib_send_wr wr, *bad;
1085 int err;
1086
1087 memset(&wr, 0, sizeof(wr));
a74d2416 1088 wr.wr_id = (u64)(unsigned long)&umr_context;
e126ba97
EC
1089 prep_umr_unreg_wqe(dev, &wr, mr->mmr.key);
1090
a74d2416 1091 mlx5_ib_init_umr_context(&umr_context);
e126ba97 1092 down(&umrc->sem);
e126ba97
EC
1093 err = ib_post_send(umrc->qp, &wr, &bad);
1094 if (err) {
1095 up(&umrc->sem);
1096 mlx5_ib_dbg(dev, "err %d\n", err);
1097 goto error;
a74d2416
SR
1098 } else {
1099 wait_for_completion(&umr_context.done);
1100 up(&umrc->sem);
e126ba97 1101 }
a74d2416 1102 if (umr_context.status != IB_WC_SUCCESS) {
e126ba97
EC
1103 mlx5_ib_warn(dev, "unreg umr failed\n");
1104 err = -EFAULT;
1105 goto error;
1106 }
1107 return 0;
1108
1109error:
1110 return err;
1111}
1112
1113int mlx5_ib_dereg_mr(struct ib_mr *ibmr)
1114{
1115 struct mlx5_ib_dev *dev = to_mdev(ibmr->device);
1116 struct mlx5_ib_mr *mr = to_mmr(ibmr);
1117 struct ib_umem *umem = mr->umem;
1118 int npages = mr->npages;
1119 int umred = mr->umred;
1120 int err;
1121
1122 if (!umred) {
9603b61d 1123 err = mlx5_core_destroy_mkey(dev->mdev, &mr->mmr);
e126ba97
EC
1124 if (err) {
1125 mlx5_ib_warn(dev, "failed to destroy mkey 0x%x (%d)\n",
1126 mr->mmr.key, err);
1127 return err;
1128 }
1129 } else {
1130 err = unreg_umr(dev, mr);
1131 if (err) {
1132 mlx5_ib_warn(dev, "failed unregister\n");
1133 return err;
1134 }
1135 free_cached_mr(dev, mr);
1136 }
1137
1138 if (umem) {
1139 ib_umem_release(umem);
1140 spin_lock(&dev->mr_lock);
9603b61d 1141 dev->mdev->priv.reg_pages -= npages;
e126ba97
EC
1142 spin_unlock(&dev->mr_lock);
1143 }
1144
1145 if (!umred)
1146 kfree(mr);
1147
1148 return 0;
1149}
1150
3121e3c4
SG
1151struct ib_mr *mlx5_ib_create_mr(struct ib_pd *pd,
1152 struct ib_mr_init_attr *mr_init_attr)
1153{
1154 struct mlx5_ib_dev *dev = to_mdev(pd->device);
1155 struct mlx5_create_mkey_mbox_in *in;
1156 struct mlx5_ib_mr *mr;
1157 int access_mode, err;
1158 int ndescs = roundup(mr_init_attr->max_reg_descriptors, 4);
1159
1160 mr = kzalloc(sizeof(*mr), GFP_KERNEL);
1161 if (!mr)
1162 return ERR_PTR(-ENOMEM);
1163
1164 in = kzalloc(sizeof(*in), GFP_KERNEL);
1165 if (!in) {
1166 err = -ENOMEM;
1167 goto err_free;
1168 }
1169
968e78dd 1170 in->seg.status = MLX5_MKEY_STATUS_FREE;
3121e3c4
SG
1171 in->seg.xlt_oct_size = cpu_to_be32(ndescs);
1172 in->seg.qpn_mkey7_0 = cpu_to_be32(0xffffff << 8);
1173 in->seg.flags_pd = cpu_to_be32(to_mpd(pd)->pdn);
1174 access_mode = MLX5_ACCESS_MODE_MTT;
1175
1176 if (mr_init_attr->flags & IB_MR_SIGNATURE_EN) {
1177 u32 psv_index[2];
1178
1179 in->seg.flags_pd = cpu_to_be32(be32_to_cpu(in->seg.flags_pd) |
1180 MLX5_MKEY_BSF_EN);
1181 in->seg.bsfs_octo_size = cpu_to_be32(MLX5_MKEY_BSF_OCTO_SIZE);
1182 mr->sig = kzalloc(sizeof(*mr->sig), GFP_KERNEL);
1183 if (!mr->sig) {
1184 err = -ENOMEM;
1185 goto err_free_in;
1186 }
1187
1188 /* create mem & wire PSVs */
9603b61d 1189 err = mlx5_core_create_psv(dev->mdev, to_mpd(pd)->pdn,
3121e3c4
SG
1190 2, psv_index);
1191 if (err)
1192 goto err_free_sig;
1193
1194 access_mode = MLX5_ACCESS_MODE_KLM;
1195 mr->sig->psv_memory.psv_idx = psv_index[0];
1196 mr->sig->psv_wire.psv_idx = psv_index[1];
d5436ba0
SG
1197
1198 mr->sig->sig_status_checked = true;
1199 mr->sig->sig_err_exists = false;
1200 /* Next UMR, Arm SIGERR */
1201 ++mr->sig->sigerr_count;
3121e3c4
SG
1202 }
1203
1204 in->seg.flags = MLX5_PERM_UMR_EN | access_mode;
9603b61d 1205 err = mlx5_core_create_mkey(dev->mdev, &mr->mmr, in, sizeof(*in),
3121e3c4
SG
1206 NULL, NULL, NULL);
1207 if (err)
1208 goto err_destroy_psv;
1209
1210 mr->ibmr.lkey = mr->mmr.key;
1211 mr->ibmr.rkey = mr->mmr.key;
1212 mr->umem = NULL;
1213 kfree(in);
1214
1215 return &mr->ibmr;
1216
1217err_destroy_psv:
1218 if (mr->sig) {
9603b61d 1219 if (mlx5_core_destroy_psv(dev->mdev,
3121e3c4
SG
1220 mr->sig->psv_memory.psv_idx))
1221 mlx5_ib_warn(dev, "failed to destroy mem psv %d\n",
1222 mr->sig->psv_memory.psv_idx);
9603b61d 1223 if (mlx5_core_destroy_psv(dev->mdev,
3121e3c4
SG
1224 mr->sig->psv_wire.psv_idx))
1225 mlx5_ib_warn(dev, "failed to destroy wire psv %d\n",
1226 mr->sig->psv_wire.psv_idx);
1227 }
1228err_free_sig:
1229 kfree(mr->sig);
1230err_free_in:
1231 kfree(in);
1232err_free:
1233 kfree(mr);
1234 return ERR_PTR(err);
1235}
1236
1237int mlx5_ib_destroy_mr(struct ib_mr *ibmr)
1238{
1239 struct mlx5_ib_dev *dev = to_mdev(ibmr->device);
1240 struct mlx5_ib_mr *mr = to_mmr(ibmr);
1241 int err;
1242
1243 if (mr->sig) {
9603b61d 1244 if (mlx5_core_destroy_psv(dev->mdev,
3121e3c4
SG
1245 mr->sig->psv_memory.psv_idx))
1246 mlx5_ib_warn(dev, "failed to destroy mem psv %d\n",
1247 mr->sig->psv_memory.psv_idx);
9603b61d 1248 if (mlx5_core_destroy_psv(dev->mdev,
3121e3c4
SG
1249 mr->sig->psv_wire.psv_idx))
1250 mlx5_ib_warn(dev, "failed to destroy wire psv %d\n",
1251 mr->sig->psv_wire.psv_idx);
1252 kfree(mr->sig);
1253 }
1254
9603b61d 1255 err = mlx5_core_destroy_mkey(dev->mdev, &mr->mmr);
3121e3c4
SG
1256 if (err) {
1257 mlx5_ib_warn(dev, "failed to destroy mkey 0x%x (%d)\n",
1258 mr->mmr.key, err);
1259 return err;
1260 }
1261
1262 kfree(mr);
1263
1264 return err;
1265}
1266
e126ba97
EC
1267struct ib_mr *mlx5_ib_alloc_fast_reg_mr(struct ib_pd *pd,
1268 int max_page_list_len)
1269{
1270 struct mlx5_ib_dev *dev = to_mdev(pd->device);
1271 struct mlx5_create_mkey_mbox_in *in;
1272 struct mlx5_ib_mr *mr;
1273 int err;
1274
1275 mr = kzalloc(sizeof(*mr), GFP_KERNEL);
1276 if (!mr)
1277 return ERR_PTR(-ENOMEM);
1278
1279 in = kzalloc(sizeof(*in), GFP_KERNEL);
1280 if (!in) {
1281 err = -ENOMEM;
1282 goto err_free;
1283 }
1284
968e78dd 1285 in->seg.status = MLX5_MKEY_STATUS_FREE;
e126ba97
EC
1286 in->seg.xlt_oct_size = cpu_to_be32((max_page_list_len + 1) / 2);
1287 in->seg.qpn_mkey7_0 = cpu_to_be32(0xffffff << 8);
1288 in->seg.flags = MLX5_PERM_UMR_EN | MLX5_ACCESS_MODE_MTT;
1289 in->seg.flags_pd = cpu_to_be32(to_mpd(pd)->pdn);
1290 /*
1291 * TBD not needed - issue 197292 */
1292 in->seg.log2_page_size = PAGE_SHIFT;
1293
9603b61d 1294 err = mlx5_core_create_mkey(dev->mdev, &mr->mmr, in, sizeof(*in), NULL,
746b5583 1295 NULL, NULL);
e126ba97
EC
1296 kfree(in);
1297 if (err)
1298 goto err_free;
1299
1300 mr->ibmr.lkey = mr->mmr.key;
1301 mr->ibmr.rkey = mr->mmr.key;
1302 mr->umem = NULL;
1303
1304 return &mr->ibmr;
1305
1306err_free:
1307 kfree(mr);
1308 return ERR_PTR(err);
1309}
1310
1311struct ib_fast_reg_page_list *mlx5_ib_alloc_fast_reg_page_list(struct ib_device *ibdev,
1312 int page_list_len)
1313{
1314 struct mlx5_ib_fast_reg_page_list *mfrpl;
1315 int size = page_list_len * sizeof(u64);
1316
1317 mfrpl = kmalloc(sizeof(*mfrpl), GFP_KERNEL);
1318 if (!mfrpl)
1319 return ERR_PTR(-ENOMEM);
1320
1321 mfrpl->ibfrpl.page_list = kmalloc(size, GFP_KERNEL);
1322 if (!mfrpl->ibfrpl.page_list)
1323 goto err_free;
1324
1325 mfrpl->mapped_page_list = dma_alloc_coherent(ibdev->dma_device,
1326 size, &mfrpl->map,
1327 GFP_KERNEL);
1328 if (!mfrpl->mapped_page_list)
1329 goto err_free;
1330
1331 WARN_ON(mfrpl->map & 0x3f);
1332
1333 return &mfrpl->ibfrpl;
1334
1335err_free:
1336 kfree(mfrpl->ibfrpl.page_list);
1337 kfree(mfrpl);
1338 return ERR_PTR(-ENOMEM);
1339}
1340
1341void mlx5_ib_free_fast_reg_page_list(struct ib_fast_reg_page_list *page_list)
1342{
1343 struct mlx5_ib_fast_reg_page_list *mfrpl = to_mfrpl(page_list);
1344 struct mlx5_ib_dev *dev = to_mdev(page_list->device);
1345 int size = page_list->max_page_list_len * sizeof(u64);
1346
9603b61d 1347 dma_free_coherent(&dev->mdev->pdev->dev, size, mfrpl->mapped_page_list,
e126ba97
EC
1348 mfrpl->map);
1349 kfree(mfrpl->ibfrpl.page_list);
1350 kfree(mfrpl);
1351}
d5436ba0
SG
1352
1353int mlx5_ib_check_mr_status(struct ib_mr *ibmr, u32 check_mask,
1354 struct ib_mr_status *mr_status)
1355{
1356 struct mlx5_ib_mr *mmr = to_mmr(ibmr);
1357 int ret = 0;
1358
1359 if (check_mask & ~IB_MR_CHECK_SIG_STATUS) {
1360 pr_err("Invalid status check mask\n");
1361 ret = -EINVAL;
1362 goto done;
1363 }
1364
1365 mr_status->fail_status = 0;
1366 if (check_mask & IB_MR_CHECK_SIG_STATUS) {
1367 if (!mmr->sig) {
1368 ret = -EINVAL;
1369 pr_err("signature status check requested on a non-signature enabled MR\n");
1370 goto done;
1371 }
1372
1373 mmr->sig->sig_status_checked = true;
1374 if (!mmr->sig->sig_err_exists)
1375 goto done;
1376
1377 if (ibmr->lkey == mmr->sig->err_item.key)
1378 memcpy(&mr_status->sig_err, &mmr->sig->err_item,
1379 sizeof(mr_status->sig_err));
1380 else {
1381 mr_status->sig_err.err_type = IB_SIG_BAD_GUARD;
1382 mr_status->sig_err.sig_err_offset = 0;
1383 mr_status->sig_err.key = mmr->sig->err_item.key;
1384 }
1385
1386 mmr->sig->sig_err_exists = false;
1387 mr_status->fail_status |= IB_MR_CHECK_SIG_STATUS;
1388 }
1389
1390done:
1391 return ret;
1392}