diff options
Diffstat (limited to 'net')
-rw-r--r-- | net/core/net_namespace.c | 14 |
1 files changed, 11 insertions, 3 deletions
diff --git a/net/core/net_namespace.c b/net/core/net_namespace.c index b7292a2719dc..5cd0b22e649d 100644 --- a/net/core/net_namespace.c +++ b/net/core/net_namespace.c | |||
@@ -6,6 +6,7 @@ | |||
6 | #include <linux/delay.h> | 6 | #include <linux/delay.h> |
7 | #include <linux/sched.h> | 7 | #include <linux/sched.h> |
8 | #include <linux/idr.h> | 8 | #include <linux/idr.h> |
9 | #include <linux/rculist.h> | ||
9 | #include <net/net_namespace.h> | 10 | #include <net/net_namespace.h> |
10 | #include <net/netns/generic.h> | 11 | #include <net/netns/generic.h> |
11 | 12 | ||
@@ -127,7 +128,7 @@ static struct net *net_create(void) | |||
127 | rv = setup_net(net); | 128 | rv = setup_net(net); |
128 | if (rv == 0) { | 129 | if (rv == 0) { |
129 | rtnl_lock(); | 130 | rtnl_lock(); |
130 | list_add_tail(&net->list, &net_namespace_list); | 131 | list_add_tail_rcu(&net->list, &net_namespace_list); |
131 | rtnl_unlock(); | 132 | rtnl_unlock(); |
132 | } | 133 | } |
133 | mutex_unlock(&net_mutex); | 134 | mutex_unlock(&net_mutex); |
@@ -156,9 +157,16 @@ static void cleanup_net(struct work_struct *work) | |||
156 | 157 | ||
157 | /* Don't let anyone else find us. */ | 158 | /* Don't let anyone else find us. */ |
158 | rtnl_lock(); | 159 | rtnl_lock(); |
159 | list_del(&net->list); | 160 | list_del_rcu(&net->list); |
160 | rtnl_unlock(); | 161 | rtnl_unlock(); |
161 | 162 | ||
163 | /* | ||
164 | * Another CPU might be rcu-iterating the list, wait for it. | ||
165 | * This needs to be before calling the exit() notifiers, so | ||
166 | * the rcu_barrier() below isn't sufficient alone. | ||
167 | */ | ||
168 | synchronize_rcu(); | ||
169 | |||
162 | /* Run all of the network namespace exit methods */ | 170 | /* Run all of the network namespace exit methods */ |
163 | list_for_each_entry_reverse(ops, &pernet_list, list) { | 171 | list_for_each_entry_reverse(ops, &pernet_list, list) { |
164 | if (ops->exit) | 172 | if (ops->exit) |
@@ -219,7 +227,7 @@ static int __init net_ns_init(void) | |||
219 | panic("Could not setup the initial network namespace"); | 227 | panic("Could not setup the initial network namespace"); |
220 | 228 | ||
221 | rtnl_lock(); | 229 | rtnl_lock(); |
222 | list_add_tail(&init_net.list, &net_namespace_list); | 230 | list_add_tail_rcu(&init_net.list, &net_namespace_list); |
223 | rtnl_unlock(); | 231 | rtnl_unlock(); |
224 | 232 | ||
225 | mutex_unlock(&net_mutex); | 233 | mutex_unlock(&net_mutex); |