Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 885842d8 authored by David S. Miller's avatar David S. Miller
Browse files

Merge branch 'Replacing-net_mutex-with-rw_semaphore'



Kirill Tkhai says:

====================
Replacing net_mutex with rw_semaphore

this is the third version of the patchset introducing net_sem
instead of net_mutex. The patchset adds net_sem in addition
to net_mutex and allows pernet_operations to be "async". This
flag means, the pernet_operations methods are safe to be
executed with any other pernet_operations (un)initializing
another net.

If there are only async pernet_operations in the system,
net_mutex is not used either for setup_net() or for cleanup_net().

The pernet_operations converted in this patchset allow
to create minimal .config to have network working, and
the changes improve the performance like you may see
below:

    %for i in {1..10000}; do unshare -n bash -c exit; done

    *before*
    real 1m40,377s
    user 0m9,672s
    sys 0m19,928s

    *after*
    real 0m17,007s
    user 0m5,311s
    sys 0m11,779

    (5.8 times faster)

In the future, when all pernet_operations become async,
we'll just remove this "async" field tree-wide.

All the new logic is concentrated in patches [1-5/32].
The rest of patches converts specific operations:
review, rationale of they can be converted, and setting
of async flag.

Kirill

v3: Improved patches descriptions. Added comment into [5/32].
Added [32/32] converting netlink_tap_net_ops (new pernet operations
introduced in 2018).

v2: Single patch -> patchset with rationale of every conversion
====================

Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents cf19e5e2 b86b47a3
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -230,4 +230,5 @@ static __net_init int loopback_net_init(struct net *net)
/* Registered in net/core/dev.c */
struct pernet_operations __net_initdata loopback_net_ops = {
	.init = loopback_net_init,
	.async = true,
};
+1 −0
Original line number Diff line number Diff line
@@ -237,6 +237,7 @@ static __net_exit void proc_net_ns_exit(struct net *net)
static struct pernet_operations __net_initdata proc_net_ns_ops = {
	.init = proc_net_ns_init,
	.exit = proc_net_ns_exit,
	.async = true,
};

int __init proc_net_init(void)
+1 −0
Original line number Diff line number Diff line
@@ -36,6 +36,7 @@ extern int rtnl_is_locked(void);

extern wait_queue_head_t netdev_unregistering_wq;
extern struct mutex net_mutex;
extern struct rw_semaphore net_sem;

#ifdef CONFIG_PROVE_LOCKING
extern bool lockdep_rtnl_is_held(void);
+6 −0
Original line number Diff line number Diff line
@@ -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;
};

/*
+1 −0
Original line number Diff line number Diff line
@@ -1526,6 +1526,7 @@ static struct pernet_operations audit_net_ops __net_initdata = {
	.exit = audit_net_exit,
	.id = &audit_net_id,
	.size = sizeof(struct audit_net),
	.async = true,
};

/* Initialize audit support at boot time. */
Loading