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) |
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 dfffa94fb9f6..cae95af9a8cc 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, | |||
180 | /* Delete an address from the bind address list in the SCTP_bind_addr | 180 | /* Delete an address from the bind address list in the SCTP_bind_addr |
181 | * structure. | 181 | * structure. |
182 | */ | 182 | */ |
183 | int sctp_del_bind_addr(struct sctp_bind_addr *bp, union sctp_addr *del_addr, | 183 | int sctp_del_bind_addr(struct sctp_bind_addr *bp, union sctp_addr *del_addr) |
184 | void fastcall (*rcu_call)(struct rcu_head *head, | ||
185 | void (*func)(struct rcu_head *head))) | ||
186 | { | 184 | { |
187 | struct sctp_sockaddr_entry *addr, *temp; | 185 | struct sctp_sockaddr_entry *addr, *temp; |
188 | 186 | ||
@@ -198,15 +196,10 @@ int sctp_del_bind_addr(struct sctp_bind_addr *bp, union sctp_addr *del_addr, | |||
198 | } | 196 | } |
199 | } | 197 | } |
200 | 198 | ||
201 | /* Call the rcu callback provided in the args. This function is | ||
202 | * called by both BH packet processing and user side socket option | ||
203 | * processing, but it works on different lists in those 2 contexts. | ||
204 | * Each context provides it's own callback, whether call_rcu_bh() | ||
205 | * or call_rcu(), to make sure that we wait for an appropriate time. | ||
206 | */ | ||
207 | if (addr && !addr->valid) { | 199 | if (addr && !addr->valid) { |
208 | rcu_call(&addr->rcu, sctp_local_addr_free); | 200 | call_rcu(&addr->rcu, sctp_local_addr_free); |
209 | SCTP_DBG_OBJCNT_DEC(addr); | 201 | SCTP_DBG_OBJCNT_DEC(addr); |
202 | return 0; | ||
210 | } | 203 | } |
211 | 204 | ||
212 | return -EINVAL; | 205 | return -EINVAL; |
diff --git a/net/sctp/sm_make_chunk.c b/net/sctp/sm_make_chunk.c index 5de4729fe993..c60564dd169d 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, | |||
2953 | /* This is always done in BH context with a socket lock | 2953 | /* This is always done in BH context with a socket lock |
2954 | * held, so the list can not change. | 2954 | * held, so the list can not change. |
2955 | */ | 2955 | */ |
2956 | local_bh_disable(); | ||
2956 | list_for_each_entry(saddr, &bp->address_list, list) { | 2957 | list_for_each_entry(saddr, &bp->address_list, list) { |
2957 | if (sctp_cmp_addr_exact(&saddr->a, &addr)) | 2958 | if (sctp_cmp_addr_exact(&saddr->a, &addr)) |
2958 | saddr->use_as_src = 1; | 2959 | saddr->use_as_src = 1; |
2959 | } | 2960 | } |
2961 | local_bh_enable(); | ||
2960 | break; | 2962 | break; |
2961 | case SCTP_PARAM_DEL_IP: | 2963 | case SCTP_PARAM_DEL_IP: |
2962 | retval = sctp_del_bind_addr(bp, &addr, call_rcu_bh); | 2964 | local_bh_disable(); |
2965 | retval = sctp_del_bind_addr(bp, &addr); | ||
2966 | local_bh_enable(); | ||
2963 | list_for_each(pos, &asoc->peer.transport_addr_list) { | 2967 | list_for_each(pos, &asoc->peer.transport_addr_list) { |
2964 | transport = list_entry(pos, struct sctp_transport, | 2968 | transport = list_entry(pos, struct sctp_transport, |
2965 | transports); | 2969 | transports); |
diff --git a/net/sctp/socket.c b/net/sctp/socket.c index a7ecf3159e53..6ce9b490fad5 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) | |||
660 | * socket routing and failover schemes. Refer to comments in | 660 | * socket routing and failover schemes. Refer to comments in |
661 | * sctp_do_bind(). -daisy | 661 | * sctp_do_bind(). -daisy |
662 | */ | 662 | */ |
663 | retval = sctp_del_bind_addr(bp, sa_addr, call_rcu); | 663 | retval = sctp_del_bind_addr(bp, sa_addr); |
664 | 664 | ||
665 | addr_buf += af->sockaddr_len; | 665 | addr_buf += af->sockaddr_len; |
666 | err_bindx_rem: | 666 | err_bindx_rem: |