diff options
Diffstat (limited to 'kernel')
-rw-r--r-- | kernel/Makefile | 2 | ||||
-rw-r--r-- | kernel/backtracetest.c | 48 | ||||
-rw-r--r-- | kernel/fork.c | 1 | ||||
-rw-r--r-- | kernel/irq/manage.c | 3 | ||||
-rw-r--r-- | kernel/irq/proc.c | 21 | ||||
-rw-r--r-- | kernel/irq/spurious.c | 5 | ||||
-rw-r--r-- | kernel/kprobes.c | 2 | ||||
-rw-r--r-- | kernel/module.c | 8 | ||||
-rw-r--r-- | kernel/panic.c | 29 | ||||
-rw-r--r-- | kernel/printk.c | 7 | ||||
-rw-r--r-- | kernel/ptrace.c | 165 | ||||
-rw-r--r-- | kernel/sched.c | 16 | ||||
-rw-r--r-- | kernel/signal.c | 4 | ||||
-rw-r--r-- | kernel/softirq.c | 11 | ||||
-rw-r--r-- | kernel/spinlock.c | 3 | ||||
-rw-r--r-- | kernel/sysctl.c | 9 | ||||
-rw-r--r-- | kernel/test_kprobes.c | 216 | ||||
-rw-r--r-- | kernel/time/clockevents.c | 13 | ||||
-rw-r--r-- | kernel/time/clocksource.c | 31 | ||||
-rw-r--r-- | kernel/time/tick-broadcast.c | 7 | ||||
-rw-r--r-- | kernel/time/tick-internal.h | 2 | ||||
-rw-r--r-- | kernel/time/tick-sched.c | 76 | ||||
-rw-r--r-- | kernel/time/timekeeping.c | 28 | ||||
-rw-r--r-- | kernel/time/timer_stats.c | 2 | ||||
-rw-r--r-- | kernel/timer.c | 82 |
25 files changed, 671 insertions, 120 deletions
diff --git a/kernel/Makefile b/kernel/Makefile index 390d42146267..8885627ea021 100644 --- a/kernel/Makefile +++ b/kernel/Makefile | |||
@@ -36,6 +36,7 @@ obj-$(CONFIG_KALLSYMS) += kallsyms.o | |||
36 | obj-$(CONFIG_PM) += power/ | 36 | obj-$(CONFIG_PM) += power/ |
37 | obj-$(CONFIG_BSD_PROCESS_ACCT) += acct.o | 37 | obj-$(CONFIG_BSD_PROCESS_ACCT) += acct.o |
38 | obj-$(CONFIG_KEXEC) += kexec.o | 38 | obj-$(CONFIG_KEXEC) += kexec.o |
39 | obj-$(CONFIG_BACKTRACE_SELF_TEST) += backtracetest.o | ||
39 | obj-$(CONFIG_COMPAT) += compat.o | 40 | obj-$(CONFIG_COMPAT) += compat.o |
40 | obj-$(CONFIG_CGROUPS) += cgroup.o | 41 | obj-$(CONFIG_CGROUPS) += cgroup.o |
41 | obj-$(CONFIG_CGROUP_DEBUG) += cgroup_debug.o | 42 | obj-$(CONFIG_CGROUP_DEBUG) += cgroup_debug.o |
@@ -43,6 +44,7 @@ obj-$(CONFIG_CPUSETS) += cpuset.o | |||
43 | obj-$(CONFIG_CGROUP_NS) += ns_cgroup.o | 44 | obj-$(CONFIG_CGROUP_NS) += ns_cgroup.o |
44 | obj-$(CONFIG_IKCONFIG) += configs.o | 45 | obj-$(CONFIG_IKCONFIG) += configs.o |
45 | obj-$(CONFIG_STOP_MACHINE) += stop_machine.o | 46 | obj-$(CONFIG_STOP_MACHINE) += stop_machine.o |
47 | obj-$(CONFIG_KPROBES_SANITY_TEST) += test_kprobes.o | ||
46 | obj-$(CONFIG_AUDIT) += audit.o auditfilter.o | 48 | obj-$(CONFIG_AUDIT) += audit.o auditfilter.o |
47 | obj-$(CONFIG_AUDITSYSCALL) += auditsc.o | 49 | obj-$(CONFIG_AUDITSYSCALL) += auditsc.o |
48 | obj-$(CONFIG_AUDIT_TREE) += audit_tree.o | 50 | obj-$(CONFIG_AUDIT_TREE) += audit_tree.o |
diff --git a/kernel/backtracetest.c b/kernel/backtracetest.c new file mode 100644 index 000000000000..d1a7605c5b8f --- /dev/null +++ b/kernel/backtracetest.c | |||
@@ -0,0 +1,48 @@ | |||
1 | /* | ||
2 | * Simple stack backtrace regression test module | ||
3 | * | ||
4 | * (C) Copyright 2008 Intel Corporation | ||
5 | * Author: Arjan van de Ven <arjan@linux.intel.com> | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or | ||
8 | * modify it under the terms of the GNU General Public License | ||
9 | * as published by the Free Software Foundation; version 2 | ||
10 | * of the License. | ||
11 | */ | ||
12 | |||
13 | #include <linux/module.h> | ||
14 | #include <linux/sched.h> | ||
15 | #include <linux/delay.h> | ||
16 | |||
17 | static struct timer_list backtrace_timer; | ||
18 | |||
19 | static void backtrace_test_timer(unsigned long data) | ||
20 | { | ||
21 | printk("Testing a backtrace from irq context.\n"); | ||
22 | printk("The following trace is a kernel self test and not a bug!\n"); | ||
23 | dump_stack(); | ||
24 | } | ||
25 | static int backtrace_regression_test(void) | ||
26 | { | ||
27 | printk("====[ backtrace testing ]===========\n"); | ||
28 | printk("Testing a backtrace from process context.\n"); | ||
29 | printk("The following trace is a kernel self test and not a bug!\n"); | ||
30 | dump_stack(); | ||
31 | |||
32 | init_timer(&backtrace_timer); | ||
33 | backtrace_timer.function = backtrace_test_timer; | ||
34 | mod_timer(&backtrace_timer, jiffies + 10); | ||
35 | |||
36 | msleep(10); | ||
37 | printk("====[ end of backtrace testing ]====\n"); | ||
38 | return 0; | ||
39 | } | ||
40 | |||
41 | static void exitf(void) | ||
42 | { | ||
43 | } | ||
44 | |||
45 | module_init(backtrace_regression_test); | ||
46 | module_exit(exitf); | ||
47 | MODULE_LICENSE("GPL"); | ||
48 | MODULE_AUTHOR("Arjan van de Ven <arjan@linux.intel.com>"); | ||
diff --git a/kernel/fork.c b/kernel/fork.c index 314f5101d2b0..05e0b6f4365b 100644 --- a/kernel/fork.c +++ b/kernel/fork.c | |||
@@ -393,6 +393,7 @@ void fastcall __mmdrop(struct mm_struct *mm) | |||
393 | destroy_context(mm); | 393 | destroy_context(mm); |
394 | free_mm(mm); | 394 | free_mm(mm); |
395 | } | 395 | } |
396 | EXPORT_SYMBOL_GPL(__mmdrop); | ||
396 | 397 | ||
397 | /* | 398 | /* |
398 | * Decrement the use count and release all resources for an mm. | 399 | * Decrement the use count and release all resources for an mm. |
diff --git a/kernel/irq/manage.c b/kernel/irq/manage.c index 1f314221d534..438a01464287 100644 --- a/kernel/irq/manage.c +++ b/kernel/irq/manage.c | |||
@@ -479,6 +479,9 @@ void free_irq(unsigned int irq, void *dev_id) | |||
479 | return; | 479 | return; |
480 | } | 480 | } |
481 | printk(KERN_ERR "Trying to free already-free IRQ %d\n", irq); | 481 | printk(KERN_ERR "Trying to free already-free IRQ %d\n", irq); |
482 | #ifdef CONFIG_DEBUG_SHIRQ | ||
483 | dump_stack(); | ||
484 | #endif | ||
482 | spin_unlock_irqrestore(&desc->lock, flags); | 485 | spin_unlock_irqrestore(&desc->lock, flags); |
483 | return; | 486 | return; |
484 | } | 487 | } |
diff --git a/kernel/irq/proc.c b/kernel/irq/proc.c index 50b81b98046a..c2f2ccb0549a 100644 --- a/kernel/irq/proc.c +++ b/kernel/irq/proc.c | |||
@@ -75,6 +75,18 @@ static int irq_affinity_write_proc(struct file *file, const char __user *buffer, | |||
75 | 75 | ||
76 | #endif | 76 | #endif |
77 | 77 | ||
78 | static int irq_spurious_read(char *page, char **start, off_t off, | ||
79 | int count, int *eof, void *data) | ||
80 | { | ||
81 | struct irq_desc *d = &irq_desc[(long) data]; | ||
82 | return sprintf(page, "count %u\n" | ||
83 | "unhandled %u\n" | ||
84 | "last_unhandled %u ms\n", | ||
85 | d->irq_count, | ||
86 | d->irqs_unhandled, | ||
87 | jiffies_to_msecs(d->last_unhandled)); | ||
88 | } | ||
89 | |||
78 | #define MAX_NAMELEN 128 | 90 | #define MAX_NAMELEN 128 |
79 | 91 | ||
80 | static int name_unique(unsigned int irq, struct irqaction *new_action) | 92 | static int name_unique(unsigned int irq, struct irqaction *new_action) |
@@ -118,6 +130,7 @@ void register_handler_proc(unsigned int irq, struct irqaction *action) | |||
118 | void register_irq_proc(unsigned int irq) | 130 | void register_irq_proc(unsigned int irq) |
119 | { | 131 | { |
120 | char name [MAX_NAMELEN]; | 132 | char name [MAX_NAMELEN]; |
133 | struct proc_dir_entry *entry; | ||
121 | 134 | ||
122 | if (!root_irq_dir || | 135 | if (!root_irq_dir || |
123 | (irq_desc[irq].chip == &no_irq_chip) || | 136 | (irq_desc[irq].chip == &no_irq_chip) || |
@@ -132,8 +145,6 @@ void register_irq_proc(unsigned int irq) | |||
132 | 145 | ||
133 | #ifdef CONFIG_SMP | 146 | #ifdef CONFIG_SMP |
134 | { | 147 | { |
135 | struct proc_dir_entry *entry; | ||
136 | |||
137 | /* create /proc/irq/<irq>/smp_affinity */ | 148 | /* create /proc/irq/<irq>/smp_affinity */ |
138 | entry = create_proc_entry("smp_affinity", 0600, irq_desc[irq].dir); | 149 | entry = create_proc_entry("smp_affinity", 0600, irq_desc[irq].dir); |
139 | 150 | ||
@@ -144,6 +155,12 @@ void register_irq_proc(unsigned int irq) | |||
144 | } | 155 | } |
145 | } | 156 | } |
146 | #endif | 157 | #endif |
158 | |||
159 | entry = create_proc_entry("spurious", 0444, irq_desc[irq].dir); | ||
160 | if (entry) { | ||
161 | entry->data = (void *)(long)irq; | ||
162 | entry->read_proc = irq_spurious_read; | ||
163 | } | ||
147 | } | 164 | } |
148 | 165 | ||
149 | #undef MAX_NAMELEN | 166 | #undef MAX_NAMELEN |
diff --git a/kernel/irq/spurious.c b/kernel/irq/spurious.c index 32b161972fad..a6b2bc831dd0 100644 --- a/kernel/irq/spurious.c +++ b/kernel/irq/spurious.c | |||
@@ -10,6 +10,7 @@ | |||
10 | #include <linux/module.h> | 10 | #include <linux/module.h> |
11 | #include <linux/kallsyms.h> | 11 | #include <linux/kallsyms.h> |
12 | #include <linux/interrupt.h> | 12 | #include <linux/interrupt.h> |
13 | #include <linux/moduleparam.h> | ||
13 | 14 | ||
14 | static int irqfixup __read_mostly; | 15 | static int irqfixup __read_mostly; |
15 | 16 | ||
@@ -225,6 +226,8 @@ int noirqdebug_setup(char *str) | |||
225 | } | 226 | } |
226 | 227 | ||
227 | __setup("noirqdebug", noirqdebug_setup); | 228 | __setup("noirqdebug", noirqdebug_setup); |
229 | module_param(noirqdebug, bool, 0644); | ||
230 | MODULE_PARM_DESC(noirqdebug, "Disable irq lockup detection when true"); | ||
228 | 231 | ||
229 | static int __init irqfixup_setup(char *str) | 232 | static int __init irqfixup_setup(char *str) |
230 | { | 233 | { |
@@ -236,6 +239,8 @@ static int __init irqfixup_setup(char *str) | |||
236 | } | 239 | } |
237 | 240 | ||
238 | __setup("irqfixup", irqfixup_setup); | 241 | __setup("irqfixup", irqfixup_setup); |
242 | module_param(irqfixup, int, 0644); | ||
243 | MODULE_PARM_DESC("irqfixup", "0: No fixup, 1: irqfixup mode 2: irqpoll mode"); | ||
239 | 244 | ||
240 | static int __init irqpoll_setup(char *str) | 245 | static int __init irqpoll_setup(char *str) |
241 | { | 246 | { |
diff --git a/kernel/kprobes.c b/kernel/kprobes.c index e3a5d817ac9b..d0493eafea3e 100644 --- a/kernel/kprobes.c +++ b/kernel/kprobes.c | |||
@@ -824,6 +824,8 @@ static int __init init_kprobes(void) | |||
824 | if (!err) | 824 | if (!err) |
825 | err = register_die_notifier(&kprobe_exceptions_nb); | 825 | err = register_die_notifier(&kprobe_exceptions_nb); |
826 | 826 | ||
827 | if (!err) | ||
828 | init_test_probes(); | ||
827 | return err; | 829 | return err; |
828 | } | 830 | } |
829 | 831 | ||
diff --git a/kernel/module.c b/kernel/module.c index f6a4e721fd49..bd60278ee703 100644 --- a/kernel/module.c +++ b/kernel/module.c | |||
@@ -430,6 +430,14 @@ static unsigned int find_pcpusec(Elf_Ehdr *hdr, | |||
430 | return find_sec(hdr, sechdrs, secstrings, ".data.percpu"); | 430 | return find_sec(hdr, sechdrs, secstrings, ".data.percpu"); |
431 | } | 431 | } |
432 | 432 | ||
433 | static void percpu_modcopy(void *pcpudest, const void *from, unsigned long size) | ||
434 | { | ||
435 | int cpu; | ||
436 | |||
437 | for_each_possible_cpu(cpu) | ||
438 | memcpy(pcpudest + per_cpu_offset(cpu), from, size); | ||
439 | } | ||
440 | |||
433 | static int percpu_modinit(void) | 441 | static int percpu_modinit(void) |
434 | { | 442 | { |
435 | pcpu_num_used = 2; | 443 | pcpu_num_used = 2; |
diff --git a/kernel/panic.c b/kernel/panic.c index da4d6bac270e..d9e90cfe3298 100644 --- a/kernel/panic.c +++ b/kernel/panic.c | |||
@@ -20,6 +20,7 @@ | |||
20 | #include <linux/kexec.h> | 20 | #include <linux/kexec.h> |
21 | #include <linux/debug_locks.h> | 21 | #include <linux/debug_locks.h> |
22 | #include <linux/random.h> | 22 | #include <linux/random.h> |
23 | #include <linux/kallsyms.h> | ||
23 | 24 | ||
24 | int panic_on_oops; | 25 | int panic_on_oops; |
25 | int tainted; | 26 | int tainted; |
@@ -280,6 +281,13 @@ static int init_oops_id(void) | |||
280 | } | 281 | } |
281 | late_initcall(init_oops_id); | 282 | late_initcall(init_oops_id); |
282 | 283 | ||
284 | static void print_oops_end_marker(void) | ||
285 | { | ||
286 | init_oops_id(); | ||
287 | printk(KERN_WARNING "---[ end trace %016llx ]---\n", | ||
288 | (unsigned long long)oops_id); | ||
289 | } | ||
290 | |||
283 | /* | 291 | /* |
284 | * Called when the architecture exits its oops handler, after printing | 292 | * Called when the architecture exits its oops handler, after printing |
285 | * everything. | 293 | * everything. |
@@ -287,11 +295,26 @@ late_initcall(init_oops_id); | |||
287 | void oops_exit(void) | 295 | void oops_exit(void) |
288 | { | 296 | { |
289 | do_oops_enter_exit(); | 297 | do_oops_enter_exit(); |
290 | init_oops_id(); | 298 | print_oops_end_marker(); |
291 | printk(KERN_WARNING "---[ end trace %016llx ]---\n", | ||
292 | (unsigned long long)oops_id); | ||
293 | } | 299 | } |
294 | 300 | ||
301 | #ifdef WANT_WARN_ON_SLOWPATH | ||
302 | void warn_on_slowpath(const char *file, int line) | ||
303 | { | ||
304 | char function[KSYM_SYMBOL_LEN]; | ||
305 | unsigned long caller = (unsigned long) __builtin_return_address(0); | ||
306 | sprint_symbol(function, caller); | ||
307 | |||
308 | printk(KERN_WARNING "------------[ cut here ]------------\n"); | ||
309 | printk(KERN_WARNING "WARNING: at %s:%d %s()\n", file, | ||
310 | line, function); | ||
311 | print_modules(); | ||
312 | dump_stack(); | ||
313 | print_oops_end_marker(); | ||
314 | } | ||
315 | EXPORT_SYMBOL(warn_on_slowpath); | ||
316 | #endif | ||
317 | |||
295 | #ifdef CONFIG_CC_STACKPROTECTOR | 318 | #ifdef CONFIG_CC_STACKPROTECTOR |
296 | /* | 319 | /* |
297 | * Called when gcc's -fstack-protector feature is used, and | 320 | * Called when gcc's -fstack-protector feature is used, and |
diff --git a/kernel/printk.c b/kernel/printk.c index 3b7c968d0ef9..58bbec684119 100644 --- a/kernel/printk.c +++ b/kernel/printk.c | |||
@@ -36,6 +36,13 @@ | |||
36 | 36 | ||
37 | #include <asm/uaccess.h> | 37 | #include <asm/uaccess.h> |
38 | 38 | ||
39 | /* | ||
40 | * Architectures can override it: | ||
41 | */ | ||
42 | void __attribute__((weak)) early_printk(const char *fmt, ...) | ||
43 | { | ||
44 | } | ||
45 | |||
39 | #define __LOG_BUF_LEN (1 << CONFIG_LOG_BUF_SHIFT) | 46 | #define __LOG_BUF_LEN (1 << CONFIG_LOG_BUF_SHIFT) |
40 | 47 | ||
41 | /* printk's without a loglevel use this.. */ | 48 | /* printk's without a loglevel use this.. */ |
diff --git a/kernel/ptrace.c b/kernel/ptrace.c index c719bb9d79ab..e6e9b8be4b05 100644 --- a/kernel/ptrace.c +++ b/kernel/ptrace.c | |||
@@ -366,12 +366,73 @@ static int ptrace_setsiginfo(struct task_struct *child, siginfo_t __user * data) | |||
366 | return error; | 366 | return error; |
367 | } | 367 | } |
368 | 368 | ||
369 | |||
370 | #ifdef PTRACE_SINGLESTEP | ||
371 | #define is_singlestep(request) ((request) == PTRACE_SINGLESTEP) | ||
372 | #else | ||
373 | #define is_singlestep(request) 0 | ||
374 | #endif | ||
375 | |||
376 | #ifdef PTRACE_SINGLEBLOCK | ||
377 | #define is_singleblock(request) ((request) == PTRACE_SINGLEBLOCK) | ||
378 | #else | ||
379 | #define is_singleblock(request) 0 | ||
380 | #endif | ||
381 | |||
382 | #ifdef PTRACE_SYSEMU | ||
383 | #define is_sysemu_singlestep(request) ((request) == PTRACE_SYSEMU_SINGLESTEP) | ||
384 | #else | ||
385 | #define is_sysemu_singlestep(request) 0 | ||
386 | #endif | ||
387 | |||
388 | static int ptrace_resume(struct task_struct *child, long request, long data) | ||
389 | { | ||
390 | if (!valid_signal(data)) | ||
391 | return -EIO; | ||
392 | |||
393 | if (request == PTRACE_SYSCALL) | ||
394 | set_tsk_thread_flag(child, TIF_SYSCALL_TRACE); | ||
395 | else | ||
396 | clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE); | ||
397 | |||
398 | #ifdef TIF_SYSCALL_EMU | ||
399 | if (request == PTRACE_SYSEMU || request == PTRACE_SYSEMU_SINGLESTEP) | ||
400 | set_tsk_thread_flag(child, TIF_SYSCALL_EMU); | ||
401 | else | ||
402 | clear_tsk_thread_flag(child, TIF_SYSCALL_EMU); | ||
403 | #endif | ||
404 | |||
405 | if (is_singleblock(request)) { | ||
406 | if (unlikely(!arch_has_block_step())) | ||
407 | return -EIO; | ||
408 | user_enable_block_step(child); | ||
409 | } else if (is_singlestep(request) || is_sysemu_singlestep(request)) { | ||
410 | if (unlikely(!arch_has_single_step())) | ||
411 | return -EIO; | ||
412 | user_enable_single_step(child); | ||
413 | } | ||
414 | else | ||
415 | user_disable_single_step(child); | ||
416 | |||
417 | child->exit_code = data; | ||
418 | wake_up_process(child); | ||
419 | |||
420 | return 0; | ||
421 | } | ||
422 | |||
369 | int ptrace_request(struct task_struct *child, long request, | 423 | int ptrace_request(struct task_struct *child, long request, |
370 | long addr, long data) | 424 | long addr, long data) |
371 | { | 425 | { |
372 | int ret = -EIO; | 426 | int ret = -EIO; |
373 | 427 | ||
374 | switch (request) { | 428 | switch (request) { |
429 | case PTRACE_PEEKTEXT: | ||
430 | case PTRACE_PEEKDATA: | ||
431 | return generic_ptrace_peekdata(child, addr, data); | ||
432 | case PTRACE_POKETEXT: | ||
433 | case PTRACE_POKEDATA: | ||
434 | return generic_ptrace_pokedata(child, addr, data); | ||
435 | |||
375 | #ifdef PTRACE_OLDSETOPTIONS | 436 | #ifdef PTRACE_OLDSETOPTIONS |
376 | case PTRACE_OLDSETOPTIONS: | 437 | case PTRACE_OLDSETOPTIONS: |
377 | #endif | 438 | #endif |
@@ -390,6 +451,26 @@ int ptrace_request(struct task_struct *child, long request, | |||
390 | case PTRACE_DETACH: /* detach a process that was attached. */ | 451 | case PTRACE_DETACH: /* detach a process that was attached. */ |
391 | ret = ptrace_detach(child, data); | 452 | ret = ptrace_detach(child, data); |
392 | break; | 453 | break; |
454 | |||
455 | #ifdef PTRACE_SINGLESTEP | ||
456 | case PTRACE_SINGLESTEP: | ||
457 | #endif | ||
458 | #ifdef PTRACE_SINGLEBLOCK | ||
459 | case PTRACE_SINGLEBLOCK: | ||
460 | #endif | ||
461 | #ifdef PTRACE_SYSEMU | ||
462 | case PTRACE_SYSEMU: | ||
463 | case PTRACE_SYSEMU_SINGLESTEP: | ||
464 | #endif | ||
465 | case PTRACE_SYSCALL: | ||
466 | case PTRACE_CONT: | ||
467 | return ptrace_resume(child, request, data); | ||
468 | |||
469 | case PTRACE_KILL: | ||
470 | if (child->exit_state) /* already dead */ | ||
471 | return 0; | ||
472 | return ptrace_resume(child, request, SIGKILL); | ||
473 | |||
393 | default: | 474 | default: |
394 | break; | 475 | break; |
395 | } | 476 | } |
@@ -526,3 +607,87 @@ int generic_ptrace_pokedata(struct task_struct *tsk, long addr, long data) | |||
526 | copied = access_process_vm(tsk, addr, &data, sizeof(data), 1); | 607 | copied = access_process_vm(tsk, addr, &data, sizeof(data), 1); |
527 | return (copied == sizeof(data)) ? 0 : -EIO; | 608 | return (copied == sizeof(data)) ? 0 : -EIO; |
528 | } | 609 | } |
610 | |||
611 | #ifdef CONFIG_COMPAT | ||
612 | #include <linux/compat.h> | ||
613 | |||
614 | int compat_ptrace_request(struct task_struct *child, compat_long_t request, | ||
615 | compat_ulong_t addr, compat_ulong_t data) | ||
616 | { | ||
617 | compat_ulong_t __user *datap = compat_ptr(data); | ||
618 | compat_ulong_t word; | ||
619 | int ret; | ||
620 | |||
621 | switch (request) { | ||
622 | case PTRACE_PEEKTEXT: | ||
623 | case PTRACE_PEEKDATA: | ||
624 | ret = access_process_vm(child, addr, &word, sizeof(word), 0); | ||
625 | if (ret != sizeof(word)) | ||
626 | ret = -EIO; | ||
627 | else | ||
628 | ret = put_user(word, datap); | ||
629 | break; | ||
630 | |||
631 | case PTRACE_POKETEXT: | ||
632 | case PTRACE_POKEDATA: | ||
633 | ret = access_process_vm(child, addr, &data, sizeof(data), 1); | ||
634 | ret = (ret != sizeof(data) ? -EIO : 0); | ||
635 | break; | ||
636 | |||
637 | case PTRACE_GETEVENTMSG: | ||
638 | ret = put_user((compat_ulong_t) child->ptrace_message, datap); | ||
639 | break; | ||
640 | |||
641 | default: | ||
642 | ret = ptrace_request(child, request, addr, data); | ||
643 | } | ||
644 | |||
645 | return ret; | ||
646 | } | ||
647 | |||
648 | #ifdef __ARCH_WANT_COMPAT_SYS_PTRACE | ||
649 | asmlinkage long compat_sys_ptrace(compat_long_t request, compat_long_t pid, | ||
650 | compat_long_t addr, compat_long_t data) | ||
651 | { | ||
652 | struct task_struct *child; | ||
653 | long ret; | ||
654 | |||
655 | /* | ||
656 | * This lock_kernel fixes a subtle race with suid exec | ||
657 | */ | ||
658 | lock_kernel(); | ||
659 | if (request == PTRACE_TRACEME) { | ||
660 | ret = ptrace_traceme(); | ||
661 | goto out; | ||
662 | } | ||
663 | |||
664 | child = ptrace_get_task_struct(pid); | ||
665 | if (IS_ERR(child)) { | ||
666 | ret = PTR_ERR(child); | ||
667 | goto out; | ||
668 | } | ||
669 | |||
670 | if (request == PTRACE_ATTACH) { | ||
671 | ret = ptrace_attach(child); | ||
672 | /* | ||
673 | * Some architectures need to do book-keeping after | ||
674 | * a ptrace attach. | ||
675 | */ | ||
676 | if (!ret) | ||
677 | arch_ptrace_attach(child); | ||
678 | goto out_put_task_struct; | ||
679 | } | ||
680 | |||
681 | ret = ptrace_check_attach(child, request == PTRACE_KILL); | ||
682 | if (!ret) | ||
683 | ret = compat_arch_ptrace(child, request, addr, data); | ||
684 | |||
685 | out_put_task_struct: | ||
686 | put_task_struct(child); | ||
687 | out: | ||
688 | unlock_kernel(); | ||
689 | return ret; | ||
690 | } | ||
691 | #endif /* __ARCH_WANT_COMPAT_SYS_PTRACE */ | ||
692 | |||
693 | #endif /* CONFIG_COMPAT */ | ||
diff --git a/kernel/sched.c b/kernel/sched.c index 524285e46fa7..ba4c88088f62 100644 --- a/kernel/sched.c +++ b/kernel/sched.c | |||
@@ -4945,19 +4945,15 @@ EXPORT_SYMBOL(_cond_resched); | |||
4945 | */ | 4945 | */ |
4946 | int cond_resched_lock(spinlock_t *lock) | 4946 | int cond_resched_lock(spinlock_t *lock) |
4947 | { | 4947 | { |
4948 | int resched = need_resched() && system_state == SYSTEM_RUNNING; | ||
4948 | int ret = 0; | 4949 | int ret = 0; |
4949 | 4950 | ||
4950 | if (need_lockbreak(lock)) { | 4951 | if (spin_needbreak(lock) || resched) { |
4951 | spin_unlock(lock); | 4952 | spin_unlock(lock); |
4952 | cpu_relax(); | 4953 | if (resched && need_resched()) |
4953 | ret = 1; | 4954 | __cond_resched(); |
4954 | spin_lock(lock); | 4955 | else |
4955 | } | 4956 | cpu_relax(); |
4956 | if (need_resched() && system_state == SYSTEM_RUNNING) { | ||
4957 | spin_release(&lock->dep_map, 1, _THIS_IP_); | ||
4958 | _raw_spin_unlock(lock); | ||
4959 | preempt_enable_no_resched(); | ||
4960 | __cond_resched(); | ||
4961 | ret = 1; | 4957 | ret = 1; |
4962 | spin_lock(lock); | 4958 | spin_lock(lock); |
4963 | } | 4959 | } |
diff --git a/kernel/signal.c b/kernel/signal.c index afa4f781f924..bf49ce6f016b 100644 --- a/kernel/signal.c +++ b/kernel/signal.c | |||
@@ -733,13 +733,13 @@ static void print_fatal_signal(struct pt_regs *regs, int signr) | |||
733 | current->comm, task_pid_nr(current), signr); | 733 | current->comm, task_pid_nr(current), signr); |
734 | 734 | ||
735 | #if defined(__i386__) && !defined(__arch_um__) | 735 | #if defined(__i386__) && !defined(__arch_um__) |
736 | printk("code at %08lx: ", regs->eip); | 736 | printk("code at %08lx: ", regs->ip); |
737 | { | 737 | { |
738 | int i; | 738 | int i; |
739 | for (i = 0; i < 16; i++) { | 739 | for (i = 0; i < 16; i++) { |
740 | unsigned char insn; | 740 | unsigned char insn; |
741 | 741 | ||
742 | __get_user(insn, (unsigned char *)(regs->eip + i)); | 742 | __get_user(insn, (unsigned char *)(regs->ip + i)); |
743 | printk("%02x ", insn); | 743 | printk("%02x ", insn); |
744 | } | 744 | } |
745 | } | 745 | } |
diff --git a/kernel/softirq.c b/kernel/softirq.c index bd89bc4eb0b9..d7837d45419e 100644 --- a/kernel/softirq.c +++ b/kernel/softirq.c | |||
@@ -3,7 +3,9 @@ | |||
3 | * | 3 | * |
4 | * Copyright (C) 1992 Linus Torvalds | 4 | * Copyright (C) 1992 Linus Torvalds |
5 | * | 5 | * |
6 | * Rewritten. Old one was good in 2.2, but in 2.3 it was immoral. --ANK (990903) | 6 | * Distribute under GPLv2. |
7 | * | ||
8 | * Rewritten. Old one was good in 2.2, but in 2.3 it was immoral. --ANK (990903) | ||
7 | */ | 9 | */ |
8 | 10 | ||
9 | #include <linux/module.h> | 11 | #include <linux/module.h> |
@@ -278,9 +280,14 @@ asmlinkage void do_softirq(void) | |||
278 | */ | 280 | */ |
279 | void irq_enter(void) | 281 | void irq_enter(void) |
280 | { | 282 | { |
283 | #ifdef CONFIG_NO_HZ | ||
284 | int cpu = smp_processor_id(); | ||
285 | if (idle_cpu(cpu) && !in_interrupt()) | ||
286 | tick_nohz_stop_idle(cpu); | ||
287 | #endif | ||
281 | __irq_enter(); | 288 | __irq_enter(); |
282 | #ifdef CONFIG_NO_HZ | 289 | #ifdef CONFIG_NO_HZ |
283 | if (idle_cpu(smp_processor_id())) | 290 | if (idle_cpu(cpu)) |
284 | tick_nohz_update_jiffies(); | 291 | tick_nohz_update_jiffies(); |
285 | #endif | 292 | #endif |
286 | } | 293 | } |
diff --git a/kernel/spinlock.c b/kernel/spinlock.c index cd72424c2662..ae28c8245123 100644 --- a/kernel/spinlock.c +++ b/kernel/spinlock.c | |||
@@ -65,8 +65,7 @@ EXPORT_SYMBOL(_write_trylock); | |||
65 | * even on CONFIG_PREEMPT, because lockdep assumes that interrupts are | 65 | * even on CONFIG_PREEMPT, because lockdep assumes that interrupts are |
66 | * not re-enabled during lock-acquire (which the preempt-spin-ops do): | 66 | * not re-enabled during lock-acquire (which the preempt-spin-ops do): |
67 | */ | 67 | */ |
68 | #if !defined(CONFIG_PREEMPT) || !defined(CONFIG_SMP) || \ | 68 | #if !defined(CONFIG_GENERIC_LOCKBREAK) || defined(CONFIG_DEBUG_LOCK_ALLOC) |
69 | defined(CONFIG_DEBUG_LOCK_ALLOC) | ||
70 | 69 | ||
71 | void __lockfunc _read_lock(rwlock_t *lock) | 70 | void __lockfunc _read_lock(rwlock_t *lock) |
72 | { | 71 | { |
diff --git a/kernel/sysctl.c b/kernel/sysctl.c index 4bc8e48434a7..357b68ba23ec 100644 --- a/kernel/sysctl.c +++ b/kernel/sysctl.c | |||
@@ -53,6 +53,7 @@ | |||
53 | #ifdef CONFIG_X86 | 53 | #ifdef CONFIG_X86 |
54 | #include <asm/nmi.h> | 54 | #include <asm/nmi.h> |
55 | #include <asm/stacktrace.h> | 55 | #include <asm/stacktrace.h> |
56 | #include <asm/io.h> | ||
56 | #endif | 57 | #endif |
57 | 58 | ||
58 | static int deprecated_sysctl_warning(struct __sysctl_args *args); | 59 | static int deprecated_sysctl_warning(struct __sysctl_args *args); |
@@ -727,6 +728,14 @@ static struct ctl_table kern_table[] = { | |||
727 | .mode = 0644, | 728 | .mode = 0644, |
728 | .proc_handler = &proc_dointvec, | 729 | .proc_handler = &proc_dointvec, |
729 | }, | 730 | }, |
731 | { | ||
732 | .ctl_name = CTL_UNNUMBERED, | ||
733 | .procname = "io_delay_type", | ||
734 | .data = &io_delay_type, | ||
735 | .maxlen = sizeof(int), | ||
736 | .mode = 0644, | ||
737 | .proc_handler = &proc_dointvec, | ||
738 | }, | ||
730 | #endif | 739 | #endif |
731 | #if defined(CONFIG_MMU) | 740 | #if defined(CONFIG_MMU) |
732 | { | 741 | { |
diff --git a/kernel/test_kprobes.c b/kernel/test_kprobes.c new file mode 100644 index 000000000000..88cdb109e13c --- /dev/null +++ b/kernel/test_kprobes.c | |||
@@ -0,0 +1,216 @@ | |||
1 | /* | ||
2 | * test_kprobes.c - simple sanity test for *probes | ||
3 | * | ||
4 | * Copyright IBM Corp. 2008 | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License as published by | ||
8 | * the Free Software Foundation; either version 2 of the License, or | ||
9 | * (at your option) any later version. | ||
10 | * | ||
11 | * This program is distributed in the hope that it would be useful, but | ||
12 | * WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See | ||
14 | * the GNU General Public License for more details. | ||
15 | */ | ||
16 | |||
17 | #include <linux/kernel.h> | ||
18 | #include <linux/kprobes.h> | ||
19 | #include <linux/random.h> | ||
20 | |||
21 | #define div_factor 3 | ||
22 | |||
23 | static u32 rand1, preh_val, posth_val, jph_val; | ||
24 | static int errors, handler_errors, num_tests; | ||
25 | |||
26 | static noinline u32 kprobe_target(u32 value) | ||
27 | { | ||
28 | /* | ||
29 | * gcc ignores noinline on some architectures unless we stuff | ||
30 | * sufficient lard into the function. The get_kprobe() here is | ||
31 | * just for that. | ||
32 | * | ||
33 | * NOTE: We aren't concerned about the correctness of get_kprobe() | ||
34 | * here; hence, this call is neither under !preempt nor with the | ||
35 | * kprobe_mutex held. This is fine(tm) | ||
36 | */ | ||
37 | if (get_kprobe((void *)0xdeadbeef)) | ||
38 | printk(KERN_INFO "Kprobe smoke test: probe on 0xdeadbeef!\n"); | ||
39 | |||
40 | return (value / div_factor); | ||
41 | } | ||
42 | |||
43 | static int kp_pre_handler(struct kprobe *p, struct pt_regs *regs) | ||
44 | { | ||
45 | preh_val = (rand1 / div_factor); | ||
46 | return 0; | ||
47 | } | ||
48 | |||
49 | static void kp_post_handler(struct kprobe *p, struct pt_regs *regs, | ||
50 | unsigned long flags) | ||
51 | { | ||
52 | if (preh_val != (rand1 / div_factor)) { | ||
53 | handler_errors++; | ||
54 | printk(KERN_ERR "Kprobe smoke test failed: " | ||
55 | "incorrect value in post_handler\n"); | ||
56 | } | ||
57 | posth_val = preh_val + div_factor; | ||
58 | } | ||
59 | |||
60 | static struct kprobe kp = { | ||
61 | .symbol_name = "kprobe_target", | ||
62 | .pre_handler = kp_pre_handler, | ||
63 | .post_handler = kp_post_handler | ||
64 | }; | ||
65 | |||
66 | static int test_kprobe(void) | ||
67 | { | ||
68 | int ret; | ||
69 | |||
70 | ret = register_kprobe(&kp); | ||
71 | if (ret < 0) { | ||
72 | printk(KERN_ERR "Kprobe smoke test failed: " | ||
73 | "register_kprobe returned %d\n", ret); | ||
74 | return ret; | ||
75 | } | ||
76 | |||
77 | ret = kprobe_target(rand1); | ||
78 | unregister_kprobe(&kp); | ||
79 | |||
80 | if (preh_val == 0) { | ||
81 | printk(KERN_ERR "Kprobe smoke test failed: " | ||
82 | "kprobe pre_handler not called\n"); | ||
83 | handler_errors++; | ||
84 | } | ||
85 | |||
86 | if (posth_val == 0) { | ||
87 | printk(KERN_ERR "Kprobe smoke test failed: " | ||
88 | "kprobe post_handler not called\n"); | ||
89 | handler_errors++; | ||
90 | } | ||
91 | |||
92 | return 0; | ||
93 | } | ||
94 | |||
95 | static u32 j_kprobe_target(u32 value) | ||
96 | { | ||
97 | if (value != rand1) { | ||
98 | handler_errors++; | ||
99 | printk(KERN_ERR "Kprobe smoke test failed: " | ||
100 | "incorrect value in jprobe handler\n"); | ||
101 | } | ||
102 | |||
103 | jph_val = rand1; | ||
104 | jprobe_return(); | ||
105 | return 0; | ||
106 | } | ||
107 | |||
108 | static struct jprobe jp = { | ||
109 | .entry = j_kprobe_target, | ||
110 | .kp.symbol_name = "kprobe_target" | ||
111 | }; | ||
112 | |||
113 | static int test_jprobe(void) | ||
114 | { | ||
115 | int ret; | ||
116 | |||
117 | ret = register_jprobe(&jp); | ||
118 | if (ret < 0) { | ||
119 | printk(KERN_ERR "Kprobe smoke test failed: " | ||
120 | "register_jprobe returned %d\n", ret); | ||
121 | return ret; | ||
122 | } | ||
123 | |||
124 | ret = kprobe_target(rand1); | ||
125 | unregister_jprobe(&jp); | ||
126 | if (jph_val == 0) { | ||
127 | printk(KERN_ERR "Kprobe smoke test failed: " | ||
128 | "jprobe handler not called\n"); | ||
129 | handler_errors++; | ||
130 | } | ||
131 | |||
132 | return 0; | ||
133 | } | ||
134 | |||
135 | #ifdef CONFIG_KRETPROBES | ||
136 | static u32 krph_val; | ||
137 | |||
138 | static int return_handler(struct kretprobe_instance *ri, struct pt_regs *regs) | ||
139 | { | ||
140 | unsigned long ret = regs_return_value(regs); | ||
141 | |||
142 | if (ret != (rand1 / div_factor)) { | ||
143 | handler_errors++; | ||
144 | printk(KERN_ERR "Kprobe smoke test failed: " | ||
145 | "incorrect value in kretprobe handler\n"); | ||
146 | } | ||
147 | |||
148 | krph_val = (rand1 / div_factor); | ||
149 | return 0; | ||
150 | } | ||
151 | |||
152 | static struct kretprobe rp = { | ||
153 | .handler = return_handler, | ||
154 | .kp.symbol_name = "kprobe_target" | ||
155 | }; | ||
156 | |||
157 | static int test_kretprobe(void) | ||
158 | { | ||
159 | int ret; | ||
160 | |||
161 | ret = register_kretprobe(&rp); | ||
162 | if (ret < 0) { | ||
163 | printk(KERN_ERR "Kprobe smoke test failed: " | ||
164 | "register_kretprobe returned %d\n", ret); | ||
165 | return ret; | ||
166 | } | ||
167 | |||
168 | ret = kprobe_target(rand1); | ||
169 | unregister_kretprobe(&rp); | ||
170 | if (krph_val == 0) { | ||
171 | printk(KERN_ERR "Kprobe smoke test failed: " | ||
172 | "kretprobe handler not called\n"); | ||
173 | handler_errors++; | ||
174 | } | ||
175 | |||
176 | return 0; | ||
177 | } | ||
178 | #endif /* CONFIG_KRETPROBES */ | ||
179 | |||
180 | int init_test_probes(void) | ||
181 | { | ||
182 | int ret; | ||
183 | |||
184 | do { | ||
185 | rand1 = random32(); | ||
186 | } while (rand1 <= div_factor); | ||
187 | |||
188 | printk(KERN_INFO "Kprobe smoke test started\n"); | ||
189 | num_tests++; | ||
190 | ret = test_kprobe(); | ||
191 | if (ret < 0) | ||
192 | errors++; | ||
193 | |||
194 | num_tests++; | ||
195 | ret = test_jprobe(); | ||
196 | if (ret < 0) | ||
197 | errors++; | ||
198 | |||
199 | #ifdef CONFIG_KRETPROBES | ||
200 | num_tests++; | ||
201 | ret = test_kretprobe(); | ||
202 | if (ret < 0) | ||
203 | errors++; | ||
204 | #endif /* CONFIG_KRETPROBES */ | ||
205 | |||
206 | if (errors) | ||
207 | printk(KERN_ERR "BUG: Kprobe smoke test: %d out of " | ||
208 | "%d tests failed\n", errors, num_tests); | ||
209 | else if (handler_errors) | ||
210 | printk(KERN_ERR "BUG: Kprobe smoke test: %d error(s) " | ||
211 | "running handlers\n", handler_errors); | ||
212 | else | ||
213 | printk(KERN_INFO "Kprobe smoke test passed successfully\n"); | ||
214 | |||
215 | return 0; | ||
216 | } | ||
diff --git a/kernel/time/clockevents.c b/kernel/time/clockevents.c index 5fb139fef9fa..3e59fce6dd43 100644 --- a/kernel/time/clockevents.c +++ b/kernel/time/clockevents.c | |||
@@ -41,6 +41,11 @@ unsigned long clockevent_delta2ns(unsigned long latch, | |||
41 | { | 41 | { |
42 | u64 clc = ((u64) latch << evt->shift); | 42 | u64 clc = ((u64) latch << evt->shift); |
43 | 43 | ||
44 | if (unlikely(!evt->mult)) { | ||
45 | evt->mult = 1; | ||
46 | WARN_ON(1); | ||
47 | } | ||
48 | |||
44 | do_div(clc, evt->mult); | 49 | do_div(clc, evt->mult); |
45 | if (clc < 1000) | 50 | if (clc < 1000) |
46 | clc = 1000; | 51 | clc = 1000; |
@@ -151,6 +156,14 @@ static void clockevents_notify_released(void) | |||
151 | void clockevents_register_device(struct clock_event_device *dev) | 156 | void clockevents_register_device(struct clock_event_device *dev) |
152 | { | 157 | { |
153 | BUG_ON(dev->mode != CLOCK_EVT_MODE_UNUSED); | 158 | BUG_ON(dev->mode != CLOCK_EVT_MODE_UNUSED); |
159 | /* | ||
160 | * A nsec2cyc multiplicator of 0 is invalid and we'd crash | ||
161 | * on it, so fix it up and emit a warning: | ||
162 | */ | ||
163 | if (unlikely(!dev->mult)) { | ||
164 | dev->mult = 1; | ||
165 | WARN_ON(1); | ||
166 | } | ||
154 | 167 | ||
155 | spin_lock(&clockevents_lock); | 168 | spin_lock(&clockevents_lock); |
156 | 169 | ||
diff --git a/kernel/time/clocksource.c b/kernel/time/clocksource.c index 8d6125ad2cf0..6e9259a5d501 100644 --- a/kernel/time/clocksource.c +++ b/kernel/time/clocksource.c | |||
@@ -142,8 +142,13 @@ static void clocksource_watchdog(unsigned long data) | |||
142 | } | 142 | } |
143 | 143 | ||
144 | if (!list_empty(&watchdog_list)) { | 144 | if (!list_empty(&watchdog_list)) { |
145 | __mod_timer(&watchdog_timer, | 145 | /* Cycle through CPUs to check if the CPUs stay synchronized to |
146 | watchdog_timer.expires + WATCHDOG_INTERVAL); | 146 | * each other. */ |
147 | int next_cpu = next_cpu(raw_smp_processor_id(), cpu_online_map); | ||
148 | if (next_cpu >= NR_CPUS) | ||
149 | next_cpu = first_cpu(cpu_online_map); | ||
150 | watchdog_timer.expires += WATCHDOG_INTERVAL; | ||
151 | add_timer_on(&watchdog_timer, next_cpu); | ||
147 | } | 152 | } |
148 | spin_unlock(&watchdog_lock); | 153 | spin_unlock(&watchdog_lock); |
149 | } | 154 | } |
@@ -165,7 +170,7 @@ static void clocksource_check_watchdog(struct clocksource *cs) | |||
165 | if (!started && watchdog) { | 170 | if (!started && watchdog) { |
166 | watchdog_last = watchdog->read(); | 171 | watchdog_last = watchdog->read(); |
167 | watchdog_timer.expires = jiffies + WATCHDOG_INTERVAL; | 172 | watchdog_timer.expires = jiffies + WATCHDOG_INTERVAL; |
168 | add_timer(&watchdog_timer); | 173 | add_timer_on(&watchdog_timer, first_cpu(cpu_online_map)); |
169 | } | 174 | } |
170 | } else { | 175 | } else { |
171 | if (cs->flags & CLOCK_SOURCE_IS_CONTINUOUS) | 176 | if (cs->flags & CLOCK_SOURCE_IS_CONTINUOUS) |
@@ -175,7 +180,7 @@ static void clocksource_check_watchdog(struct clocksource *cs) | |||
175 | if (watchdog) | 180 | if (watchdog) |
176 | del_timer(&watchdog_timer); | 181 | del_timer(&watchdog_timer); |
177 | watchdog = cs; | 182 | watchdog = cs; |
178 | init_timer(&watchdog_timer); | 183 | init_timer_deferrable(&watchdog_timer); |
179 | watchdog_timer.function = clocksource_watchdog; | 184 | watchdog_timer.function = clocksource_watchdog; |
180 | 185 | ||
181 | /* Reset watchdog cycles */ | 186 | /* Reset watchdog cycles */ |
@@ -186,7 +191,8 @@ static void clocksource_check_watchdog(struct clocksource *cs) | |||
186 | watchdog_last = watchdog->read(); | 191 | watchdog_last = watchdog->read(); |
187 | watchdog_timer.expires = | 192 | watchdog_timer.expires = |
188 | jiffies + WATCHDOG_INTERVAL; | 193 | jiffies + WATCHDOG_INTERVAL; |
189 | add_timer(&watchdog_timer); | 194 | add_timer_on(&watchdog_timer, |
195 | first_cpu(cpu_online_map)); | ||
190 | } | 196 | } |
191 | } | 197 | } |
192 | } | 198 | } |
@@ -331,6 +337,21 @@ void clocksource_change_rating(struct clocksource *cs, int rating) | |||
331 | spin_unlock_irqrestore(&clocksource_lock, flags); | 337 | spin_unlock_irqrestore(&clocksource_lock, flags); |
332 | } | 338 | } |
333 | 339 | ||
340 | /** | ||
341 | * clocksource_unregister - remove a registered clocksource | ||
342 | */ | ||
343 | void clocksource_unregister(struct clocksource *cs) | ||
344 | { | ||
345 | unsigned long flags; | ||
346 | |||
347 | spin_lock_irqsave(&clocksource_lock, flags); | ||
348 | list_del(&cs->list); | ||
349 | if (clocksource_override == cs) | ||
350 | clocksource_override = NULL; | ||
351 | next_clocksource = select_clocksource(); | ||
352 | spin_unlock_irqrestore(&clocksource_lock, flags); | ||
353 | } | ||
354 | |||
334 | #ifdef CONFIG_SYSFS | 355 | #ifdef CONFIG_SYSFS |
335 | /** | 356 | /** |
336 | * sysfs_show_current_clocksources - sysfs interface for current clocksource | 357 | * sysfs_show_current_clocksources - sysfs interface for current clocksource |
diff --git a/kernel/time/tick-broadcast.c b/kernel/time/tick-broadcast.c index 5b86698faa0b..e1bd50cbbf5d 100644 --- a/kernel/time/tick-broadcast.c +++ b/kernel/time/tick-broadcast.c | |||
@@ -126,9 +126,9 @@ int tick_device_uses_broadcast(struct clock_event_device *dev, int cpu) | |||
126 | /* | 126 | /* |
127 | * Broadcast the event to the cpus, which are set in the mask | 127 | * Broadcast the event to the cpus, which are set in the mask |
128 | */ | 128 | */ |
129 | int tick_do_broadcast(cpumask_t mask) | 129 | static void tick_do_broadcast(cpumask_t mask) |
130 | { | 130 | { |
131 | int ret = 0, cpu = smp_processor_id(); | 131 | int cpu = smp_processor_id(); |
132 | struct tick_device *td; | 132 | struct tick_device *td; |
133 | 133 | ||
134 | /* | 134 | /* |
@@ -138,7 +138,6 @@ int tick_do_broadcast(cpumask_t mask) | |||
138 | cpu_clear(cpu, mask); | 138 | cpu_clear(cpu, mask); |
139 | td = &per_cpu(tick_cpu_device, cpu); | 139 | td = &per_cpu(tick_cpu_device, cpu); |
140 | td->evtdev->event_handler(td->evtdev); | 140 | td->evtdev->event_handler(td->evtdev); |
141 | ret = 1; | ||
142 | } | 141 | } |
143 | 142 | ||
144 | if (!cpus_empty(mask)) { | 143 | if (!cpus_empty(mask)) { |
@@ -151,9 +150,7 @@ int tick_do_broadcast(cpumask_t mask) | |||
151 | cpu = first_cpu(mask); | 150 | cpu = first_cpu(mask); |
152 | td = &per_cpu(tick_cpu_device, cpu); | 151 | td = &per_cpu(tick_cpu_device, cpu); |
153 | td->evtdev->broadcast(mask); | 152 | td->evtdev->broadcast(mask); |
154 | ret = 1; | ||
155 | } | 153 | } |
156 | return ret; | ||
157 | } | 154 | } |
158 | 155 | ||
159 | /* | 156 | /* |
diff --git a/kernel/time/tick-internal.h b/kernel/time/tick-internal.h index bb13f2724905..f13f2b7f4fd4 100644 --- a/kernel/time/tick-internal.h +++ b/kernel/time/tick-internal.h | |||
@@ -70,8 +70,6 @@ static inline int tick_resume_broadcast_oneshot(struct clock_event_device *bc) | |||
70 | * Broadcasting support | 70 | * Broadcasting support |
71 | */ | 71 | */ |
72 | #ifdef CONFIG_GENERIC_CLOCKEVENTS_BROADCAST | 72 | #ifdef CONFIG_GENERIC_CLOCKEVENTS_BROADCAST |
73 | extern int tick_do_broadcast(cpumask_t mask); | ||
74 | |||
75 | extern int tick_device_uses_broadcast(struct clock_event_device *dev, int cpu); | 73 | extern int tick_device_uses_broadcast(struct clock_event_device *dev, int cpu); |
76 | extern int tick_check_broadcast_device(struct clock_event_device *dev); | 74 | extern int tick_check_broadcast_device(struct clock_event_device *dev); |
77 | extern int tick_is_broadcast_device(struct clock_event_device *dev); | 75 | extern int tick_is_broadcast_device(struct clock_event_device *dev); |
diff --git a/kernel/time/tick-sched.c b/kernel/time/tick-sched.c index 1a21b6fdb674..63f24b550695 100644 --- a/kernel/time/tick-sched.c +++ b/kernel/time/tick-sched.c | |||
@@ -9,7 +9,7 @@ | |||
9 | * | 9 | * |
10 | * Started by: Thomas Gleixner and Ingo Molnar | 10 | * Started by: Thomas Gleixner and Ingo Molnar |
11 | * | 11 | * |
12 | * For licencing details see kernel-base/COPYING | 12 | * Distribute under GPLv2. |
13 | */ | 13 | */ |
14 | #include <linux/cpu.h> | 14 | #include <linux/cpu.h> |
15 | #include <linux/err.h> | 15 | #include <linux/err.h> |
@@ -143,6 +143,44 @@ void tick_nohz_update_jiffies(void) | |||
143 | local_irq_restore(flags); | 143 | local_irq_restore(flags); |
144 | } | 144 | } |
145 | 145 | ||
146 | void tick_nohz_stop_idle(int cpu) | ||
147 | { | ||
148 | struct tick_sched *ts = &per_cpu(tick_cpu_sched, cpu); | ||
149 | |||
150 | if (ts->idle_active) { | ||
151 | ktime_t now, delta; | ||
152 | now = ktime_get(); | ||
153 | delta = ktime_sub(now, ts->idle_entrytime); | ||
154 | ts->idle_lastupdate = now; | ||
155 | ts->idle_sleeptime = ktime_add(ts->idle_sleeptime, delta); | ||
156 | ts->idle_active = 0; | ||
157 | } | ||
158 | } | ||
159 | |||
160 | static ktime_t tick_nohz_start_idle(int cpu) | ||
161 | { | ||
162 | struct tick_sched *ts = &per_cpu(tick_cpu_sched, cpu); | ||
163 | ktime_t now, delta; | ||
164 | |||
165 | now = ktime_get(); | ||
166 | if (ts->idle_active) { | ||
167 | delta = ktime_sub(now, ts->idle_entrytime); | ||
168 | ts->idle_lastupdate = now; | ||
169 | ts->idle_sleeptime = ktime_add(ts->idle_sleeptime, delta); | ||
170 | } | ||
171 | ts->idle_entrytime = now; | ||
172 | ts->idle_active = 1; | ||
173 | return now; | ||
174 | } | ||
175 | |||
176 | u64 get_cpu_idle_time_us(int cpu, u64 *last_update_time) | ||
177 | { | ||
178 | struct tick_sched *ts = &per_cpu(tick_cpu_sched, cpu); | ||
179 | |||
180 | *last_update_time = ktime_to_us(ts->idle_lastupdate); | ||
181 | return ktime_to_us(ts->idle_sleeptime); | ||
182 | } | ||
183 | |||
146 | /** | 184 | /** |
147 | * tick_nohz_stop_sched_tick - stop the idle tick from the idle task | 185 | * tick_nohz_stop_sched_tick - stop the idle tick from the idle task |
148 | * | 186 | * |
@@ -155,13 +193,14 @@ void tick_nohz_stop_sched_tick(void) | |||
155 | unsigned long seq, last_jiffies, next_jiffies, delta_jiffies, flags; | 193 | unsigned long seq, last_jiffies, next_jiffies, delta_jiffies, flags; |
156 | unsigned long rt_jiffies; | 194 | unsigned long rt_jiffies; |
157 | struct tick_sched *ts; | 195 | struct tick_sched *ts; |
158 | ktime_t last_update, expires, now, delta; | 196 | ktime_t last_update, expires, now; |
159 | struct clock_event_device *dev = __get_cpu_var(tick_cpu_device).evtdev; | 197 | struct clock_event_device *dev = __get_cpu_var(tick_cpu_device).evtdev; |
160 | int cpu; | 198 | int cpu; |
161 | 199 | ||
162 | local_irq_save(flags); | 200 | local_irq_save(flags); |
163 | 201 | ||
164 | cpu = smp_processor_id(); | 202 | cpu = smp_processor_id(); |
203 | now = tick_nohz_start_idle(cpu); | ||
165 | ts = &per_cpu(tick_cpu_sched, cpu); | 204 | ts = &per_cpu(tick_cpu_sched, cpu); |
166 | 205 | ||
167 | /* | 206 | /* |
@@ -193,19 +232,7 @@ void tick_nohz_stop_sched_tick(void) | |||
193 | } | 232 | } |
194 | } | 233 | } |
195 | 234 | ||
196 | now = ktime_get(); | ||
197 | /* | ||
198 | * When called from irq_exit we need to account the idle sleep time | ||
199 | * correctly. | ||
200 | */ | ||
201 | if (ts->tick_stopped) { | ||
202 | delta = ktime_sub(now, ts->idle_entrytime); | ||
203 | ts->idle_sleeptime = ktime_add(ts->idle_sleeptime, delta); | ||
204 | } | ||
205 | |||
206 | ts->idle_entrytime = now; | ||
207 | ts->idle_calls++; | 235 | ts->idle_calls++; |
208 | |||
209 | /* Read jiffies and the time when jiffies were updated last */ | 236 | /* Read jiffies and the time when jiffies were updated last */ |
210 | do { | 237 | do { |
211 | seq = read_seqbegin(&xtime_lock); | 238 | seq = read_seqbegin(&xtime_lock); |
@@ -296,7 +323,7 @@ void tick_nohz_stop_sched_tick(void) | |||
296 | /* Check, if the timer was already in the past */ | 323 | /* Check, if the timer was already in the past */ |
297 | if (hrtimer_active(&ts->sched_timer)) | 324 | if (hrtimer_active(&ts->sched_timer)) |
298 | goto out; | 325 | goto out; |
299 | } else if(!tick_program_event(expires, 0)) | 326 | } else if (!tick_program_event(expires, 0)) |
300 | goto out; | 327 | goto out; |
301 | /* | 328 | /* |
302 | * We are past the event already. So we crossed a | 329 | * We are past the event already. So we crossed a |
@@ -337,23 +364,22 @@ void tick_nohz_restart_sched_tick(void) | |||
337 | int cpu = smp_processor_id(); | 364 | int cpu = smp_processor_id(); |
338 | struct tick_sched *ts = &per_cpu(tick_cpu_sched, cpu); | 365 | struct tick_sched *ts = &per_cpu(tick_cpu_sched, cpu); |
339 | unsigned long ticks; | 366 | unsigned long ticks; |
340 | ktime_t now, delta; | 367 | ktime_t now; |
341 | 368 | ||
342 | if (!ts->tick_stopped) | 369 | local_irq_disable(); |
370 | tick_nohz_stop_idle(cpu); | ||
371 | |||
372 | if (!ts->tick_stopped) { | ||
373 | local_irq_enable(); | ||
343 | return; | 374 | return; |
375 | } | ||
344 | 376 | ||
345 | /* Update jiffies first */ | 377 | /* Update jiffies first */ |
346 | now = ktime_get(); | ||
347 | |||
348 | local_irq_disable(); | ||
349 | select_nohz_load_balancer(0); | 378 | select_nohz_load_balancer(0); |
379 | now = ktime_get(); | ||
350 | tick_do_update_jiffies64(now); | 380 | tick_do_update_jiffies64(now); |
351 | cpu_clear(cpu, nohz_cpu_mask); | 381 | cpu_clear(cpu, nohz_cpu_mask); |
352 | 382 | ||
353 | /* Account the idle time */ | ||
354 | delta = ktime_sub(now, ts->idle_entrytime); | ||
355 | ts->idle_sleeptime = ktime_add(ts->idle_sleeptime, delta); | ||
356 | |||
357 | /* | 383 | /* |
358 | * We stopped the tick in idle. Update process times would miss the | 384 | * We stopped the tick in idle. Update process times would miss the |
359 | * time we slept as update_process_times does only a 1 tick | 385 | * time we slept as update_process_times does only a 1 tick |
@@ -507,7 +533,7 @@ static inline void tick_nohz_switch_to_nohz(void) { } | |||
507 | */ | 533 | */ |
508 | #ifdef CONFIG_HIGH_RES_TIMERS | 534 | #ifdef CONFIG_HIGH_RES_TIMERS |
509 | /* | 535 | /* |
510 | * We rearm the timer until we get disabled by the idle code | 536 | * We rearm the timer until we get disabled by the idle code. |
511 | * Called with interrupts disabled and timer->base->cpu_base->lock held. | 537 | * Called with interrupts disabled and timer->base->cpu_base->lock held. |
512 | */ | 538 | */ |
513 | static enum hrtimer_restart tick_sched_timer(struct hrtimer *timer) | 539 | static enum hrtimer_restart tick_sched_timer(struct hrtimer *timer) |
diff --git a/kernel/time/timekeeping.c b/kernel/time/timekeeping.c index ab46ae8c062b..092a2366b5a9 100644 --- a/kernel/time/timekeeping.c +++ b/kernel/time/timekeeping.c | |||
@@ -82,13 +82,12 @@ static inline s64 __get_nsec_offset(void) | |||
82 | } | 82 | } |
83 | 83 | ||
84 | /** | 84 | /** |
85 | * __get_realtime_clock_ts - Returns the time of day in a timespec | 85 | * getnstimeofday - Returns the time of day in a timespec |
86 | * @ts: pointer to the timespec to be set | 86 | * @ts: pointer to the timespec to be set |
87 | * | 87 | * |
88 | * Returns the time of day in a timespec. Used by | 88 | * Returns the time of day in a timespec. |
89 | * do_gettimeofday() and get_realtime_clock_ts(). | ||
90 | */ | 89 | */ |
91 | static inline void __get_realtime_clock_ts(struct timespec *ts) | 90 | void getnstimeofday(struct timespec *ts) |
92 | { | 91 | { |
93 | unsigned long seq; | 92 | unsigned long seq; |
94 | s64 nsecs; | 93 | s64 nsecs; |
@@ -104,30 +103,19 @@ static inline void __get_realtime_clock_ts(struct timespec *ts) | |||
104 | timespec_add_ns(ts, nsecs); | 103 | timespec_add_ns(ts, nsecs); |
105 | } | 104 | } |
106 | 105 | ||
107 | /** | ||
108 | * getnstimeofday - Returns the time of day in a timespec | ||
109 | * @ts: pointer to the timespec to be set | ||
110 | * | ||
111 | * Returns the time of day in a timespec. | ||
112 | */ | ||
113 | void getnstimeofday(struct timespec *ts) | ||
114 | { | ||
115 | __get_realtime_clock_ts(ts); | ||
116 | } | ||
117 | |||
118 | EXPORT_SYMBOL(getnstimeofday); | 106 | EXPORT_SYMBOL(getnstimeofday); |
119 | 107 | ||
120 | /** | 108 | /** |
121 | * do_gettimeofday - Returns the time of day in a timeval | 109 | * do_gettimeofday - Returns the time of day in a timeval |
122 | * @tv: pointer to the timeval to be set | 110 | * @tv: pointer to the timeval to be set |
123 | * | 111 | * |
124 | * NOTE: Users should be converted to using get_realtime_clock_ts() | 112 | * NOTE: Users should be converted to using getnstimeofday() |
125 | */ | 113 | */ |
126 | void do_gettimeofday(struct timeval *tv) | 114 | void do_gettimeofday(struct timeval *tv) |
127 | { | 115 | { |
128 | struct timespec now; | 116 | struct timespec now; |
129 | 117 | ||
130 | __get_realtime_clock_ts(&now); | 118 | getnstimeofday(&now); |
131 | tv->tv_sec = now.tv_sec; | 119 | tv->tv_sec = now.tv_sec; |
132 | tv->tv_usec = now.tv_nsec/1000; | 120 | tv->tv_usec = now.tv_nsec/1000; |
133 | } | 121 | } |
@@ -198,7 +186,8 @@ static void change_clocksource(void) | |||
198 | 186 | ||
199 | clock->error = 0; | 187 | clock->error = 0; |
200 | clock->xtime_nsec = 0; | 188 | clock->xtime_nsec = 0; |
201 | clocksource_calculate_interval(clock, NTP_INTERVAL_LENGTH); | 189 | clocksource_calculate_interval(clock, |
190 | (unsigned long)(current_tick_length()>>TICK_LENGTH_SHIFT)); | ||
202 | 191 | ||
203 | tick_clock_notify(); | 192 | tick_clock_notify(); |
204 | 193 | ||
@@ -255,7 +244,8 @@ void __init timekeeping_init(void) | |||
255 | ntp_clear(); | 244 | ntp_clear(); |
256 | 245 | ||
257 | clock = clocksource_get_next(); | 246 | clock = clocksource_get_next(); |
258 | clocksource_calculate_interval(clock, NTP_INTERVAL_LENGTH); | 247 | clocksource_calculate_interval(clock, |
248 | (unsigned long)(current_tick_length()>>TICK_LENGTH_SHIFT)); | ||
259 | clock->cycle_last = clocksource_read(clock); | 249 | clock->cycle_last = clocksource_read(clock); |
260 | 250 | ||
261 | xtime.tv_sec = sec; | 251 | xtime.tv_sec = sec; |
diff --git a/kernel/time/timer_stats.c b/kernel/time/timer_stats.c index c36bb7ed0301..417da8c5bc72 100644 --- a/kernel/time/timer_stats.c +++ b/kernel/time/timer_stats.c | |||
@@ -26,7 +26,7 @@ | |||
26 | * the pid and cmdline from the owner process if applicable. | 26 | * the pid and cmdline from the owner process if applicable. |
27 | * | 27 | * |
28 | * Start/stop data collection: | 28 | * Start/stop data collection: |
29 | * # echo 1[0] >/proc/timer_stats | 29 | * # echo [1|0] >/proc/timer_stats |
30 | * | 30 | * |
31 | * Display the information collected so far: | 31 | * Display the information collected so far: |
32 | * # cat /proc/timer_stats | 32 | * # cat /proc/timer_stats |
diff --git a/kernel/timer.c b/kernel/timer.c index f739dfb539ce..23f7ead78fae 100644 --- a/kernel/timer.c +++ b/kernel/timer.c | |||
@@ -58,59 +58,57 @@ EXPORT_SYMBOL(jiffies_64); | |||
58 | #define TVN_MASK (TVN_SIZE - 1) | 58 | #define TVN_MASK (TVN_SIZE - 1) |
59 | #define TVR_MASK (TVR_SIZE - 1) | 59 | #define TVR_MASK (TVR_SIZE - 1) |
60 | 60 | ||
61 | typedef struct tvec_s { | 61 | struct tvec { |
62 | struct list_head vec[TVN_SIZE]; | 62 | struct list_head vec[TVN_SIZE]; |
63 | } tvec_t; | 63 | }; |
64 | 64 | ||
65 | typedef struct tvec_root_s { | 65 | struct tvec_root { |
66 | struct list_head vec[TVR_SIZE]; | 66 | struct list_head vec[TVR_SIZE]; |
67 | } tvec_root_t; | 67 | }; |
68 | 68 | ||
69 | struct tvec_t_base_s { | 69 | struct tvec_base { |
70 | spinlock_t lock; | 70 | spinlock_t lock; |
71 | struct timer_list *running_timer; | 71 | struct timer_list *running_timer; |
72 | unsigned long timer_jiffies; | 72 | unsigned long timer_jiffies; |
73 | tvec_root_t tv1; | 73 | struct tvec_root tv1; |
74 | tvec_t tv2; | 74 | struct tvec tv2; |
75 | tvec_t tv3; | 75 | struct tvec tv3; |
76 | tvec_t tv4; | 76 | struct tvec tv4; |
77 | tvec_t tv5; | 77 | struct tvec tv5; |
78 | } ____cacheline_aligned; | 78 | } ____cacheline_aligned; |
79 | 79 | ||
80 | typedef struct tvec_t_base_s tvec_base_t; | 80 | struct tvec_base boot_tvec_bases; |
81 | |||
82 | tvec_base_t boot_tvec_bases; | ||
83 | EXPORT_SYMBOL(boot_tvec_bases); | 81 | EXPORT_SYMBOL(boot_tvec_bases); |
84 | static DEFINE_PER_CPU(tvec_base_t *, tvec_bases) = &boot_tvec_bases; | 82 | static DEFINE_PER_CPU(struct tvec_base *, tvec_bases) = &boot_tvec_bases; |
85 | 83 | ||
86 | /* | 84 | /* |
87 | * Note that all tvec_bases is 2 byte aligned and lower bit of | 85 | * Note that all tvec_bases are 2 byte aligned and lower bit of |
88 | * base in timer_list is guaranteed to be zero. Use the LSB for | 86 | * base in timer_list is guaranteed to be zero. Use the LSB for |
89 | * the new flag to indicate whether the timer is deferrable | 87 | * the new flag to indicate whether the timer is deferrable |
90 | */ | 88 | */ |
91 | #define TBASE_DEFERRABLE_FLAG (0x1) | 89 | #define TBASE_DEFERRABLE_FLAG (0x1) |
92 | 90 | ||
93 | /* Functions below help us manage 'deferrable' flag */ | 91 | /* Functions below help us manage 'deferrable' flag */ |
94 | static inline unsigned int tbase_get_deferrable(tvec_base_t *base) | 92 | static inline unsigned int tbase_get_deferrable(struct tvec_base *base) |
95 | { | 93 | { |
96 | return ((unsigned int)(unsigned long)base & TBASE_DEFERRABLE_FLAG); | 94 | return ((unsigned int)(unsigned long)base & TBASE_DEFERRABLE_FLAG); |
97 | } | 95 | } |
98 | 96 | ||
99 | static inline tvec_base_t *tbase_get_base(tvec_base_t *base) | 97 | static inline struct tvec_base *tbase_get_base(struct tvec_base *base) |
100 | { | 98 | { |
101 | return ((tvec_base_t *)((unsigned long)base & ~TBASE_DEFERRABLE_FLAG)); | 99 | return ((struct tvec_base *)((unsigned long)base & ~TBASE_DEFERRABLE_FLAG)); |
102 | } | 100 | } |
103 | 101 | ||
104 | static inline void timer_set_deferrable(struct timer_list *timer) | 102 | static inline void timer_set_deferrable(struct timer_list *timer) |
105 | { | 103 | { |
106 | timer->base = ((tvec_base_t *)((unsigned long)(timer->base) | | 104 | timer->base = ((struct tvec_base *)((unsigned long)(timer->base) | |
107 | TBASE_DEFERRABLE_FLAG)); | 105 | TBASE_DEFERRABLE_FLAG)); |
108 | } | 106 | } |
109 | 107 | ||
110 | static inline void | 108 | static inline void |
111 | timer_set_base(struct timer_list *timer, tvec_base_t *new_base) | 109 | timer_set_base(struct timer_list *timer, struct tvec_base *new_base) |
112 | { | 110 | { |
113 | timer->base = (tvec_base_t *)((unsigned long)(new_base) | | 111 | timer->base = (struct tvec_base *)((unsigned long)(new_base) | |
114 | tbase_get_deferrable(timer->base)); | 112 | tbase_get_deferrable(timer->base)); |
115 | } | 113 | } |
116 | 114 | ||
@@ -246,7 +244,7 @@ unsigned long round_jiffies_relative(unsigned long j) | |||
246 | EXPORT_SYMBOL_GPL(round_jiffies_relative); | 244 | EXPORT_SYMBOL_GPL(round_jiffies_relative); |
247 | 245 | ||
248 | 246 | ||
249 | static inline void set_running_timer(tvec_base_t *base, | 247 | static inline void set_running_timer(struct tvec_base *base, |
250 | struct timer_list *timer) | 248 | struct timer_list *timer) |
251 | { | 249 | { |
252 | #ifdef CONFIG_SMP | 250 | #ifdef CONFIG_SMP |
@@ -254,7 +252,7 @@ static inline void set_running_timer(tvec_base_t *base, | |||
254 | #endif | 252 | #endif |
255 | } | 253 | } |
256 | 254 | ||
257 | static void internal_add_timer(tvec_base_t *base, struct timer_list *timer) | 255 | static void internal_add_timer(struct tvec_base *base, struct timer_list *timer) |
258 | { | 256 | { |
259 | unsigned long expires = timer->expires; | 257 | unsigned long expires = timer->expires; |
260 | unsigned long idx = expires - base->timer_jiffies; | 258 | unsigned long idx = expires - base->timer_jiffies; |
@@ -371,14 +369,14 @@ static inline void detach_timer(struct timer_list *timer, | |||
371 | * possible to set timer->base = NULL and drop the lock: the timer remains | 369 | * possible to set timer->base = NULL and drop the lock: the timer remains |
372 | * locked. | 370 | * locked. |
373 | */ | 371 | */ |
374 | static tvec_base_t *lock_timer_base(struct timer_list *timer, | 372 | static struct tvec_base *lock_timer_base(struct timer_list *timer, |
375 | unsigned long *flags) | 373 | unsigned long *flags) |
376 | __acquires(timer->base->lock) | 374 | __acquires(timer->base->lock) |
377 | { | 375 | { |
378 | tvec_base_t *base; | 376 | struct tvec_base *base; |
379 | 377 | ||
380 | for (;;) { | 378 | for (;;) { |
381 | tvec_base_t *prelock_base = timer->base; | 379 | struct tvec_base *prelock_base = timer->base; |
382 | base = tbase_get_base(prelock_base); | 380 | base = tbase_get_base(prelock_base); |
383 | if (likely(base != NULL)) { | 381 | if (likely(base != NULL)) { |
384 | spin_lock_irqsave(&base->lock, *flags); | 382 | spin_lock_irqsave(&base->lock, *flags); |
@@ -393,7 +391,7 @@ static tvec_base_t *lock_timer_base(struct timer_list *timer, | |||
393 | 391 | ||
394 | int __mod_timer(struct timer_list *timer, unsigned long expires) | 392 | int __mod_timer(struct timer_list *timer, unsigned long expires) |
395 | { | 393 | { |
396 | tvec_base_t *base, *new_base; | 394 | struct tvec_base *base, *new_base; |
397 | unsigned long flags; | 395 | unsigned long flags; |
398 | int ret = 0; | 396 | int ret = 0; |
399 | 397 | ||
@@ -445,7 +443,7 @@ EXPORT_SYMBOL(__mod_timer); | |||
445 | */ | 443 | */ |
446 | void add_timer_on(struct timer_list *timer, int cpu) | 444 | void add_timer_on(struct timer_list *timer, int cpu) |
447 | { | 445 | { |
448 | tvec_base_t *base = per_cpu(tvec_bases, cpu); | 446 | struct tvec_base *base = per_cpu(tvec_bases, cpu); |
449 | unsigned long flags; | 447 | unsigned long flags; |
450 | 448 | ||
451 | timer_stats_timer_set_start_info(timer); | 449 | timer_stats_timer_set_start_info(timer); |
@@ -508,7 +506,7 @@ EXPORT_SYMBOL(mod_timer); | |||
508 | */ | 506 | */ |
509 | int del_timer(struct timer_list *timer) | 507 | int del_timer(struct timer_list *timer) |
510 | { | 508 | { |
511 | tvec_base_t *base; | 509 | struct tvec_base *base; |
512 | unsigned long flags; | 510 | unsigned long flags; |
513 | int ret = 0; | 511 | int ret = 0; |
514 | 512 | ||
@@ -539,7 +537,7 @@ EXPORT_SYMBOL(del_timer); | |||
539 | */ | 537 | */ |
540 | int try_to_del_timer_sync(struct timer_list *timer) | 538 | int try_to_del_timer_sync(struct timer_list *timer) |
541 | { | 539 | { |
542 | tvec_base_t *base; | 540 | struct tvec_base *base; |
543 | unsigned long flags; | 541 | unsigned long flags; |
544 | int ret = -1; | 542 | int ret = -1; |
545 | 543 | ||
@@ -591,7 +589,7 @@ int del_timer_sync(struct timer_list *timer) | |||
591 | EXPORT_SYMBOL(del_timer_sync); | 589 | EXPORT_SYMBOL(del_timer_sync); |
592 | #endif | 590 | #endif |
593 | 591 | ||
594 | static int cascade(tvec_base_t *base, tvec_t *tv, int index) | 592 | static int cascade(struct tvec_base *base, struct tvec *tv, int index) |
595 | { | 593 | { |
596 | /* cascade all the timers from tv up one level */ | 594 | /* cascade all the timers from tv up one level */ |
597 | struct timer_list *timer, *tmp; | 595 | struct timer_list *timer, *tmp; |
@@ -620,7 +618,7 @@ static int cascade(tvec_base_t *base, tvec_t *tv, int index) | |||
620 | * This function cascades all vectors and executes all expired timer | 618 | * This function cascades all vectors and executes all expired timer |
621 | * vectors. | 619 | * vectors. |
622 | */ | 620 | */ |
623 | static inline void __run_timers(tvec_base_t *base) | 621 | static inline void __run_timers(struct tvec_base *base) |
624 | { | 622 | { |
625 | struct timer_list *timer; | 623 | struct timer_list *timer; |
626 | 624 | ||
@@ -657,7 +655,7 @@ static inline void __run_timers(tvec_base_t *base) | |||
657 | int preempt_count = preempt_count(); | 655 | int preempt_count = preempt_count(); |
658 | fn(data); | 656 | fn(data); |
659 | if (preempt_count != preempt_count()) { | 657 | if (preempt_count != preempt_count()) { |
660 | printk(KERN_WARNING "huh, entered %p " | 658 | printk(KERN_ERR "huh, entered %p " |
661 | "with preempt_count %08x, exited" | 659 | "with preempt_count %08x, exited" |
662 | " with %08x?\n", | 660 | " with %08x?\n", |
663 | fn, preempt_count, | 661 | fn, preempt_count, |
@@ -678,13 +676,13 @@ static inline void __run_timers(tvec_base_t *base) | |||
678 | * is used on S/390 to stop all activity when a cpus is idle. | 676 | * is used on S/390 to stop all activity when a cpus is idle. |
679 | * This functions needs to be called disabled. | 677 | * This functions needs to be called disabled. |
680 | */ | 678 | */ |
681 | static unsigned long __next_timer_interrupt(tvec_base_t *base) | 679 | static unsigned long __next_timer_interrupt(struct tvec_base *base) |
682 | { | 680 | { |
683 | unsigned long timer_jiffies = base->timer_jiffies; | 681 | unsigned long timer_jiffies = base->timer_jiffies; |
684 | unsigned long expires = timer_jiffies + NEXT_TIMER_MAX_DELTA; | 682 | unsigned long expires = timer_jiffies + NEXT_TIMER_MAX_DELTA; |
685 | int index, slot, array, found = 0; | 683 | int index, slot, array, found = 0; |
686 | struct timer_list *nte; | 684 | struct timer_list *nte; |
687 | tvec_t *varray[4]; | 685 | struct tvec *varray[4]; |
688 | 686 | ||
689 | /* Look for timer events in tv1. */ | 687 | /* Look for timer events in tv1. */ |
690 | index = slot = timer_jiffies & TVR_MASK; | 688 | index = slot = timer_jiffies & TVR_MASK; |
@@ -716,7 +714,7 @@ cascade: | |||
716 | varray[3] = &base->tv5; | 714 | varray[3] = &base->tv5; |
717 | 715 | ||
718 | for (array = 0; array < 4; array++) { | 716 | for (array = 0; array < 4; array++) { |
719 | tvec_t *varp = varray[array]; | 717 | struct tvec *varp = varray[array]; |
720 | 718 | ||
721 | index = slot = timer_jiffies & TVN_MASK; | 719 | index = slot = timer_jiffies & TVN_MASK; |
722 | do { | 720 | do { |
@@ -795,7 +793,7 @@ static unsigned long cmp_next_hrtimer_event(unsigned long now, | |||
795 | */ | 793 | */ |
796 | unsigned long get_next_timer_interrupt(unsigned long now) | 794 | unsigned long get_next_timer_interrupt(unsigned long now) |
797 | { | 795 | { |
798 | tvec_base_t *base = __get_cpu_var(tvec_bases); | 796 | struct tvec_base *base = __get_cpu_var(tvec_bases); |
799 | unsigned long expires; | 797 | unsigned long expires; |
800 | 798 | ||
801 | spin_lock(&base->lock); | 799 | spin_lock(&base->lock); |
@@ -894,7 +892,7 @@ static inline void calc_load(unsigned long ticks) | |||
894 | */ | 892 | */ |
895 | static void run_timer_softirq(struct softirq_action *h) | 893 | static void run_timer_softirq(struct softirq_action *h) |
896 | { | 894 | { |
897 | tvec_base_t *base = __get_cpu_var(tvec_bases); | 895 | struct tvec_base *base = __get_cpu_var(tvec_bases); |
898 | 896 | ||
899 | hrtimer_run_pending(); | 897 | hrtimer_run_pending(); |
900 | 898 | ||
@@ -1223,7 +1221,7 @@ static struct lock_class_key base_lock_keys[NR_CPUS]; | |||
1223 | static int __cpuinit init_timers_cpu(int cpu) | 1221 | static int __cpuinit init_timers_cpu(int cpu) |
1224 | { | 1222 | { |
1225 | int j; | 1223 | int j; |
1226 | tvec_base_t *base; | 1224 | struct tvec_base *base; |
1227 | static char __cpuinitdata tvec_base_done[NR_CPUS]; | 1225 | static char __cpuinitdata tvec_base_done[NR_CPUS]; |
1228 | 1226 | ||
1229 | if (!tvec_base_done[cpu]) { | 1227 | if (!tvec_base_done[cpu]) { |
@@ -1278,7 +1276,7 @@ static int __cpuinit init_timers_cpu(int cpu) | |||
1278 | } | 1276 | } |
1279 | 1277 | ||
1280 | #ifdef CONFIG_HOTPLUG_CPU | 1278 | #ifdef CONFIG_HOTPLUG_CPU |
1281 | static void migrate_timer_list(tvec_base_t *new_base, struct list_head *head) | 1279 | static void migrate_timer_list(struct tvec_base *new_base, struct list_head *head) |
1282 | { | 1280 | { |
1283 | struct timer_list *timer; | 1281 | struct timer_list *timer; |
1284 | 1282 | ||
@@ -1292,8 +1290,8 @@ static void migrate_timer_list(tvec_base_t *new_base, struct list_head *head) | |||
1292 | 1290 | ||
1293 | static void __cpuinit migrate_timers(int cpu) | 1291 | static void __cpuinit migrate_timers(int cpu) |
1294 | { | 1292 | { |
1295 | tvec_base_t *old_base; | 1293 | struct tvec_base *old_base; |
1296 | tvec_base_t *new_base; | 1294 | struct tvec_base *new_base; |
1297 | int i; | 1295 | int i; |
1298 | 1296 | ||
1299 | BUG_ON(cpu_online(cpu)); | 1297 | BUG_ON(cpu_online(cpu)); |