net_sem protects from pernet_list changing, while ops_free_list() makes simple kfree(), and it can't race with other pernet_operations callbacks.
So we may release net_mutex earlier then it was. Signed-off-by: Kirill Tkhai <ktk...@virtuozzo.com> Acked-by: Andrei Vagin <ava...@virtuozzo.com> --- net/core/net_namespace.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/net/core/net_namespace.c b/net/core/net_namespace.c index e89b2b7abd36..f8453c438798 100644 --- a/net/core/net_namespace.c +++ b/net/core/net_namespace.c @@ -522,11 +522,12 @@ 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); + /* Free the net generic variables */ list_for_each_entry_reverse(ops, &pernet_list, list) ops_free_list(ops, &net_exit_list); - mutex_unlock(&net_mutex); up_read(&net_sem); /* Ensure there are no outstanding rcu callbacks using this