fix the racy usage of ->signal in account_group_xxx/run_posix_cpu_timers
PATCH 1/3 fix the racy usage of ->signal in account_group_xxx/run_posix_cpu_timers
Another stupid patch for 2.6.28 until we find the good fix.
Contrary to ad474caca3e2a0550b7ce0706527ad5ab389a4d4 changelog, other acct_group_xxx() helpers can be called after exit_notify() by timer tick. Thanks to Roland for pointing out this. Somehow I missed this simple fact when I read the original patch, and I am afraid I confused Frank during the discussion. Sorry.
Fortunately, these helpers work with current, we can check ->exit_state to ensure that ->signal can't go away under us.
Also, add the comment and compiler barrier to account_group_exec_runtime(), to make sure we load ->signal only once.
kernel/sched_stats.h renamed from kernel/sched_stats.h~ACCT_CK_EXIT_CODE +11 -4
@@ -298,9 +298,11 @@ static inline void account_group_user_ti {struct signal_struct *sig; - sig = tsk->signal; -if (unlikely (!sig)) +/* tsk == current, ensure it is safe to use ->signal */ +if (unlikely (tsk->exit_state))return ; + + sig = tsk->signal;if (sig->cputime.totals) {struct task_cputime *times;
@@ -325,9 +327,11 @@ static inline void account_group_system_ {struct signal_struct *sig; - sig = tsk->signal; -if (unlikely (!sig)) +/* tsk == current, ensure it is safe to use ->signal */ +if (unlikely (tsk->exit_state))return ; + + sig = tsk->signal;if (sig->cputime.totals) {struct task_cputime *times;
@@ -353,8 +357,11 @@ static inline void account_group_exec_rustruct signal_struct *sig; sig = tsk->signal; +/* see __exit_signal()->task_rq_unlock_wait() */ +barrier ();if (unlikely (!sig))return ; +if (sig->cputime.totals) {struct task_cputime *times;
kernel/posix-cpu-timers.c renamed from kernel/posix-cpu-timers.c~ACCT_CK_EXIT_CODE +6 -2
@@ -1308,9 +1308,10 @@ static inline int task_cputime_expired(c*/ static inline int fastpath_timer_check (struct task_struct *tsk) { -struct signal_struct *sig = tsk->signal; +struct signal_struct *sig; -if (unlikely (!sig)) +/* tsk == current, ensure it is safe to use ->signal/sighand */ +if (unlikely (tsk->exit_state))return 0 ;if (!task_cputime_zero (&tsk->cputime_expires)) {
@@ -1323,6 +1324,8 @@ static inline int fastpath_timer_check(sif (task_cputime_expired (&task_sample, &tsk->cputime_expires))return 1 ; } + + sig = tsk->signal;if (!task_cputime_zero (&sig->cputime_expires)) {struct task_cputime group_sample;
@@ -1330,6 +1333,7 @@ static inline int fastpath_timer_check(sif (task_cputime_expired (&group_sample, &sig->cputime_expires))return 1 ; } +return 0 ; }
Ingo Molnar
AppliedQuoted 8 lines · Oleg Nesterov
Another stupid patch for 2.6.28 until we find the good fix.
Contrary to
ad474caca3e2a0550b7ce0706527ad5ab389a4d4changelog, otheracct_group_xxx()helpers can be called afterexit_notify()by timer tick. Thanks to Roland for pointing out this. Somehow I missed this simple fact when I read the original patch, and I am afraid I confused Frank during the discussion. Sorry.
Quoted 8 lines
Fortunately, these helpers work with current, we can check ->exit_state to ensure that ->signal can't go away under us.
Also, add the comment and compiler barrier to
account_group_exec_runtime(), to make sure we load ->signal only once.Signed-off-by Oleg Nesterov <[email protected]>
applied to tip/sched/urgent, thanks Oleg.
Ingo