diff options
Diffstat (limited to 'kernel/timer.c')
-rw-r--r-- | kernel/timer.c | 100 |
1 files changed, 60 insertions, 40 deletions
diff --git a/kernel/timer.c b/kernel/timer.c index fe3a9a9f8328..ab189dd187cb 100644 --- a/kernel/timer.c +++ b/kernel/timer.c | |||
@@ -86,7 +86,8 @@ struct tvec_t_base_s { | |||
86 | } ____cacheline_aligned_in_smp; | 86 | } ____cacheline_aligned_in_smp; |
87 | 87 | ||
88 | typedef struct tvec_t_base_s tvec_base_t; | 88 | typedef struct tvec_t_base_s tvec_base_t; |
89 | static DEFINE_PER_CPU(tvec_base_t, tvec_bases); | 89 | static DEFINE_PER_CPU(tvec_base_t *, tvec_bases); |
90 | static tvec_base_t boot_tvec_bases; | ||
90 | 91 | ||
91 | static inline void set_running_timer(tvec_base_t *base, | 92 | static inline void set_running_timer(tvec_base_t *base, |
92 | struct timer_list *timer) | 93 | struct timer_list *timer) |
@@ -157,7 +158,7 @@ EXPORT_SYMBOL(__init_timer_base); | |||
157 | void fastcall init_timer(struct timer_list *timer) | 158 | void fastcall init_timer(struct timer_list *timer) |
158 | { | 159 | { |
159 | timer->entry.next = NULL; | 160 | timer->entry.next = NULL; |
160 | timer->base = &per_cpu(tvec_bases, raw_smp_processor_id()).t_base; | 161 | timer->base = &per_cpu(tvec_bases, raw_smp_processor_id())->t_base; |
161 | } | 162 | } |
162 | EXPORT_SYMBOL(init_timer); | 163 | EXPORT_SYMBOL(init_timer); |
163 | 164 | ||
@@ -218,7 +219,7 @@ int __mod_timer(struct timer_list *timer, unsigned long expires) | |||
218 | ret = 1; | 219 | ret = 1; |
219 | } | 220 | } |
220 | 221 | ||
221 | new_base = &__get_cpu_var(tvec_bases); | 222 | new_base = __get_cpu_var(tvec_bases); |
222 | 223 | ||
223 | if (base != &new_base->t_base) { | 224 | if (base != &new_base->t_base) { |
224 | /* | 225 | /* |
@@ -258,7 +259,7 @@ EXPORT_SYMBOL(__mod_timer); | |||
258 | */ | 259 | */ |
259 | void add_timer_on(struct timer_list *timer, int cpu) | 260 | void add_timer_on(struct timer_list *timer, int cpu) |
260 | { | 261 | { |
261 | tvec_base_t *base = &per_cpu(tvec_bases, cpu); | 262 | tvec_base_t *base = per_cpu(tvec_bases, cpu); |
262 | unsigned long flags; | 263 | unsigned long flags; |
263 | 264 | ||
264 | BUG_ON(timer_pending(timer) || !timer->function); | 265 | BUG_ON(timer_pending(timer) || !timer->function); |
@@ -489,10 +490,22 @@ unsigned long next_timer_interrupt(void) | |||
489 | struct list_head *list; | 490 | struct list_head *list; |
490 | struct timer_list *nte; | 491 | struct timer_list *nte; |
491 | unsigned long expires; | 492 | unsigned long expires; |
493 | unsigned long hr_expires = MAX_JIFFY_OFFSET; | ||
494 | ktime_t hr_delta; | ||
492 | tvec_t *varray[4]; | 495 | tvec_t *varray[4]; |
493 | int i, j; | 496 | int i, j; |
494 | 497 | ||
495 | base = &__get_cpu_var(tvec_bases); | 498 | hr_delta = hrtimer_get_next_event(); |
499 | if (hr_delta.tv64 != KTIME_MAX) { | ||
500 | struct timespec tsdelta; | ||
501 | tsdelta = ktime_to_timespec(hr_delta); | ||
502 | hr_expires = timespec_to_jiffies(&tsdelta); | ||
503 | if (hr_expires < 3) | ||
504 | return hr_expires + jiffies; | ||
505 | } | ||
506 | hr_expires += jiffies; | ||
507 | |||
508 | base = __get_cpu_var(tvec_bases); | ||
496 | spin_lock(&base->t_base.lock); | 509 | spin_lock(&base->t_base.lock); |
497 | expires = base->timer_jiffies + (LONG_MAX >> 1); | 510 | expires = base->timer_jiffies + (LONG_MAX >> 1); |
498 | list = NULL; | 511 | list = NULL; |
@@ -542,6 +555,10 @@ found: | |||
542 | } | 555 | } |
543 | } | 556 | } |
544 | spin_unlock(&base->t_base.lock); | 557 | spin_unlock(&base->t_base.lock); |
558 | |||
559 | if (time_before(hr_expires, expires)) | ||
560 | return hr_expires; | ||
561 | |||
545 | return expires; | 562 | return expires; |
546 | } | 563 | } |
547 | #endif | 564 | #endif |
@@ -680,18 +697,9 @@ static void second_overflow(void) | |||
680 | 697 | ||
681 | /* | 698 | /* |
682 | * Compute the frequency estimate and additional phase adjustment due | 699 | * Compute the frequency estimate and additional phase adjustment due |
683 | * to frequency error for the next second. When the PPS signal is | 700 | * to frequency error for the next second. |
684 | * engaged, gnaw on the watchdog counter and update the frequency | ||
685 | * computed by the pll and the PPS signal. | ||
686 | */ | 701 | */ |
687 | pps_valid++; | 702 | ltemp = time_freq; |
688 | if (pps_valid == PPS_VALID) { /* PPS signal lost */ | ||
689 | pps_jitter = MAXTIME; | ||
690 | pps_stabil = MAXFREQ; | ||
691 | time_status &= ~(STA_PPSSIGNAL | STA_PPSJITTER | | ||
692 | STA_PPSWANDER | STA_PPSERROR); | ||
693 | } | ||
694 | ltemp = time_freq + pps_freq; | ||
695 | time_adj += shift_right(ltemp,(SHIFT_USEC + SHIFT_HZ - SHIFT_SCALE)); | 703 | time_adj += shift_right(ltemp,(SHIFT_USEC + SHIFT_HZ - SHIFT_SCALE)); |
696 | 704 | ||
697 | #if HZ == 100 | 705 | #if HZ == 100 |
@@ -885,7 +893,7 @@ EXPORT_SYMBOL(xtime_lock); | |||
885 | */ | 893 | */ |
886 | static void run_timer_softirq(struct softirq_action *h) | 894 | static void run_timer_softirq(struct softirq_action *h) |
887 | { | 895 | { |
888 | tvec_base_t *base = &__get_cpu_var(tvec_bases); | 896 | tvec_base_t *base = __get_cpu_var(tvec_bases); |
889 | 897 | ||
890 | hrtimer_run_queues(); | 898 | hrtimer_run_queues(); |
891 | if (time_after_eq(jiffies, base->timer_jiffies)) | 899 | if (time_after_eq(jiffies, base->timer_jiffies)) |
@@ -898,6 +906,7 @@ static void run_timer_softirq(struct softirq_action *h) | |||
898 | void run_local_timers(void) | 906 | void run_local_timers(void) |
899 | { | 907 | { |
900 | raise_softirq(TIMER_SOFTIRQ); | 908 | raise_softirq(TIMER_SOFTIRQ); |
909 | softlockup_tick(); | ||
901 | } | 910 | } |
902 | 911 | ||
903 | /* | 912 | /* |
@@ -925,8 +934,9 @@ static inline void update_times(void) | |||
925 | void do_timer(struct pt_regs *regs) | 934 | void do_timer(struct pt_regs *regs) |
926 | { | 935 | { |
927 | jiffies_64++; | 936 | jiffies_64++; |
937 | /* prevent loading jiffies before storing new jiffies_64 value. */ | ||
938 | barrier(); | ||
928 | update_times(); | 939 | update_times(); |
929 | softlockup_tick(regs); | ||
930 | } | 940 | } |
931 | 941 | ||
932 | #ifdef __ARCH_WANT_SYS_ALARM | 942 | #ifdef __ARCH_WANT_SYS_ALARM |
@@ -937,19 +947,7 @@ void do_timer(struct pt_regs *regs) | |||
937 | */ | 947 | */ |
938 | asmlinkage unsigned long sys_alarm(unsigned int seconds) | 948 | asmlinkage unsigned long sys_alarm(unsigned int seconds) |
939 | { | 949 | { |
940 | struct itimerval it_new, it_old; | 950 | return alarm_setitimer(seconds); |
941 | unsigned int oldalarm; | ||
942 | |||
943 | it_new.it_interval.tv_sec = it_new.it_interval.tv_usec = 0; | ||
944 | it_new.it_value.tv_sec = seconds; | ||
945 | it_new.it_value.tv_usec = 0; | ||
946 | do_setitimer(ITIMER_REAL, &it_new, &it_old); | ||
947 | oldalarm = it_old.it_value.tv_sec; | ||
948 | /* ehhh.. We can't return 0 if we have an alarm pending.. */ | ||
949 | /* And we'd better return too much than too little anyway */ | ||
950 | if ((!oldalarm && it_old.it_value.tv_usec) || it_old.it_value.tv_usec >= 500000) | ||
951 | oldalarm++; | ||
952 | return oldalarm; | ||
953 | } | 951 | } |
954 | 952 | ||
955 | #endif | 953 | #endif |
@@ -1238,12 +1236,32 @@ asmlinkage long sys_sysinfo(struct sysinfo __user *info) | |||
1238 | return 0; | 1236 | return 0; |
1239 | } | 1237 | } |
1240 | 1238 | ||
1241 | static void __devinit init_timers_cpu(int cpu) | 1239 | static int __devinit init_timers_cpu(int cpu) |
1242 | { | 1240 | { |
1243 | int j; | 1241 | int j; |
1244 | tvec_base_t *base; | 1242 | tvec_base_t *base; |
1245 | 1243 | ||
1246 | base = &per_cpu(tvec_bases, cpu); | 1244 | base = per_cpu(tvec_bases, cpu); |
1245 | if (!base) { | ||
1246 | static char boot_done; | ||
1247 | |||
1248 | /* | ||
1249 | * Cannot do allocation in init_timers as that runs before the | ||
1250 | * allocator initializes (and would waste memory if there are | ||
1251 | * more possible CPUs than will ever be installed/brought up). | ||
1252 | */ | ||
1253 | if (boot_done) { | ||
1254 | base = kmalloc_node(sizeof(*base), GFP_KERNEL, | ||
1255 | cpu_to_node(cpu)); | ||
1256 | if (!base) | ||
1257 | return -ENOMEM; | ||
1258 | memset(base, 0, sizeof(*base)); | ||
1259 | } else { | ||
1260 | base = &boot_tvec_bases; | ||
1261 | boot_done = 1; | ||
1262 | } | ||
1263 | per_cpu(tvec_bases, cpu) = base; | ||
1264 | } | ||
1247 | spin_lock_init(&base->t_base.lock); | 1265 | spin_lock_init(&base->t_base.lock); |
1248 | for (j = 0; j < TVN_SIZE; j++) { | 1266 | for (j = 0; j < TVN_SIZE; j++) { |
1249 | INIT_LIST_HEAD(base->tv5.vec + j); | 1267 | INIT_LIST_HEAD(base->tv5.vec + j); |
@@ -1255,6 +1273,7 @@ static void __devinit init_timers_cpu(int cpu) | |||
1255 | INIT_LIST_HEAD(base->tv1.vec + j); | 1273 | INIT_LIST_HEAD(base->tv1.vec + j); |
1256 | 1274 | ||
1257 | base->timer_jiffies = jiffies; | 1275 | base->timer_jiffies = jiffies; |
1276 | return 0; | ||
1258 | } | 1277 | } |
1259 | 1278 | ||
1260 | #ifdef CONFIG_HOTPLUG_CPU | 1279 | #ifdef CONFIG_HOTPLUG_CPU |
@@ -1277,8 +1296,8 @@ static void __devinit migrate_timers(int cpu) | |||
1277 | int i; | 1296 | int i; |
1278 | 1297 | ||
1279 | BUG_ON(cpu_online(cpu)); | 1298 | BUG_ON(cpu_online(cpu)); |
1280 | old_base = &per_cpu(tvec_bases, cpu); | 1299 | old_base = per_cpu(tvec_bases, cpu); |
1281 | new_base = &get_cpu_var(tvec_bases); | 1300 | new_base = get_cpu_var(tvec_bases); |
1282 | 1301 | ||
1283 | local_irq_disable(); | 1302 | local_irq_disable(); |
1284 | spin_lock(&new_base->t_base.lock); | 1303 | spin_lock(&new_base->t_base.lock); |
@@ -1308,7 +1327,8 @@ static int __devinit timer_cpu_notify(struct notifier_block *self, | |||
1308 | long cpu = (long)hcpu; | 1327 | long cpu = (long)hcpu; |
1309 | switch(action) { | 1328 | switch(action) { |
1310 | case CPU_UP_PREPARE: | 1329 | case CPU_UP_PREPARE: |
1311 | init_timers_cpu(cpu); | 1330 | if (init_timers_cpu(cpu) < 0) |
1331 | return NOTIFY_BAD; | ||
1312 | break; | 1332 | break; |
1313 | #ifdef CONFIG_HOTPLUG_CPU | 1333 | #ifdef CONFIG_HOTPLUG_CPU |
1314 | case CPU_DEAD: | 1334 | case CPU_DEAD: |
@@ -1336,8 +1356,8 @@ void __init init_timers(void) | |||
1336 | 1356 | ||
1337 | #ifdef CONFIG_TIME_INTERPOLATION | 1357 | #ifdef CONFIG_TIME_INTERPOLATION |
1338 | 1358 | ||
1339 | struct time_interpolator *time_interpolator; | 1359 | struct time_interpolator *time_interpolator __read_mostly; |
1340 | static struct time_interpolator *time_interpolator_list; | 1360 | static struct time_interpolator *time_interpolator_list __read_mostly; |
1341 | static DEFINE_SPINLOCK(time_interpolator_lock); | 1361 | static DEFINE_SPINLOCK(time_interpolator_lock); |
1342 | 1362 | ||
1343 | static inline u64 time_interpolator_get_cycles(unsigned int src) | 1363 | static inline u64 time_interpolator_get_cycles(unsigned int src) |
@@ -1351,10 +1371,10 @@ static inline u64 time_interpolator_get_cycles(unsigned int src) | |||
1351 | return x(); | 1371 | return x(); |
1352 | 1372 | ||
1353 | case TIME_SOURCE_MMIO64 : | 1373 | case TIME_SOURCE_MMIO64 : |
1354 | return readq((void __iomem *) time_interpolator->addr); | 1374 | return readq_relaxed((void __iomem *)time_interpolator->addr); |
1355 | 1375 | ||
1356 | case TIME_SOURCE_MMIO32 : | 1376 | case TIME_SOURCE_MMIO32 : |
1357 | return readl((void __iomem *) time_interpolator->addr); | 1377 | return readl_relaxed((void __iomem *)time_interpolator->addr); |
1358 | 1378 | ||
1359 | default: return get_cycles(); | 1379 | default: return get_cycles(); |
1360 | } | 1380 | } |