libmodprobe: allow module with soft dependencies to load in parallel
1. integrate modules which have soft dependencies into parallel loading flow. First, check the soft dependencies are in `module.load` list. If yes, regard soft dependencies as hard dependencies and load the modules only when their dependencies are loaded. If not, abandon these soft dependencies. 2. also add an allowlist and use the term "load_sequential=1" to load specific modules in sequential. Test: R4 saves 350ms+ (48%) to load all modules Bug: 229794277 Signed-off-by: chungkai <chungkai@google.com> Change-Id: I904fe31cd02f9d499dadc537335cadc88d8add70
This commit is contained in:
parent
7c43c6c9a0
commit
d84c42e3b3
1 changed files with 17 additions and 22 deletions
|
@ -440,12 +440,11 @@ bool Modprobe::IsBlocklisted(const std::string& module_name) {
|
|||
}
|
||||
|
||||
// Another option to load kernel modules. load in independent modules in parallel
|
||||
// and then load modules which only have soft dependency, third update dependency list of other
|
||||
// remaining modules, repeat these steps until all modules are loaded.
|
||||
// and then update dependency list of other remaining modules, repeat these steps
|
||||
// until all modules are loaded.
|
||||
bool Modprobe::LoadModulesParallel(int num_threads) {
|
||||
bool ret = true;
|
||||
std::map<std::string, std::set<std::string>> mod_with_deps;
|
||||
std::map<std::string, std::set<std::string>> mod_with_softdeps;
|
||||
|
||||
// Get dependencies
|
||||
for (const auto& module : module_load_) {
|
||||
|
@ -458,26 +457,33 @@ bool Modprobe::LoadModulesParallel(int num_threads) {
|
|||
|
||||
// Get soft dependencies
|
||||
for (const auto& [it_mod, it_softdep] : module_pre_softdep_) {
|
||||
mod_with_softdeps[MakeCanonical(it_mod)].emplace(it_softdep);
|
||||
if (mod_with_deps.find(MakeCanonical(it_softdep)) != mod_with_deps.end()) {
|
||||
mod_with_deps[MakeCanonical(it_mod)].emplace(
|
||||
GetDependencies(MakeCanonical(it_softdep))[0]);
|
||||
}
|
||||
}
|
||||
|
||||
// Get soft post dependencies
|
||||
for (const auto& [it_mod, it_softdep] : module_post_softdep_) {
|
||||
mod_with_softdeps[MakeCanonical(it_mod)].emplace(it_softdep);
|
||||
if (mod_with_deps.find(MakeCanonical(it_softdep)) != mod_with_deps.end()) {
|
||||
mod_with_deps[MakeCanonical(it_softdep)].emplace(
|
||||
GetDependencies(MakeCanonical(it_mod))[0]);
|
||||
}
|
||||
}
|
||||
|
||||
while (!mod_with_deps.empty()) {
|
||||
std::vector<std::thread> threads;
|
||||
std::vector<std::string> mods_path_to_load;
|
||||
std::vector<std::string> mods_with_softdep_to_load;
|
||||
std::mutex vector_lock;
|
||||
|
||||
// Find independent modules and modules only having soft dependencies
|
||||
// Find independent modules
|
||||
for (const auto& [it_mod, it_dep] : mod_with_deps) {
|
||||
if (it_dep.size() == 1 && mod_with_softdeps[it_mod].empty()) {
|
||||
mods_path_to_load.emplace_back(*(it_dep.begin()));
|
||||
} else if (it_dep.size() == 1) {
|
||||
mods_with_softdep_to_load.emplace_back(it_mod);
|
||||
if (it_dep.size() == 1) {
|
||||
if (module_options_[it_mod].find("load_sequential=1") != std::string::npos) {
|
||||
LoadWithAliases(it_mod, true);
|
||||
} else {
|
||||
mods_path_to_load.emplace_back(*(it_dep.begin()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -502,21 +508,10 @@ bool Modprobe::LoadModulesParallel(int num_threads) {
|
|||
thread.join();
|
||||
}
|
||||
|
||||
// Since we cannot assure if these soft dependencies tree are overlap,
|
||||
// we loaded these modules one by one.
|
||||
for (auto dep = mods_with_softdep_to_load.rbegin(); dep != mods_with_softdep_to_load.rend();
|
||||
dep++) {
|
||||
ret &= LoadWithAliases(*dep, true);
|
||||
}
|
||||
|
||||
std::lock_guard guard(module_loaded_lock_);
|
||||
// Remove loaded module form mod_with_deps and soft dependencies of other modules
|
||||
for (const auto& module_loaded : module_loaded_) {
|
||||
mod_with_deps.erase(module_loaded);
|
||||
|
||||
for (auto& [mod, softdeps] : mod_with_softdeps) {
|
||||
softdeps.erase(module_loaded);
|
||||
}
|
||||
}
|
||||
|
||||
// Remove loaded module form dependencies of other modules which are not loaded yet
|
||||
|
|
Loading…
Reference in a new issue