Skip to content

Commit b7eede7

Browse files
karstengrdavem330
authored andcommitted
net/smc: fix work request handling
Wait for pending sends only when smc_switch_conns() found a link to move the connections to. Do not wait during link freeing, this can lead to permanent hang situations. And refuse to provide a new tx slot on an unusable link. Fixes: c6f02eb ("net/smc: switch connections to alternate link") Reviewed-by: Ursula Braun <[email protected]> Signed-off-by: Karsten Graul <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent 6778a6b commit b7eede7

File tree

2 files changed

+10
-8
lines changed

2 files changed

+10
-8
lines changed

net/smc/smc_llc.c

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1241,8 +1241,8 @@ static void smc_llc_process_cli_delete_link(struct smc_link_group *lgr)
12411241
smc_llc_send_message(lnk, &qentry->msg); /* response */
12421242

12431243
if (smc_link_downing(&lnk_del->state)) {
1244-
smc_switch_conns(lgr, lnk_del, false);
1245-
smc_wr_tx_wait_no_pending_sends(lnk_del);
1244+
if (smc_switch_conns(lgr, lnk_del, false))
1245+
smc_wr_tx_wait_no_pending_sends(lnk_del);
12461246
}
12471247
smcr_link_clear(lnk_del, true);
12481248

@@ -1316,8 +1316,8 @@ static void smc_llc_process_srv_delete_link(struct smc_link_group *lgr)
13161316
goto out; /* asymmetric link already deleted */
13171317

13181318
if (smc_link_downing(&lnk_del->state)) {
1319-
smc_switch_conns(lgr, lnk_del, false);
1320-
smc_wr_tx_wait_no_pending_sends(lnk_del);
1319+
if (smc_switch_conns(lgr, lnk_del, false))
1320+
smc_wr_tx_wait_no_pending_sends(lnk_del);
13211321
}
13221322
if (!list_empty(&lgr->list)) {
13231323
/* qentry is either a request from peer (send it back to

net/smc/smc_wr.c

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -169,6 +169,8 @@ void smc_wr_tx_cq_handler(struct ib_cq *ib_cq, void *cq_context)
169169
static inline int smc_wr_tx_get_free_slot_index(struct smc_link *link, u32 *idx)
170170
{
171171
*idx = link->wr_tx_cnt;
172+
if (!smc_link_usable(link))
173+
return -ENOLINK;
172174
for_each_clear_bit(*idx, link->wr_tx_mask, link->wr_tx_cnt) {
173175
if (!test_and_set_bit(*idx, link->wr_tx_mask))
174176
return 0;
@@ -560,15 +562,15 @@ void smc_wr_free_link(struct smc_link *lnk)
560562
{
561563
struct ib_device *ibdev;
562564

565+
if (!lnk->smcibdev)
566+
return;
567+
ibdev = lnk->smcibdev->ibdev;
568+
563569
if (smc_wr_tx_wait_no_pending_sends(lnk))
564570
memset(lnk->wr_tx_mask, 0,
565571
BITS_TO_LONGS(SMC_WR_BUF_CNT) *
566572
sizeof(*lnk->wr_tx_mask));
567573

568-
if (!lnk->smcibdev)
569-
return;
570-
ibdev = lnk->smcibdev->ibdev;
571-
572574
if (lnk->wr_rx_dma_addr) {
573575
ib_dma_unmap_single(ibdev, lnk->wr_rx_dma_addr,
574576
SMC_WR_BUF_SIZE * lnk->wr_rx_cnt,

0 commit comments

Comments
 (0)