public inbox for linux-pm@vger.kernel.org
 help / color / mirror / Atom feed
* [PATCH v2 0/2] PM: hibernate: Drain trailing zero pages on userspace restore
@ 2026-03-09 17:39 Alberto Garcia
  2026-03-09 17:39 ` [PATCH v2 1/2] " Alberto Garcia
  2026-03-09 17:39 ` [PATCH v2 2/2] PM: hibernate: return -ENODATA if the snapshot image is not loaded Alberto Garcia
  0 siblings, 2 replies; 7+ messages in thread
From: Alberto Garcia @ 2026-03-09 17:39 UTC (permalink / raw)
  To: Rafael J . Wysocki
  Cc: Len Brown, Pavel Machek, Brian Geffon, linux-pm, Alberto Garcia

Hi,

Here's v2 of the patch.

Changes from v1:

- The extra snapshot_write_next() call happens now at the beginning of
  snapshot_write_finalize(), but only when handle->cur is in the data
  page region.

- We return -ENODATA if snapshot_write_next() returns > 0 (indicating
  that the kernel was expecting another page).

- A second patch changes the userspace restore code to return -ENODATA
  when snapshot_image_loaded() fails.

Regards,

Berto

Alberto Garcia (2):
  PM: hibernate: Drain trailing zero pages on userspace restore
  PM: hibernate: return -ENODATA if the snapshot image is not loaded

 kernel/power/snapshot.c | 11 +++++++++++
 kernel/power/user.c     |  7 +++++--
 2 files changed, 16 insertions(+), 2 deletions(-)

-- 
2.47.3


^ permalink raw reply	[flat|nested] 7+ messages in thread

* [PATCH v2 1/2] PM: hibernate: Drain trailing zero pages on userspace restore
  2026-03-09 17:39 [PATCH v2 0/2] PM: hibernate: Drain trailing zero pages on userspace restore Alberto Garcia
@ 2026-03-09 17:39 ` Alberto Garcia
  2026-03-09 17:44   ` Brian Geffon
  2026-03-09 17:39 ` [PATCH v2 2/2] PM: hibernate: return -ENODATA if the snapshot image is not loaded Alberto Garcia
  1 sibling, 1 reply; 7+ messages in thread
From: Alberto Garcia @ 2026-03-09 17:39 UTC (permalink / raw)
  To: Rafael J . Wysocki
  Cc: Len Brown, Pavel Machek, Brian Geffon, linux-pm, Alberto Garcia

Commit 005e8dddd497 ("PM: hibernate: don't store zero pages in the
image file") added an optimization to skip zero-filled pages in the
hibernation image. On restore, zero pages are handled internally by
snapshot_write_next() in a loop that processes them without returning
to the caller.

With the userspace restore interface, writing the last non-zero page
to /dev/snapshot is followed by the SNAPSHOT_ATOMIC_RESTORE ioctl. At
this point there are no more calls to snapshot_write_next() so any
trailing zero pages are not processed, snapshot_image_loaded() fails
because handle->cur is smaller than expected, the ioctl returns -EPERM
and the image is not restored.

The in-kernel restore path is not affected by this because the loop in
load_image() in swap.c calls snapshot_write_next() until it returns 0.
It is this final call that drains any trailing zero pages.

Fixed by calling snapshot_write_next() in snapshot_write_finalize(),
giving the kernel the chance to drain any trailing zero pages.

Fixes: 005e8dddd497 ("PM: hibernate: don't store zero pages in the image file")
Signed-off-by: Alberto Garcia <berto@igalia.com>
---
 kernel/power/snapshot.c | 11 +++++++++++
 1 file changed, 11 insertions(+)

diff --git a/kernel/power/snapshot.c b/kernel/power/snapshot.c
index 6e1321837c66..a564650734dc 100644
--- a/kernel/power/snapshot.c
+++ b/kernel/power/snapshot.c
@@ -2855,6 +2855,17 @@ int snapshot_write_finalize(struct snapshot_handle *handle)
 {
 	int error;
 
+	/*
+	 * Call snapshot_write_next() to drain any trailing zero pages,
+	 * but make sure we're in the data page region first.
+	 * This function can return PAGE_SIZE if the kernel was expecting
+	 * another copy page. Return -ENODATA in that situation.
+	 */
+	if (handle->cur > nr_meta_pages + 1) {
+		error = snapshot_write_next(handle);
+		if (error)
+			return error > 0 ? -ENODATA : error;
+	}
 	copy_last_highmem_page();
 	error = hibernate_restore_protect_page(handle->buffer);
 	/* Do that only if we have loaded the image entirely */
-- 
2.47.3


^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [PATCH v2 2/2] PM: hibernate: return -ENODATA if the snapshot image is not loaded
  2026-03-09 17:39 [PATCH v2 0/2] PM: hibernate: Drain trailing zero pages on userspace restore Alberto Garcia
  2026-03-09 17:39 ` [PATCH v2 1/2] " Alberto Garcia
