diff options
| -rw-r--r-- | init/main.c | 51 |
1 files changed, 35 insertions, 16 deletions
diff --git a/init/main.c b/init/main.c index 2af8f2bb5ca8..589d1226016e 100644 --- a/init/main.c +++ b/init/main.c | |||
| @@ -494,6 +494,10 @@ void __init __weak thread_stack_cache_init(void) | |||
| 494 | 494 | ||
| 495 | void __init __weak mem_encrypt_init(void) { } | 495 | void __init __weak mem_encrypt_init(void) { } |
| 496 | 496 | ||
| 497 | bool initcall_debug; | ||
| 498 | core_param(initcall_debug, initcall_debug, bool, 0644); | ||
| 499 | static void __init initcall_debug_enable(void); | ||
| 500 | |||
| 497 | /* | 501 | /* |
| 498 | * Set up kernel memory allocators | 502 | * Set up kernel memory allocators |
| 499 | */ | 503 | */ |
| @@ -615,6 +619,9 @@ asmlinkage __visible void __init start_kernel(void) | |||
| 615 | /* Trace events are available after this */ | 619 | /* Trace events are available after this */ |
| 616 | trace_init(); | 620 | trace_init(); |
| 617 | 621 | ||
| 622 | if (initcall_debug) | ||
| 623 | initcall_debug_enable(); | ||
| 624 | |||
| 618 | context_tracking_init(); | 625 | context_tracking_init(); |
| 619 | /* init some links before init_ISA_irqs() */ | 626 | /* init some links before init_ISA_irqs() */ |
| 620 | early_irq_init(); | 627 | early_irq_init(); |
| @@ -731,9 +738,6 @@ static void __init do_ctors(void) | |||
| 731 | #endif | 738 | #endif |
| 732 | } | 739 | } |
| 733 | 740 | ||
| 734 | bool initcall_debug; | ||
| 735 | core_param(initcall_debug, initcall_debug, bool, 0644); | ||
| 736 | |||
| 737 | #ifdef CONFIG_KALLSYMS | 741 | #ifdef CONFIG_KALLSYMS |
| 738 | struct blacklist_entry { | 742 | struct blacklist_entry { |
| 739 | struct list_head next; | 743 | struct list_head next; |
| @@ -803,38 +807,53 @@ static bool __init_or_module initcall_blacklisted(initcall_t fn) | |||
| 803 | #endif | 807 | #endif |
| 804 | __setup("initcall_blacklist=", initcall_blacklist); | 808 | __setup("initcall_blacklist=", initcall_blacklist); |
| 805 | 809 | ||
| 806 | static int __init_or_module do_one_initcall_debug(initcall_t fn) | 810 | static __init_or_module void |
| 811 | trace_initcall_start_cb(void *data, initcall_t fn) | ||
| 807 | { | 812 | { |
| 808 | ktime_t calltime, delta, rettime; | 813 | ktime_t *calltime = (ktime_t *)data; |
| 809 | unsigned long long duration; | ||
| 810 | int ret; | ||
| 811 | 814 | ||
| 812 | printk(KERN_DEBUG "calling %pF @ %i\n", fn, task_pid_nr(current)); | 815 | printk(KERN_DEBUG "calling %pF @ %i\n", fn, task_pid_nr(current)); |
| 813 | calltime = ktime_get(); | 816 | *calltime = ktime_get(); |
| 814 | ret = fn(); | 817 | } |
| 818 | |||
| 819 | static __init_or_module void | ||
| 820 | trace_initcall_finish_cb(void *data, initcall_t fn, int ret) | ||
| 821 | { | ||
| 822 | ktime_t *calltime = (ktime_t *)data; | ||
| 823 | ktime_t delta, rettime; | ||
| 824 | unsigned long long duration; | ||
| 825 | |||
| 815 | rettime = ktime_get(); | 826 | rettime = ktime_get(); |
| 816 | delta = ktime_sub(rettime, calltime); | 827 | delta = ktime_sub(rettime, *calltime); |
| 817 | duration = (unsigned long long) ktime_to_ns(delta) >> 10; | 828 | duration = (unsigned long long) ktime_to_ns(delta) >> 10; |
| 818 | printk(KERN_DEBUG "initcall %pF returned %d after %lld usecs\n", | 829 | printk(KERN_DEBUG "initcall %pF returned %d after %lld usecs\n", |
| 819 | fn, ret, duration); | 830 | fn, ret, duration); |
| 831 | } | ||
| 820 | 832 | ||
| 821 | return ret; | 833 | static ktime_t initcall_calltime; |
| 834 | |||
| 835 | static void __init initcall_debug_enable(void) | ||
| 836 | { | ||
| 837 | int ret; | ||
| 838 | |||
| 839 | ret = register_trace_initcall_start(trace_initcall_start_cb, | ||
| 840 | &initcall_calltime); | ||
| 841 | ret |= register_trace_initcall_finish(trace_initcall_finish_cb, | ||
| 842 | &initcall_calltime); | ||
| 843 | WARN(ret, "Failed to register initcall tracepoints\n"); | ||
| 822 | } | 844 | } |
| 823 | 845 | ||
| 824 | int __init_or_module do_one_initcall(initcall_t fn) | 846 | int __init_or_module do_one_initcall(initcall_t fn) |
| 825 | { | 847 | { |
| 826 | int count = preempt_count(); | 848 | int count = preempt_count(); |
| 827 | int ret; | ||
| 828 | char msgbuf[64]; | 849 | char msgbuf[64]; |
| 850 | int ret; | ||
| 829 | 851 | ||
| 830 | if (initcall_blacklisted(fn)) | 852 | if (initcall_blacklisted(fn)) |
| 831 | return -EPERM; | 853 | return -EPERM; |
| 832 | 854 | ||
| 833 | trace_initcall_start(fn); | 855 | trace_initcall_start(fn); |
| 834 | if (initcall_debug) | 856 | ret = fn(); |
| 835 | ret = do_one_initcall_debug(fn); | ||
| 836 | else | ||
| 837 | ret = fn(); | ||
| 838 | trace_initcall_finish(fn, ret); | 857 | trace_initcall_finish(fn, ret); |
| 839 | 858 | ||
| 840 | msgbuf[0] = 0; | 859 | msgbuf[0] = 0; |
