From: Andrey Ryabinin <aryabi...@virtuozzo.com>

So, the ptrace() hangs if we try to attach to stopped task
from freezing cgroup:

Tracee:                                               Tracer:
static bool do_signal_stop(int signr)
    __set_current_state(TASK_STOPPED);
        freezable_schedule();
             freezer_do_not_count();
             schedule(); /* waiting for wake up */

                                                      ptrace_attach()
                                                          if 
(task_is_stopped(task) &&
                                                                 
task_set_jobctl_pending(task,
                                                                     
JOBCTL_TRAP_STOP | JOBCTL_TRAPPING))
                                                              
signal_wake_up_state(task, __TASK_STOPPED);
             /* woken up by ptrace_attach() */
             freezer_count();
                __refrigerator()
                                                          /* And here we will 
hang, because tracee
                                                           *  is now frozen in 
__refrigerator() */
                                                           
wait_on_bit(&task->jobctl, JOBCTL_TRAPPING_BIT,
                                                                       
TASK_UNINTERRUPTIBLE);

The right fix for this would be to rework cgroup freezer,
but for now, we could workaround this by forbiding to freeze task
if JOBCTL_TRAPPING_BIT is set.
ptrace_attach() is the only place which sets that bit iff
task_is_stopped(), thus TRAPPING_BIT is clear indication that ptrace_attach
waits for clearing that bit => we shouldn't freeze.

https://jira.sw.ru/browse/PSBM-40683

Signed-off-by: Andrey Ryabinin <aryabi...@virtuozzo.com>
Acked-by: Andrew Vagin <ava...@virtuozzo.com>

(cherry picked from vz8 commit b91869099308cf0551819443d81b0f910382da2c)
Signed-off-by: Andrey Zhadchenko <andrey.zhadche...@virtuozzo.com>
---
 kernel/freezer.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/kernel/freezer.c b/kernel/freezer.c
index 45ab36f..1ed34ea 100644
--- a/kernel/freezer.c
+++ b/kernel/freezer.c
@@ -42,6 +42,9 @@ bool freezing_slow_path(struct task_struct *p)
        if (test_tsk_thread_flag(p, TIF_MEMDIE))
                return false;
 
+       if (p->jobctl & JOBCTL_TRAPPING)
+               return false;
+
        if (pm_nosig_freezing || cgroup_freezing(p))
                return true;
 
-- 
1.8.3.1

_______________________________________________
Devel mailing list
Devel@openvz.org
https://lists.openvz.org/mailman/listinfo/devel

Reply via email to