Message ID | 2932420.e9J7NaK4W3@kreacher (mailing list archive) |
---|---|
State | Superseded, archived |
Headers | show |
Series | PM: sleep: Fix up suspend stats handling and clean up core code | expand |
On Mon, Jan 22, 2024 at 12:27:21PM +0100, Rafael J. Wysocki wrote: > From: Rafael J. Wysocki <rafael.j.wysocki@intel.com> > > Instead of using a set of individual struct suspend_stats fields > representing suspend step failure counters, use an array of counters > indexed by enum suspend_stat_step for this purpose, which allows > dpm_save_failed_step() to increment the appropriate counter > automatically, so that its callers don't need to do that directly. > > It also allows suspend_stats_show() to carry out a loop over the > counters array to print their values. > > Because the counters cannot become negative, use unsigned int for > representing them. > > The only user-observable impact of this change is a different > ordering of entries in the suspend_stats debugfs file which is not > expected to matter. > > Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com> Reviewed-by: Stanislaw Gruszka <stanislaw.gruszka@linux.intel.com> > --- > drivers/base/power/main.c | 22 ++++++++----------- > include/linux/suspend.h | 13 +++-------- > kernel/power/main.c | 51 ++++++++++++++++++++++++---------------------- > kernel/power/suspend.c | 1 > 4 files changed, 40 insertions(+), 47 deletions(-) > > Index: linux-pm/include/linux/suspend.h > =================================================================== > --- linux-pm.orig/include/linux/suspend.h > +++ linux-pm/include/linux/suspend.h > @@ -49,20 +49,14 @@ enum suspend_stat_step { > SUSPEND_SUSPEND_NOIRQ, > SUSPEND_RESUME_NOIRQ, > SUSPEND_RESUME_EARLY, > - SUSPEND_RESUME > + SUSPEND_RESUME, > + SUSPEND_NR_STEPS > }; > > struct suspend_stats { > + unsigned int step_failures[SUSPEND_NR_STEPS]; > int success; > int fail; > - int failed_freeze; > - int failed_prepare; > - int failed_suspend; > - int failed_suspend_late; > - int failed_suspend_noirq; > - int failed_resume; > - int failed_resume_early; > - int failed_resume_noirq; > #define REC_FAILED_NUM 2 > int last_failed_dev; > char failed_devs[REC_FAILED_NUM][40]; > @@ -95,6 +89,7 @@ static inline void dpm_save_failed_errno > > static inline void dpm_save_failed_step(enum suspend_stat_step step) > { > + suspend_stats.step_failures[step]++; > suspend_stats.failed_steps[suspend_stats.last_failed_step] = step; > suspend_stats.last_failed_step++; > suspend_stats.last_failed_step %= REC_FAILED_NUM; > Index: linux-pm/kernel/power/main.c > =================================================================== > --- linux-pm.orig/kernel/power/main.c > +++ linux-pm/kernel/power/main.c > @@ -341,18 +341,28 @@ static struct kobj_attribute _name = __A > > suspend_attr(success, "%d\n"); > suspend_attr(fail, "%d\n"); > -suspend_attr(failed_freeze, "%d\n"); > -suspend_attr(failed_prepare, "%d\n"); > -suspend_attr(failed_suspend, "%d\n"); > -suspend_attr(failed_suspend_late, "%d\n"); > -suspend_attr(failed_suspend_noirq, "%d\n"); > -suspend_attr(failed_resume, "%d\n"); > -suspend_attr(failed_resume_early, "%d\n"); > -suspend_attr(failed_resume_noirq, "%d\n"); > suspend_attr(last_hw_sleep, "%llu\n"); > suspend_attr(total_hw_sleep, "%llu\n"); > suspend_attr(max_hw_sleep, "%llu\n"); > > +#define suspend_step_attr(_name, step) \ > +static ssize_t _name##_show(struct kobject *kobj, \ > + struct kobj_attribute *attr, char *buf) \ > +{ \ > + return sprintf(buf, "%u\n", \ > + suspend_stats.step_failures[step]); \ > +} \ > +static struct kobj_attribute _name = __ATTR_RO(_name) > + > +suspend_step_attr(failed_freeze, SUSPEND_FREEZE); > +suspend_step_attr(failed_prepare, SUSPEND_PREPARE); > +suspend_step_attr(failed_suspend, SUSPEND_SUSPEND); > +suspend_step_attr(failed_suspend_late, SUSPEND_SUSPEND_LATE); > +suspend_step_attr(failed_suspend_noirq, SUSPEND_SUSPEND_NOIRQ); > +suspend_step_attr(failed_resume, SUSPEND_RESUME); > +suspend_step_attr(failed_resume_early, SUSPEND_RESUME_EARLY); > +suspend_step_attr(failed_resume_noirq, SUSPEND_RESUME_NOIRQ); > + > static ssize_t last_failed_dev_show(struct kobject *kobj, > struct kobj_attribute *attr, char *buf) > { > @@ -439,6 +449,7 @@ static const struct attribute_group susp > static int suspend_stats_show(struct seq_file *s, void *unused) > { > int i, index, last_dev, last_errno, last_step; > + enum suspend_stat_step step; > > last_dev = suspend_stats.last_failed_dev + REC_FAILED_NUM - 1; > last_dev %= REC_FAILED_NUM; > @@ -446,22 +457,14 @@ static int suspend_stats_show(struct seq > last_errno %= REC_FAILED_NUM; > last_step = suspend_stats.last_failed_step + REC_FAILED_NUM - 1; > last_step %= REC_FAILED_NUM; > - seq_printf(s, "%s: %d\n%s: %d\n%s: %d\n%s: %d\n%s: %d\n" > - "%s: %d\n%s: %d\n%s: %d\n%s: %d\n%s: %d\n", > - "success", suspend_stats.success, > - "fail", suspend_stats.fail, > - "failed_freeze", suspend_stats.failed_freeze, > - "failed_prepare", suspend_stats.failed_prepare, > - "failed_suspend", suspend_stats.failed_suspend, > - "failed_suspend_late", > - suspend_stats.failed_suspend_late, > - "failed_suspend_noirq", > - suspend_stats.failed_suspend_noirq, > - "failed_resume", suspend_stats.failed_resume, > - "failed_resume_early", > - suspend_stats.failed_resume_early, > - "failed_resume_noirq", > - suspend_stats.failed_resume_noirq); > + > + seq_printf(s, "success: %d\nfail: %d\n", > + suspend_stats.success, suspend_stats.fail); > + > + for (step = SUSPEND_FREEZE; step < SUSPEND_NR_STEPS; step++) > + seq_printf(s, "failed_%s: %u\n", suspend_step_names[step], > + suspend_stats.step_failures[step]); > + > seq_printf(s, "failures:\n last_failed_dev:\t%-s\n", > suspend_stats.failed_devs[last_dev]); > for (i = 1; i < REC_FAILED_NUM; i++) { > Index: linux-pm/kernel/power/suspend.c > =================================================================== > --- linux-pm.orig/kernel/power/suspend.c > +++ linux-pm/kernel/power/suspend.c > @@ -367,7 +367,6 @@ static int suspend_prepare(suspend_state > if (!error) > return 0; > > - suspend_stats.failed_freeze++; > dpm_save_failed_step(SUSPEND_FREEZE); > pm_notifier_call_chain(PM_POST_SUSPEND); > Restore: > Index: linux-pm/drivers/base/power/main.c > =================================================================== > --- linux-pm.orig/drivers/base/power/main.c > +++ linux-pm/drivers/base/power/main.c > @@ -686,7 +686,6 @@ Out: > TRACE_RESUME(error); > > if (error) { > - suspend_stats.failed_resume_noirq++; > dpm_save_failed_step(SUSPEND_RESUME_NOIRQ); > dpm_save_failed_dev(dev_name(dev)); > pm_dev_err(dev, state, async ? " async noirq" : " noirq", error); > @@ -817,7 +816,6 @@ Out: > complete_all(&dev->power.completion); > > if (error) { > - suspend_stats.failed_resume_early++; > dpm_save_failed_step(SUSPEND_RESUME_EARLY); > dpm_save_failed_dev(dev_name(dev)); > pm_dev_err(dev, state, async ? " async early" : " early", error); > @@ -974,7 +972,6 @@ static void device_resume(struct device > TRACE_RESUME(error); > > if (error) { > - suspend_stats.failed_resume++; > dpm_save_failed_step(SUSPEND_RESUME); > dpm_save_failed_dev(dev_name(dev)); > pm_dev_err(dev, state, async ? " async" : "", error); > @@ -1323,10 +1320,9 @@ static int dpm_noirq_suspend_devices(pm_ > if (!error) > error = async_error; > > - if (error) { > - suspend_stats.failed_suspend_noirq++; > + if (error) > dpm_save_failed_step(SUSPEND_SUSPEND_NOIRQ); > - } > + > dpm_show_time(starttime, state, error, "noirq"); > trace_suspend_resume(TPS("dpm_suspend_noirq"), state.event, false); > return error; > @@ -1509,8 +1505,8 @@ int dpm_suspend_late(pm_message_t state) > async_synchronize_full(); > if (!error) > error = async_error; > + > if (error) { > - suspend_stats.failed_suspend_late++; > dpm_save_failed_step(SUSPEND_SUSPEND_LATE); > dpm_resume_early(resume_event(state)); > } > @@ -1789,10 +1785,10 @@ int dpm_suspend(pm_message_t state) > async_synchronize_full(); > if (!error) > error = async_error; > - if (error) { > - suspend_stats.failed_suspend++; > + > + if (error) > dpm_save_failed_step(SUSPEND_SUSPEND); > - } > + > dpm_show_time(starttime, state, error, NULL); > trace_suspend_resume(TPS("dpm_suspend"), state.event, false); > return error; > @@ -1943,11 +1939,11 @@ int dpm_suspend_start(pm_message_t state > int error; > > error = dpm_prepare(state); > - if (error) { > - suspend_stats.failed_prepare++; > + if (error) > dpm_save_failed_step(SUSPEND_PREPARE); > - } else > + else > error = dpm_suspend(state); > + > dpm_show_time(starttime, state, error, "start"); > return error; > } > > > >
Index: linux-pm/include/linux/suspend.h =================================================================== --- linux-pm.orig/include/linux/suspend.h +++ linux-pm/include/linux/suspend.h @@ -49,20 +49,14 @@ enum suspend_stat_step { SUSPEND_SUSPEND_NOIRQ, SUSPEND_RESUME_NOIRQ, SUSPEND_RESUME_EARLY, - SUSPEND_RESUME + SUSPEND_RESUME, + SUSPEND_NR_STEPS }; struct suspend_stats { + unsigned int step_failures[SUSPEND_NR_STEPS]; int success; int fail; - int failed_freeze; - int failed_prepare; - int failed_suspend; - int failed_suspend_late; - int failed_suspend_noirq; - int failed_resume; - int failed_resume_early; - int failed_resume_noirq; #define REC_FAILED_NUM 2 int last_failed_dev; char failed_devs[REC_FAILED_NUM][40]; @@ -95,6 +89,7 @@ static inline void dpm_save_failed_errno static inline void dpm_save_failed_step(enum suspend_stat_step step) { + suspend_stats.step_failures[step]++; suspend_stats.failed_steps[suspend_stats.last_failed_step] = step; suspend_stats.last_failed_step++; suspend_stats.last_failed_step %= REC_FAILED_NUM; Index: linux-pm/kernel/power/main.c =================================================================== --- linux-pm.orig/kernel/power/main.c +++ linux-pm/kernel/power/main.c @@ -341,18 +341,28 @@ static struct kobj_attribute _name = __A suspend_attr(success, "%d\n"); suspend_attr(fail, "%d\n"); -suspend_attr(failed_freeze, "%d\n"); -suspend_attr(failed_prepare, "%d\n"); -suspend_attr(failed_suspend, "%d\n"); -suspend_attr(failed_suspend_late, "%d\n"); -suspend_attr(failed_suspend_noirq, "%d\n"); -suspend_attr(failed_resume, "%d\n"); -suspend_attr(failed_resume_early, "%d\n"); -suspend_attr(failed_resume_noirq, "%d\n"); suspend_attr(last_hw_sleep, "%llu\n"); suspend_attr(total_hw_sleep, "%llu\n"); suspend_attr(max_hw_sleep, "%llu\n"); +#define suspend_step_attr(_name, step) \ +static ssize_t _name##_show(struct kobject *kobj, \ + struct kobj_attribute *attr, char *buf) \ +{ \ + return sprintf(buf, "%u\n", \ + suspend_stats.step_failures[step]); \ +} \ +static struct kobj_attribute _name = __ATTR_RO(_name) + +suspend_step_attr(failed_freeze, SUSPEND_FREEZE); +suspend_step_attr(failed_prepare, SUSPEND_PREPARE); +suspend_step_attr(failed_suspend, SUSPEND_SUSPEND); +suspend_step_attr(failed_suspend_late, SUSPEND_SUSPEND_LATE); +suspend_step_attr(failed_suspend_noirq, SUSPEND_SUSPEND_NOIRQ); +suspend_step_attr(failed_resume, SUSPEND_RESUME); +suspend_step_attr(failed_resume_early, SUSPEND_RESUME_EARLY); +suspend_step_attr(failed_resume_noirq, SUSPEND_RESUME_NOIRQ); + static ssize_t last_failed_dev_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf) { @@ -439,6 +449,7 @@ static const struct attribute_group susp static int suspend_stats_show(struct seq_file *s, void *unused) { int i, index, last_dev, last_errno, last_step; + enum suspend_stat_step step; last_dev = suspend_stats.last_failed_dev + REC_FAILED_NUM - 1; last_dev %= REC_FAILED_NUM; @@ -446,22 +457,14 @@ static int suspend_stats_show(struct seq last_errno %= REC_FAILED_NUM; last_step = suspend_stats.last_failed_step + REC_FAILED_NUM - 1; last_step %= REC_FAILED_NUM; - seq_printf(s, "%s: %d\n%s: %d\n%s: %d\n%s: %d\n%s: %d\n" - "%s: %d\n%s: %d\n%s: %d\n%s: %d\n%s: %d\n", - "success", suspend_stats.success, - "fail", suspend_stats.fail, - "failed_freeze", suspend_stats.failed_freeze, - "failed_prepare", suspend_stats.failed_prepare, - "failed_suspend", suspend_stats.failed_suspend, - "failed_suspend_late", - suspend_stats.failed_suspend_late, - "failed_suspend_noirq", - suspend_stats.failed_suspend_noirq, - "failed_resume", suspend_stats.failed_resume, - "failed_resume_early", - suspend_stats.failed_resume_early, - "failed_resume_noirq", - suspend_stats.failed_resume_noirq); + + seq_printf(s, "success: %d\nfail: %d\n", + suspend_stats.success, suspend_stats.fail); + + for (step = SUSPEND_FREEZE; step < SUSPEND_NR_STEPS; step++) + seq_printf(s, "failed_%s: %u\n", suspend_step_names[step], + suspend_stats.step_failures[step]); + seq_printf(s, "failures:\n last_failed_dev:\t%-s\n", suspend_stats.failed_devs[last_dev]); for (i = 1; i < REC_FAILED_NUM; i++) { Index: linux-pm/kernel/power/suspend.c =================================================================== --- linux-pm.orig/kernel/power/suspend.c +++ linux-pm/kernel/power/suspend.c @@ -367,7 +367,6 @@ static int suspend_prepare(suspend_state if (!error) return 0; - suspend_stats.failed_freeze++; dpm_save_failed_step(SUSPEND_FREEZE); pm_notifier_call_chain(PM_POST_SUSPEND); Restore: Index: linux-pm/drivers/base/power/main.c =================================================================== --- linux-pm.orig/drivers/base/power/main.c +++ linux-pm/drivers/base/power/main.c @@ -686,7 +686,6 @@ Out: TRACE_RESUME(error); if (error) { - suspend_stats.failed_resume_noirq++; dpm_save_failed_step(SUSPEND_RESUME_NOIRQ); dpm_save_failed_dev(dev_name(dev)); pm_dev_err(dev, state, async ? " async noirq" : " noirq", error); @@ -817,7 +816,6 @@ Out: complete_all(&dev->power.completion); if (error) { - suspend_stats.failed_resume_early++; dpm_save_failed_step(SUSPEND_RESUME_EARLY); dpm_save_failed_dev(dev_name(dev)); pm_dev_err(dev, state, async ? " async early" : " early", error); @@ -974,7 +972,6 @@ static void device_resume(struct device TRACE_RESUME(error); if (error) { - suspend_stats.failed_resume++; dpm_save_failed_step(SUSPEND_RESUME); dpm_save_failed_dev(dev_name(dev)); pm_dev_err(dev, state, async ? " async" : "", error); @@ -1323,10 +1320,9 @@ static int dpm_noirq_suspend_devices(pm_ if (!error) error = async_error; - if (error) { - suspend_stats.failed_suspend_noirq++; + if (error) dpm_save_failed_step(SUSPEND_SUSPEND_NOIRQ); - } + dpm_show_time(starttime, state, error, "noirq"); trace_suspend_resume(TPS("dpm_suspend_noirq"), state.event, false); return error; @@ -1509,8 +1505,8 @@ int dpm_suspend_late(pm_message_t state) async_synchronize_full(); if (!error) error = async_error; + if (error) { - suspend_stats.failed_suspend_late++; dpm_save_failed_step(SUSPEND_SUSPEND_LATE); dpm_resume_early(resume_event(state)); } @@ -1789,10 +1785,10 @@ int dpm_suspend(pm_message_t state) async_synchronize_full(); if (!error) error = async_error; - if (error) { - suspend_stats.failed_suspend++; + + if (error) dpm_save_failed_step(SUSPEND_SUSPEND); - } + dpm_show_time(starttime, state, error, NULL); trace_suspend_resume(TPS("dpm_suspend"), state.event, false); return error; @@ -1943,11 +1939,11 @@ int dpm_suspend_start(pm_message_t state int error; error = dpm_prepare(state); - if (error) { - suspend_stats.failed_prepare++; + if (error) dpm_save_failed_step(SUSPEND_PREPARE); - } else + else error = dpm_suspend(state); + dpm_show_time(starttime, state, error, "start"); return error; }