ACPI / battery: Safe unregistering of hooks
A hooking API was implemented for 4.17 infa93854f7a
followed by hooks for Thinkpad laptops in2801b9683f
. The Thinkpad drivers did not support the Thinkpad 13 and the hooking API crashes on unsupported batteries by altering a list of hooks during unsafe iteration. Thus, Thinkpad 13 laptops could no longer boot. Additionally, a lock was kept in place and debugging information was printed out of order. Fixes:fa93854f7a
(battery: Add the battery hooking API) Cc: 4.17+ <stable@vger.kernel.org> # 4.17+ Signed-off-by: Jouke Witteveen <j.witteveen@gmail.com> Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
This commit is contained in:
parent
021c91791a
commit
673b427166
@ -717,10 +717,11 @@ void battery_hook_register(struct acpi_battery_hook *hook)
|
|||||||
*/
|
*/
|
||||||
pr_err("extension failed to load: %s", hook->name);
|
pr_err("extension failed to load: %s", hook->name);
|
||||||
__battery_hook_unregister(hook, 0);
|
__battery_hook_unregister(hook, 0);
|
||||||
return;
|
goto end;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
pr_info("new extension: %s\n", hook->name);
|
pr_info("new extension: %s\n", hook->name);
|
||||||
|
end:
|
||||||
mutex_unlock(&hook_mutex);
|
mutex_unlock(&hook_mutex);
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(battery_hook_register);
|
EXPORT_SYMBOL_GPL(battery_hook_register);
|
||||||
@ -732,7 +733,7 @@ EXPORT_SYMBOL_GPL(battery_hook_register);
|
|||||||
*/
|
*/
|
||||||
static void battery_hook_add_battery(struct acpi_battery *battery)
|
static void battery_hook_add_battery(struct acpi_battery *battery)
|
||||||
{
|
{
|
||||||
struct acpi_battery_hook *hook_node;
|
struct acpi_battery_hook *hook_node, *tmp;
|
||||||
|
|
||||||
mutex_lock(&hook_mutex);
|
mutex_lock(&hook_mutex);
|
||||||
INIT_LIST_HEAD(&battery->list);
|
INIT_LIST_HEAD(&battery->list);
|
||||||
@ -744,15 +745,15 @@ static void battery_hook_add_battery(struct acpi_battery *battery)
|
|||||||
* when a battery gets hotplugged or initialized
|
* when a battery gets hotplugged or initialized
|
||||||
* during the battery module initialization.
|
* during the battery module initialization.
|
||||||
*/
|
*/
|
||||||
list_for_each_entry(hook_node, &battery_hook_list, list) {
|
list_for_each_entry_safe(hook_node, tmp, &battery_hook_list, list) {
|
||||||
if (hook_node->add_battery(battery->bat)) {
|
if (hook_node->add_battery(battery->bat)) {
|
||||||
/*
|
/*
|
||||||
* The notification of the extensions has failed, to
|
* The notification of the extensions has failed, to
|
||||||
* prevent further errors we will unload the extension.
|
* prevent further errors we will unload the extension.
|
||||||
*/
|
*/
|
||||||
__battery_hook_unregister(hook_node, 0);
|
|
||||||
pr_err("error in extension, unloading: %s",
|
pr_err("error in extension, unloading: %s",
|
||||||
hook_node->name);
|
hook_node->name);
|
||||||
|
__battery_hook_unregister(hook_node, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
mutex_unlock(&hook_mutex);
|
mutex_unlock(&hook_mutex);
|
||||||
|
Loading…
Reference in New Issue
Block a user