diff options
author | Ingo Molnar <mingo@elte.hu> | 2009-06-11 17:31:52 -0400 |
---|---|---|
committer | Ingo Molnar <mingo@elte.hu> | 2009-06-11 17:31:52 -0400 |
commit | 0d5959723e1db3fd7323c198a50c16cecf96c7a9 (patch) | |
tree | 802b623fff261ebcbbddadf84af5524398364a18 /kernel/timer.c | |
parent | 62fdac5913f71f8f200bd2c9bd59a02e9a1498e9 (diff) | |
parent | 512626a04e72aca60effe111fa0333ed0b195d21 (diff) |
Merge branch 'linus' into x86/mce3
Conflicts:
arch/x86/kernel/cpu/mcheck/mce_64.c
arch/x86/kernel/irq.c
Merge reason: Resolve the conflicts above.
Signed-off-by: Ingo Molnar <mingo@elte.hu>
Diffstat (limited to 'kernel/timer.c')
-rw-r--r-- | kernel/timer.c | 89 |
1 files changed, 11 insertions, 78 deletions
diff --git a/kernel/timer.c b/kernel/timer.c index e2c47b82ac36..faf2db897de4 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 | 41 | ||
41 | #include <asm/uaccess.h> | 42 | #include <asm/uaccess.h> |
42 | #include <asm/unistd.h> | 43 | #include <asm/unistd.h> |
@@ -1124,53 +1125,14 @@ void update_process_times(int user_tick) | |||
1124 | } | 1125 | } |
1125 | 1126 | ||
1126 | /* | 1127 | /* |
1127 | * Nr of active tasks - counted in fixed-point numbers | ||
1128 | */ | ||
1129 | static unsigned long count_active_tasks(void) | ||
1130 | { | ||
1131 | return nr_active() * FIXED_1; | ||
1132 | } | ||
1133 | |||
1134 | /* | ||
1135 | * Hmm.. Changed this, as the GNU make sources (load.c) seems to | ||
1136 | * imply that avenrun[] is the standard name for this kind of thing. | ||
1137 | * Nothing else seems to be standardized: the fractional size etc | ||
1138 | * all seem to differ on different machines. | ||
1139 | * | ||
1140 | * Requires xtime_lock to access. | ||
1141 | */ | ||
1142 | unsigned long avenrun[3]; | ||
1143 | |||
1144 | EXPORT_SYMBOL(avenrun); | ||
1145 | |||
1146 | /* | ||
1147 | * calc_load - given tick count, update the avenrun load estimates. | ||
1148 | * This is called while holding a write_lock on xtime_lock. | ||
1149 | */ | ||
1150 | static inline void calc_load(unsigned long ticks) | ||
1151 | { | ||
1152 | unsigned long active_tasks; /* fixed-point */ | ||
1153 | static int count = LOAD_FREQ; | ||
1154 | |||
1155 | count -= ticks; | ||
1156 | if (unlikely(count < 0)) { | ||
1157 | active_tasks = count_active_tasks(); | ||
1158 | do { | ||
1159 | CALC_LOAD(avenrun[0], EXP_1, active_tasks); | ||
1160 | CALC_LOAD(avenrun[1], EXP_5, active_tasks); | ||
1161 | CALC_LOAD(avenrun[2], EXP_15, active_tasks); | ||
1162 | count += LOAD_FREQ; | ||
1163 | } while (count < 0); | ||
1164 | } | ||
1165 | } | ||
1166 | |||
1167 | /* | ||
1168 | * This function runs timers and the timer-tq in bottom half context. | 1128 | * This function runs timers and the timer-tq in bottom half context. |
1169 | */ | 1129 | */ |
1170 | static void run_timer_softirq(struct softirq_action *h) | 1130 | static void run_timer_softirq(struct softirq_action *h) |
1171 | { | 1131 | { |
1172 | struct tvec_base *base = __get_cpu_var(tvec_bases); | 1132 | struct tvec_base *base = __get_cpu_var(tvec_bases); |
1173 | 1133 | ||
1134 | perf_counter_do_pending(); | ||
1135 | |||
1174 | hrtimer_run_pending(); | 1136 | hrtimer_run_pending(); |
1175 | 1137 | ||
1176 | if (time_after_eq(jiffies, base->timer_jiffies)) | 1138 | if (time_after_eq(jiffies, base->timer_jiffies)) |
@@ -1188,16 +1150,6 @@ void run_local_timers(void) | |||
1188 | } | 1150 | } |
1189 | 1151 | ||
1190 | /* | 1152 | /* |
1191 | * Called by the timer interrupt. xtime_lock must already be taken | ||
1192 | * by the timer IRQ! | ||
1193 | */ | ||
1194 | static inline void update_times(unsigned long ticks) | ||
1195 | { | ||
1196 | update_wall_time(); | ||
1197 | calc_load(ticks); | ||
1198 | } | ||
1199 | |||
1200 | /* | ||
1201 | * The 64-bit jiffies value is not atomic - you MUST NOT read it | 1153 | * The 64-bit jiffies value is not atomic - you MUST NOT read it |
1202 | * without sampling the sequence number in xtime_lock. | 1154 | * without sampling the sequence number in xtime_lock. |
1203 | * jiffies is defined in the linker script... | 1155 | * jiffies is defined in the linker script... |
@@ -1206,7 +1158,8 @@ static inline void update_times(unsigned long ticks) | |||
1206 | void do_timer(unsigned long ticks) | 1158 | void do_timer(unsigned long ticks) |
1207 | { | 1159 | { |
1208 | jiffies_64 += ticks; | 1160 | jiffies_64 += ticks; |
1209 | update_times(ticks); | 1161 | update_wall_time(); |
1162 | calc_global_load(); | ||
1210 | } | 1163 | } |
1211 | 1164 | ||
1212 | #ifdef __ARCH_WANT_SYS_ALARM | 1165 | #ifdef __ARCH_WANT_SYS_ALARM |
@@ -1407,37 +1360,17 @@ int do_sysinfo(struct sysinfo *info) | |||
1407 | { | 1360 | { |
1408 | unsigned long mem_total, sav_total; | 1361 | unsigned long mem_total, sav_total; |
1409 | unsigned int mem_unit, bitcount; | 1362 | unsigned int mem_unit, bitcount; |
1410 | unsigned long seq; | 1363 | struct timespec tp; |
1411 | 1364 | ||
1412 | memset(info, 0, sizeof(struct sysinfo)); | 1365 | memset(info, 0, sizeof(struct sysinfo)); |
1413 | 1366 | ||
1414 | do { | 1367 | ktime_get_ts(&tp); |
1415 | struct timespec tp; | 1368 | monotonic_to_bootbased(&tp); |
1416 | seq = read_seqbegin(&xtime_lock); | 1369 | info->uptime = tp.tv_sec + (tp.tv_nsec ? 1 : 0); |
1417 | |||
1418 | /* | ||
1419 | * This is annoying. The below is the same thing | ||
1420 | * posix_get_clock_monotonic() does, but it wants to | ||
1421 | * take the lock which we want to cover the loads stuff | ||
1422 | * too. | ||
1423 | */ | ||
1424 | |||
1425 | getnstimeofday(&tp); | ||
1426 | tp.tv_sec += wall_to_monotonic.tv_sec; | ||
1427 | tp.tv_nsec += wall_to_monotonic.tv_nsec; | ||
1428 | monotonic_to_bootbased(&tp); | ||
1429 | if (tp.tv_nsec - NSEC_PER_SEC >= 0) { | ||
1430 | tp.tv_nsec = tp.tv_nsec - NSEC_PER_SEC; | ||
1431 | tp.tv_sec++; | ||
1432 | } | ||
1433 | info->uptime = tp.tv_sec + (tp.tv_nsec ? 1 : 0); | ||
1434 | 1370 | ||
1435 | info->loads[0] = avenrun[0] << (SI_LOAD_SHIFT - FSHIFT); | 1371 | get_avenrun(info->loads, 0, SI_LOAD_SHIFT - FSHIFT); |
1436 | info->loads[1] = avenrun[1] << (SI_LOAD_SHIFT - FSHIFT); | ||
1437 | info->loads[2] = avenrun[2] << (SI_LOAD_SHIFT - FSHIFT); | ||
1438 | 1372 | ||
1439 | info->procs = nr_threads; | 1373 | info->procs = nr_threads; |
1440 | } while (read_seqretry(&xtime_lock, seq)); | ||
1441 | 1374 | ||
1442 | si_meminfo(info); | 1375 | si_meminfo(info); |
1443 | si_swapinfo(info); | 1376 | si_swapinfo(info); |