Message ID | 20220829162953.5947-1-mario.limonciello@amd.com |
---|---|
Headers | show |
Series | Add some extra debugging mechanisms for s0i3 | expand |
On Mon, Aug 29, 2022 at 6:29 PM Mario Limonciello <mario.limonciello@amd.com> wrote: > > On some platforms it is found that Linux more aggressively enters s2idle > than Windows enters Modern Standby and this uncovers some synchronization > issues for the platform. To aid in debugging this class of problems in > the future, add support for an extra optional callback intended for > drivers to emit extra debugging. > > Signed-off-by: Mario Limonciello <mario.limonciello@amd.com> Acked-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com> and I'm assuming that this is for Hans. > --- > v2->v3: > * Rename to *check > v1->v2: > * Add a prototype for `acpi_s2idle_enter` > > drivers/acpi/sleep.h | 1 + > drivers/acpi/x86/s2idle.c | 14 ++++++++++++++ > include/linux/acpi.h | 1 + > include/linux/suspend.h | 1 + > kernel/power/suspend.c | 3 +++ > 5 files changed, 20 insertions(+) > > diff --git a/drivers/acpi/sleep.h b/drivers/acpi/sleep.h > index 7fe41ee489d6..d960a238be4e 100644 > --- a/drivers/acpi/sleep.h > +++ b/drivers/acpi/sleep.h > @@ -18,6 +18,7 @@ static inline acpi_status acpi_set_waking_vector(u32 wakeup_address) > extern int acpi_s2idle_begin(void); > extern int acpi_s2idle_prepare(void); > extern int acpi_s2idle_prepare_late(void); > +extern void acpi_s2idle_check(void); > extern bool acpi_s2idle_wake(void); > extern void acpi_s2idle_restore_early(void); > extern void acpi_s2idle_restore(void); > diff --git a/drivers/acpi/x86/s2idle.c b/drivers/acpi/x86/s2idle.c > index f9ac12b778e6..474aa46f82f6 100644 > --- a/drivers/acpi/x86/s2idle.c > +++ b/drivers/acpi/x86/s2idle.c > @@ -486,6 +486,19 @@ int acpi_s2idle_prepare_late(void) > return 0; > } > > +void acpi_s2idle_check(void) > +{ > + struct acpi_s2idle_dev_ops *handler; > + > + if (!lps0_device_handle || sleep_no_lps0) > + return; > + > + list_for_each_entry(handler, &lps0_s2idle_devops_head, list_node) { > + if (handler->check) > + handler->check(); > + } > +} > + > void acpi_s2idle_restore_early(void) > { > struct acpi_s2idle_dev_ops *handler; > @@ -527,6 +540,7 @@ static const struct platform_s2idle_ops acpi_s2idle_ops_lps0 = { > .begin = acpi_s2idle_begin, > .prepare = acpi_s2idle_prepare, > .prepare_late = acpi_s2idle_prepare_late, > + .check = acpi_s2idle_check, > .wake = acpi_s2idle_wake, > .restore_early = acpi_s2idle_restore_early, > .restore = acpi_s2idle_restore, > diff --git a/include/linux/acpi.h b/include/linux/acpi.h > index 6f64b2f3dc54..acaa2ddc067d 100644 > --- a/include/linux/acpi.h > +++ b/include/linux/acpi.h > @@ -1075,6 +1075,7 @@ acpi_status acpi_os_prepare_extended_sleep(u8 sleep_state, > struct acpi_s2idle_dev_ops { > struct list_head list_node; > void (*prepare)(void); > + void (*check)(void); > void (*restore)(void); > }; > int acpi_register_lps0_dev(struct acpi_s2idle_dev_ops *arg); > diff --git a/include/linux/suspend.h b/include/linux/suspend.h > index 70f2921e2e70..03ed42ed2c7f 100644 > --- a/include/linux/suspend.h > +++ b/include/linux/suspend.h > @@ -191,6 +191,7 @@ struct platform_s2idle_ops { > int (*begin)(void); > int (*prepare)(void); > int (*prepare_late)(void); > + void (*check)(void); > bool (*wake)(void); > void (*restore_early)(void); > void (*restore)(void); > diff --git a/kernel/power/suspend.c b/kernel/power/suspend.c > index 827075944d28..c6272d466e58 100644 > --- a/kernel/power/suspend.c > +++ b/kernel/power/suspend.c > @@ -136,6 +136,9 @@ static void s2idle_loop(void) > break; > } > > + if (s2idle_ops && s2idle_ops->check) > + s2idle_ops->check(); > + > s2idle_enter(); > } > > -- > 2.34.1 >
On 8/30/2022 06:39, Rafael J. Wysocki wrote: > On Mon, Aug 29, 2022 at 6:29 PM Mario Limonciello > <mario.limonciello@amd.com> wrote: >> >> On some platforms it is found that Linux more aggressively enters s2idle >> than Windows enters Modern Standby and this uncovers some synchronization >> issues for the platform. To aid in debugging this class of problems in >> the future, add support for an extra optional callback intended for >> drivers to emit extra debugging. >> >> Signed-off-by: Mario Limonciello <mario.limonciello@amd.com> > > Acked-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com> > > and I'm assuming that this is for Hans. Thanks, and yeah I think it makes more sense for this to go through platform-x86. > >> --- >> v2->v3: >> * Rename to *check >> v1->v2: >> * Add a prototype for `acpi_s2idle_enter` >> >> drivers/acpi/sleep.h | 1 + >> drivers/acpi/x86/s2idle.c | 14 ++++++++++++++ >> include/linux/acpi.h | 1 + >> include/linux/suspend.h | 1 + >> kernel/power/suspend.c | 3 +++ >> 5 files changed, 20 insertions(+) >> >> diff --git a/drivers/acpi/sleep.h b/drivers/acpi/sleep.h >> index 7fe41ee489d6..d960a238be4e 100644 >> --- a/drivers/acpi/sleep.h >> +++ b/drivers/acpi/sleep.h >> @@ -18,6 +18,7 @@ static inline acpi_status acpi_set_waking_vector(u32 wakeup_address) >> extern int acpi_s2idle_begin(void); >> extern int acpi_s2idle_prepare(void); >> extern int acpi_s2idle_prepare_late(void); >> +extern void acpi_s2idle_check(void); >> extern bool acpi_s2idle_wake(void); >> extern void acpi_s2idle_restore_early(void); >> extern void acpi_s2idle_restore(void); >> diff --git a/drivers/acpi/x86/s2idle.c b/drivers/acpi/x86/s2idle.c >> index f9ac12b778e6..474aa46f82f6 100644 >> --- a/drivers/acpi/x86/s2idle.c >> +++ b/drivers/acpi/x86/s2idle.c >> @@ -486,6 +486,19 @@ int acpi_s2idle_prepare_late(void) >> return 0; >> } >> >> +void acpi_s2idle_check(void) >> +{ >> + struct acpi_s2idle_dev_ops *handler; >> + >> + if (!lps0_device_handle || sleep_no_lps0) >> + return; >> + >> + list_for_each_entry(handler, &lps0_s2idle_devops_head, list_node) { >> + if (handler->check) >> + handler->check(); >> + } >> +} >> + >> void acpi_s2idle_restore_early(void) >> { >> struct acpi_s2idle_dev_ops *handler; >> @@ -527,6 +540,7 @@ static const struct platform_s2idle_ops acpi_s2idle_ops_lps0 = { >> .begin = acpi_s2idle_begin, >> .prepare = acpi_s2idle_prepare, >> .prepare_late = acpi_s2idle_prepare_late, >> + .check = acpi_s2idle_check, >> .wake = acpi_s2idle_wake, >> .restore_early = acpi_s2idle_restore_early, >> .restore = acpi_s2idle_restore, >> diff --git a/include/linux/acpi.h b/include/linux/acpi.h >> index 6f64b2f3dc54..acaa2ddc067d 100644 >> --- a/include/linux/acpi.h >> +++ b/include/linux/acpi.h >> @@ -1075,6 +1075,7 @@ acpi_status acpi_os_prepare_extended_sleep(u8 sleep_state, >> struct acpi_s2idle_dev_ops { >> struct list_head list_node; >> void (*prepare)(void); >> + void (*check)(void); >> void (*restore)(void); >> }; >> int acpi_register_lps0_dev(struct acpi_s2idle_dev_ops *arg); >> diff --git a/include/linux/suspend.h b/include/linux/suspend.h >> index 70f2921e2e70..03ed42ed2c7f 100644 >> --- a/include/linux/suspend.h >> +++ b/include/linux/suspend.h >> @@ -191,6 +191,7 @@ struct platform_s2idle_ops { >> int (*begin)(void); >> int (*prepare)(void); >> int (*prepare_late)(void); >> + void (*check)(void); >> bool (*wake)(void); >> void (*restore_early)(void); >> void (*restore)(void); >> diff --git a/kernel/power/suspend.c b/kernel/power/suspend.c >> index 827075944d28..c6272d466e58 100644 >> --- a/kernel/power/suspend.c >> +++ b/kernel/power/suspend.c >> @@ -136,6 +136,9 @@ static void s2idle_loop(void) >> break; >> } >> >> + if (s2idle_ops && s2idle_ops->check) >> + s2idle_ops->check(); >> + >> s2idle_enter(); >> } >> >> -- >> 2.34.1 >>
Hi, On 8/30/22 13:42, Limonciello, Mario wrote: > On 8/30/2022 06:39, Rafael J. Wysocki wrote: >> On Mon, Aug 29, 2022 at 6:29 PM Mario Limonciello >> <mario.limonciello@amd.com> wrote: >>> >>> On some platforms it is found that Linux more aggressively enters s2idle >>> than Windows enters Modern Standby and this uncovers some synchronization >>> issues for the platform. To aid in debugging this class of problems in >>> the future, add support for an extra optional callback intended for >>> drivers to emit extra debugging. >>> >>> Signed-off-by: Mario Limonciello <mario.limonciello@amd.com> >> >> Acked-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com> >> >> and I'm assuming that this is for Hans. > > Thanks, and yeah I think it makes more sense for this to go through platform-x86. Ok, I will review 2-4 and merge the entire series through platform-x86. Regards, Hans > >> >>> --- >>> v2->v3: >>> * Rename to *check >>> v1->v2: >>> * Add a prototype for `acpi_s2idle_enter` >>> >>> drivers/acpi/sleep.h | 1 + >>> drivers/acpi/x86/s2idle.c | 14 ++++++++++++++ >>> include/linux/acpi.h | 1 + >>> include/linux/suspend.h | 1 + >>> kernel/power/suspend.c | 3 +++ >>> 5 files changed, 20 insertions(+) >>> >>> diff --git a/drivers/acpi/sleep.h b/drivers/acpi/sleep.h >>> index 7fe41ee489d6..d960a238be4e 100644 >>> --- a/drivers/acpi/sleep.h >>> +++ b/drivers/acpi/sleep.h >>> @@ -18,6 +18,7 @@ static inline acpi_status acpi_set_waking_vector(u32 wakeup_address) >>> extern int acpi_s2idle_begin(void); >>> extern int acpi_s2idle_prepare(void); >>> extern int acpi_s2idle_prepare_late(void); >>> +extern void acpi_s2idle_check(void); >>> extern bool acpi_s2idle_wake(void); >>> extern void acpi_s2idle_restore_early(void); >>> extern void acpi_s2idle_restore(void); >>> diff --git a/drivers/acpi/x86/s2idle.c b/drivers/acpi/x86/s2idle.c >>> index f9ac12b778e6..474aa46f82f6 100644 >>> --- a/drivers/acpi/x86/s2idle.c >>> +++ b/drivers/acpi/x86/s2idle.c >>> @@ -486,6 +486,19 @@ int acpi_s2idle_prepare_late(void) >>> return 0; >>> } >>> >>> +void acpi_s2idle_check(void) >>> +{ >>> + struct acpi_s2idle_dev_ops *handler; >>> + >>> + if (!lps0_device_handle || sleep_no_lps0) >>> + return; >>> + >>> + list_for_each_entry(handler, &lps0_s2idle_devops_head, list_node) { >>> + if (handler->check) >>> + handler->check(); >>> + } >>> +} >>> + >>> void acpi_s2idle_restore_early(void) >>> { >>> struct acpi_s2idle_dev_ops *handler; >>> @@ -527,6 +540,7 @@ static const struct platform_s2idle_ops acpi_s2idle_ops_lps0 = { >>> .begin = acpi_s2idle_begin, >>> .prepare = acpi_s2idle_prepare, >>> .prepare_late = acpi_s2idle_prepare_late, >>> + .check = acpi_s2idle_check, >>> .wake = acpi_s2idle_wake, >>> .restore_early = acpi_s2idle_restore_early, >>> .restore = acpi_s2idle_restore, >>> diff --git a/include/linux/acpi.h b/include/linux/acpi.h >>> index 6f64b2f3dc54..acaa2ddc067d 100644 >>> --- a/include/linux/acpi.h >>> +++ b/include/linux/acpi.h >>> @@ -1075,6 +1075,7 @@ acpi_status acpi_os_prepare_extended_sleep(u8 sleep_state, >>> struct acpi_s2idle_dev_ops { >>> struct list_head list_node; >>> void (*prepare)(void); >>> + void (*check)(void); >>> void (*restore)(void); >>> }; >>> int acpi_register_lps0_dev(struct acpi_s2idle_dev_ops *arg); >>> diff --git a/include/linux/suspend.h b/include/linux/suspend.h >>> index 70f2921e2e70..03ed42ed2c7f 100644 >>> --- a/include/linux/suspend.h >>> +++ b/include/linux/suspend.h >>> @@ -191,6 +191,7 @@ struct platform_s2idle_ops { >>> int (*begin)(void); >>> int (*prepare)(void); >>> int (*prepare_late)(void); >>> + void (*check)(void); >>> bool (*wake)(void); >>> void (*restore_early)(void); >>> void (*restore)(void); >>> diff --git a/kernel/power/suspend.c b/kernel/power/suspend.c >>> index 827075944d28..c6272d466e58 100644 >>> --- a/kernel/power/suspend.c >>> +++ b/kernel/power/suspend.c >>> @@ -136,6 +136,9 @@ static void s2idle_loop(void) >>> break; >>> } >>> >>> + if (s2idle_ops && s2idle_ops->check) >>> + s2idle_ops->check(); >>> + >>> s2idle_enter(); >>> } >>> >>> -- >>> 2.34.1 >>> >