From: Kirill Tkhai <ktkhai@virtuozzo.com>
To: davem@davemloft.net, vyasevic@redhat.com,
kstewart@linuxfoundation.org, pombredanne@nexb.com,
vyasevich@gmail.com, mark.rutland@arm.com,
gregkh@linuxfoundation.org, adobriyan@gmail.com, fw@strlen.de,
nicolas.dichtel@6wind.com, xiyou.wangcong@gmail.com,
roman.kapl@sysgo.com, paul@paul-moore.com, dsahern@gmail.com,
daniel@iogearbox.net, lucien.xin@gmail.com,
mschiffer@universe-factory.net, rshearma@brocade.com,
netdev@vger.kernel.org, ktkhai@virtuozzo.com,
ebiederm@xmission.com, avagin@virtuozzo.com,
gorcunov@virtuozzo.com, eric.dumazet@gmail.com,
stephen@networkplumber.org, ktkhai@virtuozzo.com
Subject: [PATCH net-next v3 05/32] net: Allow pernet_operations to be executed in parallel
Date: Tue, 13 Feb 2018 12:26:44 +0300 [thread overview]
Message-ID: <151851400426.5034.3718104605840354454.stgit@localhost.localdomain> (raw)
In-Reply-To: <151851357738.5034.10272265431844825686.stgit@localhost.localdomain>
This adds new pernet_operations::async flag to indicate operations,
which ->init(), ->exit() and ->exit_batch() methods are allowed
to be executed in parallel with the methods of any other pernet_operations.
When there are only asynchronous pernet_operations in the system,
net_mutex won't be taken for a net construction and destruction.
Also, remove BUG_ON(mutex_is_locked()) from net_assign_generic()
without replacing with the equivalent net_sem check, as there is
one more lockdep assert below.
v3: Add comment near net_mutex.
Suggested-by: Eric W. Biederman <ebiederm@xmission.com>
Signed-off-by: Kirill Tkhai <ktkhai@virtuozzo.com>
Acked-by: Andrei Vagin <avagin@virtuozzo.com>
---
include/net/net_namespace.h | 6 ++++++
net/core/net_namespace.c | 30 ++++++++++++++++++++----------
2 files changed, 26 insertions(+), 10 deletions(-)
diff --git a/include/net/net_namespace.h b/include/net/net_namespace.h
index f306b2aa15a4..9158ec1ad06f 100644
--- a/include/net/net_namespace.h
+++ b/include/net/net_namespace.h
@@ -313,6 +313,12 @@ struct pernet_operations {
void (*exit_batch)(struct list_head *net_exit_list);
unsigned int *id;
size_t size;
+ /*
+ * Indicates above methods are allowed to be executed in parallel
+ * with methods of any other pernet_operations, i.e. they are not
+ * need synchronization via net_mutex.
+ */
+ bool async;
};
/*
diff --git a/net/core/net_namespace.c b/net/core/net_namespace.c
index f8453c438798..2a01ff32d9c7 100644
--- a/net/core/net_namespace.c
+++ b/net/core/net_namespace.c
@@ -29,6 +29,7 @@
static LIST_HEAD(pernet_list);
static struct list_head *first_device = &pernet_list;
+/* Used only if there are !async pernet_operations registered */
DEFINE_MUTEX(net_mutex);
LIST_HEAD(net_namespace_list);
@@ -41,8 +42,9 @@ 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,
+ * net_sem: protects: pernet_list, net_generic_ids, nr_sync_pernet_ops,
* init_net_initialized and first_device pointer.
*/
DECLARE_RWSEM(net_sem);
@@ -70,11 +72,10 @@ static int net_assign_generic(struct net *net, unsigned int id, void *data)
{
struct net_generic *ng, *old_ng;
- BUG_ON(!mutex_is_locked(&net_mutex));
BUG_ON(id < MIN_PERNET_OPS_ID);
old_ng = rcu_dereference_protected(net->gen,
- lockdep_is_held(&net_mutex));
+ lockdep_is_held(&net_sem));
if (old_ng->s.len > id) {
old_ng->ptr[id] = data;
return 0;
@@ -426,11 +427,14 @@ struct net *copy_net_ns(unsigned long flags,
rv = down_read_killable(&net_sem);
if (rv < 0)
goto put_userns;
- rv = mutex_lock_killable(&net_mutex);
- if (rv < 0)
- goto up_read;
+ if (nr_sync_pernet_ops) {
+ rv = mutex_lock_killable(&net_mutex);
+ if (rv < 0)
+ goto up_read;
+ }
rv = setup_net(net, user_ns);
- mutex_unlock(&net_mutex);
+ if (nr_sync_pernet_ops)
+ mutex_unlock(&net_mutex);
up_read:
up_read(&net_sem);
if (rv < 0) {
@@ -487,7 +491,8 @@ static void cleanup_net(struct work_struct *work)
spin_unlock_irq(&cleanup_list_lock);
down_read(&net_sem);
- mutex_lock(&net_mutex);
+ if (nr_sync_pernet_ops)
+ mutex_lock(&net_mutex);
/* Don't let anyone else find us. */
rtnl_lock();
@@ -522,7 +527,8 @@ static void cleanup_net(struct work_struct *work)
list_for_each_entry_reverse(ops, &pernet_list, list)
ops_exit_list(ops, &net_exit_list);
- mutex_unlock(&net_mutex);
+ if (nr_sync_pernet_ops)
+ mutex_unlock(&net_mutex);
/* Free the net generic variables */
list_for_each_entry_reverse(ops, &pernet_list, list)
@@ -994,6 +1000,9 @@ static int register_pernet_operations(struct list_head *list,
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;
@@ -1001,7 +1010,8 @@ static int register_pernet_operations(struct list_head *list,
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)
next prev parent reply other threads:[~2018-02-13 9:26 UTC|newest]
Thread overview: 36+ messages / expand[flat|nested] mbox.gz Atom feed top
2018-02-13 9:25 [PATCH net-next v3 00/32] Replacing net_mutex with rw_semaphore Kirill Tkhai
2018-02-13 9:26 ` [PATCH net-next v3 01/32] net: Assign net to net_namespace_list in setup_net() Kirill Tkhai
2018-02-13 9:26 ` [PATCH net-next v3 02/32] net: Cleanup in copy_net_ns() Kirill Tkhai
2018-02-13 9:26 ` [PATCH net-next v3 03/32] net: Introduce net_sem for protection of pernet_list Kirill Tkhai
2018-02-26 2:04 ` [lkp-robot] [net] 37b927536f: kernel_BUG_at_net/core/net_namespace.c kernel test robot
2018-02-26 9:40 ` Kirill Tkhai
2018-02-13 9:26 ` [PATCH net-next v3 04/32] net: Move mutex_unlock() in cleanup_net() up Kirill Tkhai
2018-02-13 9:26 ` Kirill Tkhai [this message]
2018-02-13 9:26 ` [PATCH net-next v3 06/32] net: Convert proc_net_ns_ops Kirill Tkhai
2018-02-13 9:27 ` [PATCH net-next v3 07/32] net: Convert net_ns_ops methods Kirill Tkhai
2018-02-13 9:27 ` [PATCH net-next v3 08/32] net: Convert sysctl_pernet_ops Kirill Tkhai
2018-02-13 9:27 ` [PATCH net-next v3 09/32] net: Convert netfilter_net_ops Kirill Tkhai
2018-02-13 9:27 ` [PATCH net-next v3 10/32] net: Convert nf_log_net_ops Kirill Tkhai
2018-02-13 9:27 ` [PATCH net-next v3 11/32] net: Convert net_inuse_ops Kirill Tkhai
2018-02-13 9:27 ` [PATCH net-next v3 12/32] net: Convert net_defaults_ops Kirill Tkhai
2018-02-13 9:28 ` [PATCH net-next v3 13/32] net: Convert netlink_net_ops Kirill Tkhai
2018-02-13 9:28 ` [PATCH net-next v3 14/32] net: Convert rtnetlink_net_ops Kirill Tkhai
2018-02-13 9:28 ` [PATCH net-next v3 15/32] net: Convert audit_net_ops Kirill Tkhai
2018-02-13 9:28 ` [PATCH net-next v3 16/32] net: Convert uevent_net_ops Kirill Tkhai
2018-02-13 9:28 ` [PATCH net-next v3 17/32] net: Convert proto_net_ops Kirill Tkhai
2018-02-13 9:28 ` [PATCH net-next v3 18/32] net: Convert pernet_subsys ops, registered via net_dev_init() Kirill Tkhai
2018-02-13 9:29 ` [PATCH net-next v3 19/32] net: Convert fib_* pernet_operations, registered via subsys_initcall Kirill Tkhai
2018-02-13 9:29 ` [PATCH net-next v3 20/32] net: Convert subsys_initcall() registered pernet_operations from net/sched Kirill Tkhai
2018-02-13 9:29 ` [PATCH net-next v3 21/32] net: Convert genl_pernet_ops Kirill Tkhai
2018-02-13 9:29 ` [PATCH net-next v3 22/32] net: Convert wext_pernet_ops Kirill Tkhai
2018-02-13 9:29 ` [PATCH net-next v3 23/32] net: Convert sysctl_core_ops Kirill Tkhai
2018-02-13 9:29 ` [PATCH net-next v3 24/32] net: Convert pernet_subsys, registered from inet_init() Kirill Tkhai
2018-02-13 9:30 ` [PATCH net-next v3 25/32] net: Convert unix_net_ops Kirill Tkhai
2018-02-13 9:30 ` [PATCH net-next v3 26/32] net: Convert packet_net_ops Kirill Tkhai
2018-02-13 9:30 ` [PATCH net-next v3 27/32] net: Convert ipv4_sysctl_ops Kirill Tkhai
2018-02-13 9:30 ` [PATCH net-next v3 28/32] net: Convert addrconf_ops Kirill Tkhai
2018-02-13 9:30 ` [PATCH net-next v3 29/32] net: Convert loopback_net_ops Kirill Tkhai
2018-02-13 9:30 ` [PATCH net-next v3 30/32] net: Convert default_device_ops Kirill Tkhai
2018-02-13 9:30 ` [PATCH net-next v3 31/32] net: Convert diag_net_ops Kirill Tkhai
2018-02-13 9:31 ` [PATCH net-next v3 32/32] net: Convert netlink_tap_net_ops Kirill Tkhai
2018-02-13 15:54 ` [PATCH net-next v3 00/32] Replacing net_mutex with rw_semaphore David Miller
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=151851400426.5034.3718104605840354454.stgit@localhost.localdomain \
--to=ktkhai@virtuozzo.com \
--cc=adobriyan@gmail.com \
--cc=avagin@virtuozzo.com \
--cc=daniel@iogearbox.net \
--cc=davem@davemloft.net \
--cc=dsahern@gmail.com \
--cc=ebiederm@xmission.com \
--cc=eric.dumazet@gmail.com \
--cc=fw@strlen.de \
--cc=gorcunov@virtuozzo.com \
--cc=gregkh@linuxfoundation.org \
--cc=kstewart@linuxfoundation.org \
--cc=lucien.xin@gmail.com \
--cc=mark.rutland@arm.com \
--cc=mschiffer@universe-factory.net \
--cc=netdev@vger.kernel.org \
--cc=nicolas.dichtel@6wind.com \
--cc=paul@paul-moore.com \
--cc=pombredanne@nexb.com \
--cc=roman.kapl@sysgo.com \
--cc=rshearma@brocade.com \
--cc=stephen@networkplumber.org \
--cc=vyasevic@redhat.com \
--cc=vyasevich@gmail.com \
--cc=xiyou.wangcong@gmail.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox