Merge: acpi-cpufreq: Skip initializtion if a cpufreq driver exists

MR: https://gitlab.com/redhat/centos-stream/src/kernel/centos-stream-9/-/merge_requests/2240

Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=2028238

Return -EBUSY when attempting to reload a module in the BUSY state. This should prevent systemd from repeatedly attempting to reload multiple instances of the same driver. Specifically, this should speed up boot times on large multi-core Intel systems where the intel_pstate driver is available but acpi_cpufreq would also be an option.

Signed-off-by: Mark Langsdorf <mlangsdo@redhat.com>

Approved-by: Prarit Bhargava <prarit@redhat.com>
Approved-by: David Arcari <darcari@redhat.com>

Signed-off-by: Jan Stancek <jstancek@redhat.com>
This commit is contained in:
Jan Stancek 2023-06-01 07:25:52 +02:00
commit 4c53732f81
1 changed files with 21 additions and 5 deletions

View File

@ -3634,7 +3634,8 @@ static bool finished_loading(const char *name)
sched_annotate_sleep();
mutex_lock(&module_mutex);
mod = find_module_all(name, strlen(name), true);
ret = !mod || mod->state == MODULE_STATE_LIVE;
ret = !mod || mod->state == MODULE_STATE_LIVE
|| mod->state == MODULE_STATE_GOING;
mutex_unlock(&module_mutex);
return ret;
@ -3819,20 +3820,35 @@ static int add_unformed_module(struct module *mod)
mod->state = MODULE_STATE_UNFORMED;
again:
mutex_lock(&module_mutex);
old = find_module_all(mod->name, strlen(mod->name), true);
if (old != NULL) {
if (old->state != MODULE_STATE_LIVE) {
if (old->state == MODULE_STATE_COMING
|| old->state == MODULE_STATE_UNFORMED) {
/* Wait in case it fails to load. */
mutex_unlock(&module_mutex);
err = wait_event_interruptible(module_wq,
finished_loading(mod->name));
if (err)
goto out_unlocked;
goto again;
/* The module might have gone in the meantime. */
mutex_lock(&module_mutex);
old = find_module_all(mod->name, strlen(mod->name),
true);
}
err = -EEXIST;
/*
* We are here only when the same module was being loaded. Do
* not try to load it again right now. It prevents long delays
* caused by serialized module load failures. It might happen
* when more devices of the same type trigger load of
* a particular module.
*/
if (old && old->state == MODULE_STATE_LIVE)
err = -EEXIST;
else
err = -EBUSY;
goto out;
}
mod_update_bounds(mod);