Patch "l2tp: Avoid schedule while atomic in exit_net" has been added to the 4.4-stable tree
Subsystems (2)
This is a note to let you know that I've just added the patch titled
l2tp: Avoid schedule while atomic in exit_net
to the 4.4-stable tree which can be found at:
http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary
The filename of the patch is:
l2tp-avoid-schedule-while-atomic-in-exit_net.patch
and it can be found in the queue-4.4 subdirectory.
If you, or anyone else, feels it should not be added to the stable tree, please let <[email protected]> know about it.
Quoted 1 line
From foo@baz Thu Oct 19 14:05:19 CEST 2017
From: Ridge Kennedy <[email protected]>
Date: Wed, 22 Feb 2017 14:59:49 +1300
Subject: l2tp: Avoid schedule while atomic in exit_net
From: Ridge Kennedy <[email protected]>
[ Upstream commit 12d656af4e3d2781b9b9f52538593e1717e7c979 ]
While destroying a network namespace that contains a L2TP tunnel a "BUG: scheduling while atomic" can be observed.
Enabling lockdep shows that this is happening because l2tp_exit_net() is calling l2tp_tunnel_closeall() (via l2tp_tunnel_delete()) from within an RCU critical section.
l2tp_exit_net() takes rcu_read_lock_bh()
<< list_for_each_entry_rcu() >>
l2tp_tunnel_delete()
l2tp_tunnel_closeall()
__l2tp_session_unhash()
synchronize_rcu() << Illegal inside RCU critical section >>
BUG: sleeping function called from invalid context in_atomic(): 1, irqs_disabled(): 0, pid: 86, name: kworker/u16:2 INFO: lockdep is turned off. CPU: 2 PID: 86 Comm: kworker/u16:2 Tainted: G W O 4.4.6-at1 #2 Hardware name: Xen HVM domU, BIOS 4.6.1-xs125300 05/09/2016 Workqueue: netns cleanup_net 0000000000000000 ffff880202417b90 ffffffff812b0013 ffff880202410ac0 ffffffff81870de8 ffff880202417bb8 ffffffff8107aee8 ffffffff81870de8 0000000000000c51 0000000000000000 ffff880202417be0 ffffffff8107b024 Call Trace: [<ffffffff812b0013>] dump_stack+0x85/0xc2 [<ffffffff8107aee8>] ___might_sleep+0x148/0x240 [<ffffffff8107b024>] __might_sleep+0x44/0x80 [<ffffffff810b21bd>] synchronize_sched+0x2d/0xe0 [<ffffffff8109be6d>] ? trace_hardirqs_on+0xd/0x10 [<ffffffff8105c7bb>] ? __local_bh_enable_ip+0x6b/0xc0 [<ffffffff816a1b00>] ? _raw_spin_unlock_bh+0x30/0x40 [<ffffffff81667482>] __l2tp_session_unhash+0x172/0x220 [<ffffffff81667397>] ? __l2tp_session_unhash+0x87/0x220 [<ffffffff8166888b>] l2tp_tunnel_closeall+0x9b/0x140 [<ffffffff81668c74>] l2tp_tunnel_delete+0x14/0x60 [<ffffffff81668dd0>] l2tp_exit_net+0x110/0x270 [<ffffffff81668d5c>] ? l2tp_exit_net+0x9c/0x270 [<ffffffff815001c3>] ops_exit_list.isra.6+0x33/0x60 [<ffffffff81501166>] cleanup_net+0x1b6/0x280 ...
This bug can easily be reproduced with a few steps:
$ sudo unshare -n bash # Create a shell in a new namespace
# ip link set lo up
# ip addr add 127.0.0.1 dev lo
# ip l2tp add tunnel remote 127.0.0.1 local 127.0.0.1 tunnel_id 1 \
peer_tunnel_id 1 udp_sport 50000 udp_dport 50000
# ip l2tp add session name foo tunnel_id 1 session_id 1 \
peer_session_id 1
# ip link set foo up
# exit # Exit the shell, in turn exiting the namespace
$ dmesg
...
[942121.089216] BUG: scheduling while atomic: kworker/u16:3/13872/0x00000200
...To fix this, move the call to l2tp_tunnel_closeall() out of the RCU critical section, and instead call it from l2tp_tunnel_del_work(), which is running from the l2tp_wq workqueue.
--- net/l2tp/l2tp_core.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
net/l2tp/l2tp_core.c +3 -1
@@ -1321,6 +1321,9 @@ static void l2tp_tunnel_del_work(structstruct sock *sk =NULL ; tunnel = container_of(work, struct l2tp_tunnel, del_work); + +l2tp_tunnel_closeall (tunnel); + sk =l2tp_tunnel_sock_lookup (tunnel);if (!sk) goto out;
@@ -1643,7 +1646,6 @@ EXPORT_SYMBOL_GPL(l2tp_tunnel_create);int l2tp_tunnel_delete (struct l2tp_tunnel *tunnel) {l2tp_tunnel_inc_refcount (tunnel); -l2tp_tunnel_closeall (tunnel);if (false ==queue_work (l2tp_wq, &tunnel->del_work)) {l2tp_tunnel_dec_refcount (tunnel);return 1 ;
Patches currently in stable-queue which might be from [email protected] are
queue-4.4/l2tp-avoid-schedule-while-atomic-in-exit_net.patch