aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/posix-cpu-timers.c
diff options
context:
space:
mode:
authorIngo Molnar <mingo@kernel.org>2013-12-04 04:09:53 -0500
committerIngo Molnar <mingo@kernel.org>2013-12-04 04:09:53 -0500
commita934a56e1284f1863c9c800ff9c63183c25aec93 (patch)
tree643ffbf749b8b9d68e1b8641c6d179f535b9f9c0 /kernel/posix-cpu-timers.c
parentdea4f48a0a301b23c65af8e4fe8ccf360c272fbf (diff)
parentc925077c33fc9a546e7cf6c3be2adf4a2afe2608 (diff)
Merge branch 'timers/core-v2' of git://git.kernel.org/pub/scm/linux/kernel/git/frederic/linux-dynticks into timers/core
Pull dynticks updates from Frederic Weisbecker: * Fix a bug where posix cpu timers requeued due to interval got ignored on full dynticks CPUs (not a regression though as it only impacts full dynticks and the bug is there since we merged full dynticks). * Optimizations and cleanups on the use of per CPU APIs to improve code readability, performance and debuggability in the nohz subsystem; * Optimize posix cpu timer by sparing stub workqueue queue with full dynticks off case * Rename some functions to extend with *_this_cpu() suffix for clarity * Refine the naming of some context tracking subsystem state accessors * Trivial spelling fix by Paul Gortmaker Signed-off-by: Ingo Molnar <mingo@kernel.org>
Diffstat (limited to 'kernel/posix-cpu-timers.c')
-rw-r--r--kernel/posix-cpu-timers.c21
1 files changed, 9 insertions, 12 deletions
diff --git a/kernel/posix-cpu-timers.c b/kernel/posix-cpu-timers.c
index c7f31aa272f7..79747b7d9420 100644
--- a/kernel/posix-cpu-timers.c
+++ b/kernel/posix-cpu-timers.c
@@ -608,7 +608,8 @@ static DECLARE_WORK(nohz_kick_work, nohz_kick_work_fn);
608 */ 608 */
609static void posix_cpu_timer_kick_nohz(void) 609static void posix_cpu_timer_kick_nohz(void)
610{ 610{
611 schedule_work(&nohz_kick_work); 611 if (context_tracking_is_enabled())
612 schedule_work(&nohz_kick_work);
612} 613}
613 614
614bool posix_cpu_timers_can_stop_tick(struct task_struct *tsk) 615bool posix_cpu_timers_can_stop_tick(struct task_struct *tsk)
@@ -1090,7 +1091,8 @@ void posix_cpu_timer_schedule(struct k_itimer *timer)
1090 put_task_struct(p); 1091 put_task_struct(p);
1091 timer->it.cpu.task = p = NULL; 1092 timer->it.cpu.task = p = NULL;
1092 timer->it.cpu.expires = 0; 1093 timer->it.cpu.expires = 0;
1093 goto out_unlock; 1094 read_unlock(&tasklist_lock);
1095 goto out;
1094 } else if (unlikely(p->exit_state) && thread_group_empty(p)) { 1096 } else if (unlikely(p->exit_state) && thread_group_empty(p)) {
1095 /* 1097 /*
1096 * We've noticed that the thread is dead, but 1098 * We've noticed that the thread is dead, but
@@ -1099,7 +1101,8 @@ void posix_cpu_timer_schedule(struct k_itimer *timer)
1099 */ 1101 */
1100 cpu_timer_sample_group(timer->it_clock, p, &now); 1102 cpu_timer_sample_group(timer->it_clock, p, &now);
1101 clear_dead_task(timer, now); 1103 clear_dead_task(timer, now);
1102 goto out_unlock; 1104 read_unlock(&tasklist_lock);
1105 goto out;
1103 } 1106 }
1104 spin_lock(&p->sighand->siglock); 1107 spin_lock(&p->sighand->siglock);
1105 cpu_timer_sample_group(timer->it_clock, p, &now); 1108 cpu_timer_sample_group(timer->it_clock, p, &now);
@@ -1113,10 +1116,11 @@ void posix_cpu_timer_schedule(struct k_itimer *timer)
1113 BUG_ON(!irqs_disabled()); 1116 BUG_ON(!irqs_disabled());
1114 arm_timer(timer); 1117 arm_timer(timer);
1115 spin_unlock(&p->sighand->siglock); 1118 spin_unlock(&p->sighand->siglock);
1116
1117out_unlock:
1118 read_unlock(&tasklist_lock); 1119 read_unlock(&tasklist_lock);
1119 1120
1121 /* Kick full dynticks CPUs in case they need to tick on the new timer */
1122 posix_cpu_timer_kick_nohz();
1123
1120out: 1124out:
1121 timer->it_overrun_last = timer->it_overrun; 1125 timer->it_overrun_last = timer->it_overrun;
1122 timer->it_overrun = -1; 1126 timer->it_overrun = -1;
@@ -1256,13 +1260,6 @@ void run_posix_cpu_timers(struct task_struct *tsk)
1256 cpu_timer_fire(timer); 1260 cpu_timer_fire(timer);
1257 spin_unlock(&timer->it_lock); 1261 spin_unlock(&timer->it_lock);
1258 } 1262 }
1259
1260 /*
1261 * In case some timers were rescheduled after the queue got emptied,
1262 * wake up full dynticks CPUs.
1263 */
1264 if (tsk->signal->cputimer.running)
1265 posix_cpu_timer_kick_nohz();
1266} 1263}
1267 1264
1268/* 1265/*