Commit 024338c3 authored by David S. Miller's avatar David S. Miller Committed by James Morris

[IPV4]: Kill inetdev_lock, no longer needed.

It no longer protects anything, all users held RTNL
semaphore to boot.  Also, fix a potential race in the
new RCU inetdev code, grab the reference on the idev
before attaching it via dev->ip_ptr.

Based upon discussions with Herbert Xu.
Signed-off-by: default avatarDavid S. Miller <davem@redhat.com>
parent c96f60e4
...@@ -90,8 +90,6 @@ static void devinet_sysctl_unregister(struct ipv4_devconf *p); ...@@ -90,8 +90,6 @@ static void devinet_sysctl_unregister(struct ipv4_devconf *p);
/* Locks all the inet devices. */ /* Locks all the inet devices. */
static spinlock_t inetdev_lock = SPIN_LOCK_UNLOCKED;
static struct in_ifaddr *inet_alloc_ifa(void) static struct in_ifaddr *inet_alloc_ifa(void)
{ {
struct in_ifaddr *ifa = kmalloc(sizeof(*ifa), GFP_KERNEL); struct in_ifaddr *ifa = kmalloc(sizeof(*ifa), GFP_KERNEL);
...@@ -158,11 +156,12 @@ struct in_device *inetdev_init(struct net_device *dev) ...@@ -158,11 +156,12 @@ struct in_device *inetdev_init(struct net_device *dev)
neigh_sysctl_register(dev, in_dev->arp_parms, NET_IPV4, neigh_sysctl_register(dev, in_dev->arp_parms, NET_IPV4,
NET_IPV4_NEIGH, "ipv4", NULL); NET_IPV4_NEIGH, "ipv4", NULL);
#endif #endif
spin_lock_bh(&inetdev_lock);
dev->ip_ptr = in_dev;
/* Account for reference dev->ip_ptr */ /* Account for reference dev->ip_ptr */
in_dev_hold(in_dev); in_dev_hold(in_dev);
spin_unlock_bh(&inetdev_lock); smp_wmb();
dev->ip_ptr = in_dev;
#ifdef CONFIG_SYSCTL #ifdef CONFIG_SYSCTL
devinet_sysctl_register(in_dev, &in_dev->cnf); devinet_sysctl_register(in_dev, &in_dev->cnf);
#endif #endif
...@@ -201,10 +200,8 @@ static void inetdev_destroy(struct in_device *in_dev) ...@@ -201,10 +200,8 @@ static void inetdev_destroy(struct in_device *in_dev)
#ifdef CONFIG_SYSCTL #ifdef CONFIG_SYSCTL
devinet_sysctl_unregister(&in_dev->cnf); devinet_sysctl_unregister(&in_dev->cnf);
#endif #endif
spin_lock_bh(&inetdev_lock);
in_dev->dev->ip_ptr = NULL; in_dev->dev->ip_ptr = NULL;
/* in_dev_put following below will kill the in_device */
spin_unlock_bh(&inetdev_lock);
#ifdef CONFIG_SYSCTL #ifdef CONFIG_SYSCTL
neigh_sysctl_unregister(in_dev->arp_parms); neigh_sysctl_unregister(in_dev->arp_parms);
...@@ -248,9 +245,8 @@ static void inet_del_ifa(struct in_device *in_dev, struct in_ifaddr **ifap, ...@@ -248,9 +245,8 @@ static void inet_del_ifa(struct in_device *in_dev, struct in_ifaddr **ifap,
ifap1 = &ifa->ifa_next; ifap1 = &ifa->ifa_next;
continue; continue;
} }
spin_lock_bh(&inetdev_lock);
*ifap1 = ifa->ifa_next; *ifap1 = ifa->ifa_next;
spin_unlock_bh(&inetdev_lock);
rtmsg_ifa(RTM_DELADDR, ifa); rtmsg_ifa(RTM_DELADDR, ifa);
notifier_call_chain(&inetaddr_chain, NETDEV_DOWN, ifa); notifier_call_chain(&inetaddr_chain, NETDEV_DOWN, ifa);
...@@ -260,9 +256,7 @@ static void inet_del_ifa(struct in_device *in_dev, struct in_ifaddr **ifap, ...@@ -260,9 +256,7 @@ static void inet_del_ifa(struct in_device *in_dev, struct in_ifaddr **ifap,
/* 2. Unlink it */ /* 2. Unlink it */
spin_lock_bh(&inetdev_lock);
*ifap = ifa1->ifa_next; *ifap = ifa1->ifa_next;
spin_unlock_bh(&inetdev_lock);
/* 3. Announce address deletion */ /* 3. Announce address deletion */
...@@ -324,9 +318,7 @@ static int inet_insert_ifa(struct in_ifaddr *ifa) ...@@ -324,9 +318,7 @@ static int inet_insert_ifa(struct in_ifaddr *ifa)
} }
ifa->ifa_next = *ifap; ifa->ifa_next = *ifap;
spin_lock_bh(&inetdev_lock);
*ifap = ifa; *ifap = ifa;
spin_unlock_bh(&inetdev_lock);
/* Send message first, then call notifier. /* Send message first, then call notifier.
Notifier will trigger FIB update, so that Notifier will trigger FIB update, so that
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment