X-Git-Url: http://pileus.org/git/?a=blobdiff_plain;f=net%2Fipv4%2Ftcp_output.c;h=17a11e65e57fea3fa3728ce905df6130c580c48a;hb=632b06aa2842b12c6d6a510ec080fb6ebdb38ea5;hp=f0eb4e337ec88fc631a30adc0d168817e5812ced;hpb=4d7eaa12f33c07436939926600638b0d6ab73999;p=~andy%2Flinux diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c index f0eb4e337ec..17a11e65e57 100644 --- a/net/ipv4/tcp_output.c +++ b/net/ipv4/tcp_output.c @@ -767,6 +767,17 @@ void tcp_release_cb(struct sock *sk) if (flags & (1UL << TCP_TSQ_DEFERRED)) tcp_tsq_handler(sk); + /* Here begins the tricky part : + * We are called from release_sock() with : + * 1) BH disabled + * 2) sk_lock.slock spinlock held + * 3) socket owned by us (sk->sk_lock.owned == 1) + * + * But following code is meant to be called from BH handlers, + * so we should keep BH disabled, but early release socket ownership + */ + sock_release_ownership(sk); + if (flags & (1UL << TCP_WRITE_TIMER_DEFERRED)) { tcp_write_timer_handler(sk); __sock_put(sk);