Skip to content

Commit c223978

Browse files
Chanho Minrafaeljw
authored andcommitted
exec: make de_thread() freezable
Suspend fails due to the exec family of functions blocking the freezer. The casue is that de_thread() sleeps in TASK_UNINTERRUPTIBLE waiting for all sub-threads to die, and we have the deadlock if one of them is frozen. This also can occur with the schedule() waiting for the group thread leader to exit if it is frozen. In our machine, it causes freeze timeout as bellows. Freezing of tasks failed after 20.010 seconds (1 tasks refusing to freeze, wq_busy=0): setcpushares-ls D ffffffc00008ed70 0 5817 1483 0x0040000d Call trace: [<ffffffc00008ed70>] __switch_to+0x88/0xa0 [<ffffffc000d1c30c>] __schedule+0x1bc/0x720 [<ffffffc000d1ca90>] schedule+0x40/0xa8 [<ffffffc0001cd784>] flush_old_exec+0xdc/0x640 [<ffffffc000220360>] load_elf_binary+0x2a8/0x1090 [<ffffffc0001ccff4>] search_binary_handler+0x9c/0x240 [<ffffffc00021c584>] load_script+0x20c/0x228 [<ffffffc0001ccff4>] search_binary_handler+0x9c/0x240 [<ffffffc0001ce8e0>] do_execveat_common.isra.14+0x4f8/0x6e8 [<ffffffc0001cedd0>] compat_SyS_execve+0x38/0x48 [<ffffffc00008de30>] el0_svc_naked+0x24/0x28 To fix this, make de_thread() freezable. It looks safe and works fine. Suggested-by: Oleg Nesterov <[email protected]> Signed-off-by: Chanho Min <[email protected]> Acked-by: Oleg Nesterov <[email protected]> Acked-by: Pavel Machek <[email protected]> Acked-by: Michal Hocko <[email protected]> Signed-off-by: Rafael J. Wysocki <[email protected]>
1 parent 9ff0119 commit c223978

File tree

1 file changed

+3
-2
lines changed

1 file changed

+3
-2
lines changed

fs/exec.c

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,7 @@
6262
#include <linux/oom.h>
6363
#include <linux/compat.h>
6464
#include <linux/vmalloc.h>
65+
#include <linux/freezer.h>
6566

6667
#include <linux/uaccess.h>
6768
#include <asm/mmu_context.h>
@@ -1083,7 +1084,7 @@ static int de_thread(struct task_struct *tsk)
10831084
while (sig->notify_count) {
10841085
__set_current_state(TASK_KILLABLE);
10851086
spin_unlock_irq(lock);
1086-
schedule();
1087+
freezable_schedule();
10871088
if (unlikely(__fatal_signal_pending(tsk)))
10881089
goto killed;
10891090
spin_lock_irq(lock);
@@ -1111,7 +1112,7 @@ static int de_thread(struct task_struct *tsk)
11111112
__set_current_state(TASK_KILLABLE);
11121113
write_unlock_irq(&tasklist_lock);
11131114
cgroup_threadgroup_change_end(tsk);
1114-
schedule();
1115+
freezable_schedule();
11151116
if (unlikely(__fatal_signal_pending(tsk)))
11161117
goto killed;
11171118
}

0 commit comments

Comments
 (0)