diff options
author | 2018-03-27 13:18:10 -0400 | |
---|---|---|
committer | 2018-03-27 13:18:10 -0400 | |
commit | c709002c23f91d90eb6ee2d4efbb548a8fe3cc80 (patch) | |
tree | dc2887c1b2089055ad7c2d13df0ea20b3a27969b /net/core | |
parent | net: mvpp2: Use relaxed I/O in data path (diff) | |
parent | net: Add more comments (diff) | |
download | wireguard-linux-c709002c23f91d90eb6ee2d4efbb548a8fe3cc80.tar.xz wireguard-linux-c709002c23f91d90eb6ee2d4efbb548a8fe3cc80.zip |
Merge branch 'pernet-all-async'
Kirill Tkhai says:
====================
Make pernet_operations always read locked
All the pernet_operations are converted, and the last one
is in this patchset (nfsd_net_ops acked by J. Bruce Fields).
So, it's the time to kill pernet_operations::async field,
and make setup_net() and cleanup_net() always require
the rwsem only read locked.
All further pernet_operations have to be developed to fit
this rule. Some of previous patches added a comment to
struct pernet_operations about that.
Also, this patchset renames net_sem to pernet_ops_rwsem
to make the target area of the rwsem is more clear visible,
and adds more comments.
====================
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/core')
-rw-r--r-- | net/core/dev.c | 2 | ||||
-rw-r--r-- | net/core/fib_notifier.c | 1 | ||||
-rw-r--r-- | net/core/fib_rules.c | 1 | ||||
-rw-r--r-- | net/core/net-procfs.c | 2 | ||||
-rw-r--r-- | net/core/net_namespace.c | 77 | ||||
-rw-r--r-- | net/core/pktgen.c | 1 | ||||
-rw-r--r-- | net/core/rtnetlink.c | 7 | ||||
-rw-r--r-- | net/core/sock.c | 2 | ||||
-rw-r--r-- | net/core/sock_diag.c | 1 | ||||
-rw-r--r-- | net/core/sysctl_net_core.c | 1 |
10 files changed, 26 insertions, 69 deletions
diff --git a/net/core/dev.c b/net/core/dev.c index 97a96df4b6da..e13807b5c84d 100644 --- a/net/core/dev.c +++ b/net/core/dev.c @@ -8883,7 +8883,6 @@ static void __net_exit netdev_exit(struct net *net) static struct pernet_operations __net_initdata netdev_net_ops = { .init = netdev_init, .exit = netdev_exit, - .async = true, }; static void __net_exit default_device_exit(struct net *net) @@ -8984,7 +8983,6 @@ static void __net_exit default_device_exit_batch(struct list_head *net_list) static struct pernet_operations __net_initdata default_device_ops = { .exit = default_device_exit, .exit_batch = default_device_exit_batch, - .async = true, }; /* diff --git a/net/core/fib_notifier.c b/net/core/fib_notifier.c index 5ace0705a3f9..0c048bdeb016 100644 --- a/net/core/fib_notifier.c +++ b/net/core/fib_notifier.c @@ -171,7 +171,6 @@ static void __net_exit fib_notifier_net_exit(struct net *net) static struct pernet_operations fib_notifier_net_ops = { .init = fib_notifier_net_init, .exit = fib_notifier_net_exit, - .async = true, }; static int __init fib_notifier_init(void) diff --git a/net/core/fib_rules.c b/net/core/fib_rules.c index f6f04fc0f629..9d87ce868402 100644 --- a/net/core/fib_rules.c +++ b/net/core/fib_rules.c @@ -1130,7 +1130,6 @@ static void __net_exit fib_rules_net_exit(struct net *net) static struct pernet_operations fib_rules_net_ops = { .init = fib_rules_net_init, .exit = fib_rules_net_exit, - .async = true, }; static int __init fib_rules_init(void) diff --git a/net/core/net-procfs.c b/net/core/net-procfs.c index dd6ae431d038..9737302907b1 100644 --- a/net/core/net-procfs.c +++ b/net/core/net-procfs.c @@ -349,7 +349,6 @@ static void __net_exit dev_proc_net_exit(struct net *net) static struct pernet_operations __net_initdata dev_proc_ops = { .init = dev_proc_net_init, .exit = dev_proc_net_exit, - .async = true, }; static int dev_mc_seq_show(struct seq_file *seq, void *v) @@ -406,7 +405,6 @@ static void __net_exit dev_mc_net_exit(struct net *net) static struct pernet_operations __net_initdata dev_mc_net_ops = { .init = dev_mc_net_init, .exit = dev_mc_net_exit, - .async = true, }; int __init dev_proc_init(void) diff --git a/net/core/net_namespace.c b/net/core/net_namespace.c index 95ba2c53bd9a..b5796d17a302 100644 --- a/net/core/net_namespace.c +++ b/net/core/net_namespace.c @@ -40,12 +40,13 @@ struct net init_net = { EXPORT_SYMBOL(init_net); static bool init_net_initialized; -static unsigned nr_sync_pernet_ops; /* - * net_sem: protects: pernet_list, net_generic_ids, nr_sync_pernet_ops, + * pernet_ops_rwsem: protects: pernet_list, net_generic_ids, * init_net_initialized and first_device pointer. + * This is internal net namespace object. Please, don't use it + * outside. */ -DECLARE_RWSEM(net_sem); +DECLARE_RWSEM(pernet_ops_rwsem); #define MIN_PERNET_OPS_ID \ ((sizeof(struct net_generic) + sizeof(void *) - 1) / sizeof(void *)) @@ -73,7 +74,7 @@ static int net_assign_generic(struct net *net, unsigned int id, void *data) BUG_ON(id < MIN_PERNET_OPS_ID); old_ng = rcu_dereference_protected(net->gen, - lockdep_is_held(&net_sem)); + lockdep_is_held(&pernet_ops_rwsem)); if (old_ng->s.len > id) { old_ng->ptr[id] = data; return 0; @@ -290,7 +291,7 @@ struct net *get_net_ns_by_id(struct net *net, int id) */ static __net_init int setup_net(struct net *net, struct user_namespace *user_ns) { - /* Must be called with net_sem held */ + /* Must be called with pernet_ops_rwsem held */ const struct pernet_operations *ops, *saved_ops; int error = 0; LIST_HEAD(net_exit_list); @@ -339,7 +340,6 @@ static int __net_init net_defaults_init_net(struct net *net) static struct pernet_operations net_defaults_ops = { .init = net_defaults_init_net, - .async = true, }; static __init int net_defaults_init(void) @@ -406,7 +406,6 @@ struct net *copy_net_ns(unsigned long flags, { struct ucounts *ucounts; struct net *net; - unsigned write; int rv; if (!(flags & CLONE_NEWNET)) @@ -424,25 +423,14 @@ struct net *copy_net_ns(unsigned long flags, refcount_set(&net->passive, 1); net->ucounts = ucounts; get_user_ns(user_ns); -again: - write = READ_ONCE(nr_sync_pernet_ops); - if (write) - rv = down_write_killable(&net_sem); - else - rv = down_read_killable(&net_sem); + + rv = down_read_killable(&pernet_ops_rwsem); if (rv < 0) goto put_userns; - if (!write && unlikely(READ_ONCE(nr_sync_pernet_ops))) { - up_read(&net_sem); - goto again; - } rv = setup_net(net, user_ns); - if (write) - up_write(&net_sem); - else - up_read(&net_sem); + up_read(&pernet_ops_rwsem); if (rv < 0) { put_userns: @@ -490,21 +478,11 @@ static void cleanup_net(struct work_struct *work) struct net *net, *tmp, *last; struct llist_node *net_kill_list; LIST_HEAD(net_exit_list); - unsigned write; /* Atomically snapshot the list of namespaces to cleanup */ net_kill_list = llist_del_all(&cleanup_list); -again: - write = READ_ONCE(nr_sync_pernet_ops); - if (write) - down_write(&net_sem); - else - down_read(&net_sem); - if (!write && unlikely(READ_ONCE(nr_sync_pernet_ops))) { - up_read(&net_sem); - goto again; - } + down_read(&pernet_ops_rwsem); /* Don't let anyone else find us. */ rtnl_lock(); @@ -543,10 +521,7 @@ again: list_for_each_entry_reverse(ops, &pernet_list, list) ops_free_list(ops, &net_exit_list); - if (write) - up_write(&net_sem); - else - up_read(&net_sem); + up_read(&pernet_ops_rwsem); /* Ensure there are no outstanding rcu callbacks using this * network namespace. @@ -573,8 +548,8 @@ again: */ void net_ns_barrier(void) { - down_write(&net_sem); - up_write(&net_sem); + down_write(&pernet_ops_rwsem); + up_write(&pernet_ops_rwsem); } EXPORT_SYMBOL(net_ns_barrier); @@ -654,7 +629,6 @@ static __net_exit void net_ns_net_exit(struct net *net) static struct pernet_operations __net_initdata net_ns_ops = { .init = net_ns_net_init, .exit = net_ns_net_exit, - .async = true, }; static const struct nla_policy rtnl_net_policy[NETNSA_MAX + 1] = { @@ -897,12 +871,12 @@ static int __init net_ns_init(void) rcu_assign_pointer(init_net.gen, ng); - down_write(&net_sem); + down_write(&pernet_ops_rwsem); if (setup_net(&init_net, &init_user_ns)) panic("Could not setup the initial network namespace"); init_net_initialized = true; - up_write(&net_sem); + up_write(&pernet_ops_rwsem); register_pernet_subsys(&net_ns_ops); @@ -1006,9 +980,6 @@ again: rcu_barrier(); if (ops->id) ida_remove(&net_generic_ids, *ops->id); - } else if (!ops->async) { - pr_info_once("Pernet operations %ps are sync.\n", ops); - nr_sync_pernet_ops++; } return error; @@ -1016,8 +987,6 @@ again: static void unregister_pernet_operations(struct pernet_operations *ops) { - if (!ops->async) - BUG_ON(nr_sync_pernet_ops-- == 0); __unregister_pernet_operations(ops); rcu_barrier(); if (ops->id) @@ -1046,9 +1015,9 @@ static void unregister_pernet_operations(struct pernet_operations *ops) int register_pernet_subsys(struct pernet_operations *ops) { int error; - down_write(&net_sem); + down_write(&pernet_ops_rwsem); error = register_pernet_operations(first_device, ops); - up_write(&net_sem); + up_write(&pernet_ops_rwsem); return error; } EXPORT_SYMBOL_GPL(register_pernet_subsys); @@ -1064,9 +1033,9 @@ EXPORT_SYMBOL_GPL(register_pernet_subsys); */ void unregister_pernet_subsys(struct pernet_operations *ops) { - down_write(&net_sem); + down_write(&pernet_ops_rwsem); unregister_pernet_operations(ops); - up_write(&net_sem); + up_write(&pernet_ops_rwsem); } EXPORT_SYMBOL_GPL(unregister_pernet_subsys); @@ -1092,11 +1061,11 @@ EXPORT_SYMBOL_GPL(unregister_pernet_subsys); int register_pernet_device(struct pernet_operations *ops) { int error; - down_write(&net_sem); + down_write(&pernet_ops_rwsem); error = register_pernet_operations(&pernet_list, ops); if (!error && (first_device == &pernet_list)) first_device = &ops->list; - up_write(&net_sem); + up_write(&pernet_ops_rwsem); return error; } EXPORT_SYMBOL_GPL(register_pernet_device); @@ -1112,11 +1081,11 @@ EXPORT_SYMBOL_GPL(register_pernet_device); */ void unregister_pernet_device(struct pernet_operations *ops) { - down_write(&net_sem); + down_write(&pernet_ops_rwsem); if (&ops->list == first_device) first_device = first_device->next; unregister_pernet_operations(ops); - up_write(&net_sem); + up_write(&pernet_ops_rwsem); } EXPORT_SYMBOL_GPL(unregister_pernet_device); diff --git a/net/core/pktgen.c b/net/core/pktgen.c index 545cf08cd558..7e4ede34cc52 100644 --- a/net/core/pktgen.c +++ b/net/core/pktgen.c @@ -3852,7 +3852,6 @@ static struct pernet_operations pg_net_ops = { .exit = pg_net_exit, .id = &pg_net_id, .size = sizeof(struct pktgen_net), - .async = true, }; static int __init pg_init(void) diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c index 87079eaa871b..2d3949789cef 100644 --- a/net/core/rtnetlink.c +++ b/net/core/rtnetlink.c @@ -459,12 +459,12 @@ static void rtnl_lock_unregistering_all(void) */ void rtnl_link_unregister(struct rtnl_link_ops *ops) { - /* Close the race with cleanup_net() */ - down_write(&net_sem); + /* Close the race with setup_net() and cleanup_net() */ + down_write(&pernet_ops_rwsem); rtnl_lock_unregistering_all(); __rtnl_link_unregister(ops); rtnl_unlock(); - up_write(&net_sem); + up_write(&pernet_ops_rwsem); } EXPORT_SYMBOL_GPL(rtnl_link_unregister); @@ -4730,7 +4730,6 @@ static void __net_exit rtnetlink_net_exit(struct net *net) static struct pernet_operations rtnetlink_net_ops = { .init = rtnetlink_net_init, .exit = rtnetlink_net_exit, - .async = true, }; void __init rtnetlink_init(void) diff --git a/net/core/sock.c b/net/core/sock.c index 8cee2920a47f..6444525f610c 100644 --- a/net/core/sock.c +++ b/net/core/sock.c @@ -3175,7 +3175,6 @@ static void __net_exit sock_inuse_exit_net(struct net *net) static struct pernet_operations net_inuse_ops = { .init = sock_inuse_init_net, .exit = sock_inuse_exit_net, - .async = true, }; static __init int net_inuse_init(void) @@ -3470,7 +3469,6 @@ static __net_exit void proto_exit_net(struct net *net) static __net_initdata struct pernet_operations proto_net_ops = { .init = proto_init_net, .exit = proto_exit_net, - .async = true, }; static int __init proto_init(void) diff --git a/net/core/sock_diag.c b/net/core/sock_diag.c index a3392a8f9276..c37b5be7c5e4 100644 --- a/net/core/sock_diag.c +++ b/net/core/sock_diag.c @@ -324,7 +324,6 @@ static void __net_exit diag_net_exit(struct net *net) static struct pernet_operations diag_net_ops = { .init = diag_net_init, .exit = diag_net_exit, - .async = true, }; static int __init sock_diag_init(void) diff --git a/net/core/sysctl_net_core.c b/net/core/sysctl_net_core.c index 4f47f92459cc..b3b609f0eeb5 100644 --- a/net/core/sysctl_net_core.c +++ b/net/core/sysctl_net_core.c @@ -584,7 +584,6 @@ static __net_exit void sysctl_core_net_exit(struct net *net) static __net_initdata struct pernet_operations sysctl_core_ops = { .init = sysctl_core_net_init, .exit = sysctl_core_net_exit, - .async = true, }; static __init int sysctl_core_init(void) |