diff options
Diffstat (limited to 'net/sctp/socket.c')
| -rw-r--r-- | net/sctp/socket.c | 13 | 
1 files changed, 5 insertions, 8 deletions
diff --git a/net/sctp/socket.c b/net/sctp/socket.c index a710917c5ac7..b9b3d899a611 100644 --- a/net/sctp/socket.c +++ b/net/sctp/socket.c @@ -1520,11 +1520,9 @@ static void sctp_close(struct sock *sk, long timeout)  	/* Supposedly, no process has access to the socket, but  	 * the net layers still may. -	 * Also, sctp_destroy_sock() needs to be called with addr_wq_lock -	 * held and that should be grabbed before socket lock.  	 */ -	spin_lock_bh(&net->sctp.addr_wq_lock); -	bh_lock_sock_nested(sk); +	local_bh_disable(); +	bh_lock_sock(sk);  	/* Hold the sock, since sk_common_release() will put sock_put()  	 * and we have just a little more cleanup. @@ -1533,7 +1531,7 @@ static void sctp_close(struct sock *sk, long timeout)  	sk_common_release(sk);  	bh_unlock_sock(sk); -	spin_unlock_bh(&net->sctp.addr_wq_lock); +	local_bh_enable();  	sock_put(sk); @@ -4993,9 +4991,6 @@ static int sctp_init_sock(struct sock *sk)  	sk_sockets_allocated_inc(sk);  	sock_prot_inuse_add(net, sk->sk_prot, 1); -	/* Nothing can fail after this block, otherwise -	 * sctp_destroy_sock() will be called without addr_wq_lock held -	 */  	if (net->sctp.default_auto_asconf) {  		spin_lock(&sock_net(sk)->sctp.addr_wq_lock);  		list_add_tail(&sp->auto_asconf_list, @@ -5030,7 +5025,9 @@ static void sctp_destroy_sock(struct sock *sk)  	if (sp->do_auto_asconf) {  		sp->do_auto_asconf = 0; +		spin_lock_bh(&sock_net(sk)->sctp.addr_wq_lock);  		list_del(&sp->auto_asconf_list); +		spin_unlock_bh(&sock_net(sk)->sctp.addr_wq_lock);  	}  	sctp_endpoint_free(sp->ep);  	local_bh_disable();  | 
