summaryrefslogtreecommitdiff
path: root/net
diff options
context:
space:
mode:
authorHans Wippel <hwippel@linux.ibm.com>2019-02-07 15:56:17 +0100
committerDavid S. Miller <davem@davemloft.net>2019-02-07 18:06:18 -0800
commit62c7139f3ed011379fbbef832b4b15e3c10b355f (patch)
tree6e95eaae911df9dfc3463d26fe6af865d6eff5e0 /net
parenta225d2cd88d3303e7c6d1481578a4f23d5f92350 (diff)
downloadlwn-62c7139f3ed011379fbbef832b4b15e3c10b355f.tar.gz
lwn-62c7139f3ed011379fbbef832b4b15e3c10b355f.zip
net/smc: unlock LGR pending lock earlier for SMC-D
If SMC client and server connections are both established at the same time, smc_connect_ism() cannot send a CLC confirm message while smc_listen_work() is waiting for one due to lock contention. This can result in timeouts in smc_clc_wait_msg() and failed SMC connections. In case of SMC-D, the LGR pending lock is not needed while smc_listen_work() is waiting for the CLC confirm message. So, this patch releases the lock earlier for SMC-D to avoid the locking issue. Signed-off-by: Hans Wippel <hwippel@linux.ibm.com> Signed-off-by: Ursula Braun <ubraun@linux.ibm.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net')
-rw-r--r--net/smc/af_smc.c14
1 files changed, 9 insertions, 5 deletions
diff --git a/net/smc/af_smc.c b/net/smc/af_smc.c
index 60ccc8f50368..cf49ed05007b 100644
--- a/net/smc/af_smc.c
+++ b/net/smc/af_smc.c
@@ -1287,24 +1287,28 @@ static void smc_listen_work(struct work_struct *work)
return;
}
+ /* SMC-D does not need this lock any more */
+ if (ism_supported)
+ mutex_unlock(&smc_create_lgr_pending);
+
/* receive SMC Confirm CLC message */
reason_code = smc_clc_wait_msg(new_smc, &cclc, sizeof(cclc),
SMC_CLC_CONFIRM, CLC_WAIT_TIME);
if (reason_code) {
- mutex_unlock(&smc_create_lgr_pending);
+ if (!ism_supported)
+ mutex_unlock(&smc_create_lgr_pending);
smc_listen_decline(new_smc, reason_code, local_contact);
return;
}
/* finish worker */
if (!ism_supported) {
- if (smc_listen_rdma_finish(new_smc, &cclc, local_contact)) {
- mutex_unlock(&smc_create_lgr_pending);
+ rc = smc_listen_rdma_finish(new_smc, &cclc, local_contact);
+ mutex_unlock(&smc_create_lgr_pending);
+ if (rc)
return;
- }
}
smc_conn_save_peer_info(new_smc, &cclc);
- mutex_unlock(&smc_create_lgr_pending);
smc_listen_out_connected(new_smc);
}