* [PATCH 0/2] PM: hibernate: add helper to detect image-write phase
@ 2026-04-28 8:05 Haowen Tu
2026-04-28 8:05 ` [PATCH 1/2] PM: hibernate: add pm_hibernation_storing_image() helper Haowen Tu
` (2 more replies)
0 siblings, 3 replies; 21+ messages in thread
From: Haowen Tu @ 2026-04-28 8:05 UTC (permalink / raw)
To: rafael
Cc: lenb, pavel, linux-pm, laurent.pinchart, hansg, mchehab,
linux-media, linux-kernel, Haowen Tu
During S4 hibernation, after create_image() saves the memory snapshot,
the kernel resumes devices with PMSG_THAW solely to write the hibernation
image to storage before final powerdown. Drivers unrelated to storage I/O
have no reason to reinitialize during this transient phase.
Drivers using dev_pm_ops already have separate .thaw and .restore
callbacks and can handle this natively. However, usb_driver.resume
takes no pm_message_t argument, so a USB driver cannot distinguish
PMSG_THAW from PMSG_RESTORE without an out-of-band query.
This series adds pm_hibernation_storing_image(), a small helper that
returns true during the image-write window. As a first user, the UVC
driver uses it to skip resume in uvc_video_resume() until the real
PMSG_RESTORE wake-up.
Tested with hibernation image written to local storage and resumed from
disk on a system with a USB UVC camera attached.
Haowen Tu (2):
pm/hibernate: add pm_hibernation_storing_image() helper
media: uvcvideo: skip resume when writing hibernation image
drivers/media/usb/uvc/uvc_video.c | 10 ++++++++++
include/linux/suspend.h | 2 ++
kernel/power/hibernate.c | 19 +++++++++++++++++++
3 files changed, 31 insertions(+)
--
2.20.1
^ permalink raw reply [flat|nested] 21+ messages in thread* [PATCH 1/2] PM: hibernate: add pm_hibernation_storing_image() helper 2026-04-28 8:05 [PATCH 0/2] PM: hibernate: add helper to detect image-write phase Haowen Tu @ 2026-04-28 8:05 ` Haowen Tu 2026-05-26 13:43 ` Rafael J. Wysocki 2026-04-28 8:05 ` [PATCH 2/2] media: uvcvideo: skip resume when writing hibernation image Haowen Tu 2026-05-28 8:18 ` [PATCH v2 0/2] PM: hibernate: skip UVC resume after snapshot Haowen Tu 2 siblings, 1 reply; 21+ messages in thread From: Haowen Tu @ 2026-04-28 8:05 UTC (permalink / raw) To: rafael Cc: lenb, pavel, linux-pm, laurent.pinchart, hansg, mchehab, linux-media, linux-kernel, Haowen Tu During hibernation, after create_image() saves the memory snapshot, the kernel resumes devices with PMSG_THAW solely to write the hibernation image to storage, then powers off. Drivers for hardware not involved in storage I/O have no reason to reinitialize during this transient phase. Some subsystems, such as USB, do not expose the hibernation PM message to driver resume callbacks, so drivers there need an explicit query to distinguish the image-write phase from the final restore path. Export pm_hibernation_storing_image() for this purpose. The implementation returns !!in_suspend, which is set to 1 in create_image() just before swsusp_arch_suspend() and reset to 0 in hibernate() after swsusp_write() completes. Because in_suspend is marked __nosavedata, it is not saved into the hibernation image; on the restore path the variable remains 0 throughout, so the helper correctly returns false during PMSG_RESTORE device resume. Signed-off-by: Haowen Tu <tuhaowen@uniontech.com> --- include/linux/suspend.h | 2 ++ kernel/power/hibernate.c | 19 +++++++++++++++++++ 2 files changed, 21 insertions(+) diff --git a/include/linux/suspend.h b/include/linux/suspend.h index b02876f1ae38..28b454def83d 100644 --- a/include/linux/suspend.h +++ b/include/linux/suspend.h @@ -393,6 +393,7 @@ extern void hibernation_set_ops(const struct platform_hibernation_ops *ops); extern int hibernate(void); extern bool system_entering_hibernation(void); extern bool hibernation_available(void); +extern bool pm_hibernation_storing_image(void); asmlinkage int swsusp_save(void); extern struct pbe *restore_pblist; int pfn_is_nosave(unsigned long pfn); @@ -412,6 +413,7 @@ static inline void hibernation_set_ops(const struct platform_hibernation_ops *op static inline int hibernate(void) { return -ENOSYS; } static inline bool system_entering_hibernation(void) { return false; } static inline bool hibernation_available(void) { return false; } +static inline bool pm_hibernation_storing_image(void) { return false; } static inline int hibernate_quiet_exec(int (*func)(void *data), void *data) { return -ENOTSUPP; diff --git a/kernel/power/hibernate.c b/kernel/power/hibernate.c index af8d07bafe02..bc632cce40ff 100644 --- a/kernel/power/hibernate.c +++ b/kernel/power/hibernate.c @@ -113,6 +113,25 @@ bool hibernation_available(void) !secretmem_active() && !cxl_mem_active(); } +/** + * pm_hibernation_storing_image - check if system is writing the hibernation image + * + * After create_image() saves a memory snapshot, the kernel briefly resumes + * devices with PMSG_THAW to write the image to storage before final powerdown. + * Drivers for hardware not involved in storage I/O may call this helper from + * their resume callbacks to skip unnecessary hardware initialization during + * that transient phase. + * + * Context: May be called from device PM callbacks. + * Return: %true if a hibernation snapshot has been taken and the system is + * in the process of writing the image to persistent storage. + */ +bool pm_hibernation_storing_image(void) +{ + return !!in_suspend; +} +EXPORT_SYMBOL_GPL(pm_hibernation_storing_image); + /** * hibernation_set_ops - Set the global hibernate operations. * @ops: Hibernation operations to use in subsequent hibernation transitions. -- 2.20.1 ^ permalink raw reply related [flat|nested] 21+ messages in thread
* Re: [PATCH 1/2] PM: hibernate: add pm_hibernation_storing_image() helper 2026-04-28 8:05 ` [PATCH 1/2] PM: hibernate: add pm_hibernation_storing_image() helper Haowen Tu @ 2026-05-26 13:43 ` Rafael J. Wysocki 0 siblings, 0 replies; 21+ messages in thread From: Rafael J. Wysocki @ 2026-05-26 13:43 UTC (permalink / raw) To: Haowen Tu Cc: rafael, lenb, pavel, linux-pm, laurent.pinchart, hansg, mchehab, linux-media, linux-kernel On Tue, Apr 28, 2026 at 10:06 AM Haowen Tu <tuhaowen@uniontech.com> wrote: > > During hibernation, after create_image() saves the memory snapshot, > the kernel resumes devices with PMSG_THAW solely to write the hibernation > image to storage, then powers off. Drivers for hardware not involved in > storage I/O have no reason to reinitialize during this transient phase. > > Some subsystems, such as USB, do not expose the hibernation PM message > to driver resume callbacks, so drivers there need an explicit query to > distinguish the image-write phase from the final restore path. Export > pm_hibernation_storing_image() for this purpose. > > The implementation returns !!in_suspend, which is set to 1 in > create_image() just before swsusp_arch_suspend() and reset to 0 in > hibernate() after swsusp_write() completes. Because in_suspend is > marked __nosavedata, it is not saved into the hibernation image; on the > restore path the variable remains 0 throughout, so the helper correctly > returns false during PMSG_RESTORE device resume. > > Signed-off-by: Haowen Tu <tuhaowen@uniontech.com> > --- > include/linux/suspend.h | 2 ++ > kernel/power/hibernate.c | 19 +++++++++++++++++++ > 2 files changed, 21 insertions(+) > > diff --git a/include/linux/suspend.h b/include/linux/suspend.h > index b02876f1ae38..28b454def83d 100644 > --- a/include/linux/suspend.h > +++ b/include/linux/suspend.h > @@ -393,6 +393,7 @@ extern void hibernation_set_ops(const struct platform_hibernation_ops *ops); > extern int hibernate(void); > extern bool system_entering_hibernation(void); > extern bool hibernation_available(void); > +extern bool pm_hibernation_storing_image(void); > asmlinkage int swsusp_save(void); > extern struct pbe *restore_pblist; > int pfn_is_nosave(unsigned long pfn); > @@ -412,6 +413,7 @@ static inline void hibernation_set_ops(const struct platform_hibernation_ops *op > static inline int hibernate(void) { return -ENOSYS; } > static inline bool system_entering_hibernation(void) { return false; } > static inline bool hibernation_available(void) { return false; } > +static inline bool pm_hibernation_storing_image(void) { return false; } > > static inline int hibernate_quiet_exec(int (*func)(void *data), void *data) { > return -ENOTSUPP; > diff --git a/kernel/power/hibernate.c b/kernel/power/hibernate.c > index af8d07bafe02..bc632cce40ff 100644 > --- a/kernel/power/hibernate.c > +++ b/kernel/power/hibernate.c > @@ -113,6 +113,25 @@ bool hibernation_available(void) > !secretmem_active() && !cxl_mem_active(); > } > > +/** > + * pm_hibernation_storing_image - check if system is writing the hibernation image > + * > + * After create_image() saves a memory snapshot, the kernel briefly resumes > + * devices with PMSG_THAW to write the image to storage before final powerdown. > + * Drivers for hardware not involved in storage I/O may call this helper from > + * their resume callbacks to skip unnecessary hardware initialization during > + * that transient phase. > + * > + * Context: May be called from device PM callbacks. > + * Return: %true if a hibernation snapshot has been taken and the system is > + * in the process of writing the image to persistent storage. > + */ > +bool pm_hibernation_storing_image(void) > +{ > + return !!in_suspend; > +} > +EXPORT_SYMBOL_GPL(pm_hibernation_storing_image); Could this be called pm_hibernation_snapshot_done(), please? Also, since it relies on in_suspend, please double check that in_suspend is cleared properly in all hibernation failure/test paths (basically, it must be cleared if the snapshot memory is going to be released). ^ permalink raw reply [flat|nested] 21+ messages in thread
* [PATCH 2/2] media: uvcvideo: skip resume when writing hibernation image 2026-04-28 8:05 [PATCH 0/2] PM: hibernate: add helper to detect image-write phase Haowen Tu 2026-04-28 8:05 ` [PATCH 1/2] PM: hibernate: add pm_hibernation_storing_image() helper Haowen Tu @ 2026-04-28 8:05 ` Haowen Tu 2026-04-28 8:36 ` Oliver Neukum 2026-04-28 9:13 ` Laurent Pinchart 2026-05-28 8:18 ` [PATCH v2 0/2] PM: hibernate: skip UVC resume after snapshot Haowen Tu 2 siblings, 2 replies; 21+ messages in thread From: Haowen Tu @ 2026-04-28 8:05 UTC (permalink / raw) To: rafael Cc: lenb, pavel, linux-pm, laurent.pinchart, hansg, mchehab, linux-media, linux-kernel, Haowen Tu When a UVC camera is in active use and the system enters S4 hibernation, the camera is suspended as part of the normal device freeze sequence. However, after create_image() saves the memory snapshot, the kernel briefly resumes all devices with PMSG_THAW to write the hibernation image to storage. This causes uvc_video_resume() to run and reinitialize the camera hardware, which visibly turns on the camera indicator LED during this intermediate phase -- even though the system is about to power off. The UVC device is not needed during the image-write window, where the system only needs devices required for writing the hibernation image. USB .resume callbacks do not receive pm_message_t (unlike .suspend), so use the PM-layer helper to detect this phase and return early from uvc_video_resume(), preventing the unnecessary hardware reinitialization and the spurious LED activation. Skipping the THAW resume is safe: stream->frozen remains 1 (set during the earlier FREEZE suspend), the device is powered off immediately after swsusp_write() with no intervening suspend, and the subsequent PMSG_RESTORE resume on the restored kernel calls uvc_video_resume() with pm_hibernation_storing_image() returning false, performing the full reinitialization as normal. Signed-off-by: Haowen Tu <tuhaowen@uniontech.com> --- drivers/media/usb/uvc/uvc_video.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/drivers/media/usb/uvc/uvc_video.c b/drivers/media/usb/uvc/uvc_video.c index f6c8e3223796..16a911b684d5 100644 --- a/drivers/media/usb/uvc/uvc_video.c +++ b/drivers/media/usb/uvc/uvc_video.c @@ -12,6 +12,7 @@ #include <linux/list.h> #include <linux/module.h> #include <linux/slab.h> +#include <linux/suspend.h> #include <linux/usb.h> #include <linux/usb/hcd.h> #include <linux/videodev2.h> @@ -2135,6 +2136,15 @@ int uvc_video_resume(struct uvc_streaming *stream, int reset) { int ret; + /* + * After taking the hibernation memory snapshot, the kernel briefly resumes + * devices with PMSG_THAW to write the image to storage before powerdown. + * The UVC device is not involved in storage I/O, so skip reinitializing + * it to avoid unnecessary USB traffic during this transient phase. + */ + if (pm_hibernation_storing_image()) + return 0; + /* * If the bus has been reset on resume, set the alternate setting to 0. * This should be the default value, but some devices crash or otherwise -- 2.20.1 ^ permalink raw reply related [flat|nested] 21+ messages in thread
* Re: [PATCH 2/2] media: uvcvideo: skip resume when writing hibernation image 2026-04-28 8:05 ` [PATCH 2/2] media: uvcvideo: skip resume when writing hibernation image Haowen Tu @ 2026-04-28 8:36 ` Oliver Neukum 2026-04-28 8:58 ` Haowen Tu 2026-04-28 9:13 ` Laurent Pinchart 1 sibling, 1 reply; 21+ messages in thread From: Oliver Neukum @ 2026-04-28 8:36 UTC (permalink / raw) To: Haowen Tu, rafael Cc: lenb, pavel, linux-pm, laurent.pinchart, hansg, mchehab, linux-media, linux-kernel Hi, On 28.04.26 10:05, Haowen Tu wrote: > Skipping the THAW resume is safe: stream->frozen remains 1 (set during > the earlier FREEZE suspend), the device is powered off immediately after > swsusp_write() with no intervening suspend, and the subsequent > PMSG_RESTORE resume on the restored kernel calls uvc_video_resume() > with pm_hibernation_storing_image() returning false, performing the full > reinitialization as normal. > What happens if writing out the image fails? Regards Oliver ^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [PATCH 2/2] media: uvcvideo: skip resume when writing hibernation image 2026-04-28 8:36 ` Oliver Neukum @ 2026-04-28 8:58 ` Haowen Tu 0 siblings, 0 replies; 21+ messages in thread From: Haowen Tu @ 2026-04-28 8:58 UTC (permalink / raw) To: oneukum Cc: hansg, laurent.pinchart, lenb, linux-kernel, linux-media, linux-pm, mchehab, pavel, rafael, tuhaowen Hi Oliver, On Tue, 28 Apr 2026, Oliver Neukum wrote: > What happens if writing out the image fails? Thanks for pointing this out. If swsusp_write() fails, the system resumes in the original kernel instead of powering off, so the failure path needs to be considered as well. I was reasoning about the successful hibernation path here, but you are right that skipping resume work during THAW may not be safe if the image write does not complete. I will trace the failure path more carefully and update the series accordingly. Thanks, Haowen Tu ^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [PATCH 2/2] media: uvcvideo: skip resume when writing hibernation image 2026-04-28 8:05 ` [PATCH 2/2] media: uvcvideo: skip resume when writing hibernation image Haowen Tu 2026-04-28 8:36 ` Oliver Neukum @ 2026-04-28 9:13 ` Laurent Pinchart 2026-04-29 1:15 ` Haowen Tu 2026-04-29 1:16 ` Haowen Tu 1 sibling, 2 replies; 21+ messages in thread From: Laurent Pinchart @ 2026-04-28 9:13 UTC (permalink / raw) To: Haowen Tu Cc: rafael, lenb, pavel, linux-pm, hansg, mchehab, linux-media, linux-kernel On Tue, Apr 28, 2026 at 04:05:13PM +0800, Haowen Tu wrote: > When a UVC camera is in active use and the system enters S4 hibernation, > the camera is suspended as part of the normal device freeze sequence. > However, after create_image() saves the memory snapshot, the kernel > briefly resumes all devices with PMSG_THAW to write the hibernation image > to storage. This causes uvc_video_resume() to run and reinitialize the > camera hardware, which visibly turns on the camera indicator LED during > this intermediate phase -- even though the system is about to power off. > > The UVC device is not needed during the image-write window, where the > system only needs devices required for writing the hibernation image. > USB .resume callbacks do not receive pm_message_t (unlike .suspend), > so use the PM-layer helper to detect this phase and return early from > uvc_video_resume(), preventing the unnecessary hardware reinitialization > and the spurious LED activation. > > Skipping the THAW resume is safe: stream->frozen remains 1 (set during > the earlier FREEZE suspend), the device is powered off immediately after > swsusp_write() with no intervening suspend, and the subsequent > PMSG_RESTORE resume on the restored kernel calls uvc_video_resume() > with pm_hibernation_storing_image() returning false, performing the full > reinitialization as normal. > > Signed-off-by: Haowen Tu <tuhaowen@uniontech.com> > --- > drivers/media/usb/uvc/uvc_video.c | 10 ++++++++++ > 1 file changed, 10 insertions(+) > > diff --git a/drivers/media/usb/uvc/uvc_video.c b/drivers/media/usb/uvc/uvc_video.c > index f6c8e3223796..16a911b684d5 100644 > --- a/drivers/media/usb/uvc/uvc_video.c > +++ b/drivers/media/usb/uvc/uvc_video.c > @@ -12,6 +12,7 @@ > #include <linux/list.h> > #include <linux/module.h> > #include <linux/slab.h> > +#include <linux/suspend.h> > #include <linux/usb.h> > #include <linux/usb/hcd.h> > #include <linux/videodev2.h> > @@ -2135,6 +2136,15 @@ int uvc_video_resume(struct uvc_streaming *stream, int reset) > { > int ret; > > + /* > + * After taking the hibernation memory snapshot, the kernel briefly resumes > + * devices with PMSG_THAW to write the image to storage before powerdown. > + * The UVC device is not involved in storage I/O, so skip reinitializing > + * it to avoid unnecessary USB traffic during this transient phase. > + */ Will all leaf drivers need to implement something similar ? How does that scale ? > + if (pm_hibernation_storing_image()) > + return 0; > + > /* > * If the bus has been reset on resume, set the alternate setting to 0. > * This should be the default value, but some devices crash or otherwise -- Regards, Laurent Pinchart ^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [PATCH 2/2] media: uvcvideo: skip resume when writing hibernation image 2026-04-28 9:13 ` Laurent Pinchart @ 2026-04-29 1:15 ` Haowen Tu 2026-04-29 1:16 ` Haowen Tu 1 sibling, 0 replies; 21+ messages in thread From: Haowen Tu @ 2026-04-29 1:15 UTC (permalink / raw) To: laurent.pinchart Cc: gregkh, linux-usb, hansg, mchehab, rafael, lenb, pavel, linux-pm, linux-media, linux-kernel, Haowen Tu Hi Laurent, On Tue, Apr 28, 2026 at 12:13:56PM +0300, Laurent Pinchart wrote: > Will all leaf drivers need to implement something similar ? How does > that scale ? Thanks, that's a very valid concern. If this pattern ends up being needed in multiple USB interface drivers, then handling it in each leaf driver would clearly not scale well. My initial motivation was that the UVC streaming resume path is reached from usb_driver.resume(), which doesn't expose the hibernation PM message. As a result, the driver has no way to distinguish PMSG_THAW from PMSG_RESTORE locally. That said, I agree this points to a USB-level design question rather than just a UVC-specific one. I'll revisit the approach with that in mind, and will include the USB maintainers and list in the next round. Thanks, Haowen ^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [PATCH 2/2] media: uvcvideo: skip resume when writing hibernation image 2026-04-28 9:13 ` Laurent Pinchart 2026-04-29 1:15 ` Haowen Tu @ 2026-04-29 1:16 ` Haowen Tu 1 sibling, 0 replies; 21+ messages in thread From: Haowen Tu @ 2026-04-29 1:16 UTC (permalink / raw) To: laurent.pinchart Cc: gregkh, linux-usb, hansg, mchehab, rafael, lenb, pavel, linux-pm, linux-media, linux-kernel, Haowen Tu Hi Laurent, On Tue, Apr 28, 2026 at 12:13:56PM +0300, Laurent Pinchart wrote: > Will all leaf drivers need to implement something similar ? How does > that scale ? Thanks, that's a very valid concern. If this pattern ends up being needed in multiple USB interface drivers, then handling it in each leaf driver would clearly not scale well. My initial motivation was that the UVC streaming resume path is reached from usb_driver.resume(), which doesn't expose the hibernation PM message. As a result, the driver has no way to distinguish PMSG_THAW from PMSG_RESTORE locally. That said, I agree this points to a USB-level design question rather than just a UVC-specific one. I'll revisit the approach with that in mind, and will include the USB maintainers and list in the next round. Thanks, Haowen ^ permalink raw reply [flat|nested] 21+ messages in thread
* [PATCH v2 0/2] PM: hibernate: skip UVC resume after snapshot 2026-04-28 8:05 [PATCH 0/2] PM: hibernate: add helper to detect image-write phase Haowen Tu 2026-04-28 8:05 ` [PATCH 1/2] PM: hibernate: add pm_hibernation_storing_image() helper Haowen Tu 2026-04-28 8:05 ` [PATCH 2/2] media: uvcvideo: skip resume when writing hibernation image Haowen Tu @ 2026-05-28 8:18 ` Haowen Tu 2026-05-28 8:18 ` [PATCH v2 1/2] PM: hibernate: add pm_hibernation_snapshot_done() helper Haowen Tu 2026-05-28 8:18 ` [PATCH v2 2/2] media: uvcvideo: skip resume " Haowen Tu 2 siblings, 2 replies; 21+ messages in thread From: Haowen Tu @ 2026-05-28 8:18 UTC (permalink / raw) To: rafael Cc: lenb, pavel, linux-pm, laurent.pinchart, hansg, mchehab, linux-media, gregkh, stern, oneukum, linux-usb, linux-kernel, kernel, Haowen Tu During hibernation, after the memory snapshot has been created, the kernel briefly resumes devices with PMSG_THAW to write the snapshot to storage before powering off. USB driver resume callbacks do not receive the hibernation PM message, so uvcvideo cannot distinguish this transient image-write phase from the final restore path. This series adds pm_hibernation_snapshot_done() and uses it in uvcvideo to avoid reinitializing the camera during the image-write phase. This is not intended to make every leaf driver special-case hibernation THAW. A generic USB-core skip would not be safe because some USB interfaces may be part of the storage path, or otherwise be required by dependencies during image writeout. The helper is an opt-in mechanism for drivers with a concrete reason to avoid reinitializing hardware in this transient phase. In this case, uvcvideo has a user-visible side effect, the camera indicator LED, while the camera is not part of the image writeout path. Changes in v2: - Rename pm_hibernation_storing_image() to pm_hibernation_snapshot_done(). - Clear in_suspend before releasing snapshot memory on the hibernation failure paths and after swsusp_write() returns. - Update the uvcvideo call site for the new helper name. Haowen Tu (2): PM: hibernate: add pm_hibernation_snapshot_done() helper media: uvcvideo: skip resume after hibernation snapshot drivers/media/usb/uvc/uvc_video.c | 12 ++++++++++++ include/linux/suspend.h | 2 ++ kernel/power/hibernate.c | 31 +++++++++++++++++++++++++++---- 3 files changed, 41 insertions(+), 4 deletions(-) -- 2.20.1 ^ permalink raw reply [flat|nested] 21+ messages in thread
* [PATCH v2 1/2] PM: hibernate: add pm_hibernation_snapshot_done() helper 2026-05-28 8:18 ` [PATCH v2 0/2] PM: hibernate: skip UVC resume after snapshot Haowen Tu @ 2026-05-28 8:18 ` Haowen Tu 2026-06-01 18:22 ` Rafael J. Wysocki 2026-05-28 8:18 ` [PATCH v2 2/2] media: uvcvideo: skip resume " Haowen Tu 1 sibling, 1 reply; 21+ messages in thread From: Haowen Tu @ 2026-05-28 8:18 UTC (permalink / raw) To: rafael Cc: lenb, pavel, linux-pm, laurent.pinchart, hansg, mchehab, linux-media, gregkh, stern, oneukum, linux-usb, linux-kernel, kernel, Haowen Tu During hibernation, after create_image() saves the memory snapshot, the kernel resumes devices with PMSG_THAW solely to write the hibernation image to storage, then powers off. Drivers for hardware not involved in storage I/O have no reason to reinitialize during this transient phase. Some subsystems, such as USB, do not expose the hibernation PM message to driver resume callbacks, so drivers there need an explicit query to distinguish the image-write phase from the final restore path. Export pm_hibernation_snapshot_done() for this purpose. The implementation returns !!in_suspend, which is set to 1 in create_image() just before swsusp_arch_suspend(). Because in_suspend is marked __nosavedata, it is not saved into the hibernation image; on the restore path the variable remains 0, so the helper correctly returns false during PMSG_RESTORE device resume. Clear in_suspend before releasing snapshot memory on hibernation failure paths and after swsusp_write() returns, so the helper does not report a stale snapshot after the snapshot pages have been released. Signed-off-by: Haowen Tu <tuhaowen@uniontech.com> --- Changes in v2: - Rename pm_hibernation_storing_image() to pm_hibernation_snapshot_done(). - Clear in_suspend before releasing snapshot memory on failure paths and after swsusp_write() returns. include/linux/suspend.h | 2 ++ kernel/power/hibernate.c | 31 +++++++++++++++++++++++++++---- 2 files changed, 29 insertions(+), 4 deletions(-) diff --git a/include/linux/suspend.h b/include/linux/suspend.h index b02876f1ae38..78e7e33c3d19 100644 --- a/include/linux/suspend.h +++ b/include/linux/suspend.h @@ -393,6 +393,7 @@ extern void hibernation_set_ops(const struct platform_hibernation_ops *ops); extern int hibernate(void); extern bool system_entering_hibernation(void); extern bool hibernation_available(void); +extern bool pm_hibernation_snapshot_done(void); asmlinkage int swsusp_save(void); extern struct pbe *restore_pblist; int pfn_is_nosave(unsigned long pfn); @@ -412,6 +413,7 @@ static inline void hibernation_set_ops(const struct platform_hibernation_ops *op static inline int hibernate(void) { return -ENOSYS; } static inline bool system_entering_hibernation(void) { return false; } static inline bool hibernation_available(void) { return false; } +static inline bool pm_hibernation_snapshot_done(void) { return false; } static inline int hibernate_quiet_exec(int (*func)(void *data), void *data) { return -ENOTSUPP; diff --git a/kernel/power/hibernate.c b/kernel/power/hibernate.c index af8d07bafe02..47047937e262 100644 --- a/kernel/power/hibernate.c +++ b/kernel/power/hibernate.c @@ -113,6 +113,25 @@ bool hibernation_available(void) !secretmem_active() && !cxl_mem_active(); } +/** + * pm_hibernation_snapshot_done - check if a hibernation snapshot is available + * + * After create_image() saves a memory snapshot, the kernel briefly resumes + * devices with PMSG_THAW to write the image to storage before final powerdown. + * Drivers that do not need to participate in image writing may call this + * helper from their resume callbacks to skip unnecessary hardware + * initialization during that transient phase. + * + * Context: May be called from device PM callbacks. + * Return: %true if a hibernation snapshot has been taken and has not been + * released yet. + */ +bool pm_hibernation_snapshot_done(void) +{ + return !!in_suspend; +} +EXPORT_SYMBOL_GPL(pm_hibernation_snapshot_done); + /** * hibernation_set_ops - Set the global hibernate operations. * @ops: Hibernation operations to use in subsequent hibernation transitions. @@ -418,6 +437,7 @@ static void shrink_shmem_memory(void) int hibernation_snapshot(int platform_mode) { pm_message_t msg; + bool snapshot_done; int error; pm_suspend_clear_flags(); @@ -474,15 +494,18 @@ int hibernation_snapshot(int platform_mode) * returns here (1) after the image has been created or the * image creation has failed and (2) after a successful restore. */ + snapshot_done = in_suspend; /* We may need to release the preallocated image pages here. */ - if (error || !in_suspend) + if (error || !snapshot_done) { + in_suspend = 0; swsusp_free(); + } - msg = in_suspend ? (error ? PMSG_RECOVER : PMSG_THAW) : PMSG_RESTORE; + msg = snapshot_done ? (error ? PMSG_RECOVER : PMSG_THAW) : PMSG_RESTORE; dpm_resume(msg); - if (error || !in_suspend) + if (error || !snapshot_done) pm_restore_gfp_mask(); console_resume_all(); @@ -865,6 +888,7 @@ int hibernate(void) pm_pr_dbg("Writing hibernation image.\n"); error = swsusp_write(flags); + in_suspend = 0; swsusp_free(); if (!error) { if (hibernation_mode == HIBERNATION_TEST_RESUME) @@ -872,7 +896,6 @@ int hibernate(void) else power_down(); } - in_suspend = 0; pm_restore_gfp_mask(); } else { pm_pr_dbg("Hibernation image restored successfully.\n"); -- 2.20.1 ^ permalink raw reply related [flat|nested] 21+ messages in thread
* Re: [PATCH v2 1/2] PM: hibernate: add pm_hibernation_snapshot_done() helper 2026-05-28 8:18 ` [PATCH v2 1/2] PM: hibernate: add pm_hibernation_snapshot_done() helper Haowen Tu @ 2026-06-01 18:22 ` Rafael J. Wysocki 2026-06-02 3:24 ` Haowen Tu 0 siblings, 1 reply; 21+ messages in thread From: Rafael J. Wysocki @ 2026-06-01 18:22 UTC (permalink / raw) To: Haowen Tu Cc: rafael, lenb, pavel, linux-pm, laurent.pinchart, hansg, mchehab, linux-media, gregkh, stern, oneukum, linux-usb, linux-kernel, kernel On Thu, May 28, 2026 at 10:19 AM Haowen Tu <tuhaowen@uniontech.com> wrote: > > During hibernation, after create_image() saves the memory snapshot, the > kernel resumes devices with PMSG_THAW solely to write the hibernation > image to storage, then powers off. Drivers for hardware not involved in > storage I/O have no reason to reinitialize during this transient phase. They do have a reason for doing it. Their poweroff (or shutdown) callbacks will be called while preparing to power off the system subsequently and they need to be ready for that. The most straightforward way to achieve this is to resume so they can "suspend" again. > Some subsystems, such as USB, do not expose the hibernation PM message > to driver resume callbacks, so drivers there need an explicit query to > distinguish the image-write phase from the final restore path. Export > pm_hibernation_snapshot_done() for this purpose. > > The implementation returns !!in_suspend, which is set to 1 in > create_image() just before swsusp_arch_suspend(). Because in_suspend is > marked __nosavedata, it is not saved into the hibernation image; on the > restore path the variable remains 0, so the helper correctly returns > false during PMSG_RESTORE device resume. > > Clear in_suspend before releasing snapshot memory on hibernation failure > paths and after swsusp_write() returns, so the helper does not report a > stale snapshot after the snapshot pages have been released. This last piece needs to be split off into a separate patch. > Signed-off-by: Haowen Tu <tuhaowen@uniontech.com> > --- > Changes in v2: > - Rename pm_hibernation_storing_image() to > pm_hibernation_snapshot_done(). > - Clear in_suspend before releasing snapshot memory on failure paths and > after swsusp_write() returns. > > include/linux/suspend.h | 2 ++ > kernel/power/hibernate.c | 31 +++++++++++++++++++++++++++---- > 2 files changed, 29 insertions(+), 4 deletions(-) > > diff --git a/include/linux/suspend.h b/include/linux/suspend.h > index b02876f1ae38..78e7e33c3d19 100644 > --- a/include/linux/suspend.h > +++ b/include/linux/suspend.h > @@ -393,6 +393,7 @@ extern void hibernation_set_ops(const struct platform_hibernation_ops *ops); > extern int hibernate(void); > extern bool system_entering_hibernation(void); > extern bool hibernation_available(void); > +extern bool pm_hibernation_snapshot_done(void); > asmlinkage int swsusp_save(void); > extern struct pbe *restore_pblist; > int pfn_is_nosave(unsigned long pfn); > @@ -412,6 +413,7 @@ static inline void hibernation_set_ops(const struct platform_hibernation_ops *op > static inline int hibernate(void) { return -ENOSYS; } > static inline bool system_entering_hibernation(void) { return false; } > static inline bool hibernation_available(void) { return false; } > +static inline bool pm_hibernation_snapshot_done(void) { return false; } > > static inline int hibernate_quiet_exec(int (*func)(void *data), void *data) { > return -ENOTSUPP; > diff --git a/kernel/power/hibernate.c b/kernel/power/hibernate.c > index af8d07bafe02..47047937e262 100644 > --- a/kernel/power/hibernate.c > +++ b/kernel/power/hibernate.c > @@ -113,6 +113,25 @@ bool hibernation_available(void) > !secretmem_active() && !cxl_mem_active(); > } > > +/** > + * pm_hibernation_snapshot_done - check if a hibernation snapshot is available > + * > + * After create_image() saves a memory snapshot, the kernel briefly resumes > + * devices with PMSG_THAW to write the image to storage before final powerdown. > + * Drivers that do not need to participate in image writing may call this > + * helper from their resume callbacks to skip unnecessary hardware > + * initialization during that transient phase. > + * > + * Context: May be called from device PM callbacks. > + * Return: %true if a hibernation snapshot has been taken and has not been > + * released yet. > + */ > +bool pm_hibernation_snapshot_done(void) > +{ > + return !!in_suspend; > +} > +EXPORT_SYMBOL_GPL(pm_hibernation_snapshot_done); > + > /** > * hibernation_set_ops - Set the global hibernate operations. > * @ops: Hibernation operations to use in subsequent hibernation transitions. > @@ -418,6 +437,7 @@ static void shrink_shmem_memory(void) > int hibernation_snapshot(int platform_mode) > { > pm_message_t msg; > + bool snapshot_done; > int error; > > pm_suspend_clear_flags(); > @@ -474,15 +494,18 @@ int hibernation_snapshot(int platform_mode) > * returns here (1) after the image has been created or the > * image creation has failed and (2) after a successful restore. > */ > + snapshot_done = in_suspend; > > /* We may need to release the preallocated image pages here. */ > - if (error || !in_suspend) > + if (error || !snapshot_done) { > + in_suspend = 0; > swsusp_free(); > + } > > - msg = in_suspend ? (error ? PMSG_RECOVER : PMSG_THAW) : PMSG_RESTORE; > + msg = snapshot_done ? (error ? PMSG_RECOVER : PMSG_THAW) : PMSG_RESTORE; > dpm_resume(msg); > > - if (error || !in_suspend) > + if (error || !snapshot_done) > pm_restore_gfp_mask(); > > console_resume_all(); > @@ -865,6 +888,7 @@ int hibernate(void) > > pm_pr_dbg("Writing hibernation image.\n"); > error = swsusp_write(flags); > + in_suspend = 0; > swsusp_free(); > if (!error) { > if (hibernation_mode == HIBERNATION_TEST_RESUME) > @@ -872,7 +896,6 @@ int hibernate(void) > else > power_down(); > } > - in_suspend = 0; > pm_restore_gfp_mask(); > } else { > pm_pr_dbg("Hibernation image restored successfully.\n"); > -- > 2.20.1 ^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [PATCH v2 1/2] PM: hibernate: add pm_hibernation_snapshot_done() helper 2026-06-01 18:22 ` Rafael J. Wysocki @ 2026-06-02 3:24 ` Haowen Tu 2026-06-18 1:31 ` [PATCH v3 0/3] PM: hibernate: skip UVC streaming restart after snapshot Haowen Tu 0 siblings, 1 reply; 21+ messages in thread From: Haowen Tu @ 2026-06-02 3:24 UTC (permalink / raw) To: rafael Cc: gregkh, hansg, kernel, laurent.pinchart, lenb, linux-kernel, linux-media, linux-pm, linux-usb, mchehab, oneukum, pavel, stern, tuhaowen Hi Rafael, On Mon, Jun 01, 2026 at 08:22:00PM +0200, Rafael J. Wysocki wrote: > On Thu, May 28, 2026 at 10:19 AM Haowen Tu <tuhaowen@uniontech.com> wrote: > > > > During hibernation, after create_image() saves the memory snapshot, the > > kernel resumes devices with PMSG_THAW solely to write the hibernation > > image to storage, then powers off. Drivers for hardware not involved in > > storage I/O have no reason to reinitialize during this transient phase. > > They do have a reason for doing it. > > Their poweroff (or shutdown) callbacks will be called while preparing > to power off the system subsequently and they need to be ready for > that. The most straightforward way to achieve this is to resume so > they can "suspend" again. Thanks for pointing this out. My understanding is that the hibernation image contains the state from the snapshot point, that is before the subsequent THAW and image-write phase. Therefore, on the later restore path, the kernel resumes from the state captured at the snapshot point and still goes through the normal PMSG_RESTORE resume path. The THAW activity after the snapshot is not part of the restored image state. That said, I agree that some devices may need to be resumed before the final poweroff/shutdown callbacks run, so the wording in the changelog is too broad. I did not mean to suggest that all non-storage devices can or should skip THAW resume. The helper is meant to expose this PM state, not to prescribe that drivers should skip THAW resume. Whether a driver uses it would remain a driver-specific decision, based on whether skipping the hardware reinitialization is safe for that device, including its subsequent poweroff/shutdown handling. Drivers that need the normal THAW resume before poweroff/shutdown would simply not use it. In this series the user is uvcvideo. For USB devices, and specifically for UVC cameras, the device is hotpluggable and the driver already needs to tolerate device removal and disconnect-like conditions. The UVC driver also does not need the camera streaming engine to be restarted in order to write the hibernation image, while restarting it has a visible side effect by turning the camera LED back on. The check is placed after the driver's frozen state is cleared, so if image writeout fails, the driver is not left in the frozen state. I will reword the changelog in the next version to avoid implying that non-storage devices generally have no reason to resume during THAW. > > Clear in_suspend before releasing snapshot memory on hibernation failure > > paths and after swsusp_write() returns, so the helper does not report a > > stale snapshot after the snapshot pages have been released. > > This last piece needs to be split off into a separate patch. Sure, I will split the in_suspend cleanup into a separate patch in the next version. I will wait for your feedback before sending the next version. Thanks, Haowen ^ permalink raw reply [flat|nested] 21+ messages in thread
* [PATCH v3 0/3] PM: hibernate: skip UVC streaming restart after snapshot 2026-06-02 3:24 ` Haowen Tu @ 2026-06-18 1:31 ` Haowen Tu 2026-06-18 1:31 ` [PATCH v3 1/3] PM: hibernate: clear in_suspend before freeing the snapshot Haowen Tu ` (2 more replies) 0 siblings, 3 replies; 21+ messages in thread From: Haowen Tu @ 2026-06-18 1:31 UTC (permalink / raw) To: rafael Cc: tuhaowen, gregkh, hansg, kernel, laurent.pinchart, lenb, linux-kernel, linux-media, linux-pm, linux-usb, mchehab, oneukum, pavel, stern After a hibernation snapshot is created, devices are resumed with PMSG_THAW before the image is written and the system is powered off. USB interface driver resume callbacks do not receive the PM event, so they cannot distinguish this phase from PMSG_RESTORE. This series first makes the lifetime represented by in_suspend match the snapshot memory lifetime, then exposes that state through pm_hibernation_snapshot_done(). The helper only exposes the PM state; drivers remain responsible for deciding whether device-specific behavior is safe, including subsequent poweroff or shutdown handling. As the first user, uvcvideo skips only restarting active streaming hardware during the transient THAW phase. Its frozen state and clock are still updated, a subsequent UVC suspend can stop the stream as usual, and uvcvideo does not provide a shutdown callback that requires the streaming hardware to be restarted first. Changes in v3: - Split the in_suspend cleanup into a separate patch, as requested by Rafael. - Reword the helper description to clarify that it only exposes PM state and that callers must account for poweroff/shutdown handling. - Restrict the UVC description to skipping the streaming hardware restart and explain why it does not prevent UVC shutdown handling. - Drop extern from the new prototype to satisfy Media CI checkpatch. Changes in v2: - Rename pm_hibernation_storing_image() to pm_hibernation_snapshot_done(). - Clear in_suspend before releasing snapshot memory on failure paths and after swsusp_write() returns. - Move the UVC check after clearing the frozen state and resetting its clock. Haowen Tu (3): PM: hibernate: clear in_suspend before freeing the snapshot PM: hibernate: add pm_hibernation_snapshot_done() helper media: uvcvideo: skip streaming restart after hibernation snapshot drivers/media/usb/uvc/uvc_video.c | 8 ++++++++ include/linux/suspend.h | 2 ++ kernel/power/hibernate.c | 24 ++++++++++++++++++++---- 3 files changed, 30 insertions(+), 4 deletions(-) -- 2.20.1 ^ permalink raw reply [flat|nested] 21+ messages in thread
* [PATCH v3 1/3] PM: hibernate: clear in_suspend before freeing the snapshot 2026-06-18 1:31 ` [PATCH v3 0/3] PM: hibernate: skip UVC streaming restart after snapshot Haowen Tu @ 2026-06-18 1:31 ` Haowen Tu 2026-07-22 15:37 ` Rafael J. Wysocki (Intel) 2026-06-18 1:31 ` [PATCH v3 2/3] PM: hibernate: add pm_hibernation_snapshot_done() helper Haowen Tu 2026-06-18 1:31 ` [PATCH v3 3/3] media: uvcvideo: skip streaming restart after hibernation snapshot Haowen Tu 2 siblings, 1 reply; 21+ messages in thread From: Haowen Tu @ 2026-06-18 1:31 UTC (permalink / raw) To: rafael Cc: tuhaowen, gregkh, hansg, kernel, laurent.pinchart, lenb, linux-kernel, linux-media, linux-pm, linux-usb, mchehab, oneukum, pavel, stern in_suspend indicates that a hibernation snapshot has been created and is still available. Keep that state consistent with the lifetime of the snapshot memory by clearing in_suspend before swsusp_free() releases it. If image creation fails after in_suspend has been set, hibernation_snapshot() releases the snapshot memory but currently leaves in_suspend set. Preserve its value locally long enough to select the appropriate device resume message, then clear it before releasing the snapshot. Also clear in_suspend before releasing the snapshot after swsusp_write() returns. Signed-off-by: Haowen Tu <tuhaowen@uniontech.com> --- Changes in v3: - Split this cleanup from the helper patch. kernel/power/hibernate.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/kernel/power/hibernate.c b/kernel/power/hibernate.c index af8d07bafe02..6d3e637c5a02 100644 --- a/kernel/power/hibernate.c +++ b/kernel/power/hibernate.c @@ -418,6 +418,7 @@ static void shrink_shmem_memory(void) int hibernation_snapshot(int platform_mode) { pm_message_t msg; + bool snapshot_done; int error; pm_suspend_clear_flags(); @@ -474,15 +475,18 @@ int hibernation_snapshot(int platform_mode) * returns here (1) after the image has been created or the * image creation has failed and (2) after a successful restore. */ + snapshot_done = in_suspend; /* We may need to release the preallocated image pages here. */ - if (error || !in_suspend) + if (error || !snapshot_done) { + in_suspend = 0; swsusp_free(); + } - msg = in_suspend ? (error ? PMSG_RECOVER : PMSG_THAW) : PMSG_RESTORE; + msg = snapshot_done ? (error ? PMSG_RECOVER : PMSG_THAW) : PMSG_RESTORE; dpm_resume(msg); - if (error || !in_suspend) + if (error || !snapshot_done) pm_restore_gfp_mask(); console_resume_all(); @@ -865,6 +869,7 @@ int hibernate(void) pm_pr_dbg("Writing hibernation image.\n"); error = swsusp_write(flags); + in_suspend = 0; swsusp_free(); if (!error) { if (hibernation_mode == HIBERNATION_TEST_RESUME) @@ -872,7 +877,6 @@ int hibernate(void) else power_down(); } - in_suspend = 0; pm_restore_gfp_mask(); } else { pm_pr_dbg("Hibernation image restored successfully.\n"); -- 2.20.1 ^ permalink raw reply related [flat|nested] 21+ messages in thread
* Re: [PATCH v3 1/3] PM: hibernate: clear in_suspend before freeing the snapshot 2026-06-18 1:31 ` [PATCH v3 1/3] PM: hibernate: clear in_suspend before freeing the snapshot Haowen Tu @ 2026-07-22 15:37 ` Rafael J. Wysocki (Intel) 0 siblings, 0 replies; 21+ messages in thread From: Rafael J. Wysocki (Intel) @ 2026-07-22 15:37 UTC (permalink / raw) To: Haowen Tu Cc: rafael, gregkh, hansg, kernel, laurent.pinchart, lenb, linux-kernel, linux-media, linux-pm, linux-usb, mchehab, oneukum, pavel, stern On Thu, Jun 18, 2026 at 3:32 AM Haowen Tu <tuhaowen@uniontech.com> wrote: > > in_suspend indicates that a hibernation snapshot has been created and is > still available. Keep that state consistent with the lifetime of the > snapshot memory by clearing in_suspend before swsusp_free() releases it. > > If image creation fails after in_suspend has been set, > hibernation_snapshot() releases the snapshot memory but currently leaves > in_suspend set. Preserve its value locally long enough to select the > appropriate device resume message, then clear it before releasing the > snapshot. > > Also clear in_suspend before releasing the snapshot after swsusp_write() > returns. > > Signed-off-by: Haowen Tu <tuhaowen@uniontech.com> This is fine with me, so Acked-by: Rafael J. Wysocki (Intel) <rafael@kernel.org> and please feel free to route it along with the media patch. Alternatively, I can pick up the whole series if I get an ACK on the media patch. > --- > Changes in v3: > - Split this cleanup from the helper patch. > > kernel/power/hibernate.c | 12 ++++++++---- > 1 file changed, 8 insertions(+), 4 deletions(-) > > diff --git a/kernel/power/hibernate.c b/kernel/power/hibernate.c > index af8d07bafe02..6d3e637c5a02 100644 > --- a/kernel/power/hibernate.c > +++ b/kernel/power/hibernate.c > @@ -418,6 +418,7 @@ static void shrink_shmem_memory(void) > int hibernation_snapshot(int platform_mode) > { > pm_message_t msg; > + bool snapshot_done; > int error; > > pm_suspend_clear_flags(); > @@ -474,15 +475,18 @@ int hibernation_snapshot(int platform_mode) > * returns here (1) after the image has been created or the > * image creation has failed and (2) after a successful restore. > */ > + snapshot_done = in_suspend; > > /* We may need to release the preallocated image pages here. */ > - if (error || !in_suspend) > + if (error || !snapshot_done) { > + in_suspend = 0; > swsusp_free(); > + } > > - msg = in_suspend ? (error ? PMSG_RECOVER : PMSG_THAW) : PMSG_RESTORE; > + msg = snapshot_done ? (error ? PMSG_RECOVER : PMSG_THAW) : PMSG_RESTORE; > dpm_resume(msg); > > - if (error || !in_suspend) > + if (error || !snapshot_done) > pm_restore_gfp_mask(); > > console_resume_all(); > @@ -865,6 +869,7 @@ int hibernate(void) > > pm_pr_dbg("Writing hibernation image.\n"); > error = swsusp_write(flags); > + in_suspend = 0; > swsusp_free(); > if (!error) { > if (hibernation_mode == HIBERNATION_TEST_RESUME) > @@ -872,7 +877,6 @@ int hibernate(void) > else > power_down(); > } > - in_suspend = 0; > pm_restore_gfp_mask(); > } else { > pm_pr_dbg("Hibernation image restored successfully.\n"); > -- > 2.20.1 ^ permalink raw reply [flat|nested] 21+ messages in thread
* [PATCH v3 2/3] PM: hibernate: add pm_hibernation_snapshot_done() helper 2026-06-18 1:31 ` [PATCH v3 0/3] PM: hibernate: skip UVC streaming restart after snapshot Haowen Tu 2026-06-18 1:31 ` [PATCH v3 1/3] PM: hibernate: clear in_suspend before freeing the snapshot Haowen Tu @ 2026-06-18 1:31 ` Haowen Tu 2026-07-22 15:40 ` Rafael J. Wysocki (Intel) 2026-06-18 1:31 ` [PATCH v3 3/3] media: uvcvideo: skip streaming restart after hibernation snapshot Haowen Tu 2 siblings, 1 reply; 21+ messages in thread From: Haowen Tu @ 2026-06-18 1:31 UTC (permalink / raw) To: rafael Cc: tuhaowen, gregkh, hansg, kernel, laurent.pinchart, lenb, linux-kernel, linux-media, linux-pm, linux-usb, mchehab, oneukum, pavel, stern Some subsystem resume callbacks do not receive the PM event and therefore cannot distinguish the PMSG_THAW phase after snapshot creation from the PMSG_RESTORE phase. Export pm_hibernation_snapshot_done() so a driver can query whether the hibernation snapshot has been created and is still available. The helper only exposes the PM state; callers remain responsible for ensuring that any device-specific behavior is safe, including subsequent poweroff or shutdown handling. The helper returns !!in_suspend. This variable is set before swsusp_arch_suspend(), cleared before the snapshot memory is released, and marked __nosavedata, so it remains clear on the restore path. Signed-off-by: Haowen Tu <tuhaowen@uniontech.com> --- Changes in v3: - Split the in_suspend cleanup into a preceding patch. - Clarify that callers must account for poweroff/shutdown handling. - Drop extern from the new prototype. Changes in v2: - Rename pm_hibernation_storing_image() to pm_hibernation_snapshot_done(). include/linux/suspend.h | 2 ++ kernel/power/hibernate.c | 12 ++++++++++++ 2 files changed, 14 insertions(+) diff --git a/include/linux/suspend.h b/include/linux/suspend.h index b02876f1ae38..2cebbec3e2f7 100644 --- a/include/linux/suspend.h +++ b/include/linux/suspend.h @@ -393,6 +393,7 @@ extern void hibernation_set_ops(const struct platform_hibernation_ops *ops); extern int hibernate(void); extern bool system_entering_hibernation(void); extern bool hibernation_available(void); +bool pm_hibernation_snapshot_done(void); asmlinkage int swsusp_save(void); extern struct pbe *restore_pblist; int pfn_is_nosave(unsigned long pfn); @@ -412,6 +413,7 @@ static inline void hibernation_set_ops(const struct platform_hibernation_ops *op static inline int hibernate(void) { return -ENOSYS; } static inline bool system_entering_hibernation(void) { return false; } static inline bool hibernation_available(void) { return false; } +static inline bool pm_hibernation_snapshot_done(void) { return false; } static inline int hibernate_quiet_exec(int (*func)(void *data), void *data) { return -ENOTSUPP; diff --git a/kernel/power/hibernate.c b/kernel/power/hibernate.c index 6d3e637c5a02..045d29f55011 100644 --- a/kernel/power/hibernate.c +++ b/kernel/power/hibernate.c @@ -113,6 +113,18 @@ bool hibernation_available(void) !secretmem_active() && !cxl_mem_active(); } +/** + * pm_hibernation_snapshot_done - check if a hibernation snapshot is available + * + * Return: %true if a hibernation snapshot has been taken and has not been + * released yet. + */ +bool pm_hibernation_snapshot_done(void) +{ + return !!in_suspend; +} +EXPORT_SYMBOL_GPL(pm_hibernation_snapshot_done); + /** * hibernation_set_ops - Set the global hibernate operations. * @ops: Hibernation operations to use in subsequent hibernation transitions. -- 2.20.1 ^ permalink raw reply related [flat|nested] 21+ messages in thread
* Re: [PATCH v3 2/3] PM: hibernate: add pm_hibernation_snapshot_done() helper 2026-06-18 1:31 ` [PATCH v3 2/3] PM: hibernate: add pm_hibernation_snapshot_done() helper Haowen Tu @ 2026-07-22 15:40 ` Rafael J. Wysocki (Intel) 0 siblings, 0 replies; 21+ messages in thread From: Rafael J. Wysocki (Intel) @ 2026-07-22 15:40 UTC (permalink / raw) To: Haowen Tu Cc: rafael, gregkh, hansg, kernel, laurent.pinchart, lenb, linux-kernel, linux-media, linux-pm, linux-usb, mchehab, oneukum, pavel, stern On Thu, Jun 18, 2026 at 3:32 AM Haowen Tu <tuhaowen@uniontech.com> wrote: > > Some subsystem resume callbacks do not receive the PM event and > therefore cannot distinguish the PMSG_THAW phase after snapshot creation > from the PMSG_RESTORE phase. > > Export pm_hibernation_snapshot_done() so a driver can query whether the > hibernation snapshot has been created and is still available. The > helper only exposes the PM state; callers remain responsible for > ensuring that any device-specific behavior is safe, including subsequent > poweroff or shutdown handling. > > The helper returns !!in_suspend. This variable is set before > swsusp_arch_suspend(), cleared before the snapshot memory is released, > and marked __nosavedata, so it remains clear on the restore path. > > Signed-off-by: Haowen Tu <tuhaowen@uniontech.com> > --- > Changes in v3: > - Split the in_suspend cleanup into a preceding patch. > - Clarify that callers must account for poweroff/shutdown handling. > - Drop extern from the new prototype. Fine with me now, so Acked-by: Rafael J. Wysocki (Intel) <rafael@kernel.org> and please feel free to route it along with the media patch. > Changes in v2: > - Rename pm_hibernation_storing_image() to > pm_hibernation_snapshot_done(). > > include/linux/suspend.h | 2 ++ > kernel/power/hibernate.c | 12 ++++++++++++ > 2 files changed, 14 insertions(+) > > diff --git a/include/linux/suspend.h b/include/linux/suspend.h > index b02876f1ae38..2cebbec3e2f7 100644 > --- a/include/linux/suspend.h > +++ b/include/linux/suspend.h > @@ -393,6 +393,7 @@ extern void hibernation_set_ops(const struct platform_hibernation_ops *ops); > extern int hibernate(void); > extern bool system_entering_hibernation(void); > extern bool hibernation_available(void); > +bool pm_hibernation_snapshot_done(void); > asmlinkage int swsusp_save(void); > extern struct pbe *restore_pblist; > int pfn_is_nosave(unsigned long pfn); > @@ -412,6 +413,7 @@ static inline void hibernation_set_ops(const struct platform_hibernation_ops *op > static inline int hibernate(void) { return -ENOSYS; } > static inline bool system_entering_hibernation(void) { return false; } > static inline bool hibernation_available(void) { return false; } > +static inline bool pm_hibernation_snapshot_done(void) { return false; } > > static inline int hibernate_quiet_exec(int (*func)(void *data), void *data) { > return -ENOTSUPP; > diff --git a/kernel/power/hibernate.c b/kernel/power/hibernate.c > index 6d3e637c5a02..045d29f55011 100644 > --- a/kernel/power/hibernate.c > +++ b/kernel/power/hibernate.c > @@ -113,6 +113,18 @@ bool hibernation_available(void) > !secretmem_active() && !cxl_mem_active(); > } > > +/** > + * pm_hibernation_snapshot_done - check if a hibernation snapshot is available > + * > + * Return: %true if a hibernation snapshot has been taken and has not been > + * released yet. > + */ > +bool pm_hibernation_snapshot_done(void) > +{ > + return !!in_suspend; > +} > +EXPORT_SYMBOL_GPL(pm_hibernation_snapshot_done); > + > /** > * hibernation_set_ops - Set the global hibernate operations. > * @ops: Hibernation operations to use in subsequent hibernation transitions. > -- > 2.20.1 > ^ permalink raw reply [flat|nested] 21+ messages in thread
* [PATCH v3 3/3] media: uvcvideo: skip streaming restart after hibernation snapshot 2026-06-18 1:31 ` [PATCH v3 0/3] PM: hibernate: skip UVC streaming restart after snapshot Haowen Tu 2026-06-18 1:31 ` [PATCH v3 1/3] PM: hibernate: clear in_suspend before freeing the snapshot Haowen Tu 2026-06-18 1:31 ` [PATCH v3 2/3] PM: hibernate: add pm_hibernation_snapshot_done() helper Haowen Tu @ 2026-06-18 1:31 ` Haowen Tu 2026-07-22 20:06 ` Laurent Pinchart 2 siblings, 1 reply; 21+ messages in thread From: Haowen Tu @ 2026-06-18 1:31 UTC (permalink / raw) To: rafael Cc: tuhaowen, gregkh, hansg, kernel, laurent.pinchart, lenb, linux-kernel, linux-media, linux-pm, linux-usb, mchehab, oneukum, pavel, stern After the hibernation snapshot is created, devices are resumed with PMSG_THAW before the image is written and the system is powered off. Restarting an active UVC stream during this phase reinitializes the camera and visibly turns its indicator LED back on. Skip only the UVC streaming hardware restart while the snapshot is available. The driver's frozen state and clock are still updated before the check, and a subsequent UVC suspend can stop the stream and select alternate setting 0 as usual. uvcvideo does not provide a shutdown callback that requires the streaming hardware to be restarted first. This is a device-specific use of pm_hibernation_snapshot_done(). The helper does not cause other drivers or USB core to skip THAW resume. Tested with hibernation image written to local storage and resumed from disk on a system with a USB UVC camera attached; the camera LED remains off during image writing and the video stream resumes correctly after restore. Signed-off-by: Haowen Tu <tuhaowen@uniontech.com> --- Changes in v3: - Clarify that only the UVC streaming hardware restart is skipped. - Explain the subsequent UVC suspend and shutdown handling. Changes in v2: - Use pm_hibernation_snapshot_done() after the PM helper was renamed. - Move the check after clearing the frozen state and resetting the clock. drivers/media/usb/uvc/uvc_video.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/drivers/media/usb/uvc/uvc_video.c b/drivers/media/usb/uvc/uvc_video.c index f6c8e3223796..1744298f4b1f 100644 --- a/drivers/media/usb/uvc/uvc_video.c +++ b/drivers/media/usb/uvc/uvc_video.c @@ -12,6 +12,7 @@ #include <linux/list.h> #include <linux/module.h> #include <linux/slab.h> +#include <linux/suspend.h> #include <linux/usb.h> #include <linux/usb/hcd.h> #include <linux/videodev2.h> @@ -2151,6 +2152,13 @@ int uvc_video_resume(struct uvc_streaming *stream, int reset) if (!uvc_queue_streaming(&stream->queue)) return 0; + /* + * Avoid restarting the streaming hardware during the transient THAW + * phase after a hibernation snapshot has been created. + */ + if (pm_hibernation_snapshot_done()) + return 0; + ret = uvc_commit_video(stream, &stream->ctrl); if (ret < 0) return ret; -- 2.20.1 ^ permalink raw reply related [flat|nested] 21+ messages in thread
* Re: [PATCH v3 3/3] media: uvcvideo: skip streaming restart after hibernation snapshot 2026-06-18 1:31 ` [PATCH v3 3/3] media: uvcvideo: skip streaming restart after hibernation snapshot Haowen Tu @ 2026-07-22 20:06 ` Laurent Pinchart 0 siblings, 0 replies; 21+ messages in thread From: Laurent Pinchart @ 2026-07-22 20:06 UTC (permalink / raw) To: Haowen Tu Cc: rafael, gregkh, hansg, kernel, lenb, linux-kernel, linux-media, linux-pm, linux-usb, mchehab, oneukum, pavel, stern On Thu, Jun 18, 2026 at 09:31:33AM +0800, Haowen Tu wrote: > After the hibernation snapshot is created, devices are resumed with > PMSG_THAW before the image is written and the system is powered off. > Restarting an active UVC stream during this phase reinitializes the > camera and visibly turns its indicator LED back on. > > Skip only the UVC streaming hardware restart while the snapshot is > available. The driver's frozen state and clock are still updated before > the check, and a subsequent UVC suspend can stop the stream and select > alternate setting 0 as usual. Why is that desired (both the decision to only block the resume of the video interface, and the decision to not block the next suspend) ? > uvcvideo does not provide a shutdown > callback that requires the streaming hardware to be restarted first. > > This is a device-specific use of pm_hibernation_snapshot_done(). The > helper does not cause other drivers or USB core to skip THAW resume. I don't think this sentence belongs to the commit message. > Tested with hibernation image written to local storage and resumed from > disk on a system with a USB UVC camera attached; the camera LED remains > off during image writing and the video stream resumes correctly after > restore. > > Signed-off-by: Haowen Tu <tuhaowen@uniontech.com> > --- > Changes in v3: > - Clarify that only the UVC streaming hardware restart is skipped. > - Explain the subsequent UVC suspend and shutdown handling. > > Changes in v2: > - Use pm_hibernation_snapshot_done() after the PM helper was renamed. > - Move the check after clearing the frozen state and resetting the clock. > > drivers/media/usb/uvc/uvc_video.c | 8 ++++++++ > 1 file changed, 8 insertions(+) > > diff --git a/drivers/media/usb/uvc/uvc_video.c b/drivers/media/usb/uvc/uvc_video.c > index f6c8e3223796..1744298f4b1f 100644 > --- a/drivers/media/usb/uvc/uvc_video.c > +++ b/drivers/media/usb/uvc/uvc_video.c > @@ -12,6 +12,7 @@ > #include <linux/list.h> > #include <linux/module.h> > #include <linux/slab.h> > +#include <linux/suspend.h> > #include <linux/usb.h> > #include <linux/usb/hcd.h> > #include <linux/videodev2.h> > @@ -2151,6 +2152,13 @@ int uvc_video_resume(struct uvc_streaming *stream, int reset) > if (!uvc_queue_streaming(&stream->queue)) > return 0; > > + /* > + * Avoid restarting the streaming hardware during the transient THAW > + * phase after a hibernation snapshot has been created. > + */ > + if (pm_hibernation_snapshot_done()) > + return 0; > + > ret = uvc_commit_video(stream, &stream->ctrl); > if (ret < 0) > return ret; -- Regards, Laurent Pinchart ^ permalink raw reply [flat|nested] 21+ messages in thread
* [PATCH v2 2/2] media: uvcvideo: skip resume after hibernation snapshot 2026-05-28 8:18 ` [PATCH v2 0/2] PM: hibernate: skip UVC resume after snapshot Haowen Tu 2026-05-28 8:18 ` [PATCH v2 1/2] PM: hibernate: add pm_hibernation_snapshot_done() helper Haowen Tu @ 2026-05-28 8:18 ` Haowen Tu 1 sibling, 0 replies; 21+ messages in thread From: Haowen Tu @ 2026-05-28 8:18 UTC (permalink / raw) To: rafael Cc: lenb, pavel, linux-pm, laurent.pinchart, hansg, mchehab, linux-media, gregkh, stern, oneukum, linux-usb, linux-kernel, kernel, Haowen Tu When a UVC camera is in active use and the system enters S4 hibernation, the camera is suspended as part of the normal device freeze sequence. However, after create_image() saves the memory snapshot, the kernel briefly resumes all devices with PMSG_THAW to write the hibernation image to storage. This causes uvc_video_resume() to run and reinitialize the camera hardware, which visibly turns on the camera indicator LED during this intermediate phase even though the system is about to power off. The UVC device is not needed during the image-write window, where the system only needs devices required for writing the hibernation image. USB .resume callbacks do not receive pm_message_t, unlike .suspend, so use the PM-layer helper to detect this phase. This is intentionally handled in uvcvideo rather than in USB core. USB core cannot skip all interface resume callbacks during hibernation THAW, because some USB interfaces may be part of the image writeout path or otherwise be required by dependencies. uvcvideo has a concrete user-visible side effect from reinitializing hardware in this transient phase, and it is not involved in image writeout. The check is placed after stream->frozen is cleared and the clock is reset, so that driver state remains consistent if the image write fails and the system resumes normally instead of powering off. In that case userspace will need to restart the stream, but the driver will not be left with stale frozen state. Tested with hibernation image written to local storage and resumed from disk on a system with a USB UVC camera attached; the camera LED remains off during image writing and the video stream resumes correctly after restore. Signed-off-by: Haowen Tu <tuhaowen@uniontech.com> --- Changes in v2: - Use pm_hibernation_snapshot_done() after the PM helper was renamed. drivers/media/usb/uvc/uvc_video.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/drivers/media/usb/uvc/uvc_video.c b/drivers/media/usb/uvc/uvc_video.c index f6c8e3223796..9fa649fd47e0 100644 --- a/drivers/media/usb/uvc/uvc_video.c +++ b/drivers/media/usb/uvc/uvc_video.c @@ -12,6 +12,7 @@ #include <linux/list.h> #include <linux/module.h> #include <linux/slab.h> +#include <linux/suspend.h> #include <linux/usb.h> #include <linux/usb/hcd.h> #include <linux/videodev2.h> @@ -2151,6 +2152,17 @@ int uvc_video_resume(struct uvc_streaming *stream, int reset) if (!uvc_queue_streaming(&stream->queue)) return 0; + /* + * During hibernation image writing (PMSG_THAW), the kernel briefly + * resumes devices after the snapshot has been created. Skip hardware + * reinitialization to avoid USB traffic and the spurious camera LED + * activation. stream->frozen has already been cleared, so if the + * image write fails and the system resumes normally, driver state + * remains consistent; userspace will need to restart the stream. + */ + if (pm_hibernation_snapshot_done()) + return 0; + ret = uvc_commit_video(stream, &stream->ctrl); if (ret < 0) return ret; -- 2.20.1 ^ permalink raw reply related [flat|nested] 21+ messages in thread
end of thread, other threads:[~2026-07-22 20:06 UTC | newest] Thread overview: 21+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2026-04-28 8:05 [PATCH 0/2] PM: hibernate: add helper to detect image-write phase Haowen Tu 2026-04-28 8:05 ` [PATCH 1/2] PM: hibernate: add pm_hibernation_storing_image() helper Haowen Tu 2026-05-26 13:43 ` Rafael J. Wysocki 2026-04-28 8:05 ` [PATCH 2/2] media: uvcvideo: skip resume when writing hibernation image Haowen Tu 2026-04-28 8:36 ` Oliver Neukum 2026-04-28 8:58 ` Haowen Tu 2026-04-28 9:13 ` Laurent Pinchart 2026-04-29 1:15 ` Haowen Tu 2026-04-29 1:16 ` Haowen Tu 2026-05-28 8:18 ` [PATCH v2 0/2] PM: hibernate: skip UVC resume after snapshot Haowen Tu 2026-05-28 8:18 ` [PATCH v2 1/2] PM: hibernate: add pm_hibernation_snapshot_done() helper Haowen Tu 2026-06-01 18:22 ` Rafael J. Wysocki 2026-06-02 3:24 ` Haowen Tu 2026-06-18 1:31 ` [PATCH v3 0/3] PM: hibernate: skip UVC streaming restart after snapshot Haowen Tu 2026-06-18 1:31 ` [PATCH v3 1/3] PM: hibernate: clear in_suspend before freeing the snapshot Haowen Tu 2026-07-22 15:37 ` Rafael J. Wysocki (Intel) 2026-06-18 1:31 ` [PATCH v3 2/3] PM: hibernate: add pm_hibernation_snapshot_done() helper Haowen Tu 2026-07-22 15:40 ` Rafael J. Wysocki (Intel) 2026-06-18 1:31 ` [PATCH v3 3/3] media: uvcvideo: skip streaming restart after hibernation snapshot Haowen Tu 2026-07-22 20:06 ` Laurent Pinchart 2026-05-28 8:18 ` [PATCH v2 2/2] media: uvcvideo: skip resume " Haowen Tu
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox