On Thu, May 25, 2023, at 3:41 PM, Hans de Goede wrote: > Hi Mark, > > On 5/25/23 21:31, Mark Pearson wrote: >> Add mutex protection around cases where an operation needs multiple >> WMI calls - e.g. setting password. >> >> Signed-off-by: Mark Pearson <mpearson-lenovo@xxxxxxxxx> >> --- >> Changes in V2: New commit added after review of other patches in series. >> >> drivers/platform/x86/think-lmi.c | 46 ++++++++++++++++++++++++-------- >> 1 file changed, 35 insertions(+), 11 deletions(-) >> >> diff --git a/drivers/platform/x86/think-lmi.c b/drivers/platform/x86/think-lmi.c >> index 64cd453d6e7d..f3e1e4dacba2 100644 >> --- a/drivers/platform/x86/think-lmi.c >> +++ b/drivers/platform/x86/think-lmi.c >> @@ -14,6 +14,7 @@ >> #include <linux/acpi.h> >> #include <linux/errno.h> >> #include <linux/fs.h> >> +#include <linux/mutex.h> >> #include <linux/string.h> >> #include <linux/types.h> >> #include <linux/dmi.h> >> @@ -195,6 +196,7 @@ static const char * const level_options[] = { >> }; >> static struct think_lmi tlmi_priv; >> static struct class *fw_attr_class; >> +static DEFINE_MUTEX(tlmi_mutex); >> >> /* ------ Utility functions ------------*/ >> /* Strip out CR if one is present */ >> @@ -463,23 +465,32 @@ static ssize_t new_password_store(struct kobject *kobj, >> sprintf(pwd_type, "%s", setting->pwd_type); >> } >> >> + mutex_lock(&tlmi_mutex); >> ret = tlmi_opcode_setting("WmiOpcodePasswordType", pwd_type); >> - if (ret) >> + if (ret) { >> + mutex_unlock(&tlmi_mutex); >> goto out; >> - >> + } >> if (tlmi_priv.pwd_admin->valid) { >> ret = tlmi_opcode_setting("WmiOpcodePasswordAdmin", >> tlmi_priv.pwd_admin->password); >> - if (ret) >> + if (ret) { >> + mutex_unlock(&tlmi_mutex); >> goto out; >> + } >> } >> ret = tlmi_opcode_setting("WmiOpcodePasswordCurrent01", setting->password); >> - if (ret) >> + if (ret) { >> + mutex_unlock(&tlmi_mutex); >> goto out; >> + } >> ret = tlmi_opcode_setting("WmiOpcodePasswordNew01", new_pwd); >> - if (ret) >> + if (ret) { >> + mutex_unlock(&tlmi_mutex); >> goto out; >> + } >> ret = tlmi_simple_call(LENOVO_OPCODE_IF_GUID, "WmiOpcodePasswordSetUpdate;"); >> + mutex_unlock(&tlmi_mutex); >> } else { >> /* Format: 'PasswordType,CurrentPw,NewPw,Encoding,KbdLang;' */ >> auth_str = kasprintf(GFP_KERNEL, "%s,%s,%s,%s,%s;", > > > I haven't take a really close / good look yet. But at a first glance > I think it would be cleaner to just take the mutex at the top > and unlock it after the out label to which all the existing goto-s > already go ? > I did consider that - and it was in my first implementation; but then I got concerned about if the mutex_unlock could potentially get called without mutex_lock having been called beforehand. I couldn't find any good reference as to whether that was safe or not. I ended up deciding that a few extra brackets and unlock calls wasn't that ugly and was 'safer'...and so went that route. Happy to change it - but do you happen to know if it's safe to call unlock without a lock? If it is then that implementation is cleaner. Mark