Re: [PATCH] RDMA/mlx5: Wait for in-flight page faults on implicit MR null_mkey dereg

From: Michael Gur

Date: Mon Sep 28 2026 - 18:46:51 EST



On 9/20/2026 12:06 PM, lirongqing wrote:
External email: Use caution opening links or attachments


From: Li RongQing <lirongqing@xxxxxxxxx>

An implicit ODP MR (imr) publishes two mkeys into dev->odp_mkeys: the
main imr->mmkey and imr->null_mmkey (MLX5_MKEY_NULL). Both are stored via
mlx5r_store_odp_mkey(), which initialises their usecount to 1, and
find_odp_mkey() takes a reference on whichever mkey it finds for the
duration of a page fault.

__mlx5_ib_dereg_mr() erases and waits on the *main* mmkey usecount only.
For the null_mmkey, mlx5_ib_free_odp_mr() merely xa_erase()s it from
odp_mkeys and calls mlx5_core_destroy_mkey() -- it never waits for an
in-flight memory-scheme page fault (MLX5_MKEY_NULL) that holds a
reference on null_mmkey. After xa_erase(), find_odp_mkey() stops
returning the null_mmkey, but a fault already past the lookup still
holds a reference and dereferences the imr (via container_of and
pagefault_mr) after __mlx5_ib_dereg_mr() proceeds to kfree(mr).

Mirror the main-mmkey handling: after xa_erase() of null_mmkey, call
mlx5r_deref_wait_odp_mkey() to drop the reference taken at store time
and wait for any in-flight fault to finish before destroying the mkey
and freeing the imr.

Adding the wait after the implicit MR mkey was cleaned up and its umem was released doesn't solve the issue.

I suggest to make the implicit MR dereg wait for its null-mkey reference to drop, before any cleanup, or change how we handle the null-mkey: when a page fault hits it, take a reference on the implicit MR mkey instead.

Fixes: 6f2487bfafce ("RDMA/mlx5: Add implicit MR handling to ODP memory scheme")
Signed-off-by: Li RongQing <lirongqing@xxxxxxxxx>
---
drivers/infiniband/hw/mlx5/odp.c | 2 ++
1 file changed, 2 insertions(+)

diff --git a/drivers/infiniband/hw/mlx5/odp.c b/drivers/infiniband/hw/mlx5/odp.c
index b861861..f27ca77 100644
--- a/drivers/infiniband/hw/mlx5/odp.c
+++ b/drivers/infiniband/hw/mlx5/odp.c
@@ -683,6 +683,8 @@ void mlx5_ib_free_odp_mr(struct mlx5_ib_mr *mr)
xa_erase(&mr_to_mdev(mr)->odp_mkeys,
mlx5_base_mkey(mr->null_mmkey.key));

+ mlx5r_deref_wait_odp_mkey(&mr->null_mmkey);
+
mlx5_core_destroy_mkey(mr_to_mdev(mr)->mdev,
mr->null_mmkey.key);
}
--
2.9.4