mirror of https://gitee.com/openkylin/linux.git
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 <oleg@redhat.com> Signed-off-by: Chanho Min <chanho.min@lge.com> Acked-by: Oleg Nesterov <oleg@redhat.com> Acked-by: Pavel Machek <pavel@ucw.cz> Acked-by: Michal Hocko <mhocko@suse.com> Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
This commit is contained in:
parent
9ff01193a2
commit
c22397888f
|
@ -62,6 +62,7 @@
|
|||
#include <linux/oom.h>
|
||||
#include <linux/compat.h>
|
||||
#include <linux/vmalloc.h>
|
||||
#include <linux/freezer.h>
|
||||
|
||||
#include <linux/uaccess.h>
|
||||
#include <asm/mmu_context.h>
|
||||
|
@ -1083,7 +1084,7 @@ static int de_thread(struct task_struct *tsk)
|
|||
while (sig->notify_count) {
|
||||
__set_current_state(TASK_KILLABLE);
|
||||
spin_unlock_irq(lock);
|
||||
schedule();
|
||||
freezable_schedule();
|
||||
if (unlikely(__fatal_signal_pending(tsk)))
|
||||
goto killed;
|
||||
spin_lock_irq(lock);
|
||||
|
@ -1111,7 +1112,7 @@ static int de_thread(struct task_struct *tsk)
|
|||
__set_current_state(TASK_KILLABLE);
|
||||
write_unlock_irq(&tasklist_lock);
|
||||
cgroup_threadgroup_change_end(tsk);
|
||||
schedule();
|
||||
freezable_schedule();
|
||||
if (unlikely(__fatal_signal_pending(tsk)))
|
||||
goto killed;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue