From: Ruoyu Wang <ruoyuw560@gmail.com>
To: Bernard Metzler <bernard.metzler@linux.dev>
Cc: Jason Gunthorpe <jgg@ziepe.ca>, Leon Romanovsky <leon@kernel.org>,
linux-rdma@vger.kernel.org, linux-kernel@vger.kernel.org,
Ruoyu Wang <ruoyuw560@gmail.com>
Subject: [PATCH v2] RDMA/siw: publish QP after initialization
Date: Thu, 25 Jun 2026 21:44:26 +0800 [thread overview]
Message-ID: <20260625134426.3084850-1-ruoyuw560@gmail.com> (raw)
In-Reply-To: <20260620155306.78919-1-ruoyuw560@gmail.com>
siw_create_qp() currently calls siw_qp_add() before the queues, CQ
pointers, state, completion, and device list entry are ready. A QPN
lookup can therefore reach a QP that is still being constructed.
Move the siw_qp_add() publication step to the end of siw_create_qp(),
after the kernel-visible QP state is initialized. The QPN must still be
known before copying the siw-specific create response to userspace, so
reserve the QPN first with an empty XArray entry. This lets
siw_create_qp() report the QPN while QPN lookups still return NULL until
the QP is published.
Fixes: f29dd55b0236 ("rdma/siw: queue pair methods")
Suggested-by: Bernard Metzler <bernard.metzler@linux.dev>
Signed-off-by: Ruoyu Wang <ruoyuw560@gmail.com>
---
Changes in v2:
- Move the siw_qp_add() publication step to the end of siw_create_qp().
- Add siw_qp_reserve_qpn() so the udata response can still report qp_num
before the QP becomes visible to QPN lookups.
drivers/infiniband/sw/siw/siw.h | 1 +
drivers/infiniband/sw/siw/siw_qp.c | 26 ++++++++++++++++++--------
drivers/infiniband/sw/siw/siw_verbs.c | 14 ++++++++++++--
3 files changed, 31 insertions(+), 10 deletions(-)
diff --git a/drivers/infiniband/sw/siw/siw.h b/drivers/infiniband/sw/siw/siw.h
index f5fd71717b80..f8d28dd7dd86 100644
--- a/drivers/infiniband/sw/siw/siw.h
+++ b/drivers/infiniband/sw/siw/siw.h
@@ -510,6 +510,7 @@ void siw_send_terminate(struct siw_qp *qp);
void siw_qp_get_ref(struct ib_qp *qp);
void siw_qp_put_ref(struct ib_qp *qp);
+int siw_qp_reserve_qpn(struct siw_device *sdev, struct siw_qp *qp);
int siw_qp_add(struct siw_device *sdev, struct siw_qp *qp);
void siw_free_qp(struct kref *ref);
diff --git a/drivers/infiniband/sw/siw/siw_qp.c b/drivers/infiniband/sw/siw/siw_qp.c
index bb780e3904a2..7d6224ebfe71 100644
--- a/drivers/infiniband/sw/siw/siw_qp.c
+++ b/drivers/infiniband/sw/siw/siw_qp.c
@@ -1279,17 +1279,27 @@ void siw_rq_flush(struct siw_qp *qp)
}
}
+int siw_qp_reserve_qpn(struct siw_device *sdev, struct siw_qp *qp)
+{
+ qp->sdev = sdev;
+
+ return xa_alloc(&sdev->qp_xa, &qp->base_qp.qp_num, NULL,
+ xa_limit_32b, GFP_KERNEL);
+}
+
int siw_qp_add(struct siw_device *sdev, struct siw_qp *qp)
{
- int rv = xa_alloc(&sdev->qp_xa, &qp->base_qp.qp_num, qp, xa_limit_32b,
- GFP_KERNEL);
+ void *old;
- if (!rv) {
- kref_init(&qp->ref);
- qp->sdev = sdev;
- siw_dbg_qp(qp, "new QP\n");
- }
- return rv;
+ kref_init(&qp->ref);
+
+ old = xa_store(&sdev->qp_xa, qp_id(qp), qp, GFP_KERNEL);
+ if (xa_is_err(old))
+ return xa_err(old);
+
+ siw_dbg_qp(qp, "new QP\n");
+
+ return 0;
}
void siw_free_qp(struct kref *ref)
diff --git a/drivers/infiniband/sw/siw/siw_verbs.c b/drivers/infiniband/sw/siw/siw_verbs.c
index 1e1d262a4ae2..ef9fa9c5bf88 100644
--- a/drivers/infiniband/sw/siw/siw_verbs.c
+++ b/drivers/infiniband/sw/siw/siw_verbs.c
@@ -369,7 +369,7 @@ int siw_create_qp(struct ib_qp *ibqp, struct ib_qp_init_attr *attrs,
spin_lock_init(&qp->rq_lock);
spin_lock_init(&qp->orq_lock);
- rv = siw_qp_add(sdev, qp);
+ rv = siw_qp_reserve_qpn(sdev, qp);
if (rv)
goto err_atomic;
@@ -482,14 +482,24 @@ int siw_create_qp(struct ib_qp *ibqp, struct ib_qp_init_attr *attrs,
goto err_out_xa;
}
INIT_LIST_HEAD(&qp->devq);
+ init_completion(&qp->qp_free);
+
spin_lock_irqsave(&sdev->lock, flags);
list_add_tail(&qp->devq, &sdev->qp_list);
spin_unlock_irqrestore(&sdev->lock, flags);
- init_completion(&qp->qp_free);
+ rv = siw_qp_add(sdev, qp);
+ if (rv)
+ goto err_out_list;
return 0;
+err_out_list:
+ spin_lock_irqsave(&sdev->lock, flags);
+ list_del(&qp->devq);
+ spin_unlock_irqrestore(&sdev->lock, flags);
+
+ siw_put_tx_cpu(qp->tx_cpu);
err_out_xa:
xa_erase(&sdev->qp_xa, qp_id(qp));
if (uctx) {
next prev parent reply other threads:[~2026-06-25 13:44 UTC|newest]
Thread overview: 4+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-06-20 15:53 [PATCH] " Ruoyu Wang
2026-06-24 14:16 ` Bernard Metzler
2026-06-25 13:44 ` Ruoyu Wang [this message]
2026-06-26 12:05 ` [PATCH v2] " Bernard Metzler
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260625134426.3084850-1-ruoyuw560@gmail.com \
--to=ruoyuw560@gmail.com \
--cc=bernard.metzler@linux.dev \
--cc=jgg@ziepe.ca \
--cc=leon@kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-rdma@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®