diff options
| author | Eli Cohen <eli@mellanox.com> | 2013-09-11 09:35:26 -0400 |
|---|---|---|
| committer | Roland Dreier <roland@purestorage.com> | 2013-10-10 12:23:56 -0400 |
| commit | 203099fd731c8d74da3b00c895cfd68c6cf1ff73 (patch) | |
| tree | 70aa1827f3e59ec8417992dd9015b53398461487 | |
| parent | c1868b822515313c72445e70b7d9e47d8815bc52 (diff) | |
IB/mlx5: Decrease memory consumption of mr caches
Change the logic so we do not allocate memory nor map the device
before actually posting to the REG_UMR QP. In addition, unmap and free
the memory after we get completion.
Signed-off-by: Eli Cohen <eli@mellanox.com>
Signed-off-by: Roland Dreier <roland@purestorage.com>
| -rw-r--r-- | drivers/infiniband/hw/mlx5/mr.c | 57 |
1 files changed, 22 insertions, 35 deletions
diff --git a/drivers/infiniband/hw/mlx5/mr.c b/drivers/infiniband/hw/mlx5/mr.c index e86dbbdb3836..06e33e6cb07f 100644 --- a/drivers/infiniband/hw/mlx5/mr.c +++ b/drivers/infiniband/hw/mlx5/mr.c | |||
| @@ -61,13 +61,11 @@ static int order2idx(struct mlx5_ib_dev *dev, int order) | |||
| 61 | 61 | ||
| 62 | static int add_keys(struct mlx5_ib_dev *dev, int c, int num) | 62 | static int add_keys(struct mlx5_ib_dev *dev, int c, int num) |
| 63 | { | 63 | { |
| 64 | struct device *ddev = dev->ib_dev.dma_device; | ||
| 65 | struct mlx5_mr_cache *cache = &dev->cache; | 64 | struct mlx5_mr_cache *cache = &dev->cache; |
| 66 | struct mlx5_cache_ent *ent = &cache->ent[c]; | 65 | struct mlx5_cache_ent *ent = &cache->ent[c]; |
| 67 | struct mlx5_create_mkey_mbox_in *in; | 66 | struct mlx5_create_mkey_mbox_in *in; |
| 68 | struct mlx5_ib_mr *mr; | 67 | struct mlx5_ib_mr *mr; |
| 69 | int npages = 1 << ent->order; | 68 | int npages = 1 << ent->order; |
| 70 | int size = sizeof(u64) * npages; | ||
| 71 | int err = 0; | 69 | int err = 0; |
| 72 | int i; | 70 | int i; |
| 73 | 71 | ||
| @@ -83,21 +81,6 @@ static int add_keys(struct mlx5_ib_dev *dev, int c, int num) | |||
| 83 | } | 81 | } |
| 84 | mr->order = ent->order; | 82 | mr->order = ent->order; |
| 85 | mr->umred = 1; | 83 | mr->umred = 1; |
| 86 | mr->pas = kmalloc(size + 0x3f, GFP_KERNEL); | ||
| 87 | if (!mr->pas) { | ||
| 88 | kfree(mr); | ||
| 89 | err = -ENOMEM; | ||
| 90 | goto out; | ||
| 91 | } | ||
| 92 | mr->dma = dma_map_single(ddev, mr_align(mr->pas, 0x40), size, | ||
| 93 | DMA_TO_DEVICE); | ||
| 94 | if (dma_mapping_error(ddev, mr->dma)) { | ||
| 95 | kfree(mr->pas); | ||
| 96 | kfree(mr); | ||
| 97 | err = -ENOMEM; | ||
| 98 | goto out; | ||
| 99 | } | ||
| 100 | |||
| 101 | in->seg.status = 1 << 6; | 84 | in->seg.status = 1 << 6; |
| 102 | in->seg.xlt_oct_size = cpu_to_be32((npages + 1) / 2); | 85 | in->seg.xlt_oct_size = cpu_to_be32((npages + 1) / 2); |
| 103 | in->seg.qpn_mkey7_0 = cpu_to_be32(0xffffff << 8); | 86 | in->seg.qpn_mkey7_0 = cpu_to_be32(0xffffff << 8); |
| @@ -108,8 +91,6 @@ static int add_keys(struct mlx5_ib_dev *dev, int c, int num) | |||
| 108 | sizeof(*in)); | 91 | sizeof(*in)); |
| 109 | if (err) { | 92 | if (err) { |
| 110 | mlx5_ib_warn(dev, "create mkey failed %d\n", err); | 93 | mlx5_ib_warn(dev, "create mkey failed %d\n", err); |
| 111 | dma_unmap_single(ddev, mr->dma, size, DMA_TO_DEVICE); | ||
| 112 | kfree(mr->pas); | ||
| 113 | kfree(mr); | 94 | kfree(mr); |
| 114 | goto out; | 95 | goto out; |
| 115 | } | 96 | } |
| @@ -129,11 +110,9 @@ out: | |||
| 129 | 110 | ||
| 130 | static void remove_keys(struct mlx5_ib_dev *dev, int c, int num) | 111 | static void remove_keys(struct mlx5_ib_dev *dev, int c, int num) |
| 131 | { | 112 | { |
| 132 | struct device *ddev = dev->ib_dev.dma_device; | ||
| 133 | struct mlx5_mr_cache *cache = &dev->cache; | 113 | struct mlx5_mr_cache *cache = &dev->cache; |
| 134 | struct mlx5_cache_ent *ent = &cache->ent[c]; | 114 | struct mlx5_cache_ent *ent = &cache->ent[c]; |
| 135 | struct mlx5_ib_mr *mr; | 115 | struct mlx5_ib_mr *mr; |
| 136 | int size; | ||
| 137 | int err; | 116 | int err; |
| 138 | int i; | 117 | int i; |
| 139 | 118 | ||
| @@ -149,14 +128,10 @@ static void remove_keys(struct mlx5_ib_dev *dev, int c, int num) | |||
| 149 | ent->size--; | 128 | ent->size--; |
| 150 | spin_unlock(&ent->lock); | 129 | spin_unlock(&ent->lock); |
| 151 | err = mlx5_core_destroy_mkey(&dev->mdev, &mr->mmr); | 130 | err = mlx5_core_destroy_mkey(&dev->mdev, &mr->mmr); |
| 152 | if (err) { | 131 | if (err) |
| 153 | mlx5_ib_warn(dev, "failed destroy mkey\n"); | 132 | mlx5_ib_warn(dev, "failed destroy mkey\n"); |
| 154 | } else { | 133 | else |
| 155 | size = ALIGN(sizeof(u64) * (1 << mr->order), 0x40); | ||
| 156 | dma_unmap_single(ddev, mr->dma, size, DMA_TO_DEVICE); | ||
| 157 | kfree(mr->pas); | ||
| 158 | kfree(mr); | 134 | kfree(mr); |
| 159 | } | ||
| 160 | } | 135 | } |
| 161 | } | 136 | } |
| 162 | 137 | ||
| @@ -408,11 +383,9 @@ static void free_cached_mr(struct mlx5_ib_dev *dev, struct mlx5_ib_mr *mr) | |||
| 408 | 383 | ||
| 409 | static void clean_keys(struct mlx5_ib_dev *dev, int c) | 384 | static void clean_keys(struct mlx5_ib_dev *dev, int c) |
| 410 | { | 385 | { |
| 411 | struct device *ddev = dev->ib_dev.dma_device; | ||
| 412 | struct mlx5_mr_cache *cache = &dev->cache; | 386 | struct mlx5_mr_cache *cache = &dev->cache; |
| 413 | struct mlx5_cache_ent *ent = &cache->ent[c]; | 387 | struct mlx5_cache_ent *ent = &cache->ent[c]; |
| 414 | struct mlx5_ib_mr *mr; | 388 | struct mlx5_ib_mr *mr; |
| 415 | int size; | ||
| 416 | int err; | 389 | int err; |
| 417 | 390 | ||
| 418 | cancel_delayed_work(&ent->dwork); | 391 | cancel_delayed_work(&ent->dwork); |
| @@ -428,14 +401,10 @@ static void clean_keys(struct mlx5_ib_dev *dev, int c) | |||
| 428 | ent->size--; | 401 | ent->size--; |
| 429 | spin_unlock(&ent->lock); | 402 | spin_unlock(&ent->lock); |
| 430 | err = mlx5_core_destroy_mkey(&dev->mdev, &mr->mmr); | 403 | err = mlx5_core_destroy_mkey(&dev->mdev, &mr->mmr); |
| 431 | if (err) { | 404 | if (err) |
| 432 | mlx5_ib_warn(dev, "failed destroy mkey\n"); | 405 | mlx5_ib_warn(dev, "failed destroy mkey\n"); |
| 433 | } else { | 406 | else |
| 434 | size = ALIGN(sizeof(u64) * (1 << mr->order), 0x40); | ||
| 435 | dma_unmap_single(ddev, mr->dma, size, DMA_TO_DEVICE); | ||
| 436 | kfree(mr->pas); | ||
| 437 | kfree(mr); | 407 | kfree(mr); |
| 438 | } | ||
| 439 | } | 408 | } |
| 440 | } | 409 | } |
| 441 | 410 | ||
| @@ -678,10 +647,12 @@ static struct mlx5_ib_mr *reg_umr(struct ib_pd *pd, struct ib_umem *umem, | |||
| 678 | int page_shift, int order, int access_flags) | 647 | int page_shift, int order, int access_flags) |
| 679 | { | 648 | { |
| 680 | struct mlx5_ib_dev *dev = to_mdev(pd->device); | 649 | struct mlx5_ib_dev *dev = to_mdev(pd->device); |
| 650 | struct device *ddev = dev->ib_dev.dma_device; | ||
| 681 | struct umr_common *umrc = &dev->umrc; | 651 | struct umr_common *umrc = &dev->umrc; |
| 682 | struct ib_send_wr wr, *bad; | 652 | struct ib_send_wr wr, *bad; |
| 683 | struct mlx5_ib_mr *mr; | 653 | struct mlx5_ib_mr *mr; |
| 684 | struct ib_sge sg; | 654 | struct ib_sge sg; |
| 655 | int size = sizeof(u64) * npages; | ||
| 685 | int err; | 656 | int err; |
| 686 | int i; | 657 | int i; |
| 687 | 658 | ||
| @@ -700,6 +671,19 @@ static struct mlx5_ib_mr *reg_umr(struct ib_pd *pd, struct ib_umem *umem, | |||
| 700 | if (!mr) | 671 | if (!mr) |
| 701 | return ERR_PTR(-EAGAIN); | 672 | return ERR_PTR(-EAGAIN); |
| 702 | 673 | ||
| 674 | mr->pas = kmalloc(size + 0x3f, GFP_KERNEL); | ||
| 675 | if (!mr->pas) { | ||
| 676 | err = -ENOMEM; | ||
| 677 | goto error; | ||
| 678 | } | ||
| 679 | mr->dma = dma_map_single(ddev, mr_align(mr->pas, 0x40), size, | ||
| 680 | DMA_TO_DEVICE); | ||
| 681 | if (dma_mapping_error(ddev, mr->dma)) { | ||
| 682 | kfree(mr->pas); | ||
| 683 | err = -ENOMEM; | ||
| 684 | goto error; | ||
| 685 | } | ||
| 686 | |||
| 703 | mlx5_ib_populate_pas(dev, umem, page_shift, mr_align(mr->pas, 0x40), 1); | 687 | mlx5_ib_populate_pas(dev, umem, page_shift, mr_align(mr->pas, 0x40), 1); |
| 704 | 688 | ||
| 705 | memset(&wr, 0, sizeof(wr)); | 689 | memset(&wr, 0, sizeof(wr)); |
| @@ -721,6 +705,9 @@ static struct mlx5_ib_mr *reg_umr(struct ib_pd *pd, struct ib_umem *umem, | |||
| 721 | wait_for_completion(&mr->done); | 705 | wait_for_completion(&mr->done); |
| 722 | up(&umrc->sem); | 706 | up(&umrc->sem); |
| 723 | 707 | ||
| 708 | dma_unmap_single(ddev, mr->dma, size, DMA_TO_DEVICE); | ||
| 709 | kfree(mr->pas); | ||
| 710 | |||
| 724 | if (mr->status != IB_WC_SUCCESS) { | 711 | if (mr->status != IB_WC_SUCCESS) { |
| 725 | mlx5_ib_warn(dev, "reg umr failed\n"); | 712 | mlx5_ib_warn(dev, "reg umr failed\n"); |
| 726 | err = -EFAULT; | 713 | err = -EFAULT; |
