diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c index 685fedffdad4..096fd6309077 100644 --- a/net/ipv4/tcp.c +++ b/net/ipv4/tcp.c @@ -4729,12 +4729,6 @@ int tcp_abort(struct sock *sk, int err) /* Don't race with userspace socket closes such as tcp_close. */ lock_sock(sk); - /* Avoid closing the same socket twice. */ - if (sk->sk_state == TCP_CLOSE) { - release_sock(sk); - return -ENOENT; - } - if (sk->sk_state == TCP_LISTEN) { tcp_set_state(sk, TCP_CLOSE); inet_csk_listen_stop(sk); @@ -4744,12 +4738,15 @@ int tcp_abort(struct sock *sk, int err) local_bh_disable(); bh_lock_sock(sk); - if (tcp_need_reset(sk->sk_state)) - tcp_send_active_reset(sk, GFP_ATOMIC); - tcp_done_with_error(sk, err); + if (!sock_flag(sk, SOCK_DEAD)) { + if (tcp_need_reset(sk->sk_state)) + tcp_send_active_reset(sk, GFP_ATOMIC); + tcp_done_with_error(sk, err); + } bh_unlock_sock(sk); local_bh_enable(); + tcp_write_queue_purge(sk); release_sock(sk); return 0; }