diff options
author | Ingo Molnar <mingo@kernel.org> | 2013-12-04 04:09:53 -0500 |
---|---|---|
committer | Ingo Molnar <mingo@kernel.org> | 2013-12-04 04:09:53 -0500 |
commit | a934a56e1284f1863c9c800ff9c63183c25aec93 (patch) | |
tree | 643ffbf749b8b9d68e1b8641c6d179f535b9f9c0 /kernel/posix-cpu-timers.c | |
parent | dea4f48a0a301b23c65af8e4fe8ccf360c272fbf (diff) | |
parent | c925077c33fc9a546e7cf6c3be2adf4a2afe2608 (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.c | 21 |
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 | */ |
609 | static void posix_cpu_timer_kick_nohz(void) | 609 | static 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 | ||
614 | bool posix_cpu_timers_can_stop_tick(struct task_struct *tsk) | 615 | bool 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 | |||
1117 | out_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 | |||
1120 | out: | 1124 | out: |
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 | /* |