diff options
author | Eric Dumazet <eric.dumazet@gmail.com> | 2010-12-04 20:23:53 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2010-12-08 13:07:24 -0500 |
commit | 941666c2e3e0f9f6a1cb5808d02352d445bd702c (patch) | |
tree | 389a773580ef22908391cc71f98982b03de62804 /net/core | |
parent | a2d4b65d477aad1fe8c7218781a031fa9cf5abfc (diff) |
net: RCU conversion of dev_getbyhwaddr() and arp_ioctl()
Le dimanche 05 décembre 2010 à 09:19 +0100, Eric Dumazet a écrit :
> Hmm..
>
> If somebody can explain why RTNL is held in arp_ioctl() (and therefore
> in arp_req_delete()), we might first remove RTNL use in arp_ioctl() so
> that your patch can be applied.
>
> Right now it is not good, because RTNL wont be necessarly held when you
> are going to call arp_invalidate() ?
While doing this analysis, I found a refcount bug in llc, I'll send a
patch for net-2.6
Meanwhile, here is the patch for net-next-2.6
Your patch then can be applied after mine.
Thanks
[PATCH] net: RCU conversion of dev_getbyhwaddr() and arp_ioctl()
dev_getbyhwaddr() was called under RTNL.
Rename it to dev_getbyhwaddr_rcu() and change all its caller to now use
RCU locking instead of RTNL.
Change arp_ioctl() to use RCU instead of RTNL locking.
Note: this fix a dev refcount bug in llc
Signed-off-by: Eric Dumazet <eric.dumazet@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/core')
-rw-r--r-- | net/core/dev.c | 17 |
1 files changed, 7 insertions, 10 deletions
diff --git a/net/core/dev.c b/net/core/dev.c index ee605c0867e7..822b15b8d11c 100644 --- a/net/core/dev.c +++ b/net/core/dev.c | |||
@@ -743,34 +743,31 @@ struct net_device *dev_get_by_index(struct net *net, int ifindex) | |||
743 | EXPORT_SYMBOL(dev_get_by_index); | 743 | EXPORT_SYMBOL(dev_get_by_index); |
744 | 744 | ||
745 | /** | 745 | /** |
746 | * dev_getbyhwaddr - find a device by its hardware address | 746 | * dev_getbyhwaddr_rcu - find a device by its hardware address |
747 | * @net: the applicable net namespace | 747 | * @net: the applicable net namespace |
748 | * @type: media type of device | 748 | * @type: media type of device |
749 | * @ha: hardware address | 749 | * @ha: hardware address |
750 | * | 750 | * |
751 | * Search for an interface by MAC address. Returns NULL if the device | 751 | * Search for an interface by MAC address. Returns NULL if the device |
752 | * is not found or a pointer to the device. The caller must hold the | 752 | * is not found or a pointer to the device. The caller must hold RCU |
753 | * rtnl semaphore. The returned device has not had its ref count increased | 753 | * The returned device has not had its ref count increased |
754 | * and the caller must therefore be careful about locking | 754 | * and the caller must therefore be careful about locking |
755 | * | 755 | * |
756 | * BUGS: | ||
757 | * If the API was consistent this would be __dev_get_by_hwaddr | ||
758 | */ | 756 | */ |
759 | 757 | ||
760 | struct net_device *dev_getbyhwaddr(struct net *net, unsigned short type, char *ha) | 758 | struct net_device *dev_getbyhwaddr_rcu(struct net *net, unsigned short type, |
759 | const char *ha) | ||
761 | { | 760 | { |
762 | struct net_device *dev; | 761 | struct net_device *dev; |
763 | 762 | ||
764 | ASSERT_RTNL(); | 763 | for_each_netdev_rcu(net, dev) |
765 | |||
766 | for_each_netdev(net, dev) | ||
767 | if (dev->type == type && | 764 | if (dev->type == type && |
768 | !memcmp(dev->dev_addr, ha, dev->addr_len)) | 765 | !memcmp(dev->dev_addr, ha, dev->addr_len)) |
769 | return dev; | 766 | return dev; |
770 | 767 | ||
771 | return NULL; | 768 | return NULL; |
772 | } | 769 | } |
773 | EXPORT_SYMBOL(dev_getbyhwaddr); | 770 | EXPORT_SYMBOL(dev_getbyhwaddr_rcu); |
774 | 771 | ||
775 | struct net_device *__dev_getfirstbyhwtype(struct net *net, unsigned short type) | 772 | struct net_device *__dev_getfirstbyhwtype(struct net *net, unsigned short type) |
776 | { | 773 | { |