From 08c862fa003875cf464730c24e1b81b261f8b474 Mon Sep 17 00:00:00 2001 From: Lisa Liu Date: Wed, 3 Feb 2021 18:22:21 +0800 Subject: [PATCH] init: ro.boottime.init.modules Add a property ro.boottime.init.modules to provide kernel modules loading time in milliseconds. Also add corresponding log to show in init log along with loaded module count. Test: boot test Bug: 178143513 Change-Id: I77e3939c2a271da6841350a8c2a34ad32f637377 --- init/README.md | 3 +++ init/first_stage_init.cpp | 18 ++++++++++++++---- init/first_stage_init.h | 1 + init/init.cpp | 4 ++++ 4 files changed, 22 insertions(+), 4 deletions(-) diff --git a/init/README.md b/init/README.md index 67d55e1f6..bb1a1a094 100644 --- a/init/README.md +++ b/init/README.md @@ -795,6 +795,9 @@ Init records some boot timing information in system properties. `ro.boottime.init.selinux` > How long in ns it took to run SELinux stage. +`ro.boottime.init.modules` +> How long in ms it took to load kernel modules. + `ro.boottime.init.cold_boot_wait` > How long init waited for ueventd's coldboot phase to end. diff --git a/init/first_stage_init.cpp b/init/first_stage_init.cpp index 6954c03fb..83d2b6d37 100644 --- a/init/first_stage_init.cpp +++ b/init/first_stage_init.cpp @@ -122,7 +122,7 @@ std::string GetModuleLoadList(bool recovery, const std::string& dir_path) { } #define MODULE_BASE_DIR "/lib/modules" -bool LoadKernelModules(bool recovery, bool want_console) { +bool LoadKernelModules(bool recovery, bool want_console, int& modules_loaded) { struct utsname uts; if (uname(&uts)) { LOG(FATAL) << "Failed to get kernel version."; @@ -164,7 +164,7 @@ bool LoadKernelModules(bool recovery, bool want_console) { dir_path.append(module_dir); Modprobe m({dir_path}, GetModuleLoadList(recovery, dir_path)); bool retval = m.LoadListedModules(!want_console); - int modules_loaded = m.GetModuleCount(); + modules_loaded = m.GetModuleCount(); if (modules_loaded > 0) { return retval; } @@ -172,7 +172,7 @@ bool LoadKernelModules(bool recovery, bool want_console) { Modprobe m({MODULE_BASE_DIR}, GetModuleLoadList(recovery, MODULE_BASE_DIR)); bool retval = m.LoadListedModules(!want_console); - int modules_loaded = m.GetModuleCount(); + modules_loaded = m.GetModuleCount(); if (modules_loaded > 0) { return retval; } @@ -278,13 +278,23 @@ int FirstStageMain(int argc, char** argv) { auto want_console = ALLOW_FIRST_STAGE_CONSOLE ? FirstStageConsole(cmdline) : 0; - if (!LoadKernelModules(IsRecoveryMode() && !ForceNormalBoot(cmdline), want_console)) { + boot_clock::time_point module_start_time = boot_clock::now(); + int module_count = 0; + if (!LoadKernelModules(IsRecoveryMode() && !ForceNormalBoot(cmdline), want_console, + module_count)) { if (want_console != FirstStageConsoleParam::DISABLED) { LOG(ERROR) << "Failed to load kernel modules, starting console"; } else { LOG(FATAL) << "Failed to load kernel modules"; } } + if (module_count > 0) { + auto module_elapse_time = std::chrono::duration_cast( + boot_clock::now() - module_start_time); + setenv(kEnvInitModuleDurationMs, std::to_string(module_elapse_time.count()).c_str(), 1); + LOG(INFO) << "Loaded " << module_count << " kernel modules took " + << module_elapse_time.count() << " ms"; + } if (want_console == FirstStageConsoleParam::CONSOLE_ON_FAILURE) { StartConsole(cmdline); diff --git a/init/first_stage_init.h b/init/first_stage_init.h index 7de816f2a..1211f29b7 100644 --- a/init/first_stage_init.h +++ b/init/first_stage_init.h @@ -22,6 +22,7 @@ namespace init { int FirstStageMain(int argc, char** argv); static constexpr char kEnvFirstStageStartedAt[] = "FIRST_STAGE_STARTED_AT"; +static constexpr char kEnvInitModuleDurationMs[] = "INIT_MODULE_DURATION_MS"; } // namespace init } // namespace android diff --git a/init/init.cpp b/init/init.cpp index b08037a06..70d68097f 100644 --- a/init/init.cpp +++ b/init/init.cpp @@ -713,6 +713,10 @@ static void RecordStageBoottimes(const boot_clock::time_point& second_stage_star SetProperty("ro.boottime.init.selinux", std::to_string(second_stage_start_time.time_since_epoch().count() - selinux_start_time_ns)); + if (auto init_module_time_str = getenv(kEnvInitModuleDurationMs); init_module_time_str) { + SetProperty("ro.boottime.init.modules", init_module_time_str); + unsetenv(kEnvInitModuleDurationMs); + } } void SendLoadPersistentPropertiesMessage() {