summaryrefslogtreecommitdiffstats
path: root/net/core
diff options
context:
space:
mode:
authorGao feng <gaofeng@cn.fujitsu.com>2012-08-23 17:36:55 +0200
committerDavid S. Miller <davem@davemloft.net>2012-08-30 18:21:16 +0200
commit6549dd43c04327071571edf7aea4465b16539422 (patch)
tree4bdce0bcf486197c34f0ce5feaecf58b337d625b /net/core
parentMerge branch 'for-next' of git://git.kernel.org/pub/scm/linux/kernel/git/ebie... (diff)
downloadlinux-6549dd43c04327071571edf7aea4465b16539422.tar.xz
linux-6549dd43c04327071571edf7aea4465b16539422.zip
net: dev: fix the incorrect hold of net namespace's lo device
When moving a net device from one net namespace to another net namespace,dev_change_net_namespace calls NETDEV_DOWN event,so the original net namespace's dst entries which beloned to this net device will be put into dst_garbage list. then dev_change_net_namespace will set this net device's net to the new net namespace. If we unregister this net device's driver, this will trigger the NETDEV_UNREGISTER_FINAL event, dst_ifdown will be called, and get this net device's dst entries from dst_garbage list, put these entries' dev to the new net namespace's lo device. It's not what we want,actually we need these dst entries hold the original net namespace's lo device,this incorrect device holding will trigger emg message like below. unregister_netdevice: waiting for lo to become free. Usage count = 1 so we should call NETDEV_UNREGISTER_FINAL event in dev_change_net_namespace too,in order to make sure dst entries already in the dst_garbage list, we need rcu_barrier before we call NETDEV_UNREGISTER_FINAL event. With help form Eric Dumazet. Signed-off-by: Gao feng <gaofeng@cn.fujitsu.com> Cc: Eric Dumazet <eric.dumazet@gmail.com> Cc: "Eric W. Biederman" <ebiederm@xmission.com> Acked-by: Eric Dumazet <edumazet@google.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/core')
-rw-r--r--net/core/dev.c2
1 files changed, 2 insertions, 0 deletions
diff --git a/net/core/dev.c b/net/core/dev.c
index 3401e2dab7cc..a5fc3e301cf2 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -6259,6 +6259,8 @@ int dev_change_net_namespace(struct net_device *dev, struct net *net, const char
the device is just moving and can keep their slaves up.
*/
call_netdevice_notifiers(NETDEV_UNREGISTER, dev);
+ rcu_barrier();
+ call_netdevice_notifiers(NETDEV_UNREGISTER_FINAL, dev);
rtmsg_ifinfo(RTM_DELLINK, dev, ~0U);
/*