aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
Diffstat (limited to 'net')
-rw-r--r--net/socket.c11
1 files changed, 6 insertions, 5 deletions
diff --git a/net/socket.c b/net/socket.c
index 3ca2fd9e3720..c898df76e924 100644
--- a/net/socket.c
+++ b/net/socket.c
@@ -156,7 +156,7 @@ static const struct file_operations socket_file_ops = {
156 */ 156 */
157 157
158static DEFINE_SPINLOCK(net_family_lock); 158static DEFINE_SPINLOCK(net_family_lock);
159static const struct net_proto_family *net_families[NPROTO] __read_mostly; 159static const struct net_proto_family __rcu *net_families[NPROTO] __read_mostly;
160 160
161/* 161/*
162 * Statistics counters of the socket lists 162 * Statistics counters of the socket lists
@@ -1200,7 +1200,7 @@ int __sock_create(struct net *net, int family, int type, int protocol,
1200 * requested real, full-featured networking support upon configuration. 1200 * requested real, full-featured networking support upon configuration.
1201 * Otherwise module support will break! 1201 * Otherwise module support will break!
1202 */ 1202 */
1203 if (net_families[family] == NULL) 1203 if (rcu_access_pointer(net_families[family]) == NULL)
1204 request_module("net-pf-%d", family); 1204 request_module("net-pf-%d", family);
1205#endif 1205#endif
1206 1206
@@ -2332,10 +2332,11 @@ int sock_register(const struct net_proto_family *ops)
2332 } 2332 }
2333 2333
2334 spin_lock(&net_family_lock); 2334 spin_lock(&net_family_lock);
2335 if (net_families[ops->family]) 2335 if (rcu_dereference_protected(net_families[ops->family],
2336 lockdep_is_held(&net_family_lock)))
2336 err = -EEXIST; 2337 err = -EEXIST;
2337 else { 2338 else {
2338 net_families[ops->family] = ops; 2339 rcu_assign_pointer(net_families[ops->family], ops);
2339 err = 0; 2340 err = 0;
2340 } 2341 }
2341 spin_unlock(&net_family_lock); 2342 spin_unlock(&net_family_lock);
@@ -2363,7 +2364,7 @@ void sock_unregister(int family)
2363 BUG_ON(family < 0 || family >= NPROTO); 2364 BUG_ON(family < 0 || family >= NPROTO);
2364 2365
2365 spin_lock(&net_family_lock); 2366 spin_lock(&net_family_lock);
2366 net_families[family] = NULL; 2367 rcu_assign_pointer(net_families[family], NULL);
2367 spin_unlock(&net_family_lock); 2368 spin_unlock(&net_family_lock);
2368 2369
2369 synchronize_rcu(); 2370 synchronize_rcu();