aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/timer.c
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/timer.c')
-rw-r--r--kernel/timer.c53
1 files changed, 27 insertions, 26 deletions
diff --git a/kernel/timer.c b/kernel/timer.c
index 1d7dd6267c2d..4f55622b0d38 100644
--- a/kernel/timer.c
+++ b/kernel/timer.c
@@ -136,7 +136,7 @@ static void internal_add_timer(tvec_base_t *base, struct timer_list *timer)
136 list_add_tail(&timer->entry, vec); 136 list_add_tail(&timer->entry, vec);
137} 137}
138 138
139/*** 139/**
140 * init_timer - initialize a timer. 140 * init_timer - initialize a timer.
141 * @timer: the timer to be initialized 141 * @timer: the timer to be initialized
142 * 142 *
@@ -175,6 +175,7 @@ static inline void detach_timer(struct timer_list *timer,
175 */ 175 */
176static tvec_base_t *lock_timer_base(struct timer_list *timer, 176static tvec_base_t *lock_timer_base(struct timer_list *timer,
177 unsigned long *flags) 177 unsigned long *flags)
178 __acquires(timer->base->lock)
178{ 179{
179 tvec_base_t *base; 180 tvec_base_t *base;
180 181
@@ -235,7 +236,7 @@ int __mod_timer(struct timer_list *timer, unsigned long expires)
235 236
236EXPORT_SYMBOL(__mod_timer); 237EXPORT_SYMBOL(__mod_timer);
237 238
238/*** 239/**
239 * add_timer_on - start a timer on a particular CPU 240 * add_timer_on - start a timer on a particular CPU
240 * @timer: the timer to be added 241 * @timer: the timer to be added
241 * @cpu: the CPU to start it on 242 * @cpu: the CPU to start it on
@@ -255,9 +256,10 @@ void add_timer_on(struct timer_list *timer, int cpu)
255} 256}
256 257
257 258
258/*** 259/**
259 * mod_timer - modify a timer's timeout 260 * mod_timer - modify a timer's timeout
260 * @timer: the timer to be modified 261 * @timer: the timer to be modified
262 * @expires: new timeout in jiffies
261 * 263 *
262 * mod_timer is a more efficient way to update the expire field of an 264 * mod_timer is a more efficient way to update the expire field of an
263 * active timer (if the timer is inactive it will be activated) 265 * active timer (if the timer is inactive it will be activated)
@@ -291,7 +293,7 @@ int mod_timer(struct timer_list *timer, unsigned long expires)
291 293
292EXPORT_SYMBOL(mod_timer); 294EXPORT_SYMBOL(mod_timer);
293 295
294/*** 296/**
295 * del_timer - deactive a timer. 297 * del_timer - deactive a timer.
296 * @timer: the timer to be deactivated 298 * @timer: the timer to be deactivated
297 * 299 *
@@ -323,7 +325,10 @@ int del_timer(struct timer_list *timer)
323EXPORT_SYMBOL(del_timer); 325EXPORT_SYMBOL(del_timer);
324 326
325#ifdef CONFIG_SMP 327#ifdef CONFIG_SMP
326/* 328/**
329 * try_to_del_timer_sync - Try to deactivate a timer
330 * @timer: timer do del
331 *
327 * This function tries to deactivate a timer. Upon successful (ret >= 0) 332 * This function tries to deactivate a timer. Upon successful (ret >= 0)
328 * exit the timer is not queued and the handler is not running on any CPU. 333 * exit the timer is not queued and the handler is not running on any CPU.
329 * 334 *
@@ -351,7 +356,7 @@ out:
351 return ret; 356 return ret;
352} 357}
353 358
354/*** 359/**
355 * del_timer_sync - deactivate a timer and wait for the handler to finish. 360 * del_timer_sync - deactivate a timer and wait for the handler to finish.
356 * @timer: the timer to be deactivated 361 * @timer: the timer to be deactivated
357 * 362 *
@@ -401,15 +406,15 @@ static int cascade(tvec_base_t *base, tvec_t *tv, int index)
401 return index; 406 return index;
402} 407}
403 408
404/*** 409#define INDEX(N) ((base->timer_jiffies >> (TVR_BITS + (N) * TVN_BITS)) & TVN_MASK)
410
411/**
405 * __run_timers - run all expired timers (if any) on this CPU. 412 * __run_timers - run all expired timers (if any) on this CPU.
406 * @base: the timer vector to be processed. 413 * @base: the timer vector to be processed.
407 * 414 *
408 * This function cascades all vectors and executes all expired timer 415 * This function cascades all vectors and executes all expired timer
409 * vectors. 416 * vectors.
410 */ 417 */
411#define INDEX(N) ((base->timer_jiffies >> (TVR_BITS + (N) * TVN_BITS)) & TVN_MASK)
412
413static inline void __run_timers(tvec_base_t *base) 418static inline void __run_timers(tvec_base_t *base)
414{ 419{
415 struct timer_list *timer; 420 struct timer_list *timer;
@@ -970,7 +975,7 @@ void __init timekeeping_init(void)
970 975
971 976
972static int timekeeping_suspended; 977static int timekeeping_suspended;
973/* 978/**
974 * timekeeping_resume - Resumes the generic timekeeping subsystem. 979 * timekeeping_resume - Resumes the generic timekeeping subsystem.
975 * @dev: unused 980 * @dev: unused
976 * 981 *
@@ -1106,7 +1111,7 @@ static void clocksource_adjust(struct clocksource *clock, s64 offset)
1106 clock->error -= (interval - offset) << (TICK_LENGTH_SHIFT - clock->shift); 1111 clock->error -= (interval - offset) << (TICK_LENGTH_SHIFT - clock->shift);
1107} 1112}
1108 1113
1109/* 1114/**
1110 * update_wall_time - Uses the current clocksource to increment the wall time 1115 * update_wall_time - Uses the current clocksource to increment the wall time
1111 * 1116 *
1112 * Called from the timer interrupt, must hold a write on xtime_lock. 1117 * Called from the timer interrupt, must hold a write on xtime_lock.
@@ -1217,10 +1222,8 @@ static inline void calc_load(unsigned long ticks)
1217 unsigned long active_tasks; /* fixed-point */ 1222 unsigned long active_tasks; /* fixed-point */
1218 static int count = LOAD_FREQ; 1223 static int count = LOAD_FREQ;
1219 1224
1220 count -= ticks; 1225 active_tasks = count_active_tasks();
1221 if (count < 0) { 1226 for (count -= ticks; count < 0; count += LOAD_FREQ) {
1222 count += LOAD_FREQ;
1223 active_tasks = count_active_tasks();
1224 CALC_LOAD(avenrun[0], EXP_1, active_tasks); 1227 CALC_LOAD(avenrun[0], EXP_1, active_tasks);
1225 CALC_LOAD(avenrun[1], EXP_5, active_tasks); 1228 CALC_LOAD(avenrun[1], EXP_5, active_tasks);
1226 CALC_LOAD(avenrun[2], EXP_15, active_tasks); 1229 CALC_LOAD(avenrun[2], EXP_15, active_tasks);
@@ -1265,11 +1268,8 @@ void run_local_timers(void)
1265 * Called by the timer interrupt. xtime_lock must already be taken 1268 * Called by the timer interrupt. xtime_lock must already be taken
1266 * by the timer IRQ! 1269 * by the timer IRQ!
1267 */ 1270 */
1268static inline void update_times(void) 1271static inline void update_times(unsigned long ticks)
1269{ 1272{
1270 unsigned long ticks;
1271
1272 ticks = jiffies - wall_jiffies;
1273 wall_jiffies += ticks; 1273 wall_jiffies += ticks;
1274 update_wall_time(); 1274 update_wall_time();
1275 calc_load(ticks); 1275 calc_load(ticks);
@@ -1281,12 +1281,10 @@ static inline void update_times(void)
1281 * jiffies is defined in the linker script... 1281 * jiffies is defined in the linker script...
1282 */ 1282 */
1283 1283
1284void do_timer(struct pt_regs *regs) 1284void do_timer(unsigned long ticks)
1285{ 1285{
1286 jiffies_64++; 1286 jiffies_64 += ticks;
1287 /* prevent loading jiffies before storing new jiffies_64 value. */ 1287 update_times(ticks);
1288 barrier();
1289 update_times();
1290} 1288}
1291 1289
1292#ifdef __ARCH_WANT_SYS_ALARM 1290#ifdef __ARCH_WANT_SYS_ALARM
@@ -1470,8 +1468,9 @@ asmlinkage long sys_gettid(void)
1470 return current->pid; 1468 return current->pid;
1471} 1469}
1472 1470
1473/* 1471/**
1474 * sys_sysinfo - fill in sysinfo struct 1472 * sys_sysinfo - fill in sysinfo struct
1473 * @info: pointer to buffer to fill
1475 */ 1474 */
1476asmlinkage long sys_sysinfo(struct sysinfo __user *info) 1475asmlinkage long sys_sysinfo(struct sysinfo __user *info)
1477{ 1476{
@@ -1688,8 +1687,10 @@ static struct notifier_block __cpuinitdata timers_nb = {
1688 1687
1689void __init init_timers(void) 1688void __init init_timers(void)
1690{ 1689{
1691 timer_cpu_notify(&timers_nb, (unsigned long)CPU_UP_PREPARE, 1690 int err = timer_cpu_notify(&timers_nb, (unsigned long)CPU_UP_PREPARE,
1692 (void *)(long)smp_processor_id()); 1691 (void *)(long)smp_processor_id());
1692
1693 BUG_ON(err == NOTIFY_BAD);
1693 register_cpu_notifier(&timers_nb); 1694 register_cpu_notifier(&timers_nb);
1694 open_softirq(TIMER_SOFTIRQ, run_timer_softirq, NULL); 1695 open_softirq(TIMER_SOFTIRQ, run_timer_softirq, NULL);
1695} 1696}