init, tracing: Have printk come through the trace events for initcall_debug

With trace events set before and after the initcall function calls, instead
of having a separate routine for printing out the initcalls when
initcall_debug is specified on the kernel command line, have the code
register a callback to the tracepoints where the initcall trace events are.

This removes the need for having a separate function to do the initcalls as
the tracepoint callbacks can handle the printk. It also includes other
initcalls that are not called by the do_one_initcall() which includes
console and security initcalls.
Signed-off-by: default avatarSteven Rostedt (VMware) <rostedt@goodmis.org>
parent 58eacfff
...@@ -494,6 +494,10 @@ void __init __weak thread_stack_cache_init(void) ...@@ -494,6 +494,10 @@ void __init __weak thread_stack_cache_init(void)
void __init __weak mem_encrypt_init(void) { } void __init __weak mem_encrypt_init(void) { }
bool initcall_debug;
core_param(initcall_debug, initcall_debug, bool, 0644);
static void __init initcall_debug_enable(void);
/* /*
* Set up kernel memory allocators * Set up kernel memory allocators
*/ */
...@@ -615,6 +619,9 @@ asmlinkage __visible void __init start_kernel(void) ...@@ -615,6 +619,9 @@ asmlinkage __visible void __init start_kernel(void)
/* Trace events are available after this */ /* Trace events are available after this */
trace_init(); trace_init();
if (initcall_debug)
initcall_debug_enable();
context_tracking_init(); context_tracking_init();
/* init some links before init_ISA_irqs() */ /* init some links before init_ISA_irqs() */
early_irq_init(); early_irq_init();
...@@ -731,9 +738,6 @@ static void __init do_ctors(void) ...@@ -731,9 +738,6 @@ static void __init do_ctors(void)
#endif #endif
} }
bool initcall_debug;
core_param(initcall_debug, initcall_debug, bool, 0644);
#ifdef CONFIG_KALLSYMS #ifdef CONFIG_KALLSYMS
struct blacklist_entry { struct blacklist_entry {
struct list_head next; struct list_head next;
...@@ -803,38 +807,53 @@ static bool __init_or_module initcall_blacklisted(initcall_t fn) ...@@ -803,38 +807,53 @@ static bool __init_or_module initcall_blacklisted(initcall_t fn)
#endif #endif
__setup("initcall_blacklist=", initcall_blacklist); __setup("initcall_blacklist=", initcall_blacklist);
static int __init_or_module do_one_initcall_debug(initcall_t fn) static __init_or_module void
trace_initcall_start_cb(void *data, initcall_t fn)
{ {
ktime_t calltime, delta, rettime; ktime_t *calltime = (ktime_t *)data;
unsigned long long duration;
int ret;
printk(KERN_DEBUG "calling %pF @ %i\n", fn, task_pid_nr(current)); printk(KERN_DEBUG "calling %pF @ %i\n", fn, task_pid_nr(current));
calltime = ktime_get(); *calltime = ktime_get();
ret = fn(); }
static __init_or_module void
trace_initcall_finish_cb(void *data, initcall_t fn, int ret)
{
ktime_t *calltime = (ktime_t *)data;
ktime_t delta, rettime;
unsigned long long duration;
rettime = ktime_get(); rettime = ktime_get();
delta = ktime_sub(rettime, calltime); delta = ktime_sub(rettime, *calltime);
duration = (unsigned long long) ktime_to_ns(delta) >> 10; duration = (unsigned long long) ktime_to_ns(delta) >> 10;
printk(KERN_DEBUG "initcall %pF returned %d after %lld usecs\n", printk(KERN_DEBUG "initcall %pF returned %d after %lld usecs\n",
fn, ret, duration); fn, ret, duration);
}
return ret; static ktime_t initcall_calltime;
static void __init initcall_debug_enable(void)
{
int ret;
ret = register_trace_initcall_start(trace_initcall_start_cb,
&initcall_calltime);
ret |= register_trace_initcall_finish(trace_initcall_finish_cb,
&initcall_calltime);
WARN(ret, "Failed to register initcall tracepoints\n");
} }
int __init_or_module do_one_initcall(initcall_t fn) int __init_or_module do_one_initcall(initcall_t fn)
{ {
int count = preempt_count(); int count = preempt_count();
int ret;
char msgbuf[64]; char msgbuf[64];
int ret;
if (initcall_blacklisted(fn)) if (initcall_blacklisted(fn))
return -EPERM; return -EPERM;
trace_initcall_start(fn); trace_initcall_start(fn);
if (initcall_debug) ret = fn();
ret = do_one_initcall_debug(fn);
else
ret = fn();
trace_initcall_finish(fn, ret); trace_initcall_finish(fn, ret);
msgbuf[0] = 0; msgbuf[0] = 0;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment