]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
RDMA/core: Add ib_frmr_pool_drop for unrecoverable handles
authorMichael Guralnik <michaelgur@nvidia.com>
Wed, 10 Jun 2026 00:01:44 +0000 (03:01 +0300)
committerJason Gunthorpe <jgg@nvidia.com>
Thu, 11 Jun 2026 18:36:09 +0000 (15:36 -0300)
A driver that has popped a handle from an FRMR pool can hit failures
that leave the handle in a state where it can't safely be returned
for reuse. The driver destroys the handle itself, but the pool has
no way to learn about it, so the in_use counter drifts upward.

Add ib_frmr_pool_drop to balance the pool's accounting in this case.
Every pop is now balanced by exactly one push or drop.

Fixes: 36680ef7bceb ("RDMA/mlx5: Switch from MR cache to FRMR pools")
Link: https://patch.msgid.link/r/20260610000145.820592-9-michaelgur@nvidia.com
Signed-off-by: Michael Guralnik <michaelgur@nvidia.com>
Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
drivers/infiniband/core/frmr_pools.c
include/rdma/frmr_pools.h

index e214a8273df84430011e769d3767a8dcc91ca143..ce8ae4305b9c8fe77fc5372183a2ca0d528adf5e 100644 (file)
@@ -578,3 +578,18 @@ void ib_frmr_pool_push(struct ib_device *device, struct ib_mr *mr)
 
 }
 EXPORT_SYMBOL(ib_frmr_pool_push);
+
+/*
+ * Drop a handle previously popped from the pool without returning it for
+ * reuse. The caller is responsible for destroying the underlying hardware
+ * resource.
+ */
+void ib_frmr_pool_drop(struct ib_mr *mr)
+{
+       struct ib_frmr_pool *pool = mr->frmr.pool;
+
+       spin_lock(&pool->lock);
+       pool->in_use--;
+       spin_unlock(&pool->lock);
+}
+EXPORT_SYMBOL(ib_frmr_pool_drop);
index 5b57bafa3636690ad1362294eec9e78b5992d6df..aed4d69d3841c43160d8ae89f57cad2b508fb7b0 100644 (file)
@@ -35,5 +35,6 @@ int ib_frmr_pools_init(struct ib_device *device,
 void ib_frmr_pools_cleanup(struct ib_device *device);
 int ib_frmr_pool_pop(struct ib_device *device, struct ib_mr *mr);
 void ib_frmr_pool_push(struct ib_device *device, struct ib_mr *mr);
+void ib_frmr_pool_drop(struct ib_mr *mr);
 
 #endif /* FRMR_POOLS_H */