PM / sleep: cancel the synchronous restriction of pm-trace
Subsystems (4)
PATCH 1/1 PM / sleep: cancel the synchronous restriction of pm-trace
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.
--- drivers/base/power/main.c | 53 +++++++++++++++++++++----------------------- include/linux/pm-trace.h | 24 ++++++++++++-------- kernel/power/main.c | 2 + 3 files changed, 41 insertions(+), 38 deletions(-)
drivers/base/power/main.c +25 -28
@@ -476,9 +476,6 @@ static int device_resume_noirq(struct device *dev, pm_message_t state, bool asynchar *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 asynchar *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 achar *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 aschar *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; }
include/linux/pm-trace.h +14 -10
@@ -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
kernel/power/main.c +2 -0
@@ -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
Quoted 224 lines · Zhonghui
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 <[email protected]>--- drivers/base/power/main.c | 53 +++++++++++++++++++++----------------------- include/linux/pm-trace.h | 24 ++++++++++++-------- kernel/power/main.c | 2 + 3 files changed, 41 insertions(+), 38 deletions(-)drivers/base/power/main.c +25
-28@@ -476,9 +476,6 @@ static int device_resume_noirq(struct device *dev, pm_message_t state, bool asynchar *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 asynchar *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 achar *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 aschar *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; }include/linux/pm-trace.h +3
-6@@ -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); \
include/linux/pm-trace.h line 28
Quoted 10 lines
include/linux/pm-trace.h +7
-0set_trace_device (dev); \ } while(0) +#define TRACE_DEVICE_END () \ +do { \ + if (pm_trace_enabled) { \ + mutex_unlock(&pt_mutex); \ + } \ +} while (0) +
Won't this serialize the whole thing again?
Quoted 40 lines
include/linux/pm-trace.h +4
-4#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 kernel/power/main.c +2
-2@@ -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 --To unsubscribe from this list: send the line "unsubscribe linux-pm" in the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html
Signature · 2 lines
I speak only for myself. Rafael J. Wysocki, Intel Open Source Technology Center.
Quoted 228 lines · Rafael J. Wysocki
Quoted 227 lines · Zhonghui
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 <[email protected]>--- drivers/base/power/main.c | 53 +++++++++++++++++++++----------------------- include/linux/pm-trace.h | 24 ++++++++++++-------- kernel/power/main.c | 2 + 3 files changed, 41 insertions(+), 38 deletions(-)drivers/base/power/main.c +25
-28@@ -476,9 +476,6 @@ static int device_resume_noirq(struct device *dev, pm_message_t state, bool asynchar *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 asynchar *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 achar *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 aschar *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; }include/linux/pm-trace.h +3
-6@@ -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)
Quoted 8 lines
include/linux/pm-trace.h line 28
Quoted 7 lines
include/linux/pm-trace.h +7
-0+#define TRACE_DEVICE_END () \ +do { \ + if (pm_trace_enabled) { \ + mutex_unlock(&pt_mutex); \ + } \ +} while (0) +Won't this serialize the whole thing again?
Yes, this mutex lock will ultimately serialize all PM operations. But, all device's PM operations are asynchronous each other at first. So, the PM operation order of all devices will vary in multiple suspend/resume. This can be similar to real to an extreme, and helpful to debugging.
Thanks,
Zhonghui
Quoted 41 lines
Quoted 41 lines
include/linux/pm-trace.h +4
-4#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 kernel/power/main.c +2
-2@@ -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 --To unsubscribe from this list: send the line "unsubscribe linux-pm" in the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html
Quoted 15 lines
Quoted 7 lines
Quoted 7 lines
include/linux/pm-trace.h +2
-1-#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)Quoted 8 lines
include/linux/pm-trace.h line 28
Quoted 7 lines
include/linux/pm-trace.h +7
-0+#define TRACE_DEVICE_END () \ +do { \ + if (pm_trace_enabled) { \ + mutex_unlock(&pt_mutex); \ + } \ +} while (0) +Won't this serialize the whole thing again?
Quoted 2 lines
Yes, this mutex lock will ultimately serialize all PM operations. But, all device's PM operations are asynchronous each other at first. So, the PM operation order of all devices will vary in multiple suspend/resume. This can be similar to real to an extreme, and helpful to debugging.
I believe the tradeoff here is wrong. Just keep PM_TRACE simple, and use something else for a real tricky failures..
Pavel
Signature · 2 lines
(english) http://www.livejournal.com/~pavelmachek (cesky, pictures) http://atrey.karlin.mff.cuni.cz/~pavel/picture/horses/blog.html
Quoted 238 lines · Zhonghui
Quoted 228 lines · Rafael J. Wysocki
Quoted 227 lines · Zhonghui
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 <[email protected]>--- drivers/base/power/main.c | 53 +++++++++++++++++++++----------------------- include/linux/pm-trace.h | 24 ++++++++++++-------- kernel/power/main.c | 2 + 3 files changed, 41 insertions(+), 38 deletions(-)drivers/base/power/main.c +25
-28@@ -476,9 +476,6 @@ static int device_resume_noirq(struct device *dev, pm_message_t state, bool asynchar *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 asynchar *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 achar *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 aschar *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; }include/linux/pm-trace.h +3
-6@@ -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)Quoted 8 lines
include/linux/pm-trace.h line 28
Quoted 7 lines
include/linux/pm-trace.h +7
-0+#define TRACE_DEVICE_END () \ +do { \ + if (pm_trace_enabled) { \ + mutex_unlock(&pt_mutex); \ + } \ +} while (0) +Won't this serialize the whole thing again?
Quoted 1 line
Yes, this mutex lock will ultimately serialize all PM operations. But, all device's PM operations are asynchronous each other at first. So, the PM operation order of all devices will vary in multiple suspend/resume. This can be similar to real to an extreme, and helpful to debugging.
I see. You're saying that callbacks will be serialized, but if they originally would be asynchronous with respect to each other (they may run in parallel IOW), their respective ordering may vary between suspend-resume cycles.
The class of bugs you can catch this way is quite limited and the change is rather intrusive, so I'm with Pavel on that.
Signature · 2 lines
I speak only for myself. Rafael J. Wysocki, Intel Open Source Technology Center.
Quoted 238 lines · Rafael J. Wysocki
Quoted 237 lines · Zhonghui
Quoted 236 lines · Rafael J. Wysocki
Quoted 224 lines · Zhonghui
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 <[email protected]>--- drivers/base/power/main.c | 53 +++++++++++++++++++++----------------------- include/linux/pm-trace.h | 24 ++++++++++++-------- kernel/power/main.c | 2 + 3 files changed, 41 insertions(+), 38 deletions(-)drivers/base/power/main.c +25
-28@@ -476,9 +476,6 @@ static int device_resume_noirq(struct device *dev, pm_message_t state, bool asynchar *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 asynchar *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 achar *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 aschar *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; }include/linux/pm-trace.h +3
-6@@ -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); \include/linux/pm-trace.h line 28
Quoted 10 lines
include/linux/pm-trace.h +7
-0set_trace_device (dev); \ } while(0) +#define TRACE_DEVICE_END () \ +do { \ + if (pm_trace_enabled) { \ + mutex_unlock(&pt_mutex); \ + } \ +} while (0) +Won't this serialize the whole thing again?
Quoted 7 lines
Quoted 1 line
Yes, this mutex lock will ultimately serialize all PM operations. But, all device's PM operations are asynchronous each other at first. So, the PM operation order of all devices will vary in multiple suspend/resume. This can be similar to real to an extreme, and helpful to debugging.
I see. You're saying that callbacks will be serialized, but if they originally would be asynchronous with respect to each other (they may run in parallel IOW), their respective ordering may vary between suspend-resume cycles.
The class of bugs you can catch this way is quite limited and the change is rather intrusive, so I'm with Pavel on that.
Sorry for late reply.
Although the improvement to PM-trace is limited, I still think it is helpful for debugging some special suspend/resume bugs.
Thanks,
Zhonghui
Quoted 2 lines
Quoted 245 lines · Zhonghui
Quoted 243 lines · Rafael J. Wysocki
Quoted 237 lines · Zhonghui
Quoted 228 lines · Rafael J. Wysocki
Quoted 227 lines · Zhonghui
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 <[email protected]>--- drivers/base/power/main.c | 53 +++++++++++++++++++++----------------------- include/linux/pm-trace.h | 24 ++++++++++++-------- kernel/power/main.c | 2 + 3 files changed, 41 insertions(+), 38 deletions(-)drivers/base/power/main.c +25
-28@@ -476,9 +476,6 @@ static int device_resume_noirq(struct device *dev, pm_message_t state, bool asynchar *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 asynchar *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 achar *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 aschar *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; }include/linux/pm-trace.h +3
-6@@ -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)Quoted 8 lines
include/linux/pm-trace.h line 28
Quoted 7 lines
include/linux/pm-trace.h +7
-0+#define TRACE_DEVICE_END () \ +do { \ + if (pm_trace_enabled) { \ + mutex_unlock(&pt_mutex); \ + } \ +} while (0) +Won't this serialize the whole thing again?
Quoted 1 line
Yes, this mutex lock will ultimately serialize all PM operations. But, all device's PM operations are asynchronous each other at first. So, the PM operation order of all devices will vary in multiple suspend/resume. This can be similar to real to an extreme, and helpful to debugging.
I see. You're saying that callbacks will be serialized, but if they originally would be asynchronous with respect to each other (they may run in parallel IOW), their respective ordering may vary between suspend-resume cycles.
Quoted 5 lines
Quoted 2 lines
The class of bugs you can catch this way is quite limited and the change is rather intrusive, so I'm with Pavel on that.
Sorry for late reply.
Although the improvement to PM-trace is limited, I still think it is helpful for debugging some special suspend/resume bugs.
Hi Rafael,
This patch will not be merged into mainline kernel, right?
Thanks,
Zhonghui
Quoted 5 lines
Thanks,
ZhonghuiQuoted 1 line
Quoted 6 lines · Zhonghui
Quoted 4 lines · Zhonghui
Quoted 2 lines · Rafael J. Wysocki
Quoted 1 line · Zhonghui
On 2015/5/16 8:45, Rafael J. Wysocki wrote:
[cut]
Quoted 8 lines
Quoted 8 lines
Quoted 8 lines
Quoted 2 lines
Quoted 1 line
Won't this serialize the whole thing again?
Yes, this mutex lock will ultimately serialize all PM operations. But, all device's PM operations are asynchronous each other at first. So, the PM operation order of all devices will vary in multiple suspend/resume. This can be similar to real to an extreme, and helpful to debugging.
I see. You're saying that callbacks will be serialized, but if they originally would be asynchronous with respect to each other (they may run in parallel IOW), their respective ordering may vary between suspend-resume cycles.
The class of bugs you can catch this way is quite limited and the change is rather intrusive, so I'm with Pavel on that.
Quoted 7 lines
Quoted 3 lines
Sorry for late reply.
Although the improvement to PM-trace is limited, I still think it is helpful for debugging some special suspend/resume bugs.
Hi Rafael,
This patch will not be merged into mainline kernel, right?
No, it won't.
At least for now, the case for it is not convincing enough.
Thanks,
Rafael
Hi guys,
Could you please come up with your comments about this patch?
Thanks,
Zhonghui
Quoted 270 lines · Zhonghui
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 <[email protected]>--- drivers/base/power/main.c | 53 +++++++++++++++++++++----------------------- include/linux/pm-trace.h | 24 ++++++++++++-------- kernel/power/main.c | 2 + 3 files changed, 41 insertions(+), 38 deletions(-)drivers/base/power/main.c +25
-28@@ -476,9 +476,6 @@ static int device_resume_noirq(struct device *dev, pm_message_t state, bool asynchar *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 asynchar *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 achar *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 aschar *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; }include/linux/pm-trace.h +14
-10@@ -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 kernel/power/main.c +2
-1@@ -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
Quoted 4 lines · Zhonghui
Hi guys,
Could you please come up with your comments about this patch?
I sent one. Have you not received it?
Signature · 2 lines
I speak only for myself. Rafael J. Wysocki, Intel Open Source Technology Center.
Quoted 5 lines · Rafael J. Wysocki
Quoted 3 lines · Zhonghui
Hi guys,
Could you please come up with your comments about this patch?
I sent one. Have you not received it?
I have replied that mail. Many thanks for your comments.
Thanks,
Zhonghui