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

Andrew Vagin avagin at virtuozzo.com
Tue Nov 24 01:47:42 PST 2015


Acked-by: Andrew Vagin <avagin at virtuozzo.com>

On Fri, Nov 20, 2015 at 07:17:22PM +0300, Andrey Ryabinin wrote:
> 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>
> ---
>  kernel/freezer.c | 3 +++
>  1 file changed, 3 insertions(+)
> 
> diff --git a/kernel/freezer.c b/kernel/freezer.c
> index f6da038..3445d5d 100644
> --- a/kernel/freezer.c
> +++ b/kernel/freezer.c
> @@ -39,6 +39,9 @@ bool freezing_slow_path(struct task_struct *p)
>  	if (test_thread_flag(TIF_MEMDIE))
>  		return false;
>  
> +	if (p->jobctl & JOBCTL_TRAPPING_BIT)
> +		return false;
> +
>  	if (pm_nosig_freezing || cgroup_freezing(p))
>  		return true;
>  
> -- 
> 2.4.10
> 


More information about the Devel mailing list