diff options
Diffstat (limited to 'net/ipv4/tcp_output.c')
-rw-r--r-- | net/ipv4/tcp_output.c | 11 |
1 files changed, 11 insertions, 0 deletions
diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c index f0eb4e337ec8..17a11e65e57f 100644 --- a/net/ipv4/tcp_output.c +++ b/net/ipv4/tcp_output.c | |||
@@ -767,6 +767,17 @@ void tcp_release_cb(struct sock *sk) | |||
767 | if (flags & (1UL << TCP_TSQ_DEFERRED)) | 767 | if (flags & (1UL << TCP_TSQ_DEFERRED)) |
768 | tcp_tsq_handler(sk); | 768 | tcp_tsq_handler(sk); |
769 | 769 | ||
770 | /* Here begins the tricky part : | ||
771 | * We are called from release_sock() with : | ||
772 | * 1) BH disabled | ||
773 | * 2) sk_lock.slock spinlock held | ||
774 | * 3) socket owned by us (sk->sk_lock.owned == 1) | ||
775 | * | ||
776 | * But following code is meant to be called from BH handlers, | ||
777 | * so we should keep BH disabled, but early release socket ownership | ||
778 | */ | ||
779 | sock_release_ownership(sk); | ||
780 | |||
770 | if (flags & (1UL << TCP_WRITE_TIMER_DEFERRED)) { | 781 | if (flags & (1UL << TCP_WRITE_TIMER_DEFERRED)) { |
771 | tcp_write_timer_handler(sk); | 782 | tcp_write_timer_handler(sk); |
772 | __sock_put(sk); | 783 | __sock_put(sk); |