Commit 3fccfd67df79c6351a156eb25a7a514e5f39c4d9
Committed by
Ingo Molnar
1 parent
ff08f76d73
Exists in
master
and in
4 other branches
timers: split process wide cpu clocks/timers, fix
To decrease the chance of a missed enable, always enable the timer when we sample it, we'll always disable it when we find that there are no active timers in the jiffy tick. This fixes a flood of warnings reported by Mike Galbraith. Reported-by: Mike Galbraith <efault@gmx.de> Signed-off-by: Peter Zijlstra <a.p.zijlstra@chello.nl> Signed-off-by: Ingo Molnar <mingo@elte.hu>
Showing 2 changed files with 15 additions and 28 deletions Side-by-side Diff
include/linux/sched.h
kernel/posix-cpu-timers.c
... | ... | @@ -488,7 +488,7 @@ |
488 | 488 | { |
489 | 489 | struct task_cputime cputime; |
490 | 490 | |
491 | - thread_group_cputime(tsk, &cputime); | |
491 | + thread_group_cputimer(tsk, &cputime); | |
492 | 492 | cleanup_timers(tsk->signal->cpu_timers, |
493 | 493 | cputime.utime, cputime.stime, cputime.sum_exec_runtime); |
494 | 494 | } |
... | ... | @@ -507,29 +507,6 @@ |
507 | 507 | } |
508 | 508 | |
509 | 509 | /* |
510 | - * Enable the process wide cpu timer accounting. | |
511 | - * | |
512 | - * serialized using ->sighand->siglock | |
513 | - */ | |
514 | -static void start_process_timers(struct task_struct *tsk) | |
515 | -{ | |
516 | - tsk->signal->cputimer.running = 1; | |
517 | - barrier(); | |
518 | -} | |
519 | - | |
520 | -/* | |
521 | - * Release the process wide timer accounting -- timer stops ticking when | |
522 | - * nobody cares about it. | |
523 | - * | |
524 | - * serialized using ->sighand->siglock | |
525 | - */ | |
526 | -static void stop_process_timers(struct task_struct *tsk) | |
527 | -{ | |
528 | - tsk->signal->cputimer.running = 0; | |
529 | - barrier(); | |
530 | -} | |
531 | - | |
532 | -/* | |
533 | 510 | * Insert the timer on the appropriate list before any timers that |
534 | 511 | * expire later. This must be called with the tasklist_lock held |
535 | 512 | * for reading, and interrupts disabled. |
... | ... | @@ -549,9 +526,6 @@ |
549 | 526 | BUG_ON(!irqs_disabled()); |
550 | 527 | spin_lock(&p->sighand->siglock); |
551 | 528 | |
552 | - if (!CPUCLOCK_PERTHREAD(timer->it_clock)) | |
553 | - start_process_timers(p); | |
554 | - | |
555 | 529 | listpos = head; |
556 | 530 | if (CPUCLOCK_WHICH(timer->it_clock) == CPUCLOCK_SCHED) { |
557 | 531 | list_for_each_entry(next, head, entry) { |
... | ... | @@ -1021,6 +995,19 @@ |
1021 | 995 | } |
1022 | 996 | } |
1023 | 997 | |
998 | +static void stop_process_timers(struct task_struct *tsk) | |
999 | +{ | |
1000 | + struct thread_group_cputimer *cputimer = &tsk->signal->cputimer; | |
1001 | + unsigned long flags; | |
1002 | + | |
1003 | + if (!cputimer->running) | |
1004 | + return; | |
1005 | + | |
1006 | + spin_lock_irqsave(&cputimer->lock, flags); | |
1007 | + cputimer->running = 0; | |
1008 | + spin_unlock_irqrestore(&cputimer->lock, flags); | |
1009 | +} | |
1010 | + | |
1024 | 1011 | /* |
1025 | 1012 | * Check for any per-thread CPU timers that have fired and move them |
1026 | 1013 | * off the tsk->*_timers list onto the firing list. Per-thread timers |
... | ... | @@ -1427,7 +1414,6 @@ |
1427 | 1414 | struct list_head *head; |
1428 | 1415 | |
1429 | 1416 | BUG_ON(clock_idx == CPUCLOCK_SCHED); |
1430 | - start_process_timers(tsk); | |
1431 | 1417 | cpu_timer_sample_group(clock_idx, tsk, &now); |
1432 | 1418 | |
1433 | 1419 | if (oldval) { |