Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit d112bff3 authored by Kalesh Singh's avatar Kalesh Singh Committed by Tri Vo
Browse files

BACKPORT: PM/sleep: Expose suspend stats in sysfs



Userspace can get suspend stats from the suspend stats debugfs node.
Since debugfs doesn't have stable ABI, expose suspend stats in
sysfs under /sys/power/suspend_stats.

Signed-off-by: default avatarKalesh Singh <kaleshsingh@google.com>
Reviewed-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: default avatarRafael J. Wysocki <rafael.j.wysocki@intel.com>
(cherry picked from commit 2c8db5bef9fb442a5a0d2fee28aed20100362ce3)
[ fixed conflicts in Documentation ]
Bug: 129087298
Change-Id: Ia8f0d8551ae693cb5f3e1abc609fb9bbfeb695f5
Signed-off-by: default avatarTri Vo <trong@google.com>
parent 80384c35
Loading
Loading
Loading
Loading
+107 −1
Original line number Diff line number Diff line
@@ -301,3 +301,109 @@ Description:

		Using this sysfs file will override any values that were
		set using the kernel command line for disk offset.

What:		/sys/power/suspend_stats
Date:		July 2019
Contact:	Kalesh Singh <kaleshsingh96@gmail.com>
Description:
		The /sys/power/suspend_stats directory contains suspend related
		statistics.

What:		/sys/power/suspend_stats/success
Date:		July 2019
Contact:	Kalesh Singh <kaleshsingh96@gmail.com>
Description:
		The /sys/power/suspend_stats/success file contains the number
		of times entering system sleep state succeeded.

What:		/sys/power/suspend_stats/fail
Date:		July 2019
Contact:	Kalesh Singh <kaleshsingh96@gmail.com>
Description:
		The /sys/power/suspend_stats/fail file contains the number
		of times entering system sleep state failed.

What:		/sys/power/suspend_stats/failed_freeze
Date:		July 2019
Contact:	Kalesh Singh <kaleshsingh96@gmail.com>
Description:
		The /sys/power/suspend_stats/failed_freeze file contains the
		number of times freezing processes failed.

What:		/sys/power/suspend_stats/failed_prepare
Date:		July 2019
Contact:	Kalesh Singh <kaleshsingh96@gmail.com>
Description:
		The /sys/power/suspend_stats/failed_prepare file contains the
		number of times preparing all non-sysdev devices for
		a system PM transition failed.

What:		/sys/power/suspend_stats/failed_resume
Date:		July 2019
Contact:	Kalesh Singh <kaleshsingh96@gmail.com>
Description:
		The /sys/power/suspend_stats/failed_resume file contains the
		number of times executing "resume" callbacks of
		non-sysdev devices failed.

What:		/sys/power/suspend_stats/failed_resume_early
Date:		July 2019
Contact:	Kalesh Singh <kaleshsingh96@gmail.com>
Description:
		The /sys/power/suspend_stats/failed_resume_early file contains
		the number of times executing "early resume" callbacks
		of devices failed.

What:		/sys/power/suspend_stats/failed_resume_noirq
Date:		July 2019
Contact:	Kalesh Singh <kaleshsingh96@gmail.com>
Description:
		The /sys/power/suspend_stats/failed_resume_noirq file contains
		the number of times executing "noirq resume" callbacks
		of devices failed.

What:		/sys/power/suspend_stats/failed_suspend
Date:		July 2019
Contact:	Kalesh Singh <kaleshsingh96@gmail.com>
Description:
		The /sys/power/suspend_stats/failed_suspend file contains
		the number of times executing "suspend" callbacks
		of all non-sysdev devices failed.

What:		/sys/power/suspend_stats/failed_suspend_late
Date:		July 2019
Contact:	Kalesh Singh <kaleshsingh96@gmail.com>
Description:
		The /sys/power/suspend_stats/failed_suspend_late file contains
		the number of times executing "late suspend" callbacks
		of all devices failed.

What:		/sys/power/suspend_stats/failed_suspend_noirq
Date:		July 2019
Contact:	Kalesh Singh <kaleshsingh96@gmail.com>
Description:
		The /sys/power/suspend_stats/failed_suspend_noirq file contains
		the number of times executing "noirq suspend" callbacks
		of all devices failed.

What:		/sys/power/suspend_stats/last_failed_dev
Date:		July 2019
Contact:	Kalesh Singh <kaleshsingh96@gmail.com>
Description:
		The /sys/power/suspend_stats/last_failed_dev file contains
		the last device for which a suspend/resume callback failed.

What:		/sys/power/suspend_stats/last_failed_errno
Date:		July 2019
Contact:	Kalesh Singh <kaleshsingh96@gmail.com>
Description:
		The /sys/power/suspend_stats/last_failed_errno file contains
		the errno of the last failed attempt at entering
		system sleep state.

What:		/sys/power/suspend_stats/last_failed_step
Date:		July 2019
Contact:	Kalesh Singh <kaleshsingh96@gmail.com>
Description:
		The /sys/power/suspend_stats/last_failed_step file contains
		the last failed step in the suspend/resume path.
+95 −2
Original line number Diff line number Diff line
@@ -242,7 +242,6 @@ static ssize_t pm_test_store(struct kobject *kobj, struct kobj_attribute *attr,
power_attr(pm_test);
#endif /* CONFIG_PM_SLEEP_DEBUG */

#ifdef CONFIG_DEBUG_FS
static char *suspend_step_name(enum suspend_stat_step step)
{
	switch (step) {
@@ -263,6 +262,92 @@ static char *suspend_step_name(enum suspend_stat_step step)
	}
}

#define suspend_attr(_name)					\
static ssize_t _name##_show(struct kobject *kobj,		\
		struct kobj_attribute *attr, char *buf)		\
{								\
	return sprintf(buf, "%d\n", suspend_stats._name);	\
}								\
static struct kobj_attribute _name = __ATTR_RO(_name)

suspend_attr(success);
suspend_attr(fail);
suspend_attr(failed_freeze);
suspend_attr(failed_prepare);
suspend_attr(failed_suspend);
suspend_attr(failed_suspend_late);
suspend_attr(failed_suspend_noirq);
suspend_attr(failed_resume);
suspend_attr(failed_resume_early);
suspend_attr(failed_resume_noirq);

static ssize_t last_failed_dev_show(struct kobject *kobj,
		struct kobj_attribute *attr, char *buf)
{
	int index;
	char *last_failed_dev = NULL;

	index = suspend_stats.last_failed_dev + REC_FAILED_NUM - 1;
	index %= REC_FAILED_NUM;
	last_failed_dev = suspend_stats.failed_devs[index];

	return sprintf(buf, "%s\n", last_failed_dev);
}
static struct kobj_attribute last_failed_dev = __ATTR_RO(last_failed_dev);

static ssize_t last_failed_errno_show(struct kobject *kobj,
		struct kobj_attribute *attr, char *buf)
{
	int index;
	int last_failed_errno;

	index = suspend_stats.last_failed_errno + REC_FAILED_NUM - 1;
	index %= REC_FAILED_NUM;
	last_failed_errno = suspend_stats.errno[index];

	return sprintf(buf, "%d\n", last_failed_errno);
}
static struct kobj_attribute last_failed_errno = __ATTR_RO(last_failed_errno);

static ssize_t last_failed_step_show(struct kobject *kobj,
		struct kobj_attribute *attr, char *buf)
{
	int index;
	enum suspend_stat_step step;
	char *last_failed_step = NULL;

	index = suspend_stats.last_failed_step + REC_FAILED_NUM - 1;
	index %= REC_FAILED_NUM;
	step = suspend_stats.failed_steps[index];
	last_failed_step = suspend_step_name(step);

	return sprintf(buf, "%s\n", last_failed_step);
}
static struct kobj_attribute last_failed_step = __ATTR_RO(last_failed_step);

static struct attribute *suspend_attrs[] = {
	&success.attr,
	&fail.attr,
	&failed_freeze.attr,
	&failed_prepare.attr,
	&failed_suspend.attr,
	&failed_suspend_late.attr,
	&failed_suspend_noirq.attr,
	&failed_resume.attr,
	&failed_resume_early.attr,
	&failed_resume_noirq.attr,
	&last_failed_dev.attr,
	&last_failed_errno.attr,
	&last_failed_step.attr,
	NULL,
};

static struct attribute_group suspend_attr_group = {
	.name = "suspend_stats",
	.attrs = suspend_attrs,
};

#ifdef CONFIG_DEBUG_FS
static int suspend_stats_show(struct seq_file *s, void *unused)
{
	int i, index, last_dev, last_errno, last_step;
@@ -793,6 +878,14 @@ static const struct attribute_group attr_group = {
	.attrs = g,
};

static const struct attribute_group *attr_groups[] = {
	&attr_group,
#ifdef CONFIG_PM_SLEEP
	&suspend_attr_group,
#endif
	NULL,
};

struct workqueue_struct *pm_wq;
EXPORT_SYMBOL_GPL(pm_wq);

@@ -814,7 +907,7 @@ static int __init pm_init(void)
	power_kobj = kobject_create_and_add("power", NULL);
	if (!power_kobj)
		return -ENOMEM;
	error = sysfs_create_group(power_kobj, &attr_group);
	error = sysfs_create_groups(power_kobj, attr_groups);
	if (error)
		return error;
	pm_print_times_init();