提交 c2239788 编写于 作者: C Chanho Min 提交者: Rafael J. Wysocki

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: NOleg Nesterov <oleg@redhat.com>
Signed-off-by: NChanho Min <chanho.min@lge.com>
Acked-by: NOleg Nesterov <oleg@redhat.com>
Acked-by: NPavel Machek <pavel@ucw.cz>
Acked-by: NMichal Hocko <mhocko@suse.com>
Signed-off-by: NRafael J. Wysocki <rafael.j.wysocki@intel.com>
上级 9ff01193
...@@ -62,6 +62,7 @@ ...@@ -62,6 +62,7 @@
#include <linux/oom.h> #include <linux/oom.h>
#include <linux/compat.h> #include <linux/compat.h>
#include <linux/vmalloc.h> #include <linux/vmalloc.h>
#include <linux/freezer.h>
#include <linux/uaccess.h> #include <linux/uaccess.h>
#include <asm/mmu_context.h> #include <asm/mmu_context.h>
...@@ -1083,7 +1084,7 @@ static int de_thread(struct task_struct *tsk) ...@@ -1083,7 +1084,7 @@ static int de_thread(struct task_struct *tsk)
while (sig->notify_count) { while (sig->notify_count) {
__set_current_state(TASK_KILLABLE); __set_current_state(TASK_KILLABLE);
spin_unlock_irq(lock); spin_unlock_irq(lock);
schedule(); freezable_schedule();
if (unlikely(__fatal_signal_pending(tsk))) if (unlikely(__fatal_signal_pending(tsk)))
goto killed; goto killed;
spin_lock_irq(lock); spin_lock_irq(lock);
...@@ -1111,7 +1112,7 @@ static int de_thread(struct task_struct *tsk) ...@@ -1111,7 +1112,7 @@ static int de_thread(struct task_struct *tsk)
__set_current_state(TASK_KILLABLE); __set_current_state(TASK_KILLABLE);
write_unlock_irq(&tasklist_lock); write_unlock_irq(&tasklist_lock);
cgroup_threadgroup_change_end(tsk); cgroup_threadgroup_change_end(tsk);
schedule(); freezable_schedule();
if (unlikely(__fatal_signal_pending(tsk))) if (unlikely(__fatal_signal_pending(tsk)))
goto killed; goto killed;
} }
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册