Commit 041142d7 authored by Hans de Goede's avatar Hans de Goede Committed by Rafael J. Wysocki

ACPI: platform-profile: Fix possible deadlock in platform_profile_remove()

After a rmmod thinkpad_acpi, lockdep pointed out this possible deadlock:

Our _show and _store sysfs attr functions get called with the kn->active
lock held for the sysfs attr and then take the profile_lock.
sysfs_remove_group() also takes the kn->active lock for the sysfs attr,
so if we call it with the profile_lock held, then we get an ABBA deadlock.

platform_profile_remove() must only be called by drivers which have
first *successfully* called platform_profile_register(). Anything else
is a driver bug. So the check for cur_profile being set before calling
sysfs_remove_group() is not necessary and it can be dropped.

It is safe to call sysfs_remove_group() without holding the profile_lock
since the attr-group group cannot be re-added until after we clear
cur_profile.

Change platform_profile_remove() to only hold the profile_lock while
clearing the cur_profile, fixing the deadlock.
Signed-off-by: default avatarHans de Goede <hdegoede@redhat.com>
Signed-off-by: default avatarRafael J. Wysocki <rafael.j.wysocki@intel.com>
parent 84f9017c
...@@ -164,13 +164,9 @@ EXPORT_SYMBOL_GPL(platform_profile_register); ...@@ -164,13 +164,9 @@ EXPORT_SYMBOL_GPL(platform_profile_register);
int platform_profile_remove(void) int platform_profile_remove(void)
{ {
mutex_lock(&profile_lock);
if (!cur_profile) {
mutex_unlock(&profile_lock);
return -ENODEV;
}
sysfs_remove_group(acpi_kobj, &platform_profile_group); sysfs_remove_group(acpi_kobj, &platform_profile_group);
mutex_lock(&profile_lock);
cur_profile = NULL; cur_profile = NULL;
mutex_unlock(&profile_lock); mutex_unlock(&profile_lock);
return 0; return 0;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment