diff options
| author | Linus Torvalds <torvalds@linux-foundation.org> | 2014-04-01 14:00:07 -0400 |
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2014-04-01 14:00:07 -0400 |
| commit | 1ead65812486cda65093683a99b8907a7242fa93 (patch) | |
| tree | 094684870815537aae4aedb69c10d669ba29f0af /kernel | |
| parent | b6d739e9581272f0bbbd6edd15340fb8e108df96 (diff) | |
| parent | b97f0291a2504291aef850077f98cab68a5a2f33 (diff) | |
Merge branch 'timers-core-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip
Pull timer changes from Thomas Gleixner:
"This assorted collection provides:
- A new timer based timer broadcast feature for systems which do not
provide a global accessible timer device. That allows those
systems to put CPUs into deep idle states where the per cpu timer
device stops.
- A few NOHZ_FULL related improvements to the timer wheel
- The usual updates to timer devices found in ARM SoCs
- Small improvements and updates all over the place"
* 'timers-core-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: (44 commits)
tick: Remove code duplication in tick_handle_periodic()
tick: Fix spelling mistake in tick_handle_periodic()
x86: hpet: Use proper destructor for delayed work
workqueue: Provide destroy_delayed_work_on_stack()
clocksource: CMT, MTU2, TMU and STI should depend on GENERIC_CLOCKEVENTS
timer: Remove code redundancy while calling get_nohz_timer_target()
hrtimer: Rearrange comments in the order struct members are declared
timer: Use variable head instead of &work_list in __run_timers()
clocksource: exynos_mct: silence a static checker warning
arm: zynq: Add support for cpufreq
arm: zynq: Don't use arm_global_timer with cpufreq
clocksource/cadence_ttc: Overhaul clocksource frequency adjustment
clocksource/cadence_ttc: Call clockevents_update_freq() with IRQs enabled
clocksource: Add Kconfig entries for CMT, MTU2, TMU and STI
sh: Remove Kconfig entries for TMU, CMT and MTU2
ARM: shmobile: Remove CMT, TMU and STI Kconfig entries
clocksource: armada-370-xp: Use atomic access for shared registers
clocksource: orion: Use atomic access for shared registers
clocksource: timer-keystone: Delete unnecessary variable
clocksource: timer-keystone: introduce clocksource driver for Keystone
...
Diffstat (limited to 'kernel')
| -rw-r--r-- | kernel/hrtimer.c | 15 | ||||
| -rw-r--r-- | kernel/sched/core.c | 5 | ||||
| -rw-r--r-- | kernel/time/Kconfig | 2 | ||||
| -rw-r--r-- | kernel/time/Makefile | 5 | ||||
| -rw-r--r-- | kernel/time/clockevents.c | 40 | ||||
| -rw-r--r-- | kernel/time/ntp.c | 5 | ||||
| -rw-r--r-- | kernel/time/tick-broadcast-hrtimer.c | 106 | ||||
| -rw-r--r-- | kernel/time/tick-broadcast.c | 85 | ||||
| -rw-r--r-- | kernel/time/tick-common.c | 16 | ||||
| -rw-r--r-- | kernel/time/tick-internal.h | 11 | ||||
| -rw-r--r-- | kernel/time/timekeeping_debug.c | 2 | ||||
| -rw-r--r-- | kernel/timer.c | 57 | ||||
| -rw-r--r-- | kernel/workqueue.c | 7 |
13 files changed, 290 insertions, 66 deletions
diff --git a/kernel/hrtimer.c b/kernel/hrtimer.c index 09094361dce5..d55092ceee29 100644 --- a/kernel/hrtimer.c +++ b/kernel/hrtimer.c | |||
| @@ -168,19 +168,6 @@ struct hrtimer_clock_base *lock_hrtimer_base(const struct hrtimer *timer, | |||
| 168 | } | 168 | } |
| 169 | } | 169 | } |
| 170 | 170 | ||
| 171 | |||
| 172 | /* | ||
| 173 | * Get the preferred target CPU for NOHZ | ||
| 174 | */ | ||
| 175 | static int hrtimer_get_target(int this_cpu, int pinned) | ||
| 176 | { | ||
| 177 | #ifdef CONFIG_NO_HZ_COMMON | ||
| 178 | if (!pinned && get_sysctl_timer_migration() && idle_cpu(this_cpu)) | ||
| 179 | return get_nohz_timer_target(); | ||
| 180 | #endif | ||
| 181 | return this_cpu; | ||
| 182 | } | ||
| 183 | |||
| 184 | /* | 171 | /* |
| 185 | * With HIGHRES=y we do not migrate the timer when it is expiring | 172 | * With HIGHRES=y we do not migrate the timer when it is expiring |
| 186 | * before the next event on the target cpu because we cannot reprogram | 173 | * before the next event on the target cpu because we cannot reprogram |
| @@ -214,7 +201,7 @@ switch_hrtimer_base(struct hrtimer *timer, struct hrtimer_clock_base *base, | |||
| 214 | struct hrtimer_clock_base *new_base; | 201 | struct hrtimer_clock_base *new_base; |
| 215 | struct hrtimer_cpu_base *new_cpu_base; | 202 | struct hrtimer_cpu_base *new_cpu_base; |
| 216 | int this_cpu = smp_processor_id(); | 203 | int this_cpu = smp_processor_id(); |
| 217 | int cpu = hrtimer_get_target(this_cpu, pinned); | 204 | int cpu = get_nohz_timer_target(pinned); |
| 218 | int basenum = base->index; | 205 | int basenum = base->index; |
| 219 | 206 | ||
| 220 | again: | 207 | again: |
diff --git a/kernel/sched/core.c b/kernel/sched/core.c index d11a1768357d..3c4d096544ce 100644 --- a/kernel/sched/core.c +++ b/kernel/sched/core.c | |||
| @@ -555,12 +555,15 @@ void resched_cpu(int cpu) | |||
| 555 | * selecting an idle cpu will add more delays to the timers than intended | 555 | * selecting an idle cpu will add more delays to the timers than intended |
| 556 | * (as that cpu's timer base may not be uptodate wrt jiffies etc). | 556 | * (as that cpu's timer base may not be uptodate wrt jiffies etc). |
| 557 | */ | 557 | */ |
| 558 | int get_nohz_timer_target(void) | 558 | int get_nohz_timer_target(int pinned) |
| 559 | { | 559 | { |
| 560 | int cpu = smp_processor_id(); | 560 | int cpu = smp_processor_id(); |
| 561 | int i; | 561 | int i; |
| 562 | struct sched_domain *sd; | 562 | struct sched_domain *sd; |
| 563 | 563 | ||
| 564 | if (pinned || !get_sysctl_timer_migration() || !idle_cpu(cpu)) | ||
| 565 | return cpu; | ||
| 566 | |||
| 564 | rcu_read_lock(); | 567 | rcu_read_lock(); |
| 565 | for_each_domain(cpu, sd) { | 568 | for_each_domain(cpu, sd) { |
| 566 | for_each_cpu(i, sched_domain_span(sd)) { | 569 | for_each_cpu(i, sched_domain_span(sd)) { |
diff --git a/kernel/time/Kconfig b/kernel/time/Kconfig index 3ce6e8c5f3fc..f448513a45ed 100644 --- a/kernel/time/Kconfig +++ b/kernel/time/Kconfig | |||
| @@ -124,7 +124,7 @@ config NO_HZ_FULL | |||
| 124 | endchoice | 124 | endchoice |
| 125 | 125 | ||
| 126 | config NO_HZ_FULL_ALL | 126 | config NO_HZ_FULL_ALL |
| 127 | bool "Full dynticks system on all CPUs by default" | 127 | bool "Full dynticks system on all CPUs by default (except CPU 0)" |
| 128 | depends on NO_HZ_FULL | 128 | depends on NO_HZ_FULL |
| 129 | help | 129 | help |
| 130 | If the user doesn't pass the nohz_full boot option to | 130 | If the user doesn't pass the nohz_full boot option to |
diff --git a/kernel/time/Makefile b/kernel/time/Makefile index 9250130646f5..57a413fd0ebf 100644 --- a/kernel/time/Makefile +++ b/kernel/time/Makefile | |||
| @@ -3,7 +3,10 @@ obj-y += timeconv.o posix-clock.o alarmtimer.o | |||
| 3 | 3 | ||
| 4 | obj-$(CONFIG_GENERIC_CLOCKEVENTS_BUILD) += clockevents.o | 4 | obj-$(CONFIG_GENERIC_CLOCKEVENTS_BUILD) += clockevents.o |
| 5 | obj-$(CONFIG_GENERIC_CLOCKEVENTS) += tick-common.o | 5 | obj-$(CONFIG_GENERIC_CLOCKEVENTS) += tick-common.o |
| 6 | obj-$(CONFIG_GENERIC_CLOCKEVENTS_BROADCAST) += tick-broadcast.o | 6 | ifeq ($(CONFIG_GENERIC_CLOCKEVENTS_BROADCAST),y) |
| 7 | obj-y += tick-broadcast.o | ||
| 8 | obj-$(CONFIG_TICK_ONESHOT) += tick-broadcast-hrtimer.o | ||
| 9 | endif | ||
| 7 | obj-$(CONFIG_GENERIC_SCHED_CLOCK) += sched_clock.o | 10 | obj-$(CONFIG_GENERIC_SCHED_CLOCK) += sched_clock.o |
| 8 | obj-$(CONFIG_TICK_ONESHOT) += tick-oneshot.o | 11 | obj-$(CONFIG_TICK_ONESHOT) += tick-oneshot.o |
| 9 | obj-$(CONFIG_TICK_ONESHOT) += tick-sched.o | 12 | obj-$(CONFIG_TICK_ONESHOT) += tick-sched.o |
diff --git a/kernel/time/clockevents.c b/kernel/time/clockevents.c index 086ad6043bcb..ad362c260ef4 100644 --- a/kernel/time/clockevents.c +++ b/kernel/time/clockevents.c | |||
| @@ -439,6 +439,19 @@ void clockevents_config_and_register(struct clock_event_device *dev, | |||
| 439 | } | 439 | } |
| 440 | EXPORT_SYMBOL_GPL(clockevents_config_and_register); | 440 | EXPORT_SYMBOL_GPL(clockevents_config_and_register); |
| 441 | 441 | ||
| 442 | int __clockevents_update_freq(struct clock_event_device *dev, u32 freq) | ||
| 443 | { | ||
| 444 | clockevents_config(dev, freq); | ||
| 445 | |||
| 446 | if (dev->mode == CLOCK_EVT_MODE_ONESHOT) | ||
| 447 | return clockevents_program_event(dev, dev->next_event, false); | ||
| 448 | |||
| 449 | if (dev->mode == CLOCK_EVT_MODE_PERIODIC) | ||
| 450 | dev->set_mode(CLOCK_EVT_MODE_PERIODIC, dev); | ||
| 451 | |||
| 452 | return 0; | ||
| 453 | } | ||
| 454 | |||
| 442 | /** | 455 | /** |
| 443 | * clockevents_update_freq - Update frequency and reprogram a clock event device. | 456 | * clockevents_update_freq - Update frequency and reprogram a clock event device. |
| 444 | * @dev: device to modify | 457 | * @dev: device to modify |
| @@ -446,17 +459,22 @@ EXPORT_SYMBOL_GPL(clockevents_config_and_register); | |||
| 446 | * | 459 | * |
| 447 | * Reconfigure and reprogram a clock event device in oneshot | 460 | * Reconfigure and reprogram a clock event device in oneshot |
| 448 | * mode. Must be called on the cpu for which the device delivers per | 461 | * mode. Must be called on the cpu for which the device delivers per |
| 449 | * cpu timer events with interrupts disabled! Returns 0 on success, | 462 | * cpu timer events. If called for the broadcast device the core takes |
| 450 | * -ETIME when the event is in the past. | 463 | * care of serialization. |
| 464 | * | ||
| 465 | * Returns 0 on success, -ETIME when the event is in the past. | ||
| 451 | */ | 466 | */ |
| 452 | int clockevents_update_freq(struct clock_event_device *dev, u32 freq) | 467 | int clockevents_update_freq(struct clock_event_device *dev, u32 freq) |
| 453 | { | 468 | { |
| 454 | clockevents_config(dev, freq); | 469 | unsigned long flags; |
| 455 | 470 | int ret; | |
| 456 | if (dev->mode != CLOCK_EVT_MODE_ONESHOT) | ||
| 457 | return 0; | ||
| 458 | 471 | ||
| 459 | return clockevents_program_event(dev, dev->next_event, false); | 472 | local_irq_save(flags); |
| 473 | ret = tick_broadcast_update_freq(dev, freq); | ||
| 474 | if (ret == -ENODEV) | ||
| 475 | ret = __clockevents_update_freq(dev, freq); | ||
| 476 | local_irq_restore(flags); | ||
| 477 | return ret; | ||
| 460 | } | 478 | } |
| 461 | 479 | ||
| 462 | /* | 480 | /* |
| @@ -524,12 +542,13 @@ void clockevents_resume(void) | |||
| 524 | #ifdef CONFIG_GENERIC_CLOCKEVENTS | 542 | #ifdef CONFIG_GENERIC_CLOCKEVENTS |
| 525 | /** | 543 | /** |
| 526 | * clockevents_notify - notification about relevant events | 544 | * clockevents_notify - notification about relevant events |
| 545 | * Returns 0 on success, any other value on error | ||
| 527 | */ | 546 | */ |
| 528 | void clockevents_notify(unsigned long reason, void *arg) | 547 | int clockevents_notify(unsigned long reason, void *arg) |
| 529 | { | 548 | { |
| 530 | struct clock_event_device *dev, *tmp; | 549 | struct clock_event_device *dev, *tmp; |
| 531 | unsigned long flags; | 550 | unsigned long flags; |
| 532 | int cpu; | 551 | int cpu, ret = 0; |
| 533 | 552 | ||
| 534 | raw_spin_lock_irqsave(&clockevents_lock, flags); | 553 | raw_spin_lock_irqsave(&clockevents_lock, flags); |
| 535 | 554 | ||
| @@ -542,7 +561,7 @@ void clockevents_notify(unsigned long reason, void *arg) | |||
| 542 | 561 | ||
| 543 | case CLOCK_EVT_NOTIFY_BROADCAST_ENTER: | 562 | case CLOCK_EVT_NOTIFY_BROADCAST_ENTER: |
| 544 | case CLOCK_EVT_NOTIFY_BROADCAST_EXIT: | 563 | case CLOCK_EVT_NOTIFY_BROADCAST_EXIT: |
| 545 | tick_broadcast_oneshot_control(reason); | 564 | ret = tick_broadcast_oneshot_control(reason); |
| 546 | break; | 565 | break; |
| 547 | 566 | ||
| 548 | case CLOCK_EVT_NOTIFY_CPU_DYING: | 567 | case CLOCK_EVT_NOTIFY_CPU_DYING: |
| @@ -585,6 +604,7 @@ void clockevents_notify(unsigned long reason, void *arg) | |||
| 585 | break; | 604 | break; |
| 586 | } | 605 | } |
| 587 | raw_spin_unlock_irqrestore(&clockevents_lock, flags); | 606 | raw_spin_unlock_irqrestore(&clockevents_lock, flags); |
| 607 | return ret; | ||
| 588 | } | 608 | } |
| 589 | EXPORT_SYMBOL_GPL(clockevents_notify); | 609 | EXPORT_SYMBOL_GPL(clockevents_notify); |
| 590 | 610 | ||
diff --git a/kernel/time/ntp.c b/kernel/time/ntp.c index af8d1d4f3d55..419a52cecd20 100644 --- a/kernel/time/ntp.c +++ b/kernel/time/ntp.c | |||
| @@ -514,12 +514,13 @@ static void sync_cmos_clock(struct work_struct *work) | |||
| 514 | next.tv_sec++; | 514 | next.tv_sec++; |
| 515 | next.tv_nsec -= NSEC_PER_SEC; | 515 | next.tv_nsec -= NSEC_PER_SEC; |
| 516 | } | 516 | } |
| 517 | schedule_delayed_work(&sync_cmos_work, timespec_to_jiffies(&next)); | 517 | queue_delayed_work(system_power_efficient_wq, |
| 518 | &sync_cmos_work, timespec_to_jiffies(&next)); | ||
| 518 | } | 519 | } |
| 519 | 520 | ||
| 520 | void ntp_notify_cmos_timer(void) | 521 | void ntp_notify_cmos_timer(void) |
| 521 | { | 522 | { |
| 522 | schedule_delayed_work(&sync_cmos_work, 0); | 523 | queue_delayed_work(system_power_efficient_wq, &sync_cmos_work, 0); |
| 523 | } | 524 | } |
| 524 | 525 | ||
| 525 | #else | 526 | #else |
diff --git a/kernel/time/tick-broadcast-hrtimer.c b/kernel/time/tick-broadcast-hrtimer.c new file mode 100644 index 000000000000..eb682d5c697c --- /dev/null +++ b/kernel/time/tick-broadcast-hrtimer.c | |||
| @@ -0,0 +1,106 @@ | |||
| 1 | /* | ||
| 2 | * linux/kernel/time/tick-broadcast-hrtimer.c | ||
| 3 | * This file emulates a local clock event device | ||
| 4 | * via a pseudo clock device. | ||
| 5 | */ | ||
| 6 | #include <linux/cpu.h> | ||
| 7 | #include <linux/err.h> | ||
| 8 | #include <linux/hrtimer.h> | ||
| 9 | #include <linux/interrupt.h> | ||
| 10 | #include <linux/percpu.h> | ||
| 11 | #include <linux/profile.h> | ||
| 12 | #include <linux/clockchips.h> | ||
| 13 | #include <linux/sched.h> | ||
| 14 | #include <linux/smp.h> | ||
| 15 | #include <linux/module.h> | ||
| 16 | |||
| 17 | #include "tick-internal.h" | ||
| 18 | |||
| 19 | static struct hrtimer bctimer; | ||
| 20 | |||
| 21 | static void bc_set_mode(enum clock_event_mode mode, | ||
| 22 | struct clock_event_device *bc) | ||
| 23 | { | ||
| 24 | switch (mode) { | ||
| 25 | case CLOCK_EVT_MODE_SHUTDOWN: | ||
| 26 | /* | ||
| 27 | * Note, we cannot cancel the timer here as we might | ||
| 28 | * run into the following live lock scenario: | ||
| 29 | * | ||
| 30 | * cpu 0 cpu1 | ||
| 31 | * lock(broadcast_lock); | ||
| 32 | * hrtimer_interrupt() | ||
| 33 | * bc_handler() | ||
| 34 | * tick_handle_oneshot_broadcast(); | ||
| 35 | * lock(broadcast_lock); | ||
| 36 | * hrtimer_cancel() | ||
| 37 | * wait_for_callback() | ||
| 38 | */ | ||
| 39 | hrtimer_try_to_cancel(&bctimer); | ||
| 40 | break; | ||
| 41 | default: | ||
| 42 | break; | ||
| 43 | } | ||
| 44 | } | ||
| 45 | |||
| 46 | /* | ||
| 47 | * This is called from the guts of the broadcast code when the cpu | ||
| 48 | * which is about to enter idle has the earliest broadcast timer event. | ||
| 49 | */ | ||
| 50 | static int bc_set_next(ktime_t expires, struct clock_event_device *bc) | ||
| 51 | { | ||
| 52 | /* | ||
| 53 | * We try to cancel the timer first. If the callback is on | ||
| 54 | * flight on some other cpu then we let it handle it. If we | ||
| 55 | * were able to cancel the timer nothing can rearm it as we | ||
| 56 | * own broadcast_lock. | ||
| 57 | * | ||
| 58 | * However we can also be called from the event handler of | ||
| 59 | * ce_broadcast_hrtimer itself when it expires. We cannot | ||
| 60 | * restart the timer because we are in the callback, but we | ||
| 61 | * can set the expiry time and let the callback return | ||
| 62 | * HRTIMER_RESTART. | ||
| 63 | */ | ||
| 64 | if (hrtimer_try_to_cancel(&bctimer) >= 0) { | ||
| 65 | hrtimer_start(&bctimer, expires, HRTIMER_MODE_ABS_PINNED); | ||
| 66 | /* Bind the "device" to the cpu */ | ||
| 67 | bc->bound_on = smp_processor_id(); | ||
| 68 | } else if (bc->bound_on == smp_processor_id()) { | ||
| 69 | hrtimer_set_expires(&bctimer, expires); | ||
| 70 | } | ||
| 71 | return 0; | ||
| 72 | } | ||
| 73 | |||
| 74 | static struct clock_event_device ce_broadcast_hrtimer = { | ||
| 75 | .set_mode = bc_set_mode, | ||
| 76 | .set_next_ktime = bc_set_next, | ||
| 77 | .features = CLOCK_EVT_FEAT_ONESHOT | | ||
| 78 | CLOCK_EVT_FEAT_KTIME | | ||
| 79 | CLOCK_EVT_FEAT_HRTIMER, | ||
| 80 | .rating = 0, | ||
| 81 | .bound_on = -1, | ||
| 82 | .min_delta_ns = 1, | ||
| 83 | .max_delta_ns = KTIME_MAX, | ||
| 84 | .min_delta_ticks = 1, | ||
| 85 | .max_delta_ticks = ULONG_MAX, | ||
| 86 | .mult = 1, | ||
| 87 | .shift = 0, | ||
| 88 | .cpumask = cpu_all_mask, | ||
| 89 | }; | ||
| 90 | |||
| 91 | static enum hrtimer_restart bc_handler(struct hrtimer *t) | ||
| 92 | { | ||
| 93 | ce_broadcast_hrtimer.event_handler(&ce_broadcast_hrtimer); | ||
| 94 | |||
| 95 | if (ce_broadcast_hrtimer.next_event.tv64 == KTIME_MAX) | ||
| 96 | return HRTIMER_NORESTART; | ||
| 97 | |||
| 98 | return HRTIMER_RESTART; | ||
| 99 | } | ||
| 100 | |||
| 101 | void tick_setup_hrtimer_broadcast(void) | ||
| 102 | { | ||
| 103 | hrtimer_init(&bctimer, CLOCK_MONOTONIC, HRTIMER_MODE_ABS); | ||
| 104 | bctimer.function = bc_handler; | ||
| 105 | clockevents_register_device(&ce_broadcast_hrtimer); | ||
| 106 | } | ||
diff --git a/kernel/time/tick-broadcast.c b/kernel/time/tick-broadcast.c index 98977a57ac72..64c5990fd500 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 | /* |
| @@ -630,24 +643,61 @@ again: | |||
| 630 | raw_spin_unlock(&tick_broadcast_lock); | 643 | raw_spin_unlock(&tick_broadcast_lock); |
| 631 | } | 644 | } |
| 632 | 645 | ||
| 646 | static int broadcast_needs_cpu(struct clock_event_device *bc, int cpu) | ||
| 647 | { | ||
| 648 | if (!(bc->features & CLOCK_EVT_FEAT_HRTIMER)) | ||
| 649 | return 0; | ||
| 650 | if (bc->next_event.tv64 == KTIME_MAX) | ||
| 651 | return 0; | ||
| 652 | return bc->bound_on == cpu ? -EBUSY : 0; | ||
| 653 | } | ||
| 654 | |||
| 655 | static void broadcast_shutdown_local(struct clock_event_device *bc, | ||
| 656 | struct clock_event_device *dev) | ||
| 657 | { | ||
| 658 | /* | ||
| 659 | * For hrtimer based broadcasting we cannot shutdown the cpu | ||
| 660 | * local device if our own event is the first one to expire or | ||
| 661 | * if we own the broadcast timer. | ||
| 662 | */ | ||
| 663 | if (bc->features & CLOCK_EVT_FEAT_HRTIMER) { | ||
| 664 | if (broadcast_needs_cpu(bc, smp_processor_id())) | ||
| 665 | return; | ||
| 666 | if (dev->next_event.tv64 < bc->next_event.tv64) | ||
| 667 | return; | ||
| 668 | } | ||
| 669 | clockevents_set_mode(dev, CLOCK_EVT_MODE_SHUTDOWN); | ||
| 670 | } | ||
| 671 | |||
| 672 | static void broadcast_move_bc(int deadcpu) | ||
| 673 | { | ||
| 674 | struct clock_event_device *bc = tick_broadcast_device.evtdev; | ||
| 675 | |||
| 676 | if (!bc || !broadcast_needs_cpu(bc, deadcpu)) | ||
| 677 | return; | ||
| 678 | /* This moves the broadcast assignment to this cpu */ | ||
| 679 | clockevents_program_event(bc, bc->next_event, 1); | ||
| 680 | } | ||
| 681 | |||
| 633 | /* | 682 | /* |
| 634 | * Powerstate information: The system enters/leaves a state, where | 683 | * Powerstate information: The system enters/leaves a state, where |
| 635 | * affected devices might stop | 684 | * affected devices might stop |
| 685 | * Returns 0 on success, -EBUSY if the cpu is used to broadcast wakeups. | ||
| 636 | */ | 686 | */ |
| 637 | void tick_broadcast_oneshot_control(unsigned long reason) | 687 | int tick_broadcast_oneshot_control(unsigned long reason) |
| 638 | { | 688 | { |
| 639 | struct clock_event_device *bc, *dev; | 689 | struct clock_event_device *bc, *dev; |
| 640 | struct tick_device *td; | 690 | struct tick_device *td; |
| 641 | unsigned long flags; | 691 | unsigned long flags; |
| 642 | ktime_t now; | 692 | ktime_t now; |
| 643 | int cpu; | 693 | int cpu, ret = 0; |
| 644 | 694 | ||
| 645 | /* | 695 | /* |
| 646 | * Periodic mode does not care about the enter/exit of power | 696 | * Periodic mode does not care about the enter/exit of power |
| 647 | * states | 697 | * states |
| 648 | */ | 698 | */ |
| 649 | if (tick_broadcast_device.mode == TICKDEV_MODE_PERIODIC) | 699 | if (tick_broadcast_device.mode == TICKDEV_MODE_PERIODIC) |
| 650 | return; | 700 | return 0; |
| 651 | 701 | ||
| 652 | /* | 702 | /* |
| 653 | * We are called with preemtion disabled from the depth of the | 703 | * We are called with preemtion disabled from the depth of the |
| @@ -658,7 +708,7 @@ void tick_broadcast_oneshot_control(unsigned long reason) | |||
| 658 | dev = td->evtdev; | 708 | dev = td->evtdev; |
| 659 | 709 | ||
| 660 | if (!(dev->features & CLOCK_EVT_FEAT_C3STOP)) | 710 | if (!(dev->features & CLOCK_EVT_FEAT_C3STOP)) |
| 661 | return; | 711 | return 0; |
| 662 | 712 | ||
| 663 | bc = tick_broadcast_device.evtdev; | 713 | bc = tick_broadcast_device.evtdev; |
| 664 | 714 | ||
| @@ -666,7 +716,7 @@ void tick_broadcast_oneshot_control(unsigned long reason) | |||
| 666 | if (reason == CLOCK_EVT_NOTIFY_BROADCAST_ENTER) { | 716 | if (reason == CLOCK_EVT_NOTIFY_BROADCAST_ENTER) { |
| 667 | if (!cpumask_test_and_set_cpu(cpu, tick_broadcast_oneshot_mask)) { | 717 | if (!cpumask_test_and_set_cpu(cpu, tick_broadcast_oneshot_mask)) { |
| 668 | WARN_ON_ONCE(cpumask_test_cpu(cpu, tick_broadcast_pending_mask)); | 718 | WARN_ON_ONCE(cpumask_test_cpu(cpu, tick_broadcast_pending_mask)); |
| 669 | clockevents_set_mode(dev, CLOCK_EVT_MODE_SHUTDOWN); | 719 | broadcast_shutdown_local(bc, dev); |
| 670 | /* | 720 | /* |
| 671 | * We only reprogram the broadcast timer if we | 721 | * We only reprogram the broadcast timer if we |
| 672 | * did not mark ourself in the force mask and | 722 | * did not mark ourself in the force mask and |
| @@ -679,6 +729,16 @@ void tick_broadcast_oneshot_control(unsigned long reason) | |||
| 679 | dev->next_event.tv64 < bc->next_event.tv64) | 729 | dev->next_event.tv64 < bc->next_event.tv64) |
| 680 | tick_broadcast_set_event(bc, cpu, dev->next_event, 1); | 730 | tick_broadcast_set_event(bc, cpu, dev->next_event, 1); |
| 681 | } | 731 | } |
| 732 | /* | ||
| 733 | * If the current CPU owns the hrtimer broadcast | ||
| 734 | * mechanism, it cannot go deep idle and we remove the | ||
| 735 | * CPU from the broadcast mask. We don't have to go | ||
| 736 | * through the EXIT path as the local timer is not | ||
| 737 | * shutdown. | ||
| 738 | */ | ||
| 739 | ret = broadcast_needs_cpu(bc, cpu); | ||
| 740 | if (ret) | ||
| 741 | cpumask_clear_cpu(cpu, tick_broadcast_oneshot_mask); | ||
| 682 | } else { | 742 | } else { |
| 683 | if (cpumask_test_and_clear_cpu(cpu, tick_broadcast_oneshot_mask)) { | 743 | if (cpumask_test_and_clear_cpu(cpu, tick_broadcast_oneshot_mask)) { |
| 684 | clockevents_set_mode(dev, CLOCK_EVT_MODE_ONESHOT); | 744 | clockevents_set_mode(dev, CLOCK_EVT_MODE_ONESHOT); |
| @@ -746,6 +806,7 @@ void tick_broadcast_oneshot_control(unsigned long reason) | |||
| 746 | } | 806 | } |
| 747 | out: | 807 | out: |
| 748 | raw_spin_unlock_irqrestore(&tick_broadcast_lock, flags); | 808 | raw_spin_unlock_irqrestore(&tick_broadcast_lock, flags); |
| 809 | return ret; | ||
| 749 | } | 810 | } |
| 750 | 811 | ||
| 751 | /* | 812 | /* |
| @@ -852,6 +913,8 @@ void tick_shutdown_broadcast_oneshot(unsigned int *cpup) | |||
| 852 | cpumask_clear_cpu(cpu, tick_broadcast_pending_mask); | 913 | cpumask_clear_cpu(cpu, tick_broadcast_pending_mask); |
| 853 | cpumask_clear_cpu(cpu, tick_broadcast_force_mask); | 914 | cpumask_clear_cpu(cpu, tick_broadcast_force_mask); |
| 854 | 915 | ||
| 916 | broadcast_move_bc(cpu); | ||
| 917 | |||
| 855 | raw_spin_unlock_irqrestore(&tick_broadcast_lock, flags); | 918 | raw_spin_unlock_irqrestore(&tick_broadcast_lock, flags); |
| 856 | } | 919 | } |
| 857 | 920 | ||
diff --git a/kernel/time/tick-common.c b/kernel/time/tick-common.c index 20b2fe37d105..015661279b68 100644 --- a/kernel/time/tick-common.c +++ b/kernel/time/tick-common.c | |||
| @@ -98,18 +98,19 @@ static void tick_periodic(int cpu) | |||
| 98 | void tick_handle_periodic(struct clock_event_device *dev) | 98 | void tick_handle_periodic(struct clock_event_device *dev) |
| 99 | { | 99 | { |
| 100 | int cpu = smp_processor_id(); | 100 | int cpu = smp_processor_id(); |
| 101 | ktime_t next; | 101 | ktime_t next = dev->next_event; |
| 102 | 102 | ||
| 103 | tick_periodic(cpu); | 103 | tick_periodic(cpu); |
| 104 | 104 | ||
| 105 | if (dev->mode != CLOCK_EVT_MODE_ONESHOT) | 105 | if (dev->mode != CLOCK_EVT_MODE_ONESHOT) |
| 106 | return; | 106 | return; |
| 107 | /* | ||
| 108 | * Setup the next period for devices, which do not have | ||
| 109 | * periodic mode: | ||
| 110 | */ | ||
| 111 | next = ktime_add(dev->next_event, tick_period); | ||
| 112 | for (;;) { | 107 | for (;;) { |
| 108 | /* | ||
| 109 | * Setup the next period for devices, which do not have | ||
| 110 | * periodic mode: | ||
| 111 | */ | ||
| 112 | next = ktime_add(next, tick_period); | ||
| 113 | |||
| 113 | if (!clockevents_program_event(dev, next, false)) | 114 | if (!clockevents_program_event(dev, next, false)) |
| 114 | return; | 115 | return; |
| 115 | /* | 116 | /* |
| @@ -118,12 +119,11 @@ void tick_handle_periodic(struct clock_event_device *dev) | |||
| 118 | * to be sure we're using a real hardware clocksource. | 119 | * to be sure we're using a real hardware clocksource. |
| 119 | * Otherwise we could get trapped in an infinite | 120 | * Otherwise we could get trapped in an infinite |
| 120 | * loop, as the tick_periodic() increments jiffies, | 121 | * loop, as the tick_periodic() increments jiffies, |
| 121 | * when then will increment time, posibly causing | 122 | * which then will increment time, possibly causing |
| 122 | * the loop to trigger again and again. | 123 | * the loop to trigger again and again. |
| 123 | */ | 124 | */ |
| 124 | if (timekeeping_valid_for_hres()) | 125 | if (timekeeping_valid_for_hres()) |
| 125 | tick_periodic(cpu); | 126 | tick_periodic(cpu); |
| 126 | next = ktime_add(next, tick_period); | ||
| 127 | } | 127 | } |
| 128 | } | 128 | } |
| 129 | 129 | ||
diff --git a/kernel/time/tick-internal.h b/kernel/time/tick-internal.h index 8329669b51ec..7ab92b19965a 100644 --- a/kernel/time/tick-internal.h +++ b/kernel/time/tick-internal.h | |||
| @@ -46,7 +46,7 @@ extern int tick_switch_to_oneshot(void (*handler)(struct clock_event_device *)); | |||
| 46 | extern void tick_resume_oneshot(void); | 46 | extern void tick_resume_oneshot(void); |
| 47 | # ifdef CONFIG_GENERIC_CLOCKEVENTS_BROADCAST | 47 | # ifdef CONFIG_GENERIC_CLOCKEVENTS_BROADCAST |
| 48 | extern void tick_broadcast_setup_oneshot(struct clock_event_device *bc); | 48 | extern void tick_broadcast_setup_oneshot(struct clock_event_device *bc); |
| 49 | extern void tick_broadcast_oneshot_control(unsigned long reason); | 49 | extern int tick_broadcast_oneshot_control(unsigned long reason); |
| 50 | extern void tick_broadcast_switch_to_oneshot(void); | 50 | extern void tick_broadcast_switch_to_oneshot(void); |
| 51 | extern void tick_shutdown_broadcast_oneshot(unsigned int *cpup); | 51 | extern void tick_shutdown_broadcast_oneshot(unsigned int *cpup); |
| 52 | extern int tick_resume_broadcast_oneshot(struct clock_event_device *bc); | 52 | extern int tick_resume_broadcast_oneshot(struct clock_event_device *bc); |
| @@ -58,7 +58,7 @@ static inline void tick_broadcast_setup_oneshot(struct clock_event_device *bc) | |||
| 58 | { | 58 | { |
| 59 | BUG(); | 59 | BUG(); |
| 60 | } | 60 | } |
| 61 | static inline void tick_broadcast_oneshot_control(unsigned long reason) { } | 61 | static inline int tick_broadcast_oneshot_control(unsigned long reason) { return 0; } |
| 62 | static inline void tick_broadcast_switch_to_oneshot(void) { } | 62 | static inline void tick_broadcast_switch_to_oneshot(void) { } |
| 63 | static inline void tick_shutdown_broadcast_oneshot(unsigned int *cpup) { } | 63 | static inline void tick_shutdown_broadcast_oneshot(unsigned int *cpup) { } |
| 64 | static inline int tick_broadcast_oneshot_active(void) { return 0; } | 64 | static inline int tick_broadcast_oneshot_active(void) { return 0; } |
| @@ -87,7 +87,7 @@ static inline void tick_broadcast_setup_oneshot(struct clock_event_device *bc) | |||
| 87 | { | 87 | { |
| 88 | BUG(); | 88 | BUG(); |
| 89 | } | 89 | } |
| 90 | static inline void tick_broadcast_oneshot_control(unsigned long reason) { } | 90 | static inline int tick_broadcast_oneshot_control(unsigned long reason) { return 0; } |
| 91 | static inline void tick_shutdown_broadcast_oneshot(unsigned int *cpup) { } | 91 | static inline void tick_shutdown_broadcast_oneshot(unsigned int *cpup) { } |
| 92 | static inline int tick_resume_broadcast_oneshot(struct clock_event_device *bc) | 92 | static inline int tick_resume_broadcast_oneshot(struct clock_event_device *bc) |
| 93 | { | 93 | { |
| @@ -111,6 +111,7 @@ extern int tick_resume_broadcast(void); | |||
| 111 | extern void tick_broadcast_init(void); | 111 | extern void tick_broadcast_init(void); |
| 112 | extern void | 112 | extern void |
| 113 | tick_set_periodic_handler(struct clock_event_device *dev, int broadcast); | 113 | tick_set_periodic_handler(struct clock_event_device *dev, int broadcast); |
| 114 | int tick_broadcast_update_freq(struct clock_event_device *dev, u32 freq); | ||
| 114 | 115 | ||
| 115 | #else /* !BROADCAST */ | 116 | #else /* !BROADCAST */ |
| 116 | 117 | ||
| @@ -133,6 +134,8 @@ static inline void tick_shutdown_broadcast(unsigned int *cpup) { } | |||
| 133 | static inline void tick_suspend_broadcast(void) { } | 134 | static inline void tick_suspend_broadcast(void) { } |
| 134 | static inline int tick_resume_broadcast(void) { return 0; } | 135 | static inline int tick_resume_broadcast(void) { return 0; } |
| 135 | static inline void tick_broadcast_init(void) { } | 136 | static inline void tick_broadcast_init(void) { } |
| 137 | static inline int tick_broadcast_update_freq(struct clock_event_device *dev, | ||
| 138 | u32 freq) { return -ENODEV; } | ||
| 136 | 139 | ||
| 137 | /* | 140 | /* |
| 138 | * Set the periodic handler in non broadcast mode | 141 | * Set the periodic handler in non broadcast mode |
| @@ -152,6 +155,8 @@ static inline int tick_device_is_functional(struct clock_event_device *dev) | |||
| 152 | return !(dev->features & CLOCK_EVT_FEAT_DUMMY); | 155 | return !(dev->features & CLOCK_EVT_FEAT_DUMMY); |
| 153 | } | 156 | } |
| 154 | 157 | ||
| 158 | int __clockevents_update_freq(struct clock_event_device *dev, u32 freq); | ||
| 159 | |||
| 155 | #endif | 160 | #endif |
| 156 | 161 | ||
| 157 | extern void do_timer(unsigned long ticks); | 162 | extern void do_timer(unsigned long ticks); |
diff --git a/kernel/time/timekeeping_debug.c b/kernel/time/timekeeping_debug.c index 802433a4f5eb..4d54f97558df 100644 --- a/kernel/time/timekeeping_debug.c +++ b/kernel/time/timekeeping_debug.c | |||
| @@ -21,6 +21,8 @@ | |||
| 21 | #include <linux/seq_file.h> | 21 | #include <linux/seq_file.h> |
| 22 | #include <linux/time.h> | 22 | #include <linux/time.h> |
| 23 | 23 | ||
| 24 | #include "timekeeping_internal.h" | ||
| 25 | |||
| 24 | static unsigned int sleep_time_bin[32] = {0}; | 26 | static unsigned int sleep_time_bin[32] = {0}; |
| 25 | 27 | ||
| 26 | static int tk_debug_show_sleep_time(struct seq_file *s, void *data) | 28 | static int tk_debug_show_sleep_time(struct seq_file *s, void *data) |
diff --git a/kernel/timer.c b/kernel/timer.c index d78de047599b..87bd529879c2 100644 --- a/kernel/timer.c +++ b/kernel/timer.c | |||
| @@ -81,6 +81,7 @@ struct tvec_base { | |||
| 81 | unsigned long timer_jiffies; | 81 | unsigned long timer_jiffies; |
| 82 | unsigned long next_timer; | 82 | unsigned long next_timer; |
| 83 | unsigned long active_timers; | 83 | unsigned long active_timers; |
| 84 | unsigned long all_timers; | ||
| 84 | struct tvec_root tv1; | 85 | struct tvec_root tv1; |
| 85 | struct tvec tv2; | 86 | struct tvec tv2; |
| 86 | struct tvec tv3; | 87 | struct tvec tv3; |
| @@ -337,6 +338,20 @@ void set_timer_slack(struct timer_list *timer, int slack_hz) | |||
| 337 | } | 338 | } |
| 338 | EXPORT_SYMBOL_GPL(set_timer_slack); | 339 | EXPORT_SYMBOL_GPL(set_timer_slack); |
| 339 | 340 | ||
| 341 | /* | ||
| 342 | * If the list is empty, catch up ->timer_jiffies to the current time. | ||
| 343 | * The caller must hold the tvec_base lock. Returns true if the list | ||
| 344 | * was empty and therefore ->timer_jiffies was updated. | ||
| 345 | */ | ||
| 346 | static bool catchup_timer_jiffies(struct tvec_base *base) | ||
| 347 | { | ||
| 348 | if (!base->all_timers) { | ||
| 349 | base->timer_jiffies = jiffies; | ||
| 350 | return true; | ||
| 351 | } | ||
| 352 | return false; | ||
| 353 | } | ||
| 354 | |||
| 340 | static void | 355 | static void |
| 341 | __internal_add_timer(struct tvec_base *base, struct timer_list *timer) | 356 | __internal_add_timer(struct tvec_base *base, struct timer_list *timer) |
| 342 | { | 357 | { |
| @@ -383,15 +398,17 @@ __internal_add_timer(struct tvec_base *base, struct timer_list *timer) | |||
| 383 | 398 | ||
| 384 | static void internal_add_timer(struct tvec_base *base, struct timer_list *timer) | 399 | static void internal_add_timer(struct tvec_base *base, struct timer_list *timer) |
| 385 | { | 400 | { |
| 401 | (void)catchup_timer_jiffies(base); | ||
| 386 | __internal_add_timer(base, timer); | 402 | __internal_add_timer(base, timer); |
| 387 | /* | 403 | /* |
| 388 | * Update base->active_timers and base->next_timer | 404 | * Update base->active_timers and base->next_timer |
| 389 | */ | 405 | */ |
| 390 | if (!tbase_get_deferrable(timer->base)) { | 406 | if (!tbase_get_deferrable(timer->base)) { |
| 391 | if (time_before(timer->expires, base->next_timer)) | 407 | if (!base->active_timers++ || |
| 408 | time_before(timer->expires, base->next_timer)) | ||
| 392 | base->next_timer = timer->expires; | 409 | base->next_timer = timer->expires; |
| 393 | base->active_timers++; | ||
| 394 | } | 410 | } |
| 411 | base->all_timers++; | ||
| 395 | } | 412 | } |
| 396 | 413 | ||
| 397 | #ifdef CONFIG_TIMER_STATS | 414 | #ifdef CONFIG_TIMER_STATS |
| @@ -671,6 +688,8 @@ detach_expired_timer(struct timer_list *timer, struct tvec_base *base) | |||
| 671 | detach_timer(timer, true); | 688 | detach_timer(timer, true); |
| 672 | if (!tbase_get_deferrable(timer->base)) | 689 | if (!tbase_get_deferrable(timer->base)) |
| 673 | base->active_timers--; | 690 | base->active_timers--; |
| 691 | base->all_timers--; | ||
| 692 | (void)catchup_timer_jiffies(base); | ||
| 674 | } | 693 | } |
| 675 | 694 | ||
| 676 | static int detach_if_pending(struct timer_list *timer, struct tvec_base *base, | 695 | static int detach_if_pending(struct timer_list *timer, struct tvec_base *base, |
| @@ -685,6 +704,8 @@ static int detach_if_pending(struct timer_list *timer, struct tvec_base *base, | |||
| 685 | if (timer->expires == base->next_timer) | 704 | if (timer->expires == base->next_timer) |
| 686 | base->next_timer = base->timer_jiffies; | 705 | base->next_timer = base->timer_jiffies; |
| 687 | } | 706 | } |
| 707 | base->all_timers--; | ||
| 708 | (void)catchup_timer_jiffies(base); | ||
| 688 | return 1; | 709 | return 1; |
| 689 | } | 710 | } |
| 690 | 711 | ||
| @@ -739,12 +760,7 @@ __mod_timer(struct timer_list *timer, unsigned long expires, | |||
| 739 | 760 | ||
| 740 | debug_activate(timer, expires); | 761 | debug_activate(timer, expires); |
| 741 | 762 | ||
| 742 | cpu = smp_processor_id(); | 763 | cpu = get_nohz_timer_target(pinned); |
| 743 | |||
| 744 | #if defined(CONFIG_NO_HZ_COMMON) && defined(CONFIG_SMP) | ||
| 745 | if (!pinned && get_sysctl_timer_migration() && idle_cpu(cpu)) | ||
| 746 | cpu = get_nohz_timer_target(); | ||
| 747 | #endif | ||
| 748 | new_base = per_cpu(tvec_bases, cpu); | 764 | new_base = per_cpu(tvec_bases, cpu); |
| 749 | 765 | ||
| 750 | if (base != new_base) { | 766 | if (base != new_base) { |
| @@ -939,8 +955,15 @@ void add_timer_on(struct timer_list *timer, int cpu) | |||
| 939 | * with the timer by holding the timer base lock. This also | 955 | * with the timer by holding the timer base lock. This also |
| 940 | * makes sure that a CPU on the way to stop its tick can not | 956 | * makes sure that a CPU on the way to stop its tick can not |
| 941 | * evaluate the timer wheel. | 957 | * evaluate the timer wheel. |
| 958 | * | ||
| 959 | * Spare the IPI for deferrable timers on idle targets though. | ||
| 960 | * The next busy ticks will take care of it. Except full dynticks | ||
| 961 | * require special care against races with idle_cpu(), lets deal | ||
| 962 | * with that later. | ||
| 942 | */ | 963 | */ |
| 943 | wake_up_nohz_cpu(cpu); | 964 | if (!tbase_get_deferrable(timer->base) || tick_nohz_full_cpu(cpu)) |
| 965 | wake_up_nohz_cpu(cpu); | ||
| 966 | |||
| 944 | spin_unlock_irqrestore(&base->lock, flags); | 967 | spin_unlock_irqrestore(&base->lock, flags); |
| 945 | } | 968 | } |
| 946 | EXPORT_SYMBOL_GPL(add_timer_on); | 969 | EXPORT_SYMBOL_GPL(add_timer_on); |
| @@ -1146,6 +1169,10 @@ static inline void __run_timers(struct tvec_base *base) | |||
| 1146 | struct timer_list *timer; | 1169 | struct timer_list *timer; |
| 1147 | 1170 | ||
| 1148 | spin_lock_irq(&base->lock); | 1171 | spin_lock_irq(&base->lock); |
| 1172 | if (catchup_timer_jiffies(base)) { | ||
| 1173 | spin_unlock_irq(&base->lock); | ||
| 1174 | return; | ||
| 1175 | } | ||
| 1149 | while (time_after_eq(jiffies, base->timer_jiffies)) { | 1176 | while (time_after_eq(jiffies, base->timer_jiffies)) { |
| 1150 | struct list_head work_list; | 1177 | struct list_head work_list; |
| 1151 | struct list_head *head = &work_list; | 1178 | struct list_head *head = &work_list; |
| @@ -1160,7 +1187,7 @@ static inline void __run_timers(struct tvec_base *base) | |||
| 1160 | !cascade(base, &base->tv4, INDEX(2))) | 1187 | !cascade(base, &base->tv4, INDEX(2))) |
| 1161 | cascade(base, &base->tv5, INDEX(3)); | 1188 | cascade(base, &base->tv5, INDEX(3)); |
| 1162 | ++base->timer_jiffies; | 1189 | ++base->timer_jiffies; |
| 1163 | list_replace_init(base->tv1.vec + index, &work_list); | 1190 | list_replace_init(base->tv1.vec + index, head); |
| 1164 | while (!list_empty(head)) { | 1191 | while (!list_empty(head)) { |
| 1165 | void (*fn)(unsigned long); | 1192 | void (*fn)(unsigned long); |
| 1166 | unsigned long data; | 1193 | unsigned long data; |
| @@ -1523,9 +1550,8 @@ static int init_timers_cpu(int cpu) | |||
| 1523 | if (!base) | 1550 | if (!base) |
| 1524 | return -ENOMEM; | 1551 | return -ENOMEM; |
| 1525 | 1552 | ||
| 1526 | /* Make sure that tvec_base is 2 byte aligned */ | 1553 | /* Make sure tvec_base has TIMER_FLAG_MASK bits free */ |
| 1527 | if (tbase_get_deferrable(base)) { | 1554 | if (WARN_ON(base != tbase_get_base(base))) { |
| 1528 | WARN_ON(1); | ||
| 1529 | kfree(base); | 1555 | kfree(base); |
| 1530 | return -ENOMEM; | 1556 | return -ENOMEM; |
| 1531 | } | 1557 | } |
| @@ -1559,6 +1585,7 @@ static int init_timers_cpu(int cpu) | |||
| 1559 | base->timer_jiffies = jiffies; | 1585 | base->timer_jiffies = jiffies; |
| 1560 | base->next_timer = base->timer_jiffies; | 1586 | base->next_timer = base->timer_jiffies; |
| 1561 | base->active_timers = 0; | 1587 | base->active_timers = 0; |
| 1588 | base->all_timers = 0; | ||
| 1562 | return 0; | 1589 | return 0; |
| 1563 | } | 1590 | } |
| 1564 | 1591 | ||
| @@ -1648,9 +1675,9 @@ void __init init_timers(void) | |||
| 1648 | 1675 | ||
| 1649 | err = timer_cpu_notify(&timers_nb, (unsigned long)CPU_UP_PREPARE, | 1676 | err = timer_cpu_notify(&timers_nb, (unsigned long)CPU_UP_PREPARE, |
| 1650 | (void *)(long)smp_processor_id()); | 1677 | (void *)(long)smp_processor_id()); |
| 1651 | init_timer_stats(); | ||
| 1652 | |||
| 1653 | BUG_ON(err != NOTIFY_OK); | 1678 | BUG_ON(err != NOTIFY_OK); |
| 1679 | |||
| 1680 | init_timer_stats(); | ||
| 1654 | register_cpu_notifier(&timers_nb); | 1681 | register_cpu_notifier(&timers_nb); |
| 1655 | open_softirq(TIMER_SOFTIRQ, run_timer_softirq); | 1682 | open_softirq(TIMER_SOFTIRQ, run_timer_softirq); |
| 1656 | } | 1683 | } |
diff --git a/kernel/workqueue.c b/kernel/workqueue.c index 3fa5b8f3aae3..0ee63af30bd1 100644 --- a/kernel/workqueue.c +++ b/kernel/workqueue.c | |||
| @@ -516,6 +516,13 @@ void destroy_work_on_stack(struct work_struct *work) | |||
| 516 | } | 516 | } |
| 517 | EXPORT_SYMBOL_GPL(destroy_work_on_stack); | 517 | EXPORT_SYMBOL_GPL(destroy_work_on_stack); |
| 518 | 518 | ||
| 519 | void destroy_delayed_work_on_stack(struct delayed_work *work) | ||
| 520 | { | ||
| 521 | destroy_timer_on_stack(&work->timer); | ||
| 522 | debug_object_free(&work->work, &work_debug_descr); | ||
| 523 | } | ||
| 524 | EXPORT_SYMBOL_GPL(destroy_delayed_work_on_stack); | ||
| 525 | |||
| 519 | #else | 526 | #else |
| 520 | static inline void debug_work_activate(struct work_struct *work) { } | 527 | static inline void debug_work_activate(struct work_struct *work) { } |
| 521 | static inline void debug_work_deactivate(struct work_struct *work) { } | 528 | static inline void debug_work_deactivate(struct work_struct *work) { } |
