diff options
| author | Pengpeng Hou <pengpeng@iscas.ac.cn> | 2026-06-25 08:36:14 +0800 |
|---|---|---|
| committer | Leon Romanovsky <leon@kernel.org> | 2026-07-06 04:50:11 -0400 |
| commit | 5f9576c6734abca88a02db72c466e09d2eddf160 (patch) | |
| tree | 8eb1e9d131d48afc907d006c8b9c0ca8c1f2692f | |
| parent | 297b5b747a0a2c6b63088d3f5cc102a6cffaf292 (diff) | |
| download | linux-5f9576c6734abca88a02db72c466e09d2eddf160.tar.gz linux-5f9576c6734abca88a02db72c466e09d2eddf160.zip | |
RDMA/bng_re: return a timeout when firmware responses stall
__wait_for_resp() documents that it returns a non-zero error when a
firmware command does not complete, and bng_re_rcfw_send_message() already
marks the firmware as stalled when the helper returns -ENODEV.
However, the helper ignores wait_event_timeout() expiry. If the response
slot remains in use after the timeout and after the polled CREQ service
attempt, the loop starts another full timeout period and can repeat
forever.
Return -ENODEV after a timed out wait that still has no response. The
existing caller then marks FIRMWARE_STALL_DETECTED and returns
-ETIMEDOUT to the command issuer.
Fixes: 53c6ee7d7f68 ("RDMA/bng_re: Enable Firmware channel and query device attributes")
Signed-off-by: Pengpeng Hou <pengpeng@iscas.ac.cn>
Link: https://patch.msgid.link/20260625003614.27515-1-pengpeng@iscas.ac.cn
Reviewed-by: Siva Reddy Kallam <siva.kallam@broadcom.com>
Signed-off-by: Leon Romanovsky <leon@kernel.org>
| -rw-r--r-- | drivers/infiniband/hw/bng_re/bng_fw.c | 10 |
1 files changed, 7 insertions, 3 deletions
diff --git a/drivers/infiniband/hw/bng_re/bng_fw.c b/drivers/infiniband/hw/bng_re/bng_fw.c index 50156c300b33..ab6a2d2e95b5 100644 --- a/drivers/infiniband/hw/bng_re/bng_fw.c +++ b/drivers/infiniband/hw/bng_re/bng_fw.c @@ -401,14 +401,15 @@ static int __wait_for_resp(struct bng_re_rcfw *rcfw, u16 cookie) { struct bng_re_cmdq_ctx *cmdq; struct bng_re_crsqe *crsqe; + unsigned long time_left; cmdq = &rcfw->cmdq; crsqe = &rcfw->crsqe_tbl[cookie]; do { - wait_event_timeout(cmdq->waitq, - !crsqe->is_in_used, - secs_to_jiffies(rcfw->max_timeout)); + time_left = wait_event_timeout(cmdq->waitq, + !crsqe->is_in_used, + secs_to_jiffies(rcfw->max_timeout)); if (!crsqe->is_in_used) return 0; @@ -417,6 +418,9 @@ static int __wait_for_resp(struct bng_re_rcfw *rcfw, u16 cookie) if (!crsqe->is_in_used) return 0; + + if (!time_left) + return -ENODEV; } while (true); }; |
