summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPengpeng Hou <pengpeng@iscas.ac.cn>2026-06-25 08:36:14 +0800
committerLeon Romanovsky <leon@kernel.org>2026-07-06 04:50:11 -0400
commit5f9576c6734abca88a02db72c466e09d2eddf160 (patch)
tree8eb1e9d131d48afc907d006c8b9c0ca8c1f2692f
parent297b5b747a0a2c6b63088d3f5cc102a6cffaf292 (diff)
downloadlinux-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.c10
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);
};