Message ID | 20241031040952.109057-20-mario.limonciello@amd.com (mailing list archive) |
---|---|
State | Superseded, archived |
Headers | show |
Series | Add support for binding ACPI platform profile to multiple drivers | expand |
On Wed, 30 Oct 2024, Mario Limonciello wrote: > As multiple platform profile handlers might not all support the same > profile, cycling to the next profile could have a different result > depending on what handler are registered. > > Check what is active and supported by all handlers to decide what > to do. > > Signed-off-by: Mario Limonciello <mario.limonciello@amd.com> > --- > drivers/acpi/platform_profile.c | 35 ++++++++++++++++++++++----------- > 1 file changed, 23 insertions(+), 12 deletions(-) > > diff --git a/drivers/acpi/platform_profile.c b/drivers/acpi/platform_profile.c > index 5baac1f9a9c0e..9b681884ae324 100644 > --- a/drivers/acpi/platform_profile.c > +++ b/drivers/acpi/platform_profile.c > @@ -187,30 +187,41 @@ EXPORT_SYMBOL_GPL(platform_profile_notify); > > int platform_profile_cycle(void) > { > + enum platform_profile_option next = PLATFORM_PROFILE_LAST; > + struct platform_profile_handler *handler; > enum platform_profile_option profile; > - enum platform_profile_option next; > + unsigned long choices; > int err; > > scoped_cond_guard(mutex_intr, return -ERESTARTSYS, &profile_lock) { > - if (!cur_profile) > - return -ENODEV; > - > - err = cur_profile->profile_get(cur_profile, &profile); > + err = platform_profile_get_active(&profile); If platform_profile_cycle() is called without any profiles registered, platform_profile_get_active() will return success. I suppose you'd want check first that there is one registered and return -EINVAL if none are, especially since this is an exported function. > if (err) > return err; > > - next = find_next_bit_wrap(cur_profile->choices, PLATFORM_PROFILE_LAST, > - profile + 1); > + choices = platform_profile_get_choices(); > > - if (WARN_ON(next == PLATFORM_PROFILE_LAST)) > - return -EINVAL; > + next = find_next_bit_wrap(&choices, > + PLATFORM_PROFILE_LAST, > + profile + 1); > > - err = cur_profile->profile_set(cur_profile, next); > - if (err) > - return err; > + list_for_each_entry(handler, &platform_profile_handler_list, list) { > + err = handler->profile_set(handler, next); > + if (err) { > + pr_err("Failed to set profile for handler %s\n", handler->name); > + break; > + } > + } > + if (err) { Same here, instead of break you could goto to a rollback label to deindent the rollback loop a lot and make the code flow more obvious too. > + list_for_each_entry_continue_reverse(handler, &platform_profile_handler_list, list) { > + err = handler->profile_set(handler, PLATFORM_PROFILE_BALANCED); > + if (err) > + pr_err("Failed to revert profile for handler %s\n", handler->name); > + } > + } > } > > sysfs_notify(acpi_kobj, NULL, "platform_profile"); > + > return 0; > } > EXPORT_SYMBOL_GPL(platform_profile_cycle); >
On Thu, Oct 31, 2024, at 12:09 AM, Mario Limonciello wrote: > As multiple platform profile handlers might not all support the same > profile, cycling to the next profile could have a different result > depending on what handler are registered. > > Check what is active and supported by all handlers to decide what > to do. > > Signed-off-by: Mario Limonciello <mario.limonciello@amd.com> > --- > drivers/acpi/platform_profile.c | 35 ++++++++++++++++++++++----------- > 1 file changed, 23 insertions(+), 12 deletions(-) > > diff --git a/drivers/acpi/platform_profile.c b/drivers/acpi/platform_profile.c > index 5baac1f9a9c0e..9b681884ae324 100644 > --- a/drivers/acpi/platform_profile.c > +++ b/drivers/acpi/platform_profile.c > @@ -187,30 +187,41 @@ EXPORT_SYMBOL_GPL(platform_profile_notify); > > int platform_profile_cycle(void) > { > + enum platform_profile_option next = PLATFORM_PROFILE_LAST; > + struct platform_profile_handler *handler; > enum platform_profile_option profile; > - enum platform_profile_option next; > + unsigned long choices; > int err; > > scoped_cond_guard(mutex_intr, return -ERESTARTSYS, &profile_lock) { > - if (!cur_profile) > - return -ENODEV; > - > - err = cur_profile->profile_get(cur_profile, &profile); > + err = platform_profile_get_active(&profile); > if (err) > return err; > > - next = find_next_bit_wrap(cur_profile->choices, PLATFORM_PROFILE_LAST, > - profile + 1); > + choices = platform_profile_get_choices(); > > - if (WARN_ON(next == PLATFORM_PROFILE_LAST)) > - return -EINVAL; > + next = find_next_bit_wrap(&choices, > + PLATFORM_PROFILE_LAST, > + profile + 1); > > - err = cur_profile->profile_set(cur_profile, next); > - if (err) > - return err; > + list_for_each_entry(handler, &platform_profile_handler_list, list) { > + err = handler->profile_set(handler, next); > + if (err) { > + pr_err("Failed to set profile for handler %s\n", handler->name); Suggest highlighting which profile failed (profile_names[next]). > + break; > + } > + } > + if (err) { > + list_for_each_entry_continue_reverse(handler, > &platform_profile_handler_list, list) { > + err = handler->profile_set(handler, PLATFORM_PROFILE_BALANCED); > + if (err) > + pr_err("Failed to revert profile for handler %s\n", > handler->name); Suggest 'Failed to revert to balanced profiile for ...' > + } > + } > } > > sysfs_notify(acpi_kobj, NULL, "platform_profile"); > + > return 0; > } > EXPORT_SYMBOL_GPL(platform_profile_cycle); > -- > 2.43.0 My note from patch 15 applies here with having choices determined during registration/unregistration. Mark
diff --git a/drivers/acpi/platform_profile.c b/drivers/acpi/platform_profile.c index 5baac1f9a9c0e..9b681884ae324 100644 --- a/drivers/acpi/platform_profile.c +++ b/drivers/acpi/platform_profile.c @@ -187,30 +187,41 @@ EXPORT_SYMBOL_GPL(platform_profile_notify); int platform_profile_cycle(void) { + enum platform_profile_option next = PLATFORM_PROFILE_LAST; + struct platform_profile_handler *handler; enum platform_profile_option profile; - enum platform_profile_option next; + unsigned long choices; int err; scoped_cond_guard(mutex_intr, return -ERESTARTSYS, &profile_lock) { - if (!cur_profile) - return -ENODEV; - - err = cur_profile->profile_get(cur_profile, &profile); + err = platform_profile_get_active(&profile); if (err) return err; - next = find_next_bit_wrap(cur_profile->choices, PLATFORM_PROFILE_LAST, - profile + 1); + choices = platform_profile_get_choices(); - if (WARN_ON(next == PLATFORM_PROFILE_LAST)) - return -EINVAL; + next = find_next_bit_wrap(&choices, + PLATFORM_PROFILE_LAST, + profile + 1); - err = cur_profile->profile_set(cur_profile, next); - if (err) - return err; + list_for_each_entry(handler, &platform_profile_handler_list, list) { + err = handler->profile_set(handler, next); + if (err) { + pr_err("Failed to set profile for handler %s\n", handler->name); + break; + } + } + if (err) { + list_for_each_entry_continue_reverse(handler, &platform_profile_handler_list, list) { + err = handler->profile_set(handler, PLATFORM_PROFILE_BALANCED); + if (err) + pr_err("Failed to revert profile for handler %s\n", handler->name); + } + } } sysfs_notify(acpi_kobj, NULL, "platform_profile"); + return 0; } EXPORT_SYMBOL_GPL(platform_profile_cycle);
As multiple platform profile handlers might not all support the same profile, cycling to the next profile could have a different result depending on what handler are registered. Check what is active and supported by all handlers to decide what to do. Signed-off-by: Mario Limonciello <mario.limonciello@amd.com> --- drivers/acpi/platform_profile.c | 35 ++++++++++++++++++++++----------- 1 file changed, 23 insertions(+), 12 deletions(-)