summaryrefslogtreecommitdiffstats
path: root/net/smc/smc_wr.c
diff options
context:
space:
mode:
authorDust Li <dust.li@linux.alibaba.com>2021-12-28 10:03:24 +0100
committerDavid S. Miller <davem@davemloft.net>2021-12-28 13:42:45 +0100
commit90cee52f2e780345d3629e278291aea5ac74f40f (patch)
treebd949f7dcff078d5f1a839a41db8204e13e7205e /net/smc/smc_wr.c
parentNFC: st21nfca: Fix memory leak in device probe and remove (diff)
downloadlinux-90cee52f2e780345d3629e278291aea5ac74f40f.tar.xz
linux-90cee52f2e780345d3629e278291aea5ac74f40f.zip
net/smc: don't send CDC/LLC message if link not ready
We found smc_llc_send_link_delete_all() sometimes wait for 2s timeout when testing with RDMA link up/down. It is possible when a smc_link is in ACTIVATING state, the underlaying QP is still in RESET or RTR state, which cannot send any messages out. smc_llc_send_link_delete_all() use smc_link_usable() to checks whether the link is usable, if the QP is still in RESET or RTR state, but the smc_link is in ACTIVATING, this LLC message will always fail without any CQE entering the CQ, and we will always wait 2s before timeout. Since we cannot send any messages through the QP before the QP enter RTS. I add a wrapper smc_link_sendable() which checks the state of QP along with the link state. And replace smc_link_usable() with smc_link_sendable() in all LLC & CDC message sending routine. Fixes: 5f08318f617b ("smc: connection data control (CDC)") Signed-off-by: Dust Li <dust.li@linux.alibaba.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/smc/smc_wr.c')
-rw-r--r--net/smc/smc_wr.c4
1 files changed, 2 insertions, 2 deletions
diff --git a/net/smc/smc_wr.c b/net/smc/smc_wr.c
index 79a7431f534e..df1dc225cbab 100644
--- a/net/smc/smc_wr.c
+++ b/net/smc/smc_wr.c
@@ -188,7 +188,7 @@ void smc_wr_tx_cq_handler(struct ib_cq *ib_cq, void *cq_context)
static inline int smc_wr_tx_get_free_slot_index(struct smc_link *link, u32 *idx)
{
*idx = link->wr_tx_cnt;
- if (!smc_link_usable(link))
+ if (!smc_link_sendable(link))
return -ENOLINK;
for_each_clear_bit(*idx, link->wr_tx_mask, link->wr_tx_cnt) {
if (!test_and_set_bit(*idx, link->wr_tx_mask))
@@ -231,7 +231,7 @@ int smc_wr_tx_get_free_slot(struct smc_link *link,
} else {
rc = wait_event_interruptible_timeout(
link->wr_tx_wait,
- !smc_link_usable(link) ||
+ !smc_link_sendable(link) ||
lgr->terminating ||
(smc_wr_tx_get_free_slot_index(link, &idx) != -EBUSY),
SMC_WR_TX_WAIT_FREE_SLOT_TIME);