From: Zhu Yanjun <yanjun.zhu@linux.dev>
To: Li Zhijian <lizhijian@fujitsu.com>, linux-rdma@vger.kernel.org
Cc: linux-kernel@vger.kernel.org, zyjzyj2000@gmail.com, jgg@ziepe.ca,
leon@kernel.org
Subject: Re: [PATCH] RDMA/rxe: Fix race condition in QP timer handlers
Date: Tue, 20 Jan 2026 21:04:27 -0800 [thread overview]
Message-ID: <0f37cd78-d4d1-4910-95e2-8f91a6417b3a@linux.dev> (raw)
In-Reply-To: <20260120074437.623018-1-lizhijian@fujitsu.com>
在 2026/1/19 23:44, Li Zhijian 写道:
> I encontered the following warning:
> WARNING: drivers/infiniband/sw/rxe/rxe_task.c:249 at rxe_sched_task+0x1c8/0x238 [rdma_rxe], CPU#0: swapper/0/0
> ...
> libsha1 [last unloaded: ip6_udp_tunnel]
> CPU: 0 UID: 0 PID: 0 Comm: swapper/0 Tainted: G C 6.19.0-rc5-64k-v8+ #37 PREEMPT
> Tainted: [C]=CRAP
> Hardware name: Raspberry Pi 4 Model B Rev 1.2
> Call trace:
> rxe_sched_task+0x1c8/0x238 [rdma_rxe] (P)
> retransmit_timer+0x130/0x188 [rdma_rxe]
> call_timer_fn+0x68/0x4d0
> __run_timers+0x630/0x888
> ...
> WARNING: drivers/infiniband/sw/rxe/rxe_task.c:38 at rxe_sched_task+0x1c0/0x238 [rdma_rxe], CPU#0: swapper/0/0
> ...
> WARNING: drivers/infiniband/sw/rxe/rxe_task.c:111 at do_work+0x488/0x5c8 [rdma_rxe], CPU#3: kworker/u17:4/93400
> ...
> refcount_t: underflow; use-after-free.
> WARNING: lib/refcount.c:28 at refcount_warn_saturate+0x138/0x1a0, CPU#3: kworker/u17:4/93400
>
> The issue is caused by a race condition between retransmit_timer() and
> rxe_destroy_qp, leading to the Queue Pair's (QP) reference count dropping
> to zero during timer handler execution.
>
> It seems this warning is harmless because rxe_qp_do_cleanup() will flush
> all pending timers and requests.
>
> Example of flow causing the issue:
>
> CPU0 CPU1
> retransmit_timer() {
> spin_lock_irqsave
> rxe_destroy_qp()
> __rxe_cleanup()
> __rxe_put() // qp->ref_count decrease to 0
In __rxe_cleanup, __rxe_put decrease qp->ref_count to 0.
Then in the timer functions retransmit_timer and rnr_nak_timer will
check qp and resend the packets. IMO, it may be a solution to use the
function rxe_get to check if ref_count is 0 or not.
I am fine with it.
Reviewed-by: Zhu Yanjun <yanjun.zhu@linux.dev>
Thanks,
Zhu Yanjun
> rxe_qp_do_cleanup() {
> if (qp->valid) {
> rxe_sched_task() {
> WARN_ON(rxe_read(task->qp) <= 0);
> }
> }
> spin_unlock_irqrestore
> }
> spin_lock_irqsave
> qp->valid = 0
> spin_unlock_irqrestore
> }
>
> Ensure the QP's reference count is maintained and its validity is checked
> within the timer callbacks by adding calls to rxe_get(qp) and corresponding
> rxe_put(qp) after use.
>
> Signed-off-by: Li Zhijian <lizhijian@fujitsu.com>
> ---
> drivers/infiniband/sw/rxe/rxe_comp.c | 3 +++
> drivers/infiniband/sw/rxe/rxe_req.c | 3 +++
> 2 files changed, 6 insertions(+)
>
> diff --git a/drivers/infiniband/sw/rxe/rxe_comp.c b/drivers/infiniband/sw/rxe/rxe_comp.c
> index a5b2b62f596b..1390e861bd1d 100644
> --- a/drivers/infiniband/sw/rxe/rxe_comp.c
> +++ b/drivers/infiniband/sw/rxe/rxe_comp.c
> @@ -119,12 +119,15 @@ void retransmit_timer(struct timer_list *t)
>
> rxe_dbg_qp(qp, "retransmit timer fired\n");
>
> + if (!rxe_get(qp))
> + return;
> spin_lock_irqsave(&qp->state_lock, flags);
> if (qp->valid) {
> qp->comp.timeout = 1;
> rxe_sched_task(&qp->send_task);
> }
> spin_unlock_irqrestore(&qp->state_lock, flags);
> + rxe_put(qp);
> }
>
> void rxe_comp_queue_pkt(struct rxe_qp *qp, struct sk_buff *skb)
> diff --git a/drivers/infiniband/sw/rxe/rxe_req.c b/drivers/infiniband/sw/rxe/rxe_req.c
> index 373b03f223be..12d03f390b09 100644
> --- a/drivers/infiniband/sw/rxe/rxe_req.c
> +++ b/drivers/infiniband/sw/rxe/rxe_req.c
> @@ -102,6 +102,8 @@ void rnr_nak_timer(struct timer_list *t)
>
> rxe_dbg_qp(qp, "nak timer fired\n");
>
> + if (!rxe_get(qp))
> + return;
> spin_lock_irqsave(&qp->state_lock, flags);
> if (qp->valid) {
> /* request a send queue retry */
> @@ -110,6 +112,7 @@ void rnr_nak_timer(struct timer_list *t)
> rxe_sched_task(&qp->send_task);
> }
> spin_unlock_irqrestore(&qp->state_lock, flags);
> + rxe_put(qp);
> }
>
> static void req_check_sq_drain_done(struct rxe_qp *qp)
next prev parent reply other threads:[~2026-01-21 5:05 UTC|newest]
Thread overview: 7+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-01-20 7:44 [PATCH] RDMA/rxe: Fix race condition in QP timer handlers Li Zhijian
2026-01-21 5:04 ` Zhu Yanjun [this message]
2026-01-25 14:08 ` Leon Romanovsky
2026-01-25 21:24 ` Zhu Yanjun
2026-01-27 9:27 ` Zhijian Li (Fujitsu)
2026-01-28 10:02 ` Leon Romanovsky
2026-01-28 10:25 ` Leon Romanovsky
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=0f37cd78-d4d1-4910-95e2-8f91a6417b3a@linux.dev \
--to=yanjun.zhu@linux.dev \
--cc=jgg@ziepe.ca \
--cc=leon@kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-rdma@vger.kernel.org \
--cc=lizhijian@fujitsu.com \
--cc=zyjzyj2000@gmail.com \
/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 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.