When applications call shutdown() with SHUT_RDWR in userspace, smc_close_active() calls kernel_sock_shutdown(), and it is called twice in smc_shutdown(). This fixes this by checking sk_state before do clcsock shutdown, and avoids missing the application's call of smc_shutdown(). Link: https://lore.kernel.org/linux-s390/1f67548e-cbf6-0dce-82b5-10288a4583bd@xxxxxxxxxxxxx/ Fixes: 606a63c9783a ("net/smc: Ensure the active closing peer first closes clcsock") Signed-off-by: Tony Lu <tonylu@xxxxxxxxxxxxxxxxx> Reviewed-by: Wen Gu <guwen@xxxxxxxxxxxxxxxxx> --- net/smc/af_smc.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/net/smc/af_smc.c b/net/smc/af_smc.c index 4b62c925a13e..7b04cb4d15f4 100644 --- a/net/smc/af_smc.c +++ b/net/smc/af_smc.c @@ -2373,6 +2373,7 @@ static int smc_shutdown(struct socket *sock, int how) struct smc_sock *smc; int rc = -EINVAL; int rc1 = 0; + int old_state; smc = smc_sk(sk); @@ -2398,7 +2399,12 @@ static int smc_shutdown(struct socket *sock, int how) } switch (how) { case SHUT_RDWR: /* shutdown in both directions */ + old_state = sk->sk_state; rc = smc_close_active(smc); + if (old_state == SMC_ACTIVE && + sk->sk_state == SMC_PEERCLOSEWAIT1) + goto out_no_shutdown; + break; case SHUT_WR: rc = smc_close_shutdown_write(smc); @@ -2410,6 +2416,8 @@ static int smc_shutdown(struct socket *sock, int how) } if (smc->clcsock) rc1 = kernel_sock_shutdown(smc->clcsock, how); + +out_no_shutdown: /* map sock_shutdown_cmd constants to sk_shutdown value range */ sk->sk_shutdown |= how + 1; -- 2.32.0.3.g01195cf9f