Skip to content

Commit 0bdd2ed

Browse files
oleg-nesterovIngo Molnar
authored andcommitted
sched: run_posix_cpu_timers: Don't check ->exit_state, use lock_task_sighand()
run_posix_cpu_timers() doesn't work if current has already passed exit_notify(). This was needed to prevent the races with do_wait(). Since ea6d290 ->signal is always valid and can't go away. We can remove the "tsk->exit_state == 0" in fastpath_timer_check() and convert run_posix_cpu_timers() to use lock_task_sighand(). Note: it makes sense to take group_leader's sighand instead, the sub-thread still uses CPU after release_task(). But we need more changes to do this. Signed-off-by: Oleg Nesterov <[email protected]> Signed-off-by: Peter Zijlstra <[email protected]> LKML-Reference: <[email protected]> Signed-off-by: Ingo Molnar <[email protected]>
1 parent bfac700 commit 0bdd2ed

File tree

1 file changed

+4
-6
lines changed

1 file changed

+4
-6
lines changed

kernel/posix-cpu-timers.c

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1272,10 +1272,6 @@ static inline int fastpath_timer_check(struct task_struct *tsk)
12721272
{
12731273
struct signal_struct *sig;
12741274

1275-
/* tsk == current, ensure it is safe to use ->signal/sighand */
1276-
if (unlikely(tsk->exit_state))
1277-
return 0;
1278-
12791275
if (!task_cputime_zero(&tsk->cputime_expires)) {
12801276
struct task_cputime task_sample = {
12811277
.utime = tsk->utime,
@@ -1308,6 +1304,7 @@ void run_posix_cpu_timers(struct task_struct *tsk)
13081304
{
13091305
LIST_HEAD(firing);
13101306
struct k_itimer *timer, *next;
1307+
unsigned long flags;
13111308

13121309
BUG_ON(!irqs_disabled());
13131310

@@ -1318,7 +1315,8 @@ void run_posix_cpu_timers(struct task_struct *tsk)
13181315
if (!fastpath_timer_check(tsk))
13191316
return;
13201317

1321-
spin_lock(&tsk->sighand->siglock);
1318+
if (!lock_task_sighand(tsk, &flags))
1319+
return;
13221320
/*
13231321
* Here we take off tsk->signal->cpu_timers[N] and
13241322
* tsk->cpu_timers[N] all the timers that are firing, and
@@ -1340,7 +1338,7 @@ void run_posix_cpu_timers(struct task_struct *tsk)
13401338
* that gets the timer lock before we do will give it up and
13411339
* spin until we've taken care of that timer below.
13421340
*/
1343-
spin_unlock(&tsk->sighand->siglock);
1341+
unlock_task_sighand(tsk, &flags);
13441342

13451343
/*
13461344
* Now that all the timers on our list have the firing flag,

0 commit comments

Comments
 (0)