All of lore.kernel.org
 help / color / mirror / Atom feed
* RDMA/mlx5: question about a failed destroy in the SRQ create error path
@ 2026-10-28  5:38 Yuho Choi
  2026-10-28  5:53 ` sashiko-bot
  0 siblings, 1 reply; 2+ messages in thread
From: Yuho Choi @ 2026-10-28  5:38 UTC (permalink / raw)
  To: Leon Romanovsky; +Cc: Jason Gunthorpe, Yishai Hadas, linux-rdma

Hi Leon,

I have a question about the error path of mlx5_ib_create_srq() (rdma
for-next, c3e8e9451e6f) and would appreciate your view. When copying
the response to user space fails, the result of the destroy is not
checked:

	err_core:
		mlx5_cmd_destroy_srq(dev, &srq->msrq);

	err_usr_kern_srq:
		if (udata)
			destroy_srq_user(ib_srq->pd, srq, udata);

If I read it correctly, a failed destroy here would leave the firmware
SRQ using the SRQ buffer and doorbell record that are then released.
Since fd89099d635e ("RDMA/mlx5: Issue FW command to destroy SRQ on
reentry") the SRQ would also be back in dev->srq_table after the core
frees the ib_srq, so SRQ events and ODP page faults (odp_get_rsc())
could find freed memory.

Thanks for explaining in [1] that DESTROY of kernel-owned objects does
not fail on working firmware. I wondered whether user SRQs might be
different, since they carry the uid of their context and a DEVX QP of
the same uid can use them, which 43d781b9fa56 ("RDMA: Allow fail of
destroy CQ") mentions as a reason for destroy to fail. For example,
could user space create such a DEVX QP on the new SRQ number (probing
for it) while the response copy is held up, say on a FUSE-backed
buffer, and then let the copy fail? I could not tell from the tree
whether the firmware would refuse the destroy in that case, so I may
well be missing something.

If this is a real problem, would something like the untested diff below
be acceptable? It keeps the memory and drops the table entry, at the
cost of leaking the SRQ. If you prefer, such SRQs could instead be kept
on the ucontext and destroyed again from mlx5_ib_dealloc_ucontext(),
which avoids the leak.

This was found with a static analysis tool from ongoing, not yet
published research, and confirmed by code inspection. It has not been
reproduced, and I used an LLM to help with the analysis and this mail.

[1] https://lore.kernel.org/r/20261016045849.813696-6-oss.patchbox@gmail.com

Thanks,
Yuho

diff --git a/drivers/infiniband/hw/mlx5/srq.c b/drivers/infiniband/hw/mlx5/srq.c
index 6a4a937d97ce..96ea15ba0487 100644
--- a/drivers/infiniband/hw/mlx5/srq.c
+++ b/drivers/infiniband/hw/mlx5/srq.c
@@ -310,7 +310,15 @@ int mlx5_ib_create_srq(struct ib_srq *ib_srq,
 	return 0;

 err_core:
-	mlx5_cmd_destroy_srq(dev, &srq->msrq);
+	/*
+	 * Only user SRQs get here. If a DEVX object still uses the SRQ, the
+	 * firmware may refuse to destroy it; leak the buffer and doorbell
+	 * record rather than free pages the device can still access.
+	 */
+	if (mlx5_cmd_destroy_srq(dev, &srq->msrq)) {
+		mlx5_cmd_untrack_srq(dev, &srq->msrq);
+		return err;
+	}

 err_usr_kern_srq:
 	if (udata)
diff --git a/drivers/infiniband/hw/mlx5/srq.h b/drivers/infiniband/hw/mlx5/srq.h
index a7e3dc5564ac..4cd63e8d8579 100644
--- a/drivers/infiniband/hw/mlx5/srq.h
+++ b/drivers/infiniband/hw/mlx5/srq.h
@@ -58,6 +58,7 @@ struct mlx5_srq_table {
 int mlx5_cmd_create_srq(struct mlx5_ib_dev *dev, struct mlx5_core_srq *srq,
 			struct mlx5_srq_attr *in);
 int mlx5_cmd_destroy_srq(struct mlx5_ib_dev *dev, struct mlx5_core_srq *srq);
+void mlx5_cmd_untrack_srq(struct mlx5_ib_dev *dev, struct mlx5_core_srq *srq);
 int mlx5_cmd_query_srq(struct mlx5_ib_dev *dev, struct mlx5_core_srq *srq,
 		       struct mlx5_srq_attr *out);
 int mlx5_cmd_arm_srq(struct mlx5_ib_dev *dev, struct mlx5_core_srq *srq,
diff --git a/drivers/infiniband/hw/mlx5/srq_cmd.c b/drivers/infiniband/hw/mlx5/srq_cmd.c
index c1a088120915..c97e22946ef3 100644
--- a/drivers/infiniband/hw/mlx5/srq_cmd.c
+++ b/drivers/infiniband/hw/mlx5/srq_cmd.c
@@ -697,6 +697,22 @@ int mlx5_cmd_destroy_srq(struct mlx5_ib_dev *dev, struct mlx5_core_srq *srq)
 	return 0;
 }

+/*
+ * For an SRQ whose destroy failed in the error flow of its creation: the
+ * firmware object stays, but the caller is about to free @srq, which
+ * mlx5_cmd_destroy_srq() put back into the table. Remove it and wait for
+ * concurrent lookups to drop their references.
+ */
+void mlx5_cmd_untrack_srq(struct mlx5_ib_dev *dev, struct mlx5_core_srq *srq)
+{
+	struct mlx5_srq_table *table = &dev->srq_table;
+
+	xa_cmpxchg_irq(&table->array, srq->srqn, srq, NULL, 0);
+
+	mlx5_core_res_put(&srq->common);
+	wait_for_completion(&srq->common.free);
+}
+
 int mlx5_cmd_query_srq(struct mlx5_ib_dev *dev, struct mlx5_core_srq *srq,
 		       struct mlx5_srq_attr *out)
 {

^ permalink raw reply related	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2026-10-28  5:53 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-10-28  5:38 RDMA/mlx5: question about a failed destroy in the SRQ create error path Yuho Choi
2026-10-28  5:53 ` sashiko-bot

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.