From 46c28dbd4c23c3f7fa37f5ea48772af79c9cc40e Mon Sep 17 00:00:00 2001 From: Ursula Braun Date: Mon, 10 Apr 2017 14:58:01 +0200 Subject: net/smc: no socket state changes in tasklet context Several state changes occur during SMC socket closing. Currently state changes triggered locally occur in process context with lock_sock() taken while state changes triggered by peer occur in tasklet context with bh_lock_sock() taken. bh_lock_sock() does not wait till a lock_sock(() task in process context is finished. This may lead to races in socket state transitions resulting in dangling SMC-sockets, or it may lead to duplicate SMC socket freeing. This patch introduces a closing worker to run all state changes under lock_sock(). Signed-off-by: Ursula Braun Reviewed-by: Thomas Richter Reported-by: Dave Jones Signed-off-by: David S. Miller --- net/smc/af_smc.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'net/smc/af_smc.c') diff --git a/net/smc/af_smc.c b/net/smc/af_smc.c index 093803786eac..3b7eda6c27de 100644 --- a/net/smc/af_smc.c +++ b/net/smc/af_smc.c @@ -451,6 +451,9 @@ static int smc_connect_rdma(struct smc_sock *smc) goto decline_rdma_unlock; } + smc_close_init(smc); + smc_rx_init(smc); + if (local_contact == SMC_FIRST_CONTACT) { rc = smc_ib_ready_link(link); if (rc) { @@ -477,7 +480,6 @@ static int smc_connect_rdma(struct smc_sock *smc) mutex_unlock(&smc_create_lgr_pending); smc_tx_init(smc); - smc_rx_init(smc); out_connected: smc_copy_sock_settings_to_clc(smc); @@ -800,6 +802,9 @@ static void smc_listen_work(struct work_struct *work) goto decline_rdma; } + smc_close_init(new_smc); + smc_rx_init(new_smc); + rc = smc_clc_send_accept(new_smc, local_contact); if (rc) goto out_err; @@ -839,7 +844,6 @@ static void smc_listen_work(struct work_struct *work) } smc_tx_init(new_smc); - smc_rx_init(new_smc); out_connected: sk_refcnt_debug_inc(newsmcsk); -- cgit v1.2.3