RDMA/mlx5: Fix MR cache initialization error flow
authorMichael Guralnik <michaelgur@nvidia.com>
Thu, 13 Mar 2025 14:29:48 +0000 (16:29 +0200)
committerLeon Romanovsky <leon@kernel.org>
Tue, 18 Mar 2025 10:30:47 +0000 (06:30 -0400)
Destroy all previously created cache entries and work queue when rolling
back the MR cache initialization upon an error.

Fixes: 73d09b2fe833 ("RDMA/mlx5: Introduce mlx5r_cache_rb_key")
Signed-off-by: Michael Guralnik <michaelgur@nvidia.com>
Reviewed-by: Yishai Hadas <yishaih@nvidia.com>
Link: https://patch.msgid.link/c41d525fb3c72e28dd38511bf3aaccb5d584063e.1741875692.git.leon@kernel.org
Signed-off-by: Leon Romanovsky <leon@kernel.org>
drivers/infiniband/hw/mlx5/mr.c

index bb02b6adbf2c21ba1554783f9686130f7d05eb2d..1ffa4b3d0f760f2c148a48666e7d80801c067688 100644 (file)
@@ -919,6 +919,25 @@ mkeys_err:
        return ERR_PTR(ret);
 }
 
+static void mlx5r_destroy_cache_entries(struct mlx5_ib_dev *dev)
+{
+       struct rb_root *root = &dev->cache.rb_root;
+       struct mlx5_cache_ent *ent;
+       struct rb_node *node;
+
+       mutex_lock(&dev->cache.rb_lock);
+       node = rb_first(root);
+       while (node) {
+               ent = rb_entry(node, struct mlx5_cache_ent, node);
+               node = rb_next(node);
+               clean_keys(dev, ent);
+               rb_erase(&ent->node, root);
+               mlx5r_mkeys_uninit(ent);
+               kfree(ent);
+       }
+       mutex_unlock(&dev->cache.rb_lock);
+}
+
 int mlx5_mkey_cache_init(struct mlx5_ib_dev *dev)
 {
        struct mlx5_mkey_cache *cache = &dev->cache;
@@ -970,6 +989,8 @@ int mlx5_mkey_cache_init(struct mlx5_ib_dev *dev)
 err:
        mutex_unlock(&cache->rb_lock);
        mlx5_mkey_cache_debugfs_cleanup(dev);
+       mlx5r_destroy_cache_entries(dev);
+       destroy_workqueue(cache->wq);
        mlx5_ib_warn(dev, "failed to create mkey cache entry\n");
        return ret;
 }
@@ -1003,17 +1024,7 @@ void mlx5_mkey_cache_cleanup(struct mlx5_ib_dev *dev)
        mlx5_cmd_cleanup_async_ctx(&dev->async_ctx);
 
        /* At this point all entries are disabled and have no concurrent work. */
-       mutex_lock(&dev->cache.rb_lock);
-       node = rb_first(root);
-       while (node) {
-               ent = rb_entry(node, struct mlx5_cache_ent, node);
-               node = rb_next(node);
-               clean_keys(dev, ent);
-               rb_erase(&ent->node, root);
-               mlx5r_mkeys_uninit(ent);
-               kfree(ent);
-       }
-       mutex_unlock(&dev->cache.rb_lock);
+       mlx5r_destroy_cache_entries(dev);
 
        destroy_workqueue(dev->cache.wq);
        del_timer_sync(&dev->delay_timer);