diff options
author | Mark Brown <broonie@kernel.org> | 2021-10-29 22:00:00 +0100 |
---|---|---|
committer | Mark Brown <broonie@kernel.org> | 2021-10-29 22:00:00 +0100 |
commit | 318a54c0ee4aaa3bfd69fdf505588510c7672c0c (patch) | |
tree | fcd342658639851179ab88c0eb317e83b586eb71 /net/smc/smc_core.c | |
parent | 8e14329645bc7d722e1ec913025b54199fafaee3 (diff) | |
parent | 6195eb15f6d60dd92d1644dc11f1c1c2e84ebfeb (diff) |
Merge remote-tracking branch 'asoc/for-5.16' into asoc-next
Diffstat (limited to 'net/smc/smc_core.c')
-rw-r--r-- | net/smc/smc_core.c | 20 |
1 files changed, 11 insertions, 9 deletions
diff --git a/net/smc/smc_core.c b/net/smc/smc_core.c index 8280c938be80..d2206743dc71 100644 --- a/net/smc/smc_core.c +++ b/net/smc/smc_core.c @@ -949,7 +949,7 @@ struct smc_link *smc_switch_conns(struct smc_link_group *lgr, to_lnk = &lgr->lnk[i]; break; } - if (!to_lnk) { + if (!to_lnk || !smc_wr_tx_link_hold(to_lnk)) { smc_lgr_terminate_sched(lgr); return NULL; } @@ -981,24 +981,26 @@ again: read_unlock_bh(&lgr->conns_lock); /* pre-fetch buffer outside of send_lock, might sleep */ rc = smc_cdc_get_free_slot(conn, to_lnk, &wr_buf, NULL, &pend); - if (rc) { - smcr_link_down_cond_sched(to_lnk); - return NULL; - } + if (rc) + goto err_out; /* avoid race with smcr_tx_sndbuf_nonempty() */ spin_lock_bh(&conn->send_lock); smc_switch_link_and_count(conn, to_lnk); rc = smc_switch_cursor(smc, pend, wr_buf); spin_unlock_bh(&conn->send_lock); sock_put(&smc->sk); - if (rc) { - smcr_link_down_cond_sched(to_lnk); - return NULL; - } + if (rc) + goto err_out; goto again; } read_unlock_bh(&lgr->conns_lock); + smc_wr_tx_link_put(to_lnk); return to_lnk; + +err_out: + smcr_link_down_cond_sched(to_lnk); + smc_wr_tx_link_put(to_lnk); + return NULL; } static void smcr_buf_unuse(struct smc_buf_desc *rmb_desc, |