diff options
| author | YOSHIFUJI Hideaki <yoshfuji@linux-ipv6.org> | 2006-09-22 14:44:24 -0700 | 
|---|---|---|
| committer | David S. Miller <davem@sunset.davemloft.net> | 2006-09-22 15:20:26 -0700 | 
| commit | 8814c4b533817df825485ff32ce6ac406c3a54d1 (patch) | |
| tree | b72cc3513e7dc4b60e98c7ddebe76bca188f88fc /net | |
| parent | fbea49e1e2404baa2d88ab47e2db89e49551b53b (diff) | |
[IPV6] ADDRCONF: Convert addrconf_lock to RCU.
Signed-off-by: YOSHIFUJI Hideaki <yoshfuji@linux-ipv6.org>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net')
| -rw-r--r-- | net/core/pktgen.c | 4 | ||||
| -rw-r--r-- | net/ipv6/addrconf.c | 46 | ||||
| -rw-r--r-- | net/ipv6/anycast.c | 4 | ||||
| -rw-r--r-- | net/ipv6/ipv6_syms.c | 1 | ||||
| -rw-r--r-- | net/sctp/ipv6.c | 6 | 
5 files changed, 31 insertions, 30 deletions
| diff --git a/net/core/pktgen.c b/net/core/pktgen.c index 6a7320b39ed0..72145d4a2600 100644 --- a/net/core/pktgen.c +++ b/net/core/pktgen.c @@ -1786,7 +1786,7 @@ static void pktgen_setup_inject(struct pktgen_dev *pkt_dev)  			 * use ipv6_get_lladdr if/when it's get exported  			 */ -			read_lock(&addrconf_lock); +			rcu_read_lock();  			if ((idev = __in6_dev_get(pkt_dev->odev)) != NULL) {  				struct inet6_ifaddr *ifp; @@ -1805,7 +1805,7 @@ static void pktgen_setup_inject(struct pktgen_dev *pkt_dev)  				}  				read_unlock_bh(&idev->lock);  			} -			read_unlock(&addrconf_lock); +			rcu_read_unlock();  			if (err)  				printk("pktgen: ERROR: IPv6 link address not availble.\n");  		} diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c index 825a291d5aa5..c09ebb7bb98a 100644 --- a/net/ipv6/addrconf.c +++ b/net/ipv6/addrconf.c @@ -119,9 +119,6 @@ static int ipv6_count_addresses(struct inet6_dev *idev);  static struct inet6_ifaddr		*inet6_addr_lst[IN6_ADDR_HSIZE];  static DEFINE_RWLOCK(addrconf_hash_lock); -/* Protects inet6 devices */ -DEFINE_RWLOCK(addrconf_lock); -  static void addrconf_verify(unsigned long);  static DEFINE_TIMER(addr_chk_timer, addrconf_verify, 0, 0); @@ -318,6 +315,12 @@ static void addrconf_mod_timer(struct inet6_ifaddr *ifp,  /* Nobody refers to this device, we may destroy it. */ +static void in6_dev_finish_destroy_rcu(struct rcu_head *head) +{ +	struct inet6_dev *idev = container_of(head, struct inet6_dev, rcu); +	kfree(idev); +} +  void in6_dev_finish_destroy(struct inet6_dev *idev)  {  	struct net_device *dev = idev->dev; @@ -332,7 +335,7 @@ void in6_dev_finish_destroy(struct inet6_dev *idev)  		return;  	}  	snmp6_free_dev(idev); -	kfree(idev); +	call_rcu(&idev->rcu, in6_dev_finish_destroy_rcu);  }  static struct inet6_dev * ipv6_add_dev(struct net_device *dev) @@ -408,9 +411,8 @@ static struct inet6_dev * ipv6_add_dev(struct net_device *dev)  	if (netif_carrier_ok(dev))  		ndev->if_flags |= IF_READY; -	write_lock_bh(&addrconf_lock); -	dev->ip6_ptr = ndev; -	write_unlock_bh(&addrconf_lock); +	/* protected by rtnl_lock */ +	rcu_assign_pointer(dev->ip6_ptr, ndev);  	ipv6_mc_init_dev(ndev);  	ndev->tstamp = jiffies; @@ -474,7 +476,7 @@ static void addrconf_forward_change(void)  	read_lock(&dev_base_lock);  	for (dev=dev_base; dev; dev=dev->next) { -		read_lock(&addrconf_lock); +		rcu_read_lock();  		idev = __in6_dev_get(dev);  		if (idev) {  			int changed = (!idev->cnf.forwarding) ^ (!ipv6_devconf.forwarding); @@ -482,7 +484,7 @@ static void addrconf_forward_change(void)  			if (changed)  				dev_forward_change(idev);  		} -		read_unlock(&addrconf_lock); +		rcu_read_unlock();  	}  	read_unlock(&dev_base_lock);  } @@ -543,7 +545,7 @@ ipv6_add_addr(struct inet6_dev *idev, const struct in6_addr *addr, int pfxlen,  	int hash;  	int err = 0; -	read_lock_bh(&addrconf_lock); +	rcu_read_lock_bh();  	if (idev->dead) {  		err = -ENODEV;			/*XXX*/  		goto out2; @@ -612,7 +614,7 @@ ipv6_add_addr(struct inet6_dev *idev, const struct in6_addr *addr, int pfxlen,  	in6_ifa_hold(ifa);  	write_unlock(&idev->lock);  out2: -	read_unlock_bh(&addrconf_lock); +	rcu_read_unlock_bh();  	if (likely(err == 0))  		atomic_notifier_call_chain(&inet6addr_chain, NETDEV_UP, ifa); @@ -915,7 +917,7 @@ int ipv6_dev_get_saddr(struct net_device *daddr_dev,  	memset(&hiscore, 0, sizeof(hiscore));  	read_lock(&dev_base_lock); -	read_lock(&addrconf_lock); +	rcu_read_lock();  	for (dev = dev_base; dev; dev=dev->next) {  		struct inet6_dev *idev; @@ -1127,7 +1129,7 @@ record_it:  		}  		read_unlock_bh(&idev->lock);  	} -	read_unlock(&addrconf_lock); +	rcu_read_unlock();  	read_unlock(&dev_base_lock);  	if (!ifa_result) @@ -1151,7 +1153,7 @@ int ipv6_get_lladdr(struct net_device *dev, struct in6_addr *addr)  	struct inet6_dev *idev;  	int err = -EADDRNOTAVAIL; -	read_lock(&addrconf_lock); +	rcu_read_lock();  	if ((idev = __in6_dev_get(dev)) != NULL) {  		struct inet6_ifaddr *ifp; @@ -1165,7 +1167,7 @@ int ipv6_get_lladdr(struct net_device *dev, struct in6_addr *addr)  		}  		read_unlock_bh(&idev->lock);  	} -	read_unlock(&addrconf_lock); +	rcu_read_unlock();  	return err;  } @@ -1466,7 +1468,7 @@ static void ipv6_regen_rndid(unsigned long data)  	struct inet6_dev *idev = (struct inet6_dev *) data;  	unsigned long expires; -	read_lock_bh(&addrconf_lock); +	rcu_read_lock_bh();  	write_lock_bh(&idev->lock);  	if (idev->dead) @@ -1490,7 +1492,7 @@ static void ipv6_regen_rndid(unsigned long data)  out:  	write_unlock_bh(&idev->lock); -	read_unlock_bh(&addrconf_lock); +	rcu_read_unlock_bh();  	in6_dev_put(idev);  } @@ -2342,10 +2344,10 @@ static int addrconf_ifdown(struct net_device *dev, int how)  	           Do not dev_put!  	 */  	if (how == 1) { -		write_lock_bh(&addrconf_lock); -		dev->ip6_ptr = NULL;  		idev->dead = 1; -		write_unlock_bh(&addrconf_lock); + +		/* protected by rtnl_lock */ +		rcu_assign_pointer(dev->ip6_ptr, NULL);  		/* Step 1.5: remove snmp6 entry */  		snmp6_unregister_dev(idev); @@ -3573,10 +3575,10 @@ static void __ipv6_ifa_notify(int event, struct inet6_ifaddr *ifp)  static void ipv6_ifa_notify(int event, struct inet6_ifaddr *ifp)  { -	read_lock_bh(&addrconf_lock); +	rcu_read_lock_bh();  	if (likely(ifp->idev->dead == 0))  		__ipv6_ifa_notify(event, ifp); -	read_unlock_bh(&addrconf_lock); +	rcu_read_unlock_bh();  }  #ifdef CONFIG_SYSCTL diff --git a/net/ipv6/anycast.c b/net/ipv6/anycast.c index b80fc502ca03..a9604764e015 100644 --- a/net/ipv6/anycast.c +++ b/net/ipv6/anycast.c @@ -56,7 +56,7 @@ ip6_onlink(struct in6_addr *addr, struct net_device *dev)  	int	onlink;  	onlink = 0; -	read_lock(&addrconf_lock); +	rcu_read_lock();  	idev = __in6_dev_get(dev);  	if (idev) {  		read_lock_bh(&idev->lock); @@ -68,7 +68,7 @@ ip6_onlink(struct in6_addr *addr, struct net_device *dev)  		}  		read_unlock_bh(&idev->lock);  	} -	read_unlock(&addrconf_lock); +	rcu_read_unlock();  	return onlink;  } diff --git a/net/ipv6/ipv6_syms.c b/net/ipv6/ipv6_syms.c index 7b7b90d9c3d0..0e8e0676a033 100644 --- a/net/ipv6/ipv6_syms.c +++ b/net/ipv6/ipv6_syms.c @@ -14,7 +14,6 @@ EXPORT_SYMBOL(ndisc_mc_map);  EXPORT_SYMBOL(register_inet6addr_notifier);  EXPORT_SYMBOL(unregister_inet6addr_notifier);  EXPORT_SYMBOL(ip6_route_output); -EXPORT_SYMBOL(addrconf_lock);  EXPORT_SYMBOL(ipv6_setsockopt);  EXPORT_SYMBOL(ipv6_getsockopt);  EXPORT_SYMBOL(inet6_register_protosw); diff --git a/net/sctp/ipv6.c b/net/sctp/ipv6.c index fd87e3ceb56e..249e5033c1a8 100644 --- a/net/sctp/ipv6.c +++ b/net/sctp/ipv6.c @@ -321,9 +321,9 @@ static void sctp_v6_copy_addrlist(struct list_head *addrlist,  	struct inet6_ifaddr *ifp;  	struct sctp_sockaddr_entry *addr; -	read_lock(&addrconf_lock); +	rcu_read_lock();  	if ((in6_dev = __in6_dev_get(dev)) == NULL) { -		read_unlock(&addrconf_lock); +		rcu_read_unlock();  		return;  	} @@ -342,7 +342,7 @@ static void sctp_v6_copy_addrlist(struct list_head *addrlist,  	}  	read_unlock(&in6_dev->lock); -	read_unlock(&addrconf_lock); +	rcu_read_unlock();  }  /* Initialize a sockaddr_storage from in incoming skb. */ | 