@ 2026-03-09 17:39 ` Alberto Garcia
  2026-03-09 17:45   ` Brian Geffon
  1 sibling, 1 reply; 7+ messages in thread
From: Alberto Garcia @ 2026-03-09 17:39 UTC (permalink / raw)
  To: Rafael J . Wysocki
  Cc: Len Brown, Pavel Machek, Brian Geffon, linux-pm, Alberto Garcia

snapshot_image_loaded() is used in both the in-kernel and the
userspace restore path to ensure that the snapshot image has been
completely loaded. However the latter path returns -EPERM in such
situations, which is meant for cases where the operation is neither
write-only nor ready.

This patch updates the check so the returned error code is -ENODATA in
both cases.

Suggested-by: Brian Geffon <bgeffon@google.com>
Signed-off-by: Alberto Garcia <berto@igalia.com>
---
 kernel/power/user.c | 7 +++++--
 1 file changed, 5 insertions(+), 2 deletions(-)

diff --git a/kernel/power/user.c b/kernel/power/user.c
index 4401cfe26e5c..be77f3556bd7 100644
--- a/kernel/power/user.c
+++ b/kernel/power/user.c
@@ -322,11 +322,14 @@ static long snapshot_ioctl(struct file *filp, unsigned int cmd,
 		error = snapshot_write_finalize(&data->handle);
 		if (error)
 			break;
-		if (data->mode != O_WRONLY || !data->frozen ||
-		    !snapshot_image_loaded(&data->handle)) {
+		if (data->mode != O_WRONLY || !data->frozen) {
 			error = -EPERM;
 			break;
 		}
+		if (!snapshot_image_loaded(&data->handle)) {
+			error = -ENODATA;
+			break;
+		}
 		error = hibernation_restore(data->platform_support);
 		break;
 
-- 
2.47.3


^ permalink raw reply related	[flat|nested] 7+ messages in thread

* Re: [PATCH v2 1/2] PM: hibernate: Drain trailing zero pages on userspace restore
  2026-03-09 17:39 ` [PATCH v2 1/2] " Alberto Garcia
@ 2026-03-09 17:44   ` Brian Geffon
  2026-03-20 18:54     ` Rafael J. Wysocki
  0 siblings, 1 reply; 7+ messages in thread
From: Brian Geffon @ 2026-03-09 17:44 UTC (permalink / raw)
  To: Alberto Garcia; +Cc: Rafael J . Wysocki, Len Brown, Pavel Machek, linux-pm

On Mon, Mar 9, 2026 at 1:40 PM Alberto Garcia <berto@igalia.com> wrote:
>
> Commit 005e8dddd497 ("PM: hibernate: don't store zero pages in the
> image file") added an optimization to skip zero-filled pages in the
> hibernation image. On restore, zero pages are handled internally by
> snapshot_write_next() in a loop that processes them without returning
> to the caller.
>
> With the userspace restore interface, writing the last non-zero page
> to /dev/snapshot is followed by the SNAPSHOT_ATOMIC_RESTORE ioctl. At
> this point there are no more calls to snapshot_write_next() so any
> trailing zero pages are not processed, snapshot_image_loaded() fails
> because handle->cur is smaller than expected, the ioctl returns -EPERM
> and the image is not restored.
>
> The in-kernel restore path is not affected by this because the loop in
> load_image() in swap.c calls snapshot_write_next() until it returns 0.
> It is this final call that drains any trailing zero pages.
>
> Fixed by calling snapshot_write_next() in snapshot_write_finalize(),
> giving the kernel the chance to drain any trailing zero pages.
>
> Fixes: 005e8dddd497 ("PM: hibernate: don't store zero pages in the image file")
> Signed-off-by: Alberto Garcia <berto@igalia.com>

Acked-by: Brian Geffon <bgeffon@google.com>

> ---
>  kernel/power/snapshot.c | 11 +++++++++++
>  1 file changed, 11 insertions(+)
>
> diff --git a/kernel/power/snapshot.c b/kernel/power/snapshot.c
> index 6e1321837c66..a564650734dc 100644
> --- a/kernel/power/snapshot.c
> +++ b/kernel/power/snapshot.c
> @@ -2855,6 +2855,17 @@ int snapshot_write_finalize(struct snapshot_handle *handle)
>  {
>         int error;
>
> +       /*
> +        * Call snapshot_write_next() to drain any trailing zero pages,
> +        * but make sure we're in the data page region first.
> +        * This function can return PAGE_SIZE if the kernel was expecting
> +        * another copy page. Return -ENODATA in that situation.
> +        */
> +       if (handle->cur > nr_meta_pages + 1) {
> +               error = snapshot_write_next(handle);
> +               if (error)
> +                       return error > 0 ? -ENODATA : error;
> +       }
>         copy_last_highmem_page();
>         error = hibernate_restore_protect_page(handle->buffer);
>         /* Do that only if we have loaded the image entirely */
> --
> 2.47.3
>

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH v2 2/2] PM: hibernate: return -ENODATA if the snapshot image is not loaded
  2026-03-09 17:39 ` [PATCH v2 2/2] PM: hibernate: return -ENODATA if the snapshot image is not loaded Alberto Garcia
@ 2026-03-09 17:45   ` Brian Geffon
  2026-03-20 19:00     ` Rafael J. Wysocki
  0 siblings, 1 reply; 7+ messages in thread
From: Brian Geffon @ 2026-03-09 17:45 UTC (permalink / raw)
  To: Alberto Garcia; +Cc: Rafael J . Wysocki, Len Brown, Pavel Machek, linux-pm

On Mon, Mar 9, 2026 at 1:40 PM Alberto Garcia <berto@igalia.com> wrote:
>
> snapshot_image_loaded() is used in both the in-kernel and the
> userspace restore path to ensure that the snapshot image has been
> completely loaded. However the latter path returns -EPERM in such
> situations, which is meant for cases where the operation is neither
> write-only nor ready.
>
> This patch updates the check so the returned error code is -ENODATA in
> both cases.
>
> Suggested-by: Brian Geffon <bgeffon@google.com>
> Signed-off-by: Alberto Garcia <berto@igalia.com>

Acked-by: Brian Geffon <bgeffon@google.com>

> ---
>  kernel/power/user.c | 7 +++++--
>  1 file changed, 5 insertions(+), 2 deletions(-)
>
> diff --git a/kernel/power/user.c b/kernel/power/user.c
> index 4401cfe26e5c..be77f3556bd7 100644
> --- a/kernel/power/user.c
> +++ b/kernel/power/user.c
> @@ -322,11 +322,14 @@ static long snapshot_ioctl(struct file *filp, unsigned int cmd,
>                 error = snapshot_write_finalize(&data->handle);
>                 if (error)
>                         break;
> -               if (data->mode != O_WRONLY || !data->frozen ||
> -                   !snapshot_image_loaded(&data->handle)) {
> +               if (data->mode != O_WRONLY || !data->frozen) {
>                         error = -EPERM;
>                         break;
>                 }
> +               if (!snapshot_image_loaded(&data->handle)) {
> +                       error = -ENODATA;
> +                       break;
> +               }
>                 error = hibernation_restore(data->platform_support);
>                 break;
>
> --
> 2.47.3
>

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH v2 1/2] PM: hibernate: Drain trailing zero pages on userspace restore
  2026-03-09 17:44   ` Brian Geffon
@ 2026-03-20 18:54     ` Rafael J. Wysocki
  0 siblings, 0 replies; 7+ messages in thread
From: Rafael J. Wysocki @ 2026-03-20 18:54 UTC (permalink / raw)
  To: Brian Geffon, Alberto Garcia; +Cc: Pavel Machek, linux-pm

On Mon, Mar 9, 2026 at 6:45 PM Brian Geffon <bgeffon@google.com> wrote:
>
> On Mon, Mar 9, 2026 at 1:40 PM Alberto Garcia <berto@igalia.com> wrote:
> >
> > Commit 005e8dddd497 ("PM: hibernate: don't store zero pages in the
> > image file") added an optimization to skip zero-filled pages in the
> > hibernation image. On restore, zero pages are handled internally by
> > snapshot_write_next() in a loop that processes them without returning
> > to the caller.
> >
> > With the userspace restore interface, writing the last non-zero page
> > to /dev/snapshot is followed by the SNAPSHOT_ATOMIC_RESTORE ioctl. At
> > this point there are no more calls to snapshot_write_next() so any
> > trailing zero pages are not processed, snapshot_image_loaded() fails
> > because handle->cur is smaller than expected, the ioctl returns -EPERM
> > and the image is not restored.
> >
> > The in-kernel restore path is not affected by this because the loop in
> > load_image() in swap.c calls snapshot_write_next() until it returns 0.
> > It is this final call that drains any trailing zero pages.
> >
> > Fixed by calling snapshot_write_next() in snapshot_write_finalize(),
> > giving the kernel the chance to drain any trailing zero pages.
> >
> > Fixes: 005e8dddd497 ("PM: hibernate: don't store zero pages in the image file")
> > Signed-off-by: Alberto Garcia <berto@igalia.com>
>
> Acked-by: Brian Geffon <bgeffon@google.com>

Applied as 7.0-rc material, thanks!

> > ---
> >  kernel/power/snapshot.c | 11 +++++++++++
> >  1 file changed, 11 insertions(+)
> >
> > diff --git a/kernel/power/snapshot.c b/kernel/power/snapshot.c
> > index 6e1321837c66..a564650734dc 100644
> > --- a/kernel/power/snapshot.c
> > +++ b/kernel/power/snapshot.c
> > @@ -2855,6 +2855,17 @@ int snapshot_write_finalize(struct snapshot_handle *handle)
> >  {
> >         int error;
> >
> > +       /*
> > +        * Call snapshot_write_next() to drain any trailing zero pages,
> > +        * but make sure we're in the data page region first.
> > +        * This function can return PAGE_SIZE if the kernel was expecting
> > +        * another copy page. Return -ENODATA in that situation.
> > +        */
> > +       if (handle->cur > nr_meta_pages + 1) {
> > +               error = snapshot_write_next(handle);
> > +               if (error)
> > +                       return error > 0 ? -ENODATA : error;
> > +       }
> >         copy_last_highmem_page();
> >         error = hibernate_restore_protect_page(handle->buffer);
> >         /* Do that only if we have loaded the image entirely */
> > --
> > 2.47.3
> >

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH v2 2/2] PM: hibernate: return -ENODATA if the snapshot image is not loaded
  2026-03-09 17:45   ` Brian Geffon
@ 2026-03-20 19:00     ` Rafael J. Wysocki
  0 siblings, 0 replies; 7+ messages in thread
From: Rafael J. Wysocki @ 2026-03-20 19:00 UTC (permalink / raw)
  To: Brian Geffon, Alberto Garcia; +Cc: Pavel Machek, linux-pm

On Mon, Mar 9, 2026 at 6:45 PM Brian Geffon <bgeffon@google.com> wrote:
>
> On Mon, Mar 9, 2026 at 1:40 PM Alberto Garcia <berto@igalia.com> wrote:
> >
> > snapshot_image_loaded() is used in both the in-kernel and the
> > userspace restore path to ensure that the snapshot image has been
> > completely loaded. However the latter path returns -EPERM in such
> > situations, which is meant for cases where the operation is neither
> > write-only nor ready.
> >
> > This patch updates the check so the returned error code is -ENODATA in
> > both cases.
> >
> > Suggested-by: Brian Geffon <bgeffon@google.com>
> > Signed-off-by: Alberto Garcia <berto@igalia.com>
>
> Acked-by: Brian Geffon <bgeffon@google.com>

Applied as 7.1 material, thanks!

> > ---
> >  kernel/power/user.c | 7 +++++--
> >  1 file changed, 5 insertions(+), 2 deletions(-)
> >
> > diff --git a/kernel/power/user.c b/kernel/power/user.c
> > index 4401cfe26e5c..be77f3556bd7 100644
> > --- a/kernel/power/user.c
> > +++ b/kernel/power/user.c
> > @@ -322,11 +322,14 @@ static long snapshot_ioctl(struct file *filp, unsigned int cmd,
> >                 error = snapshot_write_finalize(&data->handle);
> >                 if (error)
> >                         break;
> > -               if (data->mode != O_WRONLY || !data->frozen ||
> > -                   !snapshot_image_loaded(&data->handle)) {
> > +               if (data->mode != O_WRONLY || !data->frozen) {
> >                         error = -EPERM;
> >                         break;
> >                 }
> > +               if (!snapshot_image_loaded(&data->handle)) {
> > +                       error = -ENODATA;
> > +                       break;
> > +               }
> >                 error = hibernation_restore(data->platform_support);
> >                 break;
> >
> > --
> > 2.47.3
> >

^ permalink raw reply	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2026-03-20 19:00 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-03-09 17:39 [PATCH v2 0/2] PM: hibernate: Drain trailing zero pages on userspace restore Alberto Garcia
2026-03-09 17:39 ` [PATCH v2 1/2] " Alberto Garcia
2026-03-09 17:44   ` Brian Geffon
2026-03-20 18:54     ` Rafael J. Wysocki
2026-03-09 17:39 ` [PATCH v2 2/2] PM: hibernate: return -ENODATA if the snapshot image is not loaded Alberto Garcia
2026-03-09 17:45   ` Brian Geffon
2026-03-20 19:00     ` Rafael J. Wysocki

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox