diff options
author | Thomas Gleixner <tglx@linutronix.de> | 2014-02-03 17:34:31 -0500 |
---|---|---|
committer | Thomas Gleixner <tglx@linutronix.de> | 2014-02-07 09:34:28 -0500 |
commit | 627ee7947e2e83ba565c31c5c9373d6e364b1ecd (patch) | |
tree | 30fc40a08542f0411e28ba9becc00e07f7ec3b44 /kernel/time/tick-broadcast.c | |
parent | e8b175946c16d7001b22620f52d78ab497efc9d0 (diff) |
clockevents: Serialize calls to clockevents_update_freq() in the core
We can identify the broadcast device in the core and serialize all
callers including interrupts on a different CPU against the update.
Also, disabling interrupts is moved into the core allowing callers to
leave interrutps enabled when calling clockevents_update_freq().
Signed-off-by: Soren Brinkmann <soren.brinkmann@xilinx.com>
Cc: linux-arm-kernel@lists.infradead.org
Cc: Soeren Brinkmann <soren.brinkmann@xilinx.com>
Cc: Daniel Lezcano <daniel.lezcano@linaro.org>
Cc: Michal Simek <michal.simek@xilinx.com>
Link: http://lkml.kernel.org/r/1391466877-28908-2-git-send-email-soren.brinkmann@xilinx.com
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Diffstat (limited to 'kernel/time/tick-broadcast.c')
-rw-r--r-- | kernel/time/tick-broadcast.c | 25 |
1 files changed, 19 insertions, 6 deletions
diff --git a/kernel/time/tick-broadcast.c b/kernel/time/tick-broadcast.c index 43780ab5e279..003e6c3663b1 100644 --- a/kernel/time/tick-broadcast.c +++ b/kernel/time/tick-broadcast.c | |||
@@ -120,6 +120,19 @@ int tick_is_broadcast_device(struct clock_event_device *dev) | |||
120 | return (dev && tick_broadcast_device.evtdev == dev); | 120 | return (dev && tick_broadcast_device.evtdev == dev); |
121 | } | 121 | } |
122 | 122 | ||
123 | int tick_broadcast_update_freq(struct clock_event_device *dev, u32 freq) | ||
124 | { | ||
125 | int ret = -ENODEV; | ||
126 | |||
127 | if (tick_is_broadcast_device(dev)) { | ||
128 | raw_spin_lock(&tick_broadcast_lock); | ||
129 | ret = __clockevents_update_freq(dev, freq); | ||
130 | raw_spin_unlock(&tick_broadcast_lock); | ||
131 | } | ||
132 | return ret; | ||
133 | } | ||
134 | |||
135 | |||
123 | static void err_broadcast(const struct cpumask *mask) | 136 | static void err_broadcast(const struct cpumask *mask) |
124 | { | 137 | { |
125 | pr_crit_once("Failed to broadcast timer tick. Some CPUs may be unresponsive.\n"); | 138 | pr_crit_once("Failed to broadcast timer tick. Some CPUs may be unresponsive.\n"); |
@@ -272,12 +285,8 @@ static void tick_do_broadcast(struct cpumask *mask) | |||
272 | */ | 285 | */ |
273 | static void tick_do_periodic_broadcast(void) | 286 | static void tick_do_periodic_broadcast(void) |
274 | { | 287 | { |
275 | raw_spin_lock(&tick_broadcast_lock); | ||
276 | |||
277 | cpumask_and(tmpmask, cpu_online_mask, tick_broadcast_mask); | 288 | cpumask_and(tmpmask, cpu_online_mask, tick_broadcast_mask); |
278 | tick_do_broadcast(tmpmask); | 289 | tick_do_broadcast(tmpmask); |
279 | |||
280 | raw_spin_unlock(&tick_broadcast_lock); | ||
281 | } | 290 | } |
282 | 291 | ||
283 | /* | 292 | /* |
@@ -287,13 +296,15 @@ static void tick_handle_periodic_broadcast(struct clock_event_device *dev) | |||
287 | { | 296 | { |
288 | ktime_t next; | 297 | ktime_t next; |
289 | 298 | ||
299 | raw_spin_lock(&tick_broadcast_lock); | ||
300 | |||
290 | tick_do_periodic_broadcast(); | 301 | tick_do_periodic_broadcast(); |
291 | 302 | ||
292 | /* | 303 | /* |
293 | * The device is in periodic mode. No reprogramming necessary: | 304 | * The device is in periodic mode. No reprogramming necessary: |
294 | */ | 305 | */ |
295 | if (dev->mode == CLOCK_EVT_MODE_PERIODIC) | 306 | if (dev->mode == CLOCK_EVT_MODE_PERIODIC) |
296 | return; | 307 | goto unlock; |
297 | 308 | ||
298 | /* | 309 | /* |
299 | * Setup the next period for devices, which do not have | 310 | * Setup the next period for devices, which do not have |
@@ -306,9 +317,11 @@ static void tick_handle_periodic_broadcast(struct clock_event_device *dev) | |||
306 | next = ktime_add(next, tick_period); | 317 | next = ktime_add(next, tick_period); |
307 | 318 | ||
308 | if (!clockevents_program_event(dev, next, false)) | 319 | if (!clockevents_program_event(dev, next, false)) |
309 | return; | 320 | goto unlock; |
310 | tick_do_periodic_broadcast(); | 321 | tick_do_periodic_broadcast(); |
311 | } | 322 | } |
323 | unlock: | ||
324 | raw_spin_unlock(&tick_broadcast_lock); | ||
312 | } | 325 | } |
313 | 326 | ||
314 | /* | 327 | /* |