diff options
Diffstat (limited to 'kernel/timer.c')
-rw-r--r-- | kernel/timer.c | 90 |
1 files changed, 12 insertions, 78 deletions
diff --git a/kernel/timer.c b/kernel/timer.c index 3f841db5edf9..54d3912f8cad 100644 --- a/kernel/timer.c +++ b/kernel/timer.c | |||
@@ -37,6 +37,7 @@ | |||
37 | #include <linux/delay.h> | 37 | #include <linux/delay.h> |
38 | #include <linux/tick.h> | 38 | #include <linux/tick.h> |
39 | #include <linux/kallsyms.h> | 39 | #include <linux/kallsyms.h> |
40 | #include <linux/perf_counter.h> | ||
40 | #include <linux/sched.h> | 41 | #include <linux/sched.h> |
41 | 42 | ||
42 | #include <asm/uaccess.h> | 43 | #include <asm/uaccess.h> |
@@ -790,6 +791,7 @@ void add_timer_on(struct timer_list *timer, int cpu) | |||
790 | wake_up_idle_cpu(cpu); | 791 | wake_up_idle_cpu(cpu); |
791 | spin_unlock_irqrestore(&base->lock, flags); | 792 | spin_unlock_irqrestore(&base->lock, flags); |
792 | } | 793 | } |
794 | EXPORT_SYMBOL_GPL(add_timer_on); | ||
793 | 795 | ||
794 | /** | 796 | /** |
795 | * del_timer - deactive a timer. | 797 | * del_timer - deactive a timer. |
@@ -1160,53 +1162,14 @@ void update_process_times(int user_tick) | |||
1160 | } | 1162 | } |
1161 | 1163 | ||
1162 | /* | 1164 | /* |
1163 | * Nr of active tasks - counted in fixed-point numbers | ||
1164 | */ | ||
1165 | static unsigned long count_active_tasks(void) | ||
1166 | { | ||
1167 | return nr_active() * FIXED_1; | ||
1168 | } | ||
1169 | |||
1170 | /* | ||
1171 | * Hmm.. Changed this, as the GNU make sources (load.c) seems to | ||
1172 | * imply that avenrun[] is the standard name for this kind of thing. | ||
1173 | * Nothing else seems to be standardized: the fractional size etc | ||
1174 | * all seem to differ on different machines. | ||
1175 | * | ||
1176 | * Requires xtime_lock to access. | ||
1177 | */ | ||
1178 | unsigned long avenrun[3]; | ||
1179 | |||
1180 | EXPORT_SYMBOL(avenrun); | ||
1181 | |||
1182 | /* | ||
1183 | * calc_load - given tick count, update the avenrun load estimates. | ||
1184 | * This is called while holding a write_lock on xtime_lock. | ||
1185 | */ | ||
1186 | static inline void calc_load(unsigned long ticks) | ||
1187 | { | ||
1188 | unsigned long active_tasks; /* fixed-point */ | ||
1189 | static int count = LOAD_FREQ; | ||
1190 | |||
1191 | count -= ticks; | ||
1192 | if (unlikely(count < 0)) { | ||
1193 | active_tasks = count_active_tasks(); | ||
1194 | do { | ||
1195 | CALC_LOAD(avenrun[0], EXP_1, active_tasks); | ||
1196 | CALC_LOAD(avenrun[1], EXP_5, active_tasks); | ||
1197 | CALC_LOAD(avenrun[2], EXP_15, active_tasks); | ||
1198 | count += LOAD_FREQ; | ||
1199 | } while (count < 0); | ||
1200 | } | ||
1201 | } | ||
1202 | |||
1203 | /* | ||
1204 | * This function runs timers and the timer-tq in bottom half context. | 1165 | * This function runs timers and the timer-tq in bottom half context. |
1205 | */ | 1166 | */ |
1206 | static void run_timer_softirq(struct softirq_action *h) | 1167 | static void run_timer_softirq(struct softirq_action *h) |
1207 | { | 1168 | { |
1208 | struct tvec_base *base = __get_cpu_var(tvec_bases); | 1169 | struct tvec_base *base = __get_cpu_var(tvec_bases); |
1209 | 1170 | ||
1171 | perf_counter_do_pending(); | ||
1172 | |||
1210 | hrtimer_run_pending(); | 1173 | hrtimer_run_pending(); |
1211 | 1174 | ||
1212 | if (time_after_eq(jiffies, base->timer_jiffies)) | 1175 | if (time_after_eq(jiffies, base->timer_jiffies)) |
@@ -1224,16 +1187,6 @@ void run_local_timers(void) | |||
1224 | } | 1187 | } |
1225 | 1188 | ||
1226 | /* | 1189 | /* |
1227 | * Called by the timer interrupt. xtime_lock must already be taken | ||
1228 | * by the timer IRQ! | ||
1229 | */ | ||
1230 | static inline void update_times(unsigned long ticks) | ||
1231 | { | ||
1232 | update_wall_time(); | ||
1233 | calc_load(ticks); | ||
1234 | } | ||
1235 | |||
1236 | /* | ||
1237 | * The 64-bit jiffies value is not atomic - you MUST NOT read it | 1190 | * The 64-bit jiffies value is not atomic - you MUST NOT read it |
1238 | * without sampling the sequence number in xtime_lock. | 1191 | * without sampling the sequence number in xtime_lock. |
1239 | * jiffies is defined in the linker script... | 1192 | * jiffies is defined in the linker script... |
@@ -1242,7 +1195,8 @@ static inline void update_times(unsigned long ticks) | |||
1242 | void do_timer(unsigned long ticks) | 1195 | void do_timer(unsigned long ticks) |
1243 | { | 1196 | { |
1244 | jiffies_64 += ticks; | 1197 | jiffies_64 += ticks; |
1245 | update_times(ticks); | 1198 | update_wall_time(); |
1199 | calc_global_load(); | ||
1246 | } | 1200 | } |
1247 | 1201 | ||
1248 | #ifdef __ARCH_WANT_SYS_ALARM | 1202 | #ifdef __ARCH_WANT_SYS_ALARM |
@@ -1443,37 +1397,17 @@ int do_sysinfo(struct sysinfo *info) | |||
1443 | { | 1397 | { |
1444 | unsigned long mem_total, sav_total; | 1398 | unsigned long mem_total, sav_total; |
1445 | unsigned int mem_unit, bitcount; | 1399 | unsigned int mem_unit, bitcount; |
1446 | unsigned long seq; | 1400 | struct timespec tp; |
1447 | 1401 | ||
1448 | memset(info, 0, sizeof(struct sysinfo)); | 1402 | memset(info, 0, sizeof(struct sysinfo)); |
1449 | 1403 | ||
1450 | do { | 1404 | ktime_get_ts(&tp); |
1451 | struct timespec tp; | 1405 | monotonic_to_bootbased(&tp); |
1452 | seq = read_seqbegin(&xtime_lock); | 1406 | info->uptime = tp.tv_sec + (tp.tv_nsec ? 1 : 0); |
1453 | |||
1454 | /* | ||
1455 | * This is annoying. The below is the same thing | ||
1456 | * posix_get_clock_monotonic() does, but it wants to | ||
1457 | * take the lock which we want to cover the loads stuff | ||
1458 | * too. | ||
1459 | */ | ||
1460 | |||
1461 | getnstimeofday(&tp); | ||
1462 | tp.tv_sec += wall_to_monotonic.tv_sec; | ||
1463 | tp.tv_nsec += wall_to_monotonic.tv_nsec; | ||
1464 | monotonic_to_bootbased(&tp); | ||
1465 | if (tp.tv_nsec - NSEC_PER_SEC >= 0) { | ||
1466 | tp.tv_nsec = tp.tv_nsec - NSEC_PER_SEC; | ||
1467 | tp.tv_sec++; | ||
1468 | } | ||
1469 | info->uptime = tp.tv_sec + (tp.tv_nsec ? 1 : 0); | ||
1470 | 1407 | ||
1471 | info->loads[0] = avenrun[0] << (SI_LOAD_SHIFT - FSHIFT); | 1408 | get_avenrun(info->loads, 0, SI_LOAD_SHIFT - FSHIFT); |
1472 | info->loads[1] = avenrun[1] << (SI_LOAD_SHIFT - FSHIFT); | ||
1473 | info->loads[2] = avenrun[2] << (SI_LOAD_SHIFT - FSHIFT); | ||
1474 | 1409 | ||
1475 | info->procs = nr_threads; | 1410 | info->procs = nr_threads; |
1476 | } while (read_seqretry(&xtime_lock, seq)); | ||
1477 | 1411 | ||
1478 | si_meminfo(info); | 1412 | si_meminfo(info); |
1479 | si_swapinfo(info); | 1413 | si_swapinfo(info); |