From: "Fu, Zhonghui" <zhonghui.fu@linux.intel.com>
To: "Rafael J. Wysocki" <rjw@rjwysocki.net>
Cc: len.brown@intel.com, pavel@ucw.cz,
Greg Kroah-Hartman <gregkh@linuxfoundation.org>,
linux-pm@vger.kernel.org,
"linux-kernel@vger.kernel.org" <linux-kernel@vger.kernel.org>
Subject: [PATCH] PM / sleep: cancel the synchronous restriction of pm-trace
Date: Wed, 06 May 2015 22:47:24 +0800 [thread overview]
Message-ID: <554A297C.2040305@linux.intel.com> (raw)
Some system-hang occur only when multiple device PM methods
are running asynchronously. So should cancel the synchronization
of pm-trace, and make it suitable for asynchronous PM environment.
Signed-off-by: Zhonghui Fu <zhonghui.fu@linux.intel.com>
---
drivers/base/power/main.c | 53 +++++++++++++++++++++-----------------------
include/linux/pm-trace.h | 24 ++++++++++++--------
kernel/power/main.c | 2 +
3 files changed, 41 insertions(+), 38 deletions(-)
diff --git a/drivers/base/power/main.c b/drivers/base/power/main.c
index 3d874ec..40daf48 100644
--- a/drivers/base/power/main.c
+++ b/drivers/base/power/main.c
@@ -476,9 +476,6 @@ static int device_resume_noirq(struct device *dev, pm_message_t state, bool asyn
char *info = NULL;
int error = 0;
- TRACE_DEVICE(dev);
- TRACE_RESUME(0);
-
if (dev->power.syscore || dev->power.direct_complete)
goto Out;
@@ -506,19 +503,21 @@ static int device_resume_noirq(struct device *dev, pm_message_t state, bool asyn
callback = pm_noirq_op(dev->driver->pm, state);
}
+ TRACE_DEVICE_START(dev);
+ TRACE_RESUME(0);
+
error = dpm_run_callback(callback, dev, state, info);
dev->power.is_noirq_suspended = false;
+ TRACE_DEVICE_END();
Out:
complete_all(&dev->power.completion);
- TRACE_RESUME(error);
return error;
}
static bool is_async(struct device *dev)
{
- return dev->power.async_suspend && pm_async_enabled
- && !pm_trace_is_enabled();
+ return dev->power.async_suspend && pm_async_enabled;
}
static void async_resume_noirq(void *data, async_cookie_t cookie)
@@ -605,9 +604,6 @@ static int device_resume_early(struct device *dev, pm_message_t state, bool asyn
char *info = NULL;
int error = 0;
- TRACE_DEVICE(dev);
- TRACE_RESUME(0);
-
if (dev->power.syscore || dev->power.direct_complete)
goto Out;
@@ -635,12 +631,14 @@ static int device_resume_early(struct device *dev, pm_message_t state, bool asyn
callback = pm_late_early_op(dev->driver->pm, state);
}
+ TRACE_DEVICE_START(dev);
+ TRACE_RESUME(0);
+
error = dpm_run_callback(callback, dev, state, info);
dev->power.is_late_suspended = false;
+ TRACE_DEVICE_END();
Out:
- TRACE_RESUME(error);
-
pm_runtime_enable(dev);
complete_all(&dev->power.completion);
return error;
@@ -734,9 +732,6 @@ static int device_resume(struct device *dev, pm_message_t state, bool async)
int error = 0;
DECLARE_DPM_WATCHDOG_ON_STACK(wd);
- TRACE_DEVICE(dev);
- TRACE_RESUME(0);
-
if (dev->power.syscore)
goto Complete;
@@ -801,9 +796,13 @@ static int device_resume(struct device *dev, pm_message_t state, bool async)
}
End:
+ TRACE_DEVICE_START(dev);
+ TRACE_RESUME(0);
+
error = dpm_run_callback(callback, dev, state, info);
dev->power.is_suspended = false;
+ TRACE_DEVICE_END();
Unlock:
device_unlock(dev);
dpm_watchdog_clear(&wd);
@@ -811,8 +810,6 @@ static int device_resume(struct device *dev, pm_message_t state, bool async)
Complete:
complete_all(&dev->power.completion);
- TRACE_RESUME(error);
-
return error;
}
@@ -1017,9 +1014,6 @@ static int __device_suspend_noirq(struct device *dev, pm_message_t state, bool a
char *info = NULL;
int error = 0;
- TRACE_DEVICE(dev);
- TRACE_SUSPEND(0);
-
if (async_error)
goto Complete;
@@ -1052,15 +1046,18 @@ static int __device_suspend_noirq(struct device *dev, pm_message_t state, bool a
callback = pm_noirq_op(dev->driver->pm, state);
}
+ TRACE_DEVICE_START(dev);
+ TRACE_SUSPEND(0);
+
error = dpm_run_callback(callback, dev, state, info);
if (!error)
dev->power.is_noirq_suspended = true;
else
async_error = error;
+ TRACE_DEVICE_END();
Complete:
complete_all(&dev->power.completion);
- TRACE_SUSPEND(error);
return error;
}
@@ -1161,9 +1158,6 @@ static int __device_suspend_late(struct device *dev, pm_message_t state, bool as
char *info = NULL;
int error = 0;
- TRACE_DEVICE(dev);
- TRACE_SUSPEND(0);
-
__pm_runtime_disable(dev, false);
if (async_error)
@@ -1198,14 +1192,17 @@ static int __device_suspend_late(struct device *dev, pm_message_t state, bool as
callback = pm_late_early_op(dev->driver->pm, state);
}
+ TRACE_DEVICE_START(dev);
+ TRACE_SUSPEND(0);
+
error = dpm_run_callback(callback, dev, state, info);
if (!error)
dev->power.is_late_suspended = true;
else
async_error = error;
+ TRACE_DEVICE_END();
Complete:
- TRACE_SUSPEND(error);
complete_all(&dev->power.completion);
return error;
}
@@ -1346,9 +1343,6 @@ static int __device_suspend(struct device *dev, pm_message_t state, bool async)
int error = 0;
DECLARE_DPM_WATCHDOG_ON_STACK(wd);
- TRACE_DEVICE(dev);
- TRACE_SUSPEND(0);
-
dpm_wait_for_children(dev, async);
if (async_error)
@@ -1428,8 +1422,12 @@ static int __device_suspend(struct device *dev, pm_message_t state, bool async)
callback = pm_op(dev->driver->pm, state);
}
+ TRACE_DEVICE_START(dev);
+ TRACE_SUSPEND(0);
+
error = dpm_run_callback(callback, dev, state, info);
+ TRACE_DEVICE_END();
End:
if (!error) {
struct device *parent = dev->parent;
@@ -1455,7 +1453,6 @@ static int __device_suspend(struct device *dev, pm_message_t state, bool async)
if (error)
async_error = error;
- TRACE_SUSPEND(error);
return error;
}
diff --git a/include/linux/pm-trace.h b/include/linux/pm-trace.h
index ecbde7a..aa480b1 100644
--- a/include/linux/pm-trace.h
+++ b/include/linux/pm-trace.h
@@ -6,29 +6,33 @@
#include <linux/types.h>
extern int pm_trace_enabled;
-
-static inline int pm_trace_is_enabled(void)
-{
- return pm_trace_enabled;
-}
+extern struct mutex pt_mutex;
struct device;
extern void set_trace_device(struct device *);
extern void generate_pm_trace(const void *tracedata, unsigned int user);
extern int show_trace_dev_match(char *buf, size_t size);
-#define TRACE_DEVICE(dev) do { \
+#define TRACE_DEVICE_START(dev) do { \
if (pm_trace_enabled) \
+ mutex_lock(&pt_mutex); \
set_trace_device(dev); \
} while(0)
+#define TRACE_DEVICE_END() \
+do { \
+ if (pm_trace_enabled) { \
+ mutex_unlock(&pt_mutex); \
+ } \
+} while (0)
+
#else
-static inline int pm_trace_is_enabled(void) { return 0; }
+#define TRACE_DEVICE_START(dev) do { } while (0)
+#define TRACE_DEVICE_END() do { } while (0)
-#define TRACE_DEVICE(dev) do { } while (0)
-#define TRACE_RESUME(dev) do { } while (0)
-#define TRACE_SUSPEND(dev) do { } while (0)
+#define TRACE_RESUME(user) do { } while (0)
+#define TRACE_SUSPEND(user) do { } while (0)
#endif
diff --git a/kernel/power/main.c b/kernel/power/main.c
index 86e8157..ffd5145 100644
--- a/kernel/power/main.c
+++ b/kernel/power/main.c
@@ -515,6 +515,7 @@ power_attr(wake_unlock);
#ifdef CONFIG_PM_TRACE
int pm_trace_enabled;
+struct mutex pt_mutex;
static ssize_t pm_trace_show(struct kobject *kobj, struct kobj_attribute *attr,
char *buf)
@@ -533,6 +534,7 @@ pm_trace_store(struct kobject *kobj, struct kobj_attribute *attr,
if (pm_trace_enabled) {
pr_warn("PM: Enabling pm_trace changes system date and time during resume.\n"
"PM: Correct system time has to be restored manually after resume.\n");
+ mutex_init(&pt_mutex);
}
return n;
}
-- 1.7.1
next reply other threads:[~2015-05-06 14:47 UTC|newest]
Thread overview: 11+ messages / expand[flat|nested] mbox.gz Atom feed top
2015-05-06 14:47 Fu, Zhonghui [this message]
2015-05-16 0:45 ` [PATCH] PM / sleep: cancel the synchronous restriction of pm-trace Rafael J. Wysocki
2015-05-20 8:50 ` Fu, Zhonghui
2015-05-20 13:45 ` Pavel Machek
2015-05-21 1:16 ` Rafael J. Wysocki
2015-05-28 14:43 ` Fu, Zhonghui
2015-06-15 5:32 ` Fu, Zhonghui
2015-06-15 23:05 ` Rafael J. Wysocki
2015-05-18 6:33 ` Fu, Zhonghui
2015-05-19 0:38 ` Rafael J. Wysocki
2015-05-20 8:57 ` Fu, Zhonghui
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=554A297C.2040305@linux.intel.com \
--to=zhonghui.fu@linux.intel.com \
--cc=gregkh@linuxfoundation.org \
--cc=len.brown@intel.com \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-pm@vger.kernel.org \
--cc=pavel@ucw.cz \
--cc=rjw@rjwysocki.net \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.