mirror of
https://github.com/Fishwaldo/Star64_linux.git
synced 2025-06-28 17:41:50 +00:00
cgroup: prevent spurious transition into non-frozen state
If freezing of a cgroup races with waking of a task from the frozen state (like waiting in vfork() or in do_signal_stop()), a spurious transition of the cgroup state can happen. The task enters cgroup_leave_frozen(true), the cgroup->nr_frozen_tasks counter decrements, and the cgroup is switched to the unfrozen state. To prevent it, let's reserve cgroup_leave_frozen(true) for terminating processes and use cgroup_leave_frozen(false) otherwise. To avoid busy-looping in the signal handling loop waiting for JOBCTL_TRAP_FREEZE set from the cgroup freezing path, let's do it explicitly in cgroup_leave_frozen(), if the task is going to stay frozen. Suggested-by: Oleg Nesterov <oleg@redhat.com> Signed-off-by: Roman Gushchin <guro@fb.com> Signed-off-by: Tejun Heo <tj@kernel.org>
This commit is contained in:
parent
533307dc20
commit
cb2c4cd878
2 changed files with 6 additions and 12 deletions
|
@ -139,19 +139,13 @@ void cgroup_leave_frozen(bool always_leave)
|
||||||
cgroup_update_frozen(cgrp);
|
cgroup_update_frozen(cgrp);
|
||||||
WARN_ON_ONCE(!current->frozen);
|
WARN_ON_ONCE(!current->frozen);
|
||||||
current->frozen = false;
|
current->frozen = false;
|
||||||
|
} else if (!(current->jobctl & JOBCTL_TRAP_FREEZE)) {
|
||||||
|
spin_lock(¤t->sighand->siglock);
|
||||||
|
current->jobctl |= JOBCTL_TRAP_FREEZE;
|
||||||
|
set_thread_flag(TIF_SIGPENDING);
|
||||||
|
spin_unlock(¤t->sighand->siglock);
|
||||||
}
|
}
|
||||||
spin_unlock_irq(&css_set_lock);
|
spin_unlock_irq(&css_set_lock);
|
||||||
|
|
||||||
if (unlikely(current->frozen)) {
|
|
||||||
/*
|
|
||||||
* If the task remained in the frozen state,
|
|
||||||
* make sure it won't reach userspace without
|
|
||||||
* entering the signal handling loop.
|
|
||||||
*/
|
|
||||||
spin_lock_irq(¤t->sighand->siglock);
|
|
||||||
recalc_sigpending();
|
|
||||||
spin_unlock_irq(¤t->sighand->siglock);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -2514,7 +2514,7 @@ relock:
|
||||||
*/
|
*/
|
||||||
if (unlikely(cgroup_task_frozen(current))) {
|
if (unlikely(cgroup_task_frozen(current))) {
|
||||||
spin_unlock_irq(&sighand->siglock);
|
spin_unlock_irq(&sighand->siglock);
|
||||||
cgroup_leave_frozen(true);
|
cgroup_leave_frozen(false);
|
||||||
goto relock;
|
goto relock;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue