2
0
mirror of git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git synced 2025-09-04 20:19:47 +08:00

init/main.c: log initcall level when initcall_debug is used

When initcall_debug is specified on the command line, the start and return
point for each initcall is printed.  However, no information on the
initcall level is reported.

Add to the initcall_debug infrastructure an additional print that informs
when a new initcall level is entered.  This is particularly useful when
debugging dependency chains and/or working on boot time reduction.

Link: https://lkml.kernel.org/r/20250316205014.2830071-2-francesco@valla.it
Signed-off-by: Francesco Valla <francesco@valla.it>
Cc: Steven Rostedt <rostedt@goodmis.org>
Cc: Tim Bird <tim.bird@sony.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
This commit is contained in:
Francesco Valla 2025-03-16 21:50:15 +01:00 committed by Andrew Morton
parent 3ca55ca225
commit 3330dc1b20

View File

@ -1214,6 +1214,12 @@ trace_initcall_finish_cb(void *data, initcall_t fn, int ret)
fn, ret, (unsigned long long)ktime_us_delta(rettime, *calltime)); fn, ret, (unsigned long long)ktime_us_delta(rettime, *calltime));
} }
static __init_or_module void
trace_initcall_level_cb(void *data, const char *level)
{
printk(KERN_DEBUG "entering initcall level: %s\n", level);
}
static ktime_t initcall_calltime; static ktime_t initcall_calltime;
#ifdef TRACEPOINTS_ENABLED #ifdef TRACEPOINTS_ENABLED
@ -1225,10 +1231,12 @@ static void __init initcall_debug_enable(void)
&initcall_calltime); &initcall_calltime);
ret |= register_trace_initcall_finish(trace_initcall_finish_cb, ret |= register_trace_initcall_finish(trace_initcall_finish_cb,
&initcall_calltime); &initcall_calltime);
ret |= register_trace_initcall_level(trace_initcall_level_cb, NULL);
WARN(ret, "Failed to register initcall tracepoints\n"); WARN(ret, "Failed to register initcall tracepoints\n");
} }
# define do_trace_initcall_start trace_initcall_start # define do_trace_initcall_start trace_initcall_start
# define do_trace_initcall_finish trace_initcall_finish # define do_trace_initcall_finish trace_initcall_finish
# define do_trace_initcall_level trace_initcall_level
#else #else
static inline void do_trace_initcall_start(initcall_t fn) static inline void do_trace_initcall_start(initcall_t fn)
{ {
@ -1242,6 +1250,12 @@ static inline void do_trace_initcall_finish(initcall_t fn, int ret)
return; return;
trace_initcall_finish_cb(&initcall_calltime, fn, ret); trace_initcall_finish_cb(&initcall_calltime, fn, ret);
} }
static inline void do_trace_initcall_level(const char *level)
{
if (!initcall_debug)
return;
trace_initcall_level_cb(NULL, level);
}
#endif /* !TRACEPOINTS_ENABLED */ #endif /* !TRACEPOINTS_ENABLED */
int __init_or_module do_one_initcall(initcall_t fn) int __init_or_module do_one_initcall(initcall_t fn)
@ -1314,7 +1328,7 @@ static void __init do_initcall_level(int level, char *command_line)
level, level, level, level,
NULL, ignore_unknown_bootoption); NULL, ignore_unknown_bootoption);
trace_initcall_level(initcall_level_names[level]); do_trace_initcall_level(initcall_level_names[level]);
for (fn = initcall_levels[level]; fn < initcall_levels[level+1]; fn++) for (fn = initcall_levels[level]; fn < initcall_levels[level+1]; fn++)
do_one_initcall(initcall_from_entry(fn)); do_one_initcall(initcall_from_entry(fn));
} }
@ -1358,7 +1372,7 @@ static void __init do_pre_smp_initcalls(void)
{ {
initcall_entry_t *fn; initcall_entry_t *fn;
trace_initcall_level("early"); do_trace_initcall_level("early");
for (fn = __initcall_start; fn < __initcall0_start; fn++) for (fn = __initcall_start; fn < __initcall0_start; fn++)
do_one_initcall(initcall_from_entry(fn)); do_one_initcall(initcall_from_entry(fn));
} }