Skip to content

Commit 5211c97

Browse files
D. Wythedavem330
authored andcommitted
net/smc: fix dangling sock under state SMC_APPFINCLOSEWAIT
Considering scenario: smc_cdc_rx_handler __smc_release sock_set_flag smc_close_active() sock_set_flag __set_bit(DEAD) __set_bit(DONE) Dues to __set_bit is not atomic, the DEAD or DONE might be lost. if the DEAD flag lost, the state SMC_CLOSED will be never be reached in smc_close_passive_work: if (sock_flag(sk, SOCK_DEAD) && smc_close_sent_any_close(conn)) { sk->sk_state = SMC_CLOSED; } else { /* just shutdown, but not yet closed locally */ sk->sk_state = SMC_APPFINCLOSEWAIT; } Replace sock_set_flags or __set_bit to set_bit will fix this problem. Since set_bit is atomic. Fixes: b38d732 ("smc: socket closing and linkgroup cleanup") Signed-off-by: D. Wythe <alibuda@linux.alibaba.com> Reviewed-by: Dust Li <dust.li@linux.alibaba.com> Signed-off-by: David S. Miller <davem@davemloft.net>
1 parent d93f952 commit 5211c97

File tree

4 files changed

+9
-4
lines changed

4 files changed

+9
-4
lines changed

net/smc/af_smc.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -275,7 +275,7 @@ static int __smc_release(struct smc_sock *smc)
275275

276276
if (!smc->use_fallback) {
277277
rc = smc_close_active(smc);
278-
sock_set_flag(sk, SOCK_DEAD);
278+
smc_sock_set_flag(sk, SOCK_DEAD);
279279
sk->sk_shutdown |= SHUTDOWN_MASK;
280280
} else {
281281
if (sk->sk_state != SMC_CLOSED) {
@@ -1743,7 +1743,7 @@ static int smc_clcsock_accept(struct smc_sock *lsmc, struct smc_sock **new_smc)
17431743
if (new_clcsock)
17441744
sock_release(new_clcsock);
17451745
new_sk->sk_state = SMC_CLOSED;
1746-
sock_set_flag(new_sk, SOCK_DEAD);
1746+
smc_sock_set_flag(new_sk, SOCK_DEAD);
17471747
sock_put(new_sk); /* final */
17481748
*new_smc = NULL;
17491749
goto out;

net/smc/smc.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -377,4 +377,9 @@ int smc_nl_dump_hs_limitation(struct sk_buff *skb, struct netlink_callback *cb);
377377
int smc_nl_enable_hs_limitation(struct sk_buff *skb, struct genl_info *info);
378378
int smc_nl_disable_hs_limitation(struct sk_buff *skb, struct genl_info *info);
379379

380+
static inline void smc_sock_set_flag(struct sock *sk, enum sock_flags flag)
381+
{
382+
set_bit(flag, &sk->sk_flags);
383+
}
384+
380385
#endif /* __SMC_H */

net/smc/smc_cdc.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -385,7 +385,7 @@ static void smc_cdc_msg_recv_action(struct smc_sock *smc,
385385
smc->sk.sk_shutdown |= RCV_SHUTDOWN;
386386
if (smc->clcsock && smc->clcsock->sk)
387387
smc->clcsock->sk->sk_shutdown |= RCV_SHUTDOWN;
388-
sock_set_flag(&smc->sk, SOCK_DONE);
388+
smc_sock_set_flag(&smc->sk, SOCK_DONE);
389389
sock_hold(&smc->sk); /* sock_put in close_work */
390390
if (!queue_work(smc_close_wq, &conn->close_work))
391391
sock_put(&smc->sk);

net/smc/smc_close.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -173,7 +173,7 @@ void smc_close_active_abort(struct smc_sock *smc)
173173
break;
174174
}
175175

176-
sock_set_flag(sk, SOCK_DEAD);
176+
smc_sock_set_flag(sk, SOCK_DEAD);
177177
sk->sk_state_change(sk);
178178

179179
if (release_clcsock) {

0 commit comments

Comments
 (0)