diff options
| author | Vlad Yasevich <vladislav.yasevich@hp.com> | 2007-10-24 16:10:00 -0400 | 
|---|---|---|
| committer | Vlad Yasevich <vladislav.yasevich@hp.com> | 2007-11-07 11:39:27 -0500 | 
| commit | 0ed90fb0f668fd07f14ae2007a809e8b26cd27a6 (patch) | |
| tree | 114e48301b89a8e82f7238d8b691880607842947 /net | |
| parent | b6157d8e03e1e780660a328f7183bcbfa4a93a19 (diff) | |
| download | olio-linux-3.10-0ed90fb0f668fd07f14ae2007a809e8b26cd27a6.tar.xz olio-linux-3.10-0ed90fb0f668fd07f14ae2007a809e8b26cd27a6.zip  | |
SCTP: Update RCU handling during the ADD-IP case
After learning more about rcu, it looks like the ADD-IP hadling
doesn't need to call call_rcu_bh.  All the rcu critical sections
use rcu_read_lock, so using call_rcu_bh is wrong here.
Now, restore the local_bh_disable() code blocks and use normal
call_rcu() calls.  Also restore the missing return statement.
Signed-off-by: Vlad Yasevich <vladislav.yasevich@hp.com>
Diffstat (limited to 'net')
| -rw-r--r-- | net/sctp/bind_addr.c | 13 | ||||
| -rw-r--r-- | net/sctp/sm_make_chunk.c | 6 | ||||
| -rw-r--r-- | net/sctp/socket.c | 2 | 
3 files changed, 9 insertions, 12 deletions
diff --git a/net/sctp/bind_addr.c b/net/sctp/bind_addr.c index dfffa94fb9f..cae95af9a8c 100644 --- a/net/sctp/bind_addr.c +++ b/net/sctp/bind_addr.c @@ -180,9 +180,7 @@ int sctp_add_bind_addr(struct sctp_bind_addr *bp, union sctp_addr *new,  /* Delete an address from the bind address list in the SCTP_bind_addr   * structure.   */ -int sctp_del_bind_addr(struct sctp_bind_addr *bp, union sctp_addr *del_addr, -			void fastcall (*rcu_call)(struct rcu_head *head, -					 void (*func)(struct rcu_head *head))) +int sctp_del_bind_addr(struct sctp_bind_addr *bp, union sctp_addr *del_addr)  {  	struct sctp_sockaddr_entry *addr, *temp; @@ -198,15 +196,10 @@ int sctp_del_bind_addr(struct sctp_bind_addr *bp, union sctp_addr *del_addr,  		}  	} -	/* Call the rcu callback provided in the args.  This function is -	 * called by both BH packet processing and user side socket option -	 * processing, but it works on different lists in those 2 contexts. -	 * Each context provides it's own callback, whether call_rcu_bh() -	 * or call_rcu(), to make sure that we wait for an appropriate time. -	 */  	if (addr && !addr->valid) { -		rcu_call(&addr->rcu, sctp_local_addr_free); +		call_rcu(&addr->rcu, sctp_local_addr_free);  		SCTP_DBG_OBJCNT_DEC(addr); +		return 0;  	}  	return -EINVAL; diff --git a/net/sctp/sm_make_chunk.c b/net/sctp/sm_make_chunk.c index 5de4729fe99..c60564dd169 100644 --- a/net/sctp/sm_make_chunk.c +++ b/net/sctp/sm_make_chunk.c @@ -2953,13 +2953,17 @@ static int sctp_asconf_param_success(struct sctp_association *asoc,  		/* This is always done in BH context with a socket lock  		 * held, so the list can not change.  		 */ +		local_bh_disable();  		list_for_each_entry(saddr, &bp->address_list, list) {  			if (sctp_cmp_addr_exact(&saddr->a, &addr))  				saddr->use_as_src = 1;  		} +		local_bh_enable();  		break;  	case SCTP_PARAM_DEL_IP: -		retval = sctp_del_bind_addr(bp, &addr, call_rcu_bh); +		local_bh_disable(); +		retval = sctp_del_bind_addr(bp, &addr); +		local_bh_enable();  		list_for_each(pos, &asoc->peer.transport_addr_list) {  			transport = list_entry(pos, struct sctp_transport,  						 transports); diff --git a/net/sctp/socket.c b/net/sctp/socket.c index a7ecf3159e5..6ce9b490fad 100644 --- a/net/sctp/socket.c +++ b/net/sctp/socket.c @@ -660,7 +660,7 @@ static int sctp_bindx_rem(struct sock *sk, struct sockaddr *addrs, int addrcnt)  		 * socket routing and failover schemes. Refer to comments in  		 * sctp_do_bind(). -daisy  		 */ -		retval = sctp_del_bind_addr(bp, sa_addr, call_rcu); +		retval = sctp_del_bind_addr(bp, sa_addr);  		addr_buf += af->sockaddr_len;  err_bindx_rem:  |