netns: remove useless synchronize_net()
Subsystems (2)
PATCH 1/1 netns: remove useless synchronize_net()
In dev_change_net_namespace(), synchronize_net() is called at the end of the function, but there is no reason (no deletion occurs).
net/core/dev.c +0 -1
@@ -4546,7 +4546,6 @@ int dev_change_net_namespace(struct net_/* Notify protocols, that a new device appeared. */ call_netdevice_notifiers (NETDEV_REGISTER , dev); -synchronize_net (); err =0 ; out:return err;
David Miller
maintainerFrom: Nicolas Dichtel <[email protected]>
Date: Thu, 05 Feb 2009 11:21:22 +0100
Quoted 4 lines
In
dev_change_net_namespace(),synchronize_net()is called at the end of the function, but there is no reason (no deletion occurs).Signed-off-by Nicolas Dichtel <[email protected]>
It is necessary to make sure all cpus stop looking at the previous namespace the device was attached to, and only see the new mapping.
That's why this function has two synchronize_net() calls.
Quoted 11 lines · David Miller
From: Nicolas Dichtel <[email protected]>
Date: Thu, 05 Feb 2009 11:21:22 +0100Quoted 4 lines
In
dev_change_net_namespace(),synchronize_net()is called at the end of the function, but there is no reason (no deletion occurs).Signed-off-by Nicolas Dichtel <[email protected]>It is necessary to make sure all cpus stop looking at the previous namespace the device was attached to, and only see the new mapping.
I didn't really understand why it is 'necessary'.
If namespace is destroyed after this function, then cleanup_net() will ensure that nobody is looking at it There is only two callers, rtnetlink and default_device_exit().
Thank you for your answer,
Nicolas
Quoted 2 lines
That's why this function has two
synchronize_net()calls.
David Miller
maintainerFrom: Nicolas Dichtel <[email protected]>
Date: Fri, 06 Feb 2009 14:50:53 +0100
Quoted 2 lines
If namespace is destroyed after this function, then
cleanup_net()will ensure that nobody is looking at it
Maybe, but you better get some opinions from the people who wrote and maintain the network namespace code before I can consider your change seriously.
None of them responded to your patch posting, probably because you failed to CC: any of them.
Quoted 6 lines · David Miller
From: Nicolas Dichtel <[email protected]>
Date: Fri, 06 Feb 2009 14:50:53 +0100Quoted 2 lines
If namespace is destroyed after this function, then
cleanup_net()will ensure that nobody is looking at it
Quoted 6 lines
Maybe, but you better get some opinions from the people who wrote and maintain the network namespace code before I can consider your change seriously.
None of them responded to your patch posting, probably because you failed to CC: any of them.
Sorry, I forget to cc them, now it's done.
The thread can be found here: http://marc.info/?l=linux-netdev&m=123382930115535&w=2
So, I'm waiting for maintainers's opinions.
Thank you,
Nicolas
Quoted 11 lines · Nicolas Dichtel
Quoted 10 lines · David Miller
From: Nicolas Dichtel <[email protected]>
Date: Fri, 06 Feb 2009 14:50:53 +0100Quoted 2 lines
If namespace is destroyed after this function, then
cleanup_net()will ensure that nobody is looking at itMaybe, but you better get some opinions from the people who wrote and maintain the network namespace code before I can consider your change seriously.
Quoted 6 lines
Quoted 2 lines
None of them responded to your patch posting, probably because you failed to CC: any of them.
Sorry, I forget to cc them, now it's done.
The thread can be found here: http://marc.info/?l=linux-netdev&m=123382930115535&w=2So, I'm waiting for maintainers's opinions.
We can move one network device from one namespace to another namespace, and that do not necessarily implies the network namespace will die and call cleanup_net. Without synchronize_net, it would be possible to have netif_receive_skb and dev_change_net_namespace to be executed concurrently, no ?
Wouldn't the execution of one of this function be problematic if we are in the delivery of a packet to the upper protocol in the big rcu_read_lock section of netif_receive_skb ?
dev_shutdown(dev);
/* Notify protocols, that we are about to destroy
this device. They should clean all the things.
*/ call_netdevice_notifiers(NETDEV_UNREGISTER, dev);
/*
* Flush the unicast and multicast chains
*/
dev_addr_discard(dev);
netdev_unregister_kobject(dev);
/* Actually switch the network namespace */
dev_net_set(dev, net);
Thanks
-- Daniel
Quoted 14 lines · Daniel Lezcano
Quoted 13 lines · Nicolas Dichtel
Quoted 12 lines · David Miller
From: Nicolas Dichtel <[email protected]>
Date: Fri, 06 Feb 2009 14:50:53 +0100Quoted 2 lines
If namespace is destroyed after this function, then
cleanup_net()will ensure that nobody is looking at itMaybe, but you better get some opinions from the people who wrote and maintain the network namespace code before I can consider your change seriously.
None of them responded to your patch posting, probably because you failed to CC: any of them.
Quoted 7 lines
Quoted 4 lines
Sorry, I forget to cc them, now it's done.
The thread can be found here: http://marc.info/?l=linux-netdev&m=123382930115535&w=2So, I'm waiting for maintainers's opinions.
We can move one network device from one namespace to another namespace, and that do not necessarily implies the network namespace will die and call
cleanup_net. Withoutsynchronize_net, it would be possible to havenetif_receive_skbanddev_change_net_namespaceto be executed concurrently, no ?
Wouldn't the execution of one of this function be problematic if we are in the delivery of a packet to the upper protocol in the bigrcu_read_locksection ofnetif_receive_skb?
Just to be sure: there is two synchronize_net() in dev_change_net_namespace(), and I was talking about the second one. The second one is called just before exiting the function.
Regards,
Nicolas
Quoted 22 lines
dev_shutdown(dev);/* Notify protocols, that we are about to destroy this device. They should clean all the things. */ call_netdevice_notifiers(NETDEV_UNREGISTER, dev); /* * Flush the unicast and multicast chains */ dev_addr_discard(dev); netdev_unregister_kobject(dev); /* Actually switch the network namespace */ dev_net_set(dev, net);Thanks
-- Daniel
Quoted 19 lines · Nicolas Dichtel
Quoted 18 lines · Daniel Lezcano
Quoted 17 lines · Nicolas Dichtel
Quoted 6 lines · David Miller
From: Nicolas Dichtel <[email protected]>
Date: Fri, 06 Feb 2009 14:50:53 +0100Quoted 2 lines
If namespace is destroyed after this function, then
cleanup_net()will ensure that nobody is looking at itQuoted 6 lines
Maybe, but you better get some opinions from the people who wrote and maintain the network namespace code before I can consider your change seriously.
None of them responded to your patch posting, probably because you failed to CC: any of them.
Sorry, I forget to cc them, now it's done.
The thread can be found here: http://marc.info/?l=linux-netdev&m=123382930115535&w=2So, I'm waiting for maintainers's opinions.
Quoted 8 lines
Quoted 3 lines
We can move one network device from one namespace to another namespace, and that do not necessarily implies the network namespace will die and call
cleanup_net. Withoutsynchronize_net, it would be possible to havenetif_receive_skbanddev_change_net_namespaceto be executed concurrently, no ?
Wouldn't the execution of one of this function be problematic if we are in the delivery of a packet to the upper protocol in the bigrcu_read_locksection ofnetif_receive_skb?Just to be sure: there is two
synchronize_net()indev_change_net_namespace(), and I was talking about the second one. The second one is called just before exiting the function.Regards,
Nicolas
Ah, ok :)
Hmm, at the first glance I would say it is useless but perhaps there is a trick here I do not understand. Eric, is there any particular reason to call synchronize_net before exiting the dev_change_net_namespace function ?
Quoted 5 lines · Daniel Lezcano
Hmm, at the first glance I would say it is useless but perhaps there is a trick here I do not understand.
Eric, is there any particular reason to callsynchronize_netbefore exiting thedev_change_net_namespacefunction ?
I haven't thought about that part of the code path in detail in a long time. dev_change_net_namespace() is a condensed version of register_netdevice() unregister_netdevice(). With the calls down into the driver removed.
On a side note. It looks like we now cope with:call_netdevice_notifiers(NETDEV_REGISTER, dev); failing in register_netdev, but no one updated dev_change_net_namespace to handle the change, looks like a real pain to cope with.
As for the synchronize_net, and in response to the original comment as best as I can tell we do have things being being deleted that are at least candidates for synchronize_net.
dev_addr_discard(dev);dev_net_set(dev, net);netdev_unregister_kobject(dev);
We very much do access dev->net with only rcu protection.
Hmm.
It looks like I originally took the second synchronize_net from what became rollback_registered, which happens just before we start freeing the netdevice.
The nastiest case that I can envision is if we happen to receive a packet (on another cpu) for the network device that we are moving, just after it has registered in the new network namespace. If we read the old network namespace and forward it up the network stack in that context I can imagine it being a recipe for all kinds of strange non-deterministic behavior.
So unless there is a reason for this change beyond general cleanup I would prefer not to think about it potential weirdness, and keep the code the way it is.
I seem to remember a conversation about this synchronize_net when the code was merged as well so if we are going to change it, let's look up those arguments if we can and see if there was something useful said.
Eric
Quoted 34 lines · Eric W. Biederman
Quoted 5 lines · Daniel Lezcano
Hmm, at the first glance I would say it is useless but perhaps there is a trick here I do not understand.
Eric, is there any particular reason to callsynchronize_netbefore exiting thedev_change_net_namespacefunction ?I haven't thought about that part of the code path in detail in a long time.
dev_change_net_namespace()is a condensed version ofregister_netdevice()unregister_netdevice(). With the calls down into the driver removed.On a side note. It looks like we now cope with:
call_netdevice_notifiers(NETDEV_REGISTER, dev); failing inregister_netdev, but no one updateddev_change_net_namespaceto handle the change, looks like a real pain to cope with.As for the
synchronize_net, and in response to the original comment as best as I can tell we do have things being being deleted that are at least candidates forsynchronize_net.
dev_addr_discard(dev);dev_net_set(dev, net);netdev_unregister_kobject(dev);We very much do access
dev->netwith only rcu protection.Hmm.
It looks like I originally took the second
synchronize_netfrom what becamerollback_registered, which happens just before we start freeing the netdevice.
Quoted 7 lines
The nastiest case that I can envision is if we happen to receive a packet (on another cpu) for the network device that we are moving, just after it has registered in the new network namespace. If we read the old network namespace and forward it up the network stack in that context I can imagine it being a recipe for all kinds of strange non-deterministic behavior.
The code does:
dev_close
dev_deactive
synchronize_rcu
synchronize_net
...
dev_shutdown
...
synchronize_net
The network device can no longer receive packets after dev_deactive, no ?
The first synchronize_net will wait for the outstanding packets to be delivered to the upper layer and we change the nd_net field after. Your scenario makes sense for the first synchronize_net but I am not sure that can happen if we remove the second synchronize_net.
Quoted 13 lines
So unless there is a reason for this change beyond general cleanup I would prefer not to think about it potential weirdness, and keep the code the way it is.
I seem to remember a conversation about this
synchronize_netwhen the code was merged as well so if we are going to change it, let's look up those arguments if we can and see if there was something useful said.Eric
Quoted 56 lines · Daniel Lezcano
Quoted 3 lines · Eric W. Biederman
Quoted 1 line · Daniel Lezcano
Hmm, at the first glance I would say it is useless but perhaps there is a
trick
Quoted 2 lines
Quoted 2 lines
here I do not understand.
Eric, is there any particular reason to callsynchronize_netbefore exitingthe
Quoted 29 lines
Quoted 2 lines
dev_change_net_namespacefunction ?I haven't thought about that part of the code path in detail in a long time.
dev_change_net_namespace()is a condensed version ofregister_netdevice()unregister_netdevice(). With the calls down into the driver removed.On a side note. It looks like we now cope with:
call_netdevice_notifiers(NETDEV_REGISTER, dev); failing inregister_netdev, but no one updateddev_change_net_namespaceto handle the change, looks like a real pain to cope with.As for the
synchronize_net, and in response to the original comment as best as I can tell we do have things being being deleted that are at least candidates forsynchronize_net.
dev_addr_discard(dev);dev_net_set(dev, net);netdev_unregister_kobject(dev);We very much do access
dev->netwith only rcu protection.Hmm.
It looks like I originally took the second
synchronize_netfrom what becamerollback_registered, which happens just before we start freeing the netdevice.Quoted 7 lines
The nastiest case that I can envision is if we happen to receive a packet (on another cpu) for the network device that we are moving, just after it has registered in the new network namespace. If we read the old network namespace and forward it up the network stack in that context I can imagine it being a recipe for all kinds of strange non-deterministic behavior.
The code does:
dev_close dev_deactive synchronize_rcu synchronize_net ... dev_shutdown ... synchronize_net
Quoted 5 lines
The network device can no longer receive packets after
dev_deactive, no ? The firstsynchronize_netwill wait for the outstanding packets to be delivered to the upper layer and we change thend_netfield after.
Your scenario makes sense for the firstsynchronize_netbut I am not sure that can happen if we remove the secondsynchronize_net.
Good point. Visibility is key. What can find us after we call list_netdevice() ? Aren't there some pieces of code that do for_each_netdevice under the rcu lock?
Eric
Quoted 72 lines · Eric W. Biederman
Quoted 62 lines · Daniel Lezcano
Quoted 5 lines · Eric W. Biederman
Quoted 2 lines · Daniel Lezcano
Hmm, at the first glance I would say it is useless but perhaps there is a
trick
Quoted 3 lines
Quoted 3 lines
here I do not understand.
Eric, is there any particular reason to callsynchronize_netbefore exitingthe
Quoted 29 lines
Quoted 3 lines
dev_change_net_namespacefunction ?I haven't thought about that part of the code path in detail in a long time.
dev_change_net_namespace()is a condensed version ofregister_netdevice()unregister_netdevice(). With the calls down into the driver removed.On a side note. It looks like we now cope with:
call_netdevice_notifiers(NETDEV_REGISTER, dev); failing inregister_netdev, but no one updateddev_change_net_namespaceto handle the change, looks like a real pain to cope with.As for the
synchronize_net, and in response to the original comment as best as I can tell we do have things being being deleted that are at least candidates forsynchronize_net.
dev_addr_discard(dev);dev_net_set(dev, net);netdev_unregister_kobject(dev);We very much do access
dev->netwith only rcu protection.Hmm.
It looks like I originally took the second
synchronize_netfrom what becamerollback_registered, which happens just before we start freeing the netdevice.Quoted 8 lines
The nastiest case that I can envision is if we happen to receive a packet (on another cpu) for the network device that we are moving, just after it has registered in the new network namespace. If we read the old network namespace and forward it up the network stack in that context I can imagine it being a recipe for all kinds of strange non-deterministic behavior.
The code does:
dev_close dev_deactive synchronize_rcu synchronize_net ... dev_shutdown ... synchronize_netQuoted 6 lines
The network device can no longer receive packets after
dev_deactive, no ? The firstsynchronize_netwill wait for the outstanding packets to be delivered to the upper layer and we change thend_netfield after.
Your scenario makes sense for the firstsynchronize_netbut I am not sure that can happen if we remove the secondsynchronize_net.
Quoted 4 lines
Good point. Visibility is key. What can find us after we call
list_netdevice()? Aren't there some pieces of code that dofor_each_netdeviceunder the rcu lock?
AFAIR, no. for_each_netdev is protected by rtnl_lock.
A message that is not in the archive (sent off-list or not yet received): [email protected]
Quoted 83 lines · Daniel Lezcano
Quoted 81 lines · Eric W. Biederman
Quoted 77 lines · Daniel Lezcano
Quoted 7 lines · Eric W. Biederman
Quoted 3 lines · Daniel Lezcano
Hmm, at the first glance I would say it is useless but perhaps there is a
trick
Quoted 4 lines
Quoted 4 lines
here I do not understand.
Eric, is there any particular reason to callsynchronize_netbefore exitingthe
Quoted 30 lines
Quoted 4 lines
dev_change_net_namespacefunction ?I haven't thought about that part of the code path in detail in a long time.
dev_change_net_namespace()is a condensed version ofregister_netdevice()unregister_netdevice(). With the calls down into the driver removed.On a side note. It looks like we now cope with:
call_netdevice_notifiers(NETDEV_REGISTER, dev); failing inregister_netdev, but no one updateddev_change_net_namespaceto handle the change, looks like a real pain to cope with.As for the
synchronize_net, and in response to the original comment as best as I can tell we do have things being being deleted that are at least candidates forsynchronize_net.
dev_addr_discard(dev);dev_net_set(dev, net);netdev_unregister_kobject(dev);We very much do access
dev->netwith only rcu protection.Hmm.
It looks like I originally took the second
synchronize_netfrom what becamerollback_registered, which happens just before we start freeing the netdevice.Quoted 9 lines
The nastiest case that I can envision is if we happen to receive a packet (on another cpu) for the network device that we are moving, just after it has registered in the new network namespace. If we read the old network namespace and forward it up the network stack in that context I can imagine it being a recipe for all kinds of strange non-deterministic behavior.
The code does:
dev_close dev_deactive synchronize_rcu synchronize_net ... dev_shutdown ... synchronize_netThe network device can no longer receive packets after
dev_deactive, no ? The firstsynchronize_netwill wait for the outstanding packets to be delivered to the upper layer and we change thend_netfield after.
Your scenario makes sense for the firstsynchronize_netbut I am not sure that can happen if we remove the secondsynchronize_net.
Quoted 7 lines
Quoted 5 lines
Good point. Visibility is key. What can find us after we call
list_netdevice()? Aren't there some pieces of code that dofor_each_netdeviceunder the rcu lock?AFAIR, no.
for_each_netdevis protected byrtnl_lock.
Nicolas,
At the first glance it looks like the removing of the second synchronize_net is fine, but before posting the patch do you mind to wait a little ?
I would like to do some tests with your patch to check if we don't missed something.
Thanks
-- Daniel
A message that is not in the archive (sent off-list or not yet received): [email protected]
Quoted 83 lines · Daniel Lezcano
Quoted 75 lines · Daniel Lezcano
Quoted 73 lines · Eric W. Biederman
Quoted 70 lines · Daniel Lezcano
Quoted 5 lines · Eric W. Biederman
Quoted 3 lines · Daniel Lezcano
Hmm, at the first glance I would say it is useless but perhaps there is a
trick
Quoted 4 lines
Quoted 4 lines
here I do not understand.
Eric, is there any particular reason to callsynchronize_netbefore exitingthe
Quoted 28 lines
Quoted 2 lines
dev_change_net_namespacefunction ?I haven't thought about that part of the code path in detail in a long time.
dev_change_net_namespace()is a condensed version ofregister_netdevice()unregister_netdevice(). With the calls down into the driver removed.On a side note. It looks like we now cope with:
call_netdevice_notifiers(NETDEV_REGISTER, dev); failing inregister_netdev, but no one updateddev_change_net_namespaceto handle the change, looks like a real pain to cope with.As for the
synchronize_net, and in response to the original comment as best as I can tell we do have things being being deleted that are at least candidates forsynchronize_net.
dev_addr_discard(dev);dev_net_set(dev, net);netdev_unregister_kobject(dev);We very much do access
dev->netwith only rcu protection.Hmm.
It looks like I originally took the second
synchronize_netfrom what becamerollback_registered, which happens just before we start freeing the netdevice.Quoted 7 lines
The nastiest case that I can envision is if we happen to receive a packet (on another cpu) for the network device that we are moving, just after it has registered in the new network namespace. If we read the old network namespace and forward it up the network stack in that context I can imagine it being a recipe for all kinds of strange non-deterministic behavior.
The code does:
dev_close dev_deactive synchronize_rcu synchronize_net ... dev_shutdown ... synchronize_netThe network device can no longer receive packets after
dev_deactive, no ?
The firstsynchronize_netwill wait for the outstanding packets to be delivered
to the upper layer and we change thend_netfield after. Your scenario makes sense for the firstsynchronize_netbut I am not sure that
can happen if we remove the secondsynchronize_net.Quoted 6 lines
Quoted 4 lines
Good point. Visibility is key. What can find us after we call
list_netdevice()? Aren't there some pieces of code that dofor_each_netdeviceunder the rcu lock?AFAIR, no.
for_each_netdevis protected byrtnl_lock.
Quoted 8 lines
Nicolas,
At the first glance it looks like the removing of the second
synchronize_netis fine, but before posting the patch do you mind to wait a little ?
I would like to do some tests with your patch to check if we don't missed something.
Hi Daniel,
no problem, there is no hurry. Let me know the result of your tests.
Thanks,
Nicolas