aboutsummaryrefslogtreecommitdiffstats
path: root/net/sctp/ipv6.c
diff options
context:
space:
mode:
authorVlad Yasevich <vladislav.yasevich@hp.com>2007-09-16 19:03:28 -0400
committerDavid S. Miller <davem@davemloft.net>2007-09-16 19:03:28 -0400
commit559cf710b07c5e2cfa3fb8d8f4a1320fd84c53f9 (patch)
treedeb74aea811a7d7c7e203f3743fd15372f8a6589 /net/sctp/ipv6.c
parent293035479942400a7fe8e4f72465d4e4e466b91a (diff)
[SCTP]: Convert bind_addr_list locking to RCU
Since the sctp_sockaddr_entry is now RCU enabled as part of the patch to synchronize sctp_localaddr_list, it makes sense to change all handling of these entries to RCU. This includes the sctp_bind_addrs structure and it's list of bound addresses. This list is currently protected by an external rw_lock and that looks like an overkill. There are only 2 writers to the list: bind()/bindx() calls, and BH processing of ASCONF-ACK chunks. These are already seriealized via the socket lock, so they will not step on each other. These are also relatively rare, so we should be good with RCU. The readers are varied and they are easily converted to RCU. Signed-off-by: Vlad Yasevich <vladislav.yasevich@hp.com> Acked-by: Paul E. McKenney <paulmck@linux.vnet.ibm.com> Acked-by: Sridhar Samdurala <sri@us.ibm.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/sctp/ipv6.c')
-rw-r--r--net/sctp/ipv6.c12
1 files changed, 5 insertions, 7 deletions
diff --git a/net/sctp/ipv6.c b/net/sctp/ipv6.c
index e12fa0a91da4..670fd2740b89 100644
--- a/net/sctp/ipv6.c
+++ b/net/sctp/ipv6.c
@@ -302,9 +302,7 @@ static void sctp_v6_get_saddr(struct sctp_association *asoc,
302 union sctp_addr *saddr) 302 union sctp_addr *saddr)
303{ 303{
304 struct sctp_bind_addr *bp; 304 struct sctp_bind_addr *bp;
305 rwlock_t *addr_lock;
306 struct sctp_sockaddr_entry *laddr; 305 struct sctp_sockaddr_entry *laddr;
307 struct list_head *pos;
308 sctp_scope_t scope; 306 sctp_scope_t scope;
309 union sctp_addr *baddr = NULL; 307 union sctp_addr *baddr = NULL;
310 __u8 matchlen = 0; 308 __u8 matchlen = 0;
@@ -324,14 +322,14 @@ static void sctp_v6_get_saddr(struct sctp_association *asoc,
324 scope = sctp_scope(daddr); 322 scope = sctp_scope(daddr);
325 323
326 bp = &asoc->base.bind_addr; 324 bp = &asoc->base.bind_addr;
327 addr_lock = &asoc->base.addr_lock;
328 325
329 /* Go through the bind address list and find the best source address 326 /* Go through the bind address list and find the best source address
330 * that matches the scope of the destination address. 327 * that matches the scope of the destination address.
331 */ 328 */
332 sctp_read_lock(addr_lock); 329 rcu_read_lock();
333 list_for_each(pos, &bp->address_list) { 330 list_for_each_entry_rcu(laddr, &bp->address_list, list) {
334 laddr = list_entry(pos, struct sctp_sockaddr_entry, list); 331 if (!laddr->valid)
332 continue;
335 if ((laddr->use_as_src) && 333 if ((laddr->use_as_src) &&
336 (laddr->a.sa.sa_family == AF_INET6) && 334 (laddr->a.sa.sa_family == AF_INET6) &&
337 (scope <= sctp_scope(&laddr->a))) { 335 (scope <= sctp_scope(&laddr->a))) {
@@ -353,7 +351,7 @@ static void sctp_v6_get_saddr(struct sctp_association *asoc,
353 __FUNCTION__, asoc, NIP6(daddr->v6.sin6_addr)); 351 __FUNCTION__, asoc, NIP6(daddr->v6.sin6_addr));
354 } 352 }
355 353
356 sctp_read_unlock(addr_lock); 354 rcu_read_unlock();
357} 355}
358 356
359/* Make a copy of all potential local addresses. */ 357/* Make a copy of all potential local addresses. */