[Devel] [PATCH RHEL COMMIT] kernel/freezer: don't freeze stopped & about to be ptraced task

Konstantin Khorenko khorenko at virtuozzo.com
Fri Sep 24 15:04:58 MSK 2021


The commit is pushed to "branch-rh9-5.14.vz9.1.x-ovz" and will appear at https://src.openvz.org/scm/ovz/vzkernel.git
after ark-5.14
------>
commit b3033cb01148843ec6949973f07718f20dd9734f
Author: Andrey Ryabinin <ryabinin.a.a at gmail.com>
Date:   Fri Sep 24 15:04:58 2021 +0300

    kernel/freezer: don't freeze stopped & about to be ptraced task
    
    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 <aryabinin at virtuozzo.com>
    
    Acked-by: Andrew Vagin <avagin at virtuozzo.com>
    
    (cherry picked from vz8 commit b91869099308cf0551819443d81b0f910382da2c)
    Signed-off-by: Andrey Zhadchenko <andrey.zhadchenko at virtuozzo.com>
---
 kernel/freezer.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/kernel/freezer.c b/kernel/freezer.c
index 45ab36ffd0e7..1ed34ea7e90d 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;
 


More information about the Devel mailing list