diff options
author | Eric Dumazet <edumazet@google.com> | 2019-06-18 11:08:59 -0700 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2019-06-19 11:37:47 -0400 |
commit | d7d99872c144a2c2f5d9c9d83627fa833836cba5 (patch) | |
tree | f3a83dacc74fbe6c81665fb4c46ac2572173fcc8 /include | |
parent | 2a54003e7af1eaddc05848dac14f7bcd77301478 (diff) | |
download | linux-stable-d7d99872c144a2c2f5d9c9d83627fa833836cba5.tar.gz linux-stable-d7d99872c144a2c2f5d9c9d83627fa833836cba5.tar.bz2 linux-stable-d7d99872c144a2c2f5d9c9d83627fa833836cba5.zip |
netns: add pre_exit method to struct pernet_operations
Current struct pernet_operations exit() handlers are highly
discouraged to call synchronize_rcu().
There are cases where we need them, and exit_batch() does
not help the common case where a single netns is dismantled.
This patch leverages the existing synchronize_rcu() call
in cleanup_net()
Calling optional ->pre_exit() method before ->exit() or
->exit_batch() allows to benefit from a single synchronize_rcu()
call.
Note that the synchronize_rcu() calls added in this patch
are only in error paths or slow paths.
Tested:
$ time for i in {1..1000}; do unshare -n /bin/false;done
real 0m2.612s
user 0m0.171s
sys 0m2.216s
Signed-off-by: Eric Dumazet <edumazet@google.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'include')
-rw-r--r-- | include/net/net_namespace.h | 5 |
1 files changed, 5 insertions, 0 deletions
diff --git a/include/net/net_namespace.h b/include/net/net_namespace.h index abb4f92456e1..ad9243afac67 100644 --- a/include/net/net_namespace.h +++ b/include/net/net_namespace.h @@ -355,8 +355,13 @@ struct pernet_operations { * synchronize_rcu() related to these pernet_operations, * instead of separate synchronize_rcu() for every net. * Please, avoid synchronize_rcu() at all, where it's possible. + * + * Note that a combination of pre_exit() and exit() can + * be used, since a synchronize_rcu() is guaranteed between + * the calls. */ int (*init)(struct net *net); + void (*pre_exit)(struct net *net); void (*exit)(struct net *net); void (*exit_batch)(struct list_head *net_exit_list); unsigned int *id; |