IB/mlx5: Use direct mkey destroy command upon UMR unreg failure [Linux 4.14.137]

This Linux kernel change "IB/mlx5: Use direct mkey destroy command upon UMR unreg failure" is included in the Linux 4.14.137 release. This change is authored by Yishai Hadas <yishaih [at] mellanox.com> on Tue Jul 23 09:57:26 2019 +0300. The commit for this change in Linux stable tree is 7d9a437 (patch) which is from upstream commit afd1417. The same Linux upstream change may have been applied to various maintained Linux releases and you can find all Linux releases containing changes from upstream afd1417.

IB/mlx5: Use direct mkey destroy command upon UMR unreg failure

commit afd1417404fba6dbfa6c0a8e5763bd348da682e4 upstream.

Use a direct firmware command to destroy the mkey in case the unreg UMR
operation has failed.

This prevents a case that a mkey will leak out from the cache post a
failure to be destroyed by a UMR WR.

In case the MR cache limit didn't reach a call to add another entry to the
cache instead of the destroyed one is issued.

In addition, replaced a warn message to WARN_ON() as this flow is fatal
and can't happen unless some bug around.

Link: https://lore.kernel.org/r/[email protected]
Cc: <[email protected]> # 4.10
Fixes: 49780d42dfc9 ("IB/mlx5: Expose MR cache for mlx5_ib")
Signed-off-by: Yishai Hadas <[email protected]>
Reviewed-by: Artemy Kovalyov <[email protected]>
Signed-off-by: Leon Romanovsky <[email protected]>
Reviewed-by: Jason Gunthorpe <[email protected]>
Signed-off-by: Jason Gunthorpe <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>

There are 13 lines of Linux source code added/deleted in this change. Code changes to Linux kernel are as follows.

 drivers/infiniband/hw/mlx5/mr.c | 13 ++++++++-----
 1 file changed, 8 insertions(+), 5 deletions(-)

diff --git a/drivers/infiniband/hw/mlx5/mr.c b/drivers/infiniband/hw/mlx5/mr.c
index 2c2742b..903f4c1 100644
--- a/drivers/infiniband/hw/mlx5/mr.c
+++ b/drivers/infiniband/hw/mlx5/mr.c
@@ -538,14 +538,17 @@ void mlx5_mr_cache_free(struct mlx5_ib_dev *dev, struct mlx5_ib_mr *mr)
    int c;

    c = order2idx(dev, mr->order);
-   if (c < 0 || c >= MAX_MR_CACHE_ENTRIES) {
-       mlx5_ib_warn(dev, "order %d, cache index %d\n", mr->order, c);
+   WARN_ON(c < 0 || c >= MAX_MR_CACHE_ENTRIES);
+
+   if (unreg_umr(dev, mr)) {
+       mr->allocated_from_cache = false;
+       destroy_mkey(dev, mr);
+       ent = &cache->ent[c];
+       if (ent->cur < ent->limit)
+           queue_work(cache->wq, &ent->work);
        return;
    }

-   if (unreg_umr(dev, mr))
-       return;
-
    ent = &cache->ent[c];
    spin_lock_irq(&ent->lock);
    list_add_tail(&mr->list, &ent->head);

Leave a Reply

Your email address will not be published. Required fields are marked *