diff options
Diffstat (limited to 'kernel/time')
-rw-r--r-- | kernel/time/Kconfig | 5 | ||||
-rw-r--r-- | kernel/time/Makefile | 2 | ||||
-rw-r--r-- | kernel/time/clockevents.c | 3 | ||||
-rw-r--r-- | kernel/time/clocksource.c | 22 | ||||
-rw-r--r-- | kernel/time/tick-broadcast.c | 51 | ||||
-rw-r--r-- | kernel/time/tick-common.c | 5 | ||||
-rw-r--r-- | kernel/time/tick-sched.c | 2 | ||||
-rw-r--r-- | kernel/time/timekeeping.c | 12 |
8 files changed, 43 insertions, 59 deletions
diff --git a/kernel/time/Kconfig b/kernel/time/Kconfig index f66351126544..8d53106a0a92 100644 --- a/kernel/time/Kconfig +++ b/kernel/time/Kconfig | |||
@@ -23,3 +23,8 @@ config HIGH_RES_TIMERS | |||
23 | hardware is not capable then this option only increases | 23 | hardware is not capable then this option only increases |
24 | the size of the kernel image. | 24 | the size of the kernel image. |
25 | 25 | ||
26 | config GENERIC_CLOCKEVENTS_BUILD | ||
27 | bool | ||
28 | default y | ||
29 | depends on GENERIC_CLOCKEVENTS || GENERIC_CLOCKEVENTS_MIGR | ||
30 | |||
diff --git a/kernel/time/Makefile b/kernel/time/Makefile index 99b6034fc86b..905b0b50792d 100644 --- a/kernel/time/Makefile +++ b/kernel/time/Makefile | |||
@@ -1,6 +1,6 @@ | |||
1 | obj-y += timekeeping.o ntp.o clocksource.o jiffies.o timer_list.o | 1 | obj-y += timekeeping.o ntp.o clocksource.o jiffies.o timer_list.o |
2 | 2 | ||
3 | obj-$(CONFIG_GENERIC_CLOCKEVENTS) += clockevents.o | 3 | obj-$(CONFIG_GENERIC_CLOCKEVENTS_BUILD) += clockevents.o |
4 | obj-$(CONFIG_GENERIC_CLOCKEVENTS) += tick-common.o | 4 | obj-$(CONFIG_GENERIC_CLOCKEVENTS) += tick-common.o |
5 | obj-$(CONFIG_GENERIC_CLOCKEVENTS_BROADCAST) += tick-broadcast.o | 5 | obj-$(CONFIG_GENERIC_CLOCKEVENTS_BROADCAST) += tick-broadcast.o |
6 | obj-$(CONFIG_TICK_ONESHOT) += tick-oneshot.o | 6 | obj-$(CONFIG_TICK_ONESHOT) += tick-oneshot.o |
diff --git a/kernel/time/clockevents.c b/kernel/time/clockevents.c index 41dd3105ce7f..822beebe664a 100644 --- a/kernel/time/clockevents.c +++ b/kernel/time/clockevents.c | |||
@@ -194,6 +194,7 @@ void clockevents_exchange_device(struct clock_event_device *old, | |||
194 | local_irq_restore(flags); | 194 | local_irq_restore(flags); |
195 | } | 195 | } |
196 | 196 | ||
197 | #ifdef CONFIG_GENERIC_CLOCKEVENTS | ||
197 | /** | 198 | /** |
198 | * clockevents_notify - notification about relevant events | 199 | * clockevents_notify - notification about relevant events |
199 | */ | 200 | */ |
@@ -222,4 +223,4 @@ void clockevents_notify(unsigned long reason, void *arg) | |||
222 | spin_unlock(&clockevents_lock); | 223 | spin_unlock(&clockevents_lock); |
223 | } | 224 | } |
224 | EXPORT_SYMBOL_GPL(clockevents_notify); | 225 | EXPORT_SYMBOL_GPL(clockevents_notify); |
225 | 226 | #endif | |
diff --git a/kernel/time/clocksource.c b/kernel/time/clocksource.c index 51b6a6a6158c..c8a9d13874df 100644 --- a/kernel/time/clocksource.c +++ b/kernel/time/clocksource.c | |||
@@ -207,15 +207,12 @@ static inline void clocksource_resume_watchdog(void) { } | |||
207 | */ | 207 | */ |
208 | void clocksource_resume(void) | 208 | void clocksource_resume(void) |
209 | { | 209 | { |
210 | struct list_head *tmp; | 210 | struct clocksource *cs; |
211 | unsigned long flags; | 211 | unsigned long flags; |
212 | 212 | ||
213 | spin_lock_irqsave(&clocksource_lock, flags); | 213 | spin_lock_irqsave(&clocksource_lock, flags); |
214 | 214 | ||
215 | list_for_each(tmp, &clocksource_list) { | 215 | list_for_each_entry(cs, &clocksource_list, list) { |
216 | struct clocksource *cs; | ||
217 | |||
218 | cs = list_entry(tmp, struct clocksource, list); | ||
219 | if (cs->resume) | 216 | if (cs->resume) |
220 | cs->resume(); | 217 | cs->resume(); |
221 | } | 218 | } |
@@ -369,7 +366,6 @@ static ssize_t sysfs_override_clocksource(struct sys_device *dev, | |||
369 | const char *buf, size_t count) | 366 | const char *buf, size_t count) |
370 | { | 367 | { |
371 | struct clocksource *ovr = NULL; | 368 | struct clocksource *ovr = NULL; |
372 | struct list_head *tmp; | ||
373 | size_t ret = count; | 369 | size_t ret = count; |
374 | int len; | 370 | int len; |
375 | 371 | ||
@@ -389,12 +385,11 @@ static ssize_t sysfs_override_clocksource(struct sys_device *dev, | |||
389 | 385 | ||
390 | len = strlen(override_name); | 386 | len = strlen(override_name); |
391 | if (len) { | 387 | if (len) { |
388 | struct clocksource *cs; | ||
389 | |||
392 | ovr = clocksource_override; | 390 | ovr = clocksource_override; |
393 | /* try to select it: */ | 391 | /* try to select it: */ |
394 | list_for_each(tmp, &clocksource_list) { | 392 | list_for_each_entry(cs, &clocksource_list, list) { |
395 | struct clocksource *cs; | ||
396 | |||
397 | cs = list_entry(tmp, struct clocksource, list); | ||
398 | if (strlen(cs->name) == len && | 393 | if (strlen(cs->name) == len && |
399 | !strcmp(cs->name, override_name)) | 394 | !strcmp(cs->name, override_name)) |
400 | ovr = cs; | 395 | ovr = cs; |
@@ -422,14 +417,11 @@ static ssize_t sysfs_override_clocksource(struct sys_device *dev, | |||
422 | static ssize_t | 417 | static ssize_t |
423 | sysfs_show_available_clocksources(struct sys_device *dev, char *buf) | 418 | sysfs_show_available_clocksources(struct sys_device *dev, char *buf) |
424 | { | 419 | { |
425 | struct list_head *tmp; | 420 | struct clocksource *src; |
426 | char *curr = buf; | 421 | char *curr = buf; |
427 | 422 | ||
428 | spin_lock_irq(&clocksource_lock); | 423 | spin_lock_irq(&clocksource_lock); |
429 | list_for_each(tmp, &clocksource_list) { | 424 | list_for_each_entry(src, &clocksource_list, list) { |
430 | struct clocksource *src; | ||
431 | |||
432 | src = list_entry(tmp, struct clocksource, list); | ||
433 | curr += sprintf(curr, "%s ", src->name); | 425 | curr += sprintf(curr, "%s ", src->name); |
434 | } | 426 | } |
435 | spin_unlock_irq(&clocksource_lock); | 427 | spin_unlock_irq(&clocksource_lock); |
diff --git a/kernel/time/tick-broadcast.c b/kernel/time/tick-broadcast.c index 0962e0577660..8cfb8b2ce773 100644 --- a/kernel/time/tick-broadcast.c +++ b/kernel/time/tick-broadcast.c | |||
@@ -64,8 +64,9 @@ static void tick_broadcast_start_periodic(struct clock_event_device *bc) | |||
64 | */ | 64 | */ |
65 | int tick_check_broadcast_device(struct clock_event_device *dev) | 65 | int tick_check_broadcast_device(struct clock_event_device *dev) |
66 | { | 66 | { |
67 | if (tick_broadcast_device.evtdev || | 67 | if ((tick_broadcast_device.evtdev && |
68 | (dev->features & CLOCK_EVT_FEAT_C3STOP)) | 68 | tick_broadcast_device.evtdev->rating >= dev->rating) || |
69 | (dev->features & CLOCK_EVT_FEAT_C3STOP)) | ||
69 | return 0; | 70 | return 0; |
70 | 71 | ||
71 | clockevents_exchange_device(NULL, dev); | 72 | clockevents_exchange_device(NULL, dev); |
@@ -176,8 +177,6 @@ static void tick_do_periodic_broadcast(void) | |||
176 | */ | 177 | */ |
177 | static void tick_handle_periodic_broadcast(struct clock_event_device *dev) | 178 | static void tick_handle_periodic_broadcast(struct clock_event_device *dev) |
178 | { | 179 | { |
179 | dev->next_event.tv64 = KTIME_MAX; | ||
180 | |||
181 | tick_do_periodic_broadcast(); | 180 | tick_do_periodic_broadcast(); |
182 | 181 | ||
183 | /* | 182 | /* |
@@ -218,26 +217,33 @@ static void tick_do_broadcast_on_off(void *why) | |||
218 | bc = tick_broadcast_device.evtdev; | 217 | bc = tick_broadcast_device.evtdev; |
219 | 218 | ||
220 | /* | 219 | /* |
221 | * Is the device in broadcast mode forever or is it not | 220 | * Is the device not affected by the powerstate ? |
222 | * affected by the powerstate ? | ||
223 | */ | 221 | */ |
224 | if (!dev || !tick_device_is_functional(dev) || | 222 | if (!dev || !(dev->features & CLOCK_EVT_FEAT_C3STOP)) |
225 | !(dev->features & CLOCK_EVT_FEAT_C3STOP)) | 223 | goto out; |
224 | |||
225 | if (!tick_device_is_functional(dev)) | ||
226 | goto out; | 226 | goto out; |
227 | 227 | ||
228 | if (*reason == CLOCK_EVT_NOTIFY_BROADCAST_ON) { | 228 | switch (*reason) { |
229 | case CLOCK_EVT_NOTIFY_BROADCAST_ON: | ||
230 | case CLOCK_EVT_NOTIFY_BROADCAST_FORCE: | ||
229 | if (!cpu_isset(cpu, tick_broadcast_mask)) { | 231 | if (!cpu_isset(cpu, tick_broadcast_mask)) { |
230 | cpu_set(cpu, tick_broadcast_mask); | 232 | cpu_set(cpu, tick_broadcast_mask); |
231 | if (td->mode == TICKDEV_MODE_PERIODIC) | 233 | if (td->mode == TICKDEV_MODE_PERIODIC) |
232 | clockevents_set_mode(dev, | 234 | clockevents_set_mode(dev, |
233 | CLOCK_EVT_MODE_SHUTDOWN); | 235 | CLOCK_EVT_MODE_SHUTDOWN); |
234 | } | 236 | } |
235 | } else { | 237 | if (*reason == CLOCK_EVT_NOTIFY_BROADCAST_FORCE) |
238 | dev->features |= CLOCK_EVT_FEAT_DUMMY; | ||
239 | break; | ||
240 | case CLOCK_EVT_NOTIFY_BROADCAST_OFF: | ||
236 | if (cpu_isset(cpu, tick_broadcast_mask)) { | 241 | if (cpu_isset(cpu, tick_broadcast_mask)) { |
237 | cpu_clear(cpu, tick_broadcast_mask); | 242 | cpu_clear(cpu, tick_broadcast_mask); |
238 | if (td->mode == TICKDEV_MODE_PERIODIC) | 243 | if (td->mode == TICKDEV_MODE_PERIODIC) |
239 | tick_setup_periodic(dev, 0); | 244 | tick_setup_periodic(dev, 0); |
240 | } | 245 | } |
246 | break; | ||
241 | } | 247 | } |
242 | 248 | ||
243 | if (cpus_empty(tick_broadcast_mask)) | 249 | if (cpus_empty(tick_broadcast_mask)) |
@@ -258,21 +264,12 @@ out: | |||
258 | */ | 264 | */ |
259 | void tick_broadcast_on_off(unsigned long reason, int *oncpu) | 265 | void tick_broadcast_on_off(unsigned long reason, int *oncpu) |
260 | { | 266 | { |
261 | int cpu = get_cpu(); | 267 | if (!cpu_isset(*oncpu, cpu_online_map)) |
262 | |||
263 | if (!cpu_isset(*oncpu, cpu_online_map)) { | ||
264 | printk(KERN_ERR "tick-braodcast: ignoring broadcast for " | 268 | printk(KERN_ERR "tick-braodcast: ignoring broadcast for " |
265 | "offline CPU #%d\n", *oncpu); | 269 | "offline CPU #%d\n", *oncpu); |
266 | } else { | 270 | else |
267 | 271 | smp_call_function_single(*oncpu, tick_do_broadcast_on_off, | |
268 | if (cpu == *oncpu) | 272 | &reason, 1, 1); |
269 | tick_do_broadcast_on_off(&reason); | ||
270 | else | ||
271 | smp_call_function_single(*oncpu, | ||
272 | tick_do_broadcast_on_off, | ||
273 | &reason, 1, 1); | ||
274 | } | ||
275 | put_cpu(); | ||
276 | } | 273 | } |
277 | 274 | ||
278 | /* | 275 | /* |
@@ -515,11 +512,9 @@ static void tick_broadcast_clear_oneshot(int cpu) | |||
515 | */ | 512 | */ |
516 | void tick_broadcast_setup_oneshot(struct clock_event_device *bc) | 513 | void tick_broadcast_setup_oneshot(struct clock_event_device *bc) |
517 | { | 514 | { |
518 | if (bc->mode != CLOCK_EVT_MODE_ONESHOT) { | 515 | bc->event_handler = tick_handle_oneshot_broadcast; |
519 | bc->event_handler = tick_handle_oneshot_broadcast; | 516 | clockevents_set_mode(bc, CLOCK_EVT_MODE_ONESHOT); |
520 | clockevents_set_mode(bc, CLOCK_EVT_MODE_ONESHOT); | 517 | bc->next_event.tv64 = KTIME_MAX; |
521 | bc->next_event.tv64 = KTIME_MAX; | ||
522 | } | ||
523 | } | 518 | } |
524 | 519 | ||
525 | /* | 520 | /* |
diff --git a/kernel/time/tick-common.c b/kernel/time/tick-common.c index 77a21abc8716..1bea399a9ef0 100644 --- a/kernel/time/tick-common.c +++ b/kernel/time/tick-common.c | |||
@@ -200,7 +200,7 @@ static int tick_check_new_device(struct clock_event_device *newdev) | |||
200 | 200 | ||
201 | cpu = smp_processor_id(); | 201 | cpu = smp_processor_id(); |
202 | if (!cpu_isset(cpu, newdev->cpumask)) | 202 | if (!cpu_isset(cpu, newdev->cpumask)) |
203 | goto out; | 203 | goto out_bc; |
204 | 204 | ||
205 | td = &per_cpu(tick_cpu_device, cpu); | 205 | td = &per_cpu(tick_cpu_device, cpu); |
206 | curdev = td->evtdev; | 206 | curdev = td->evtdev; |
@@ -265,7 +265,7 @@ out_bc: | |||
265 | */ | 265 | */ |
266 | if (tick_check_broadcast_device(newdev)) | 266 | if (tick_check_broadcast_device(newdev)) |
267 | ret = NOTIFY_STOP; | 267 | ret = NOTIFY_STOP; |
268 | out: | 268 | |
269 | spin_unlock_irqrestore(&tick_device_lock, flags); | 269 | spin_unlock_irqrestore(&tick_device_lock, flags); |
270 | 270 | ||
271 | return ret; | 271 | return ret; |
@@ -345,6 +345,7 @@ static int tick_notify(struct notifier_block *nb, unsigned long reason, | |||
345 | 345 | ||
346 | case CLOCK_EVT_NOTIFY_BROADCAST_ON: | 346 | case CLOCK_EVT_NOTIFY_BROADCAST_ON: |
347 | case CLOCK_EVT_NOTIFY_BROADCAST_OFF: | 347 | case CLOCK_EVT_NOTIFY_BROADCAST_OFF: |
348 | case CLOCK_EVT_NOTIFY_BROADCAST_FORCE: | ||
348 | tick_broadcast_on_off(reason, dev); | 349 | tick_broadcast_on_off(reason, dev); |
349 | break; | 350 | break; |
350 | 351 | ||
diff --git a/kernel/time/tick-sched.c b/kernel/time/tick-sched.c index 637519af6151..10a1347597fd 100644 --- a/kernel/time/tick-sched.c +++ b/kernel/time/tick-sched.c | |||
@@ -586,7 +586,7 @@ void tick_setup_sched_timer(void) | |||
586 | /* Get the next period (per cpu) */ | 586 | /* Get the next period (per cpu) */ |
587 | ts->sched_timer.expires = tick_init_jiffy_update(); | 587 | ts->sched_timer.expires = tick_init_jiffy_update(); |
588 | offset = ktime_to_ns(tick_period) >> 1; | 588 | offset = ktime_to_ns(tick_period) >> 1; |
589 | do_div(offset, NR_CPUS); | 589 | do_div(offset, num_possible_cpus()); |
590 | offset *= smp_processor_id(); | 590 | offset *= smp_processor_id(); |
591 | ts->sched_timer.expires = ktime_add_ns(ts->sched_timer.expires, offset); | 591 | ts->sched_timer.expires = ktime_add_ns(ts->sched_timer.expires, offset); |
592 | 592 | ||
diff --git a/kernel/time/timekeeping.c b/kernel/time/timekeeping.c index 4ad79f6bdec6..e5e466b27598 100644 --- a/kernel/time/timekeeping.c +++ b/kernel/time/timekeeping.c | |||
@@ -24,9 +24,7 @@ | |||
24 | * This read-write spinlock protects us from races in SMP while | 24 | * This read-write spinlock protects us from races in SMP while |
25 | * playing with xtime and avenrun. | 25 | * playing with xtime and avenrun. |
26 | */ | 26 | */ |
27 | __attribute__((weak)) __cacheline_aligned_in_smp DEFINE_SEQLOCK(xtime_lock); | 27 | __cacheline_aligned_in_smp DEFINE_SEQLOCK(xtime_lock); |
28 | |||
29 | EXPORT_SYMBOL(xtime_lock); | ||
30 | 28 | ||
31 | 29 | ||
32 | /* | 30 | /* |
@@ -47,21 +45,13 @@ EXPORT_SYMBOL(xtime_lock); | |||
47 | struct timespec xtime __attribute__ ((aligned (16))); | 45 | struct timespec xtime __attribute__ ((aligned (16))); |
48 | struct timespec wall_to_monotonic __attribute__ ((aligned (16))); | 46 | struct timespec wall_to_monotonic __attribute__ ((aligned (16))); |
49 | static unsigned long total_sleep_time; /* seconds */ | 47 | static unsigned long total_sleep_time; /* seconds */ |
50 | EXPORT_SYMBOL(xtime); | ||
51 | |||
52 | 48 | ||
53 | #ifdef CONFIG_NO_HZ | ||
54 | static struct timespec xtime_cache __attribute__ ((aligned (16))); | 49 | static struct timespec xtime_cache __attribute__ ((aligned (16))); |
55 | static inline void update_xtime_cache(u64 nsec) | 50 | static inline void update_xtime_cache(u64 nsec) |
56 | { | 51 | { |
57 | xtime_cache = xtime; | 52 | xtime_cache = xtime; |
58 | timespec_add_ns(&xtime_cache, nsec); | 53 | timespec_add_ns(&xtime_cache, nsec); |
59 | } | 54 | } |
60 | #else | ||
61 | #define xtime_cache xtime | ||
62 | /* We do *not* want to evaluate the argument for this case */ | ||
63 | #define update_xtime_cache(n) do { } while (0) | ||
64 | #endif | ||
65 | 55 | ||
66 | static struct clocksource *clock; /* pointer to current clocksource */ | 56 | static struct clocksource *clock; /* pointer to current clocksource */ |
67 | 57 | ||