summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--init/main.c51
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
495void __init __weak mem_encrypt_init(void) { } 495void __init __weak mem_encrypt_init(void) { }
496 496
497bool initcall_debug;
498core_param(initcall_debug, initcall_debug, bool, 0644);
499static 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
734bool initcall_debug;
735core_param(initcall_debug, initcall_debug, bool, 0644);
736
737#ifdef CONFIG_KALLSYMS 741#ifdef CONFIG_KALLSYMS
738struct blacklist_entry { 742struct 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
806static int __init_or_module do_one_initcall_debug(initcall_t fn) 810static __init_or_module void
811trace_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
819static __init_or_module void
820trace_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; 833static ktime_t initcall_calltime;
834
835static 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
824int __init_or_module do_one_initcall(initcall_t fn) 846int __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;