* [PATCH v5 0/5] reduce system memory requirement for hibernation
@ 2025-07-09 10:05 Samuel Zhang
2025-07-09 10:05 ` [PATCH v5 1/5] drm/ttm: add new api ttm_device_prepare_hibernation() Samuel Zhang
` (4 more replies)
0 siblings, 5 replies; 13+ messages in thread
From: Samuel Zhang @ 2025-07-09 10:05 UTC (permalink / raw)
To: alexander.deucher, christian.koenig, rafael, len.brown, pavel,
gregkh, dakr, airlied, simona, ray.huang, matthew.auld,
matthew.brost, maarten.lankhorst, mripard, tzimmermann
Cc: mario.limonciello, lijo.lazar, victor.zhao, haijun.chang, Qing.Ma,
Owen.Zhang2, linux-pm, linux-kernel, amd-gfx, dri-devel,
Samuel Zhang
Modern data center dGPUs are usually equipped with very large VRAM. On
server with such dGPUs(192GB VRAM * 8) and 2TB system memory, hibernate
will fail due to no enough free memory.
The root cause is that during hibernation all VRAM memory get evicted to
GTT or shmem. In both case, it is in system memory and kernel will try to
copy the pages to hibernation image. In the worst case, this causes 2
copies of VRAM memory in system memory, 2TB is not enough for the
hibernation image. 192GB * 8 * 2 = 3TB > 2TB.
The fix includes following changes. With these changes, there's much less
pages needed to be copied to hibernate image and hibernation can succeed.
* patch 1 and 2: move GTT to shmem after evicting VRAM. so that the GTT
pages can be freed.
* patch 3: force write shmem pages to swap disk and free shmem pages.
After swapout GTT to shmem in hibernation prepare stage, the GPU will be
resumed again in thaw stage. The swapin and restore BOs of resume takes
lots of time (50 mintues observed for 8 dGPUs). And it's unnecessary since
writing hibernation image do not need GPU for hibernate successful case.
* patch 4 and 5: skip resume of device in thaw stage for successful
hibernation case to reduce the hibernation time.
v2:
* split first patch to 2 patches, 1 for ttm, 1 for amdgpu
* refined the new ttm api
* add more comments for shrink_shmem_memory() and its callsite
* export variable pm_transition in kernel
* skip resume in thaw() for successful hibernation case
v3:
* refined ttm_device_prepare_hibernation() to accept device argument
* use guard(mutex) to replace mutex_lock and mutex_unlock
* move ttm_device_prepare_hibernation call to amdgpu_device_evict_resources()
* add pm_transition_event(), instead of exporting pm_transition variable
* refined amdgpu_pmops_thaw(), use switch-case for more clarity
v4:
* remove guard(mutex) and fix kdoc for ttm_device_prepare_hibernation
* refined kdoc for pm_transition_event() and PM_EVENT_ messages
* use dev_err in amdgpu_pmops_thaw()
* add Reviewed-by and Acked-by for patch 2 3 and 5
v5:
* add Reviewed-by for patch 1
* use pm_hibernate_is_recovering() to replace pm_transition_event()
* check in_suspend in amdgpu_pmops_prepare() and amdgpu_pmops_poweroff()
The merge options are either:
* the linux-pm changes go to linux-pm and an immutable branch for drm to
merge
* everything goes through amd-staging-drm-next (and an amdgpu PR to drm
later)
* everything goes through drm-misc-next
Mario Limonciello think everything through drm-misc-next makes most sense
if everyone is amenable.
Samuel Zhang (5):
1. drm/ttm: add new api ttm_device_prepare_hibernation()
2. drm/amdgpu: move GTT to shmem after eviction for hibernation
3. PM: hibernate: shrink shmem pages after dev_pm_ops.prepare()
4. PM: hibernate: add new api pm_hibernate_is_recovering()
5. drm/amdgpu: do not resume device in thaw for normal hibernation
drivers/base/power/main.c | 14 ++++++++++++
drivers/gpu/drm/amd/amdgpu/amdgpu_device.c | 10 ++++++++-
drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c | 7 ++++++
drivers/gpu/drm/ttm/ttm_device.c | 23 +++++++++++++++++++
include/drm/ttm/ttm_device.h | 1 +
include/linux/pm.h | 2 ++
kernel/power/hibernate.c | 26 ++++++++++++++++++++++
7 files changed, 82 insertions(+), 1 deletion(-)
--
2.43.5
^ permalink raw reply [flat|nested] 13+ messages in thread
* [PATCH v5 1/5] drm/ttm: add new api ttm_device_prepare_hibernation()
2025-07-09 10:05 [PATCH v5 0/5] reduce system memory requirement for hibernation Samuel Zhang
@ 2025-07-09 10:05 ` Samuel Zhang
2025-07-09 16:41 ` Mario Limonciello
2025-07-09 10:05 ` [PATCH v5 2/5] drm/amdgpu: move GTT to shmem after eviction for hibernation Samuel Zhang
` (3 subsequent siblings)
4 siblings, 1 reply; 13+ messages in thread
From: Samuel Zhang @ 2025-07-09 10:05 UTC (permalink / raw)
To: alexander.deucher, christian.koenig, rafael, len.brown, pavel,
gregkh, dakr, airlied, simona, ray.huang, matthew.auld,
matthew.brost, maarten.lankhorst, mripard, tzimmermann
Cc: mario.limonciello, lijo.lazar, victor.zhao, haijun.chang, Qing.Ma,
Owen.Zhang2, linux-pm, linux-kernel, amd-gfx, dri-devel,
Samuel Zhang
This new api is used for hibernation to move GTT BOs to shmem after
VRAM eviction. shmem will be flushed to swap disk later to reduce
the system memory usage for hibernation.
Signed-off-by: Samuel Zhang <guoqing.zhang@amd.com>
Reviewed-by: Christian König <christian.koenig@amd.com>
---
drivers/gpu/drm/ttm/ttm_device.c | 23 +++++++++++++++++++++++
include/drm/ttm/ttm_device.h | 1 +
2 files changed, 24 insertions(+)
diff --git a/drivers/gpu/drm/ttm/ttm_device.c b/drivers/gpu/drm/ttm/ttm_device.c
index 02e797fd1891..9c9ab1903919 100644
--- a/drivers/gpu/drm/ttm/ttm_device.c
+++ b/drivers/gpu/drm/ttm/ttm_device.c
@@ -123,6 +123,29 @@ static int ttm_global_init(void)
return ret;
}
+/**
+ * ttm_device_prepare_hibernation - move GTT BOs to shmem for hibernation.
+ *
+ * @bdev: A pointer to a struct ttm_device to prepare hibernation for.
+ *
+ * Return: 0 on success, negative number on failure.
+ */
+int ttm_device_prepare_hibernation(struct ttm_device *bdev)
+{
+ struct ttm_operation_ctx ctx = {
+ .interruptible = false,
+ .no_wait_gpu = false,
+ .force_alloc = true
+ };
+ int ret;
+
+ do {
+ ret = ttm_device_swapout(bdev, &ctx, GFP_KERNEL);
+ } while (ret > 0);
+ return ret;
+}
+EXPORT_SYMBOL(ttm_device_prepare_hibernation);
+
/*
* A buffer object shrink method that tries to swap out the first
* buffer object on the global::swap_lru list.
diff --git a/include/drm/ttm/ttm_device.h b/include/drm/ttm/ttm_device.h
index 39b8636b1845..592b5f802859 100644
--- a/include/drm/ttm/ttm_device.h
+++ b/include/drm/ttm/ttm_device.h
@@ -272,6 +272,7 @@ struct ttm_device {
int ttm_global_swapout(struct ttm_operation_ctx *ctx, gfp_t gfp_flags);
int ttm_device_swapout(struct ttm_device *bdev, struct ttm_operation_ctx *ctx,
gfp_t gfp_flags);
+int ttm_device_prepare_hibernation(struct ttm_device *bdev);
static inline struct ttm_resource_manager *
ttm_manager_type(struct ttm_device *bdev, int mem_type)
--
2.43.5
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [PATCH v5 2/5] drm/amdgpu: move GTT to shmem after eviction for hibernation
2025-07-09 10:05 [PATCH v5 0/5] reduce system memory requirement for hibernation Samuel Zhang
2025-07-09 10:05 ` [PATCH v5 1/5] drm/ttm: add new api ttm_device_prepare_hibernation() Samuel Zhang
@ 2025-07-09 10:05 ` Samuel Zhang
2025-07-09 10:05 ` [PATCH v5 3/5] PM: hibernate: shrink shmem pages after dev_pm_ops.prepare() Samuel Zhang
` (2 subsequent siblings)
4 siblings, 0 replies; 13+ messages in thread
From: Samuel Zhang @ 2025-07-09 10:05 UTC (permalink / raw)
To: alexander.deucher, christian.koenig, rafael, len.brown, pavel,
gregkh, dakr, airlied, simona, ray.huang, matthew.auld,
matthew.brost, maarten.lankhorst, mripard, tzimmermann
Cc: mario.limonciello, lijo.lazar, victor.zhao, haijun.chang, Qing.Ma,
Owen.Zhang2, linux-pm, linux-kernel, amd-gfx, dri-devel,
Samuel Zhang
When hibernate with data center dGPUs, huge number of VRAM BOs evicted
to GTT and takes too much system memory. This will cause hibernation
fail due to insufficient memory for creating the hibernation image.
Move GTT BOs to shmem in KMD, then shmem to swap disk in kernel
hibernation code to make room for hibernation image.
Signed-off-by: Samuel Zhang <guoqing.zhang@amd.com>
Reviewed-by: Christian König <christian.koenig@amd.com>
---
drivers/gpu/drm/amd/amdgpu/amdgpu_device.c | 10 +++++++++-
1 file changed, 9 insertions(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
index 684d66bc0b5f..2f977fece08f 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
@@ -5021,8 +5021,16 @@ static int amdgpu_device_evict_resources(struct amdgpu_device *adev)
return 0;
ret = amdgpu_ttm_evict_resources(adev, TTM_PL_VRAM);
- if (ret)
+ if (ret) {
dev_warn(adev->dev, "evicting device resources failed\n");
+ return ret;
+ }
+
+ if (adev->in_s4) {
+ ret = ttm_device_prepare_hibernation(&adev->mman.bdev);
+ if (ret)
+ dev_err(adev->dev, "prepare hibernation failed, %d\n", ret);
+ }
return ret;
}
--
2.43.5
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [PATCH v5 3/5] PM: hibernate: shrink shmem pages after dev_pm_ops.prepare()
2025-07-09 10:05 [PATCH v5 0/5] reduce system memory requirement for hibernation Samuel Zhang
2025-07-09 10:05 ` [PATCH v5 1/5] drm/ttm: add new api ttm_device_prepare_hibernation() Samuel Zhang
2025-07-09 10:05 ` [PATCH v5 2/5] drm/amdgpu: move GTT to shmem after eviction for hibernation Samuel Zhang
@ 2025-07-09 10:05 ` Samuel Zhang
2025-07-09 16:08 ` Mario Limonciello
2025-07-09 10:05 ` [PATCH v5 4/5] PM: hibernate: add new api pm_hibernate_is_recovering() Samuel Zhang
2025-07-09 10:05 ` [PATCH v5 5/5] drm/amdgpu: do not resume device in thaw for normal hibernation Samuel Zhang
4 siblings, 1 reply; 13+ messages in thread
From: Samuel Zhang @ 2025-07-09 10:05 UTC (permalink / raw)
To: alexander.deucher, christian.koenig, rafael, len.brown, pavel,
gregkh, dakr, airlied, simona, ray.huang, matthew.auld,
matthew.brost, maarten.lankhorst, mripard, tzimmermann
Cc: mario.limonciello, lijo.lazar, victor.zhao, haijun.chang, Qing.Ma,
Owen.Zhang2, linux-pm, linux-kernel, amd-gfx, dri-devel,
Samuel Zhang
When hibernate with data center dGPUs, huge number of VRAM data will be
moved to shmem during dev_pm_ops.prepare(). These shmem pages take a lot
of system memory so that there's no enough free memory for creating the
hibernation image. This will cause hibernation fail and abort.
After dev_pm_ops.prepare(), call shrink_all_memory() to force move shmem
pages to swap disk and reclaim the pages, so that there's enough system
memory for hibernation image and less pages needed to copy to the image.
This patch can only flush and free about half shmem pages. It will be
better to flush and free more pages, even all of shmem pages, so that
there're less pages to be copied to the hibernation image and the overall
hibernation time can be reduced.
Signed-off-by: Samuel Zhang <guoqing.zhang@amd.com>
Acked-by: Rafael J. Wysocki <rafael@kernel.org>
---
kernel/power/hibernate.c | 26 ++++++++++++++++++++++++++
1 file changed, 26 insertions(+)
diff --git a/kernel/power/hibernate.c b/kernel/power/hibernate.c
index 10a01af63a80..7ae9d9a7aa1d 100644
--- a/kernel/power/hibernate.c
+++ b/kernel/power/hibernate.c
@@ -370,6 +370,23 @@ static int create_image(int platform_mode)
return error;
}
+static void shrink_shmem_memory(void)
+{
+ struct sysinfo info;
+ unsigned long nr_shmem_pages, nr_freed_pages;
+
+ si_meminfo(&info);
+ nr_shmem_pages = info.sharedram; /* current page count used for shmem */
+ /*
+ * The intent is to reclaim all shmem pages. Though shrink_all_memory() can
+ * only reclaim about half of them, it's enough for creating the hibernation
+ * image.
+ */
+ nr_freed_pages = shrink_all_memory(nr_shmem_pages);
+ pr_debug("requested to reclaim %lu shmem pages, actually freed %lu pages\n",
+ nr_shmem_pages, nr_freed_pages);
+}
+
/**
* hibernation_snapshot - Quiesce devices and create a hibernation image.
* @platform_mode: If set, use platform driver to prepare for the transition.
@@ -411,6 +428,15 @@ int hibernation_snapshot(int platform_mode)
goto Thaw;
}
+ /*
+ * Device drivers may move lots of data to shmem in dpm_prepare(). The shmem
+ * pages will use lots of system memory, causing hibernation image creation
+ * fail due to insufficient free memory.
+ * This call is to force flush the shmem pages to swap disk and reclaim
+ * the system memory so that image creation can succeed.
+ */
+ shrink_shmem_memory();
+
suspend_console();
pm_restrict_gfp_mask();
--
2.43.5
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [PATCH v5 4/5] PM: hibernate: add new api pm_hibernate_is_recovering()
2025-07-09 10:05 [PATCH v5 0/5] reduce system memory requirement for hibernation Samuel Zhang
` (2 preceding siblings ...)
2025-07-09 10:05 ` [PATCH v5 3/5] PM: hibernate: shrink shmem pages after dev_pm_ops.prepare() Samuel Zhang
@ 2025-07-09 10:05 ` Samuel Zhang
2025-07-09 10:14 ` Rafael J. Wysocki
2025-07-09 16:11 ` Mario Limonciello
2025-07-09 10:05 ` [PATCH v5 5/5] drm/amdgpu: do not resume device in thaw for normal hibernation Samuel Zhang
4 siblings, 2 replies; 13+ messages in thread
From: Samuel Zhang @ 2025-07-09 10:05 UTC (permalink / raw)
To: alexander.deucher, christian.koenig, rafael, len.brown, pavel,
gregkh, dakr, airlied, simona, ray.huang, matthew.auld,
matthew.brost, maarten.lankhorst, mripard, tzimmermann
Cc: mario.limonciello, lijo.lazar, victor.zhao, haijun.chang, Qing.Ma,
Owen.Zhang2, linux-pm, linux-kernel, amd-gfx, dri-devel,
Samuel Zhang
dev_pm_ops.thaw() is called in following cases:
* normal case: after hibernation image has been created.
* error case 1: creation of a hibernation image has failed.
* error case 2: restoration from a hibernation image has failed.
For normal case, it is called mainly for resume storage devices for
saving the hibernation image. Other devices that are not involved
in the image saving do not need to resume the device. But since there's
no api to know which case thaw() is called, device drivers can't
conditionally resume device in thaw().
The new pm_hibernate_is_recovering() is such a api to query if thaw() is
called in normal case.
Signed-off-by: Samuel Zhang <guoqing.zhang@amd.com>
---
drivers/base/power/main.c | 14 ++++++++++++++
include/linux/pm.h | 2 ++
2 files changed, 16 insertions(+)
diff --git a/drivers/base/power/main.c b/drivers/base/power/main.c
index 40e1d8d8a589..ff78cf96f795 100644
--- a/drivers/base/power/main.c
+++ b/drivers/base/power/main.c
@@ -63,6 +63,20 @@ static LIST_HEAD(dpm_noirq_list);
static DEFINE_MUTEX(dpm_list_mtx);
static pm_message_t pm_transition;
+/**
+ * pm_hibernate_is_recovering - if recovering from hibernate due to error.
+ *
+ * Used to query if dev_pm_ops.thaw() is called for normal hibernation case or
+ * recovering from some error.
+ *
+ * Return: true for error case, false for normal case.
+ */
+bool pm_hibernate_is_recovering(void)
+{
+ return pm_transition.event == PM_EVENT_RECOVER;
+}
+EXPORT_SYMBOL_GPL(pm_hibernate_is_recovering);
+
static int async_error;
static const char *pm_verb(int event)
diff --git a/include/linux/pm.h b/include/linux/pm.h
index 78855d794342..f54a803f2afb 100644
--- a/include/linux/pm.h
+++ b/include/linux/pm.h
@@ -657,6 +657,8 @@ struct pm_subsys_data {
#define DPM_FLAG_SMART_SUSPEND BIT(2)
#define DPM_FLAG_MAY_SKIP_RESUME BIT(3)
+bool pm_hibernate_is_recovering(void);
+
struct dev_pm_info {
pm_message_t power_state;
bool can_wakeup:1;
--
2.43.5
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [PATCH v5 5/5] drm/amdgpu: do not resume device in thaw for normal hibernation
2025-07-09 10:05 [PATCH v5 0/5] reduce system memory requirement for hibernation Samuel Zhang
` (3 preceding siblings ...)
2025-07-09 10:05 ` [PATCH v5 4/5] PM: hibernate: add new api pm_hibernate_is_recovering() Samuel Zhang
@ 2025-07-09 10:05 ` Samuel Zhang
2025-07-09 19:50 ` Mario Limonciello
4 siblings, 1 reply; 13+ messages in thread
From: Samuel Zhang @ 2025-07-09 10:05 UTC (permalink / raw)
To: alexander.deucher, christian.koenig, rafael, len.brown, pavel,
gregkh, dakr, airlied, simona, ray.huang, matthew.auld,
matthew.brost, maarten.lankhorst, mripard, tzimmermann
Cc: mario.limonciello, lijo.lazar, victor.zhao, haijun.chang, Qing.Ma,
Owen.Zhang2, linux-pm, linux-kernel, amd-gfx, dri-devel,
Samuel Zhang
For normal hibernation, GPU do not need to be resumed in thaw since it is
not involved in writing the hibernation image. Skip resume in this case
can reduce the hibernation time.
On VM with 8 * 192GB VRAM dGPUs, 98% VRAM usage and 1.7TB system memory,
this can save 50 minutes.
Signed-off-by: Samuel Zhang <guoqing.zhang@amd.com>
---
drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c | 17 +++++++++++++++++
1 file changed, 17 insertions(+)
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
index 4f8632737574..b24c420983ef 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
@@ -2541,6 +2541,10 @@ amdgpu_pci_shutdown(struct pci_dev *pdev)
if (amdgpu_ras_intr_triggered())
return;
+ /* device maybe not resumed here, return immediately in this case */
+ if (adev->in_s4 && adev->in_suspend)
+ return;
+
/* if we are running in a VM, make sure the device
* torn down properly on reboot/shutdown.
* unfortunately we can't detect certain
@@ -2557,6 +2561,10 @@ static int amdgpu_pmops_prepare(struct device *dev)
struct drm_device *drm_dev = dev_get_drvdata(dev);
struct amdgpu_device *adev = drm_to_adev(drm_dev);
+ /* device maybe not resumed here, return immediately in this case */
+ if (adev->in_s4 && adev->in_suspend)
+ return 0;
+
/* Return a positive number here so
* DPM_FLAG_SMART_SUSPEND works properly
*/
@@ -2655,12 +2663,21 @@ static int amdgpu_pmops_thaw(struct device *dev)
{
struct drm_device *drm_dev = dev_get_drvdata(dev);
+ /* do not resume device if it's normal hibernation */
+ if (!pm_hibernate_is_recovering())
+ return 0;
+
return amdgpu_device_resume(drm_dev, true);
}
static int amdgpu_pmops_poweroff(struct device *dev)
{
struct drm_device *drm_dev = dev_get_drvdata(dev);
+ struct amdgpu_device *adev = drm_to_adev(drm_dev);
+
+ /* device maybe not resumed here, return immediately in this case */
+ if (adev->in_s4 && adev->in_suspend)
+ return 0;
return amdgpu_device_suspend(drm_dev, true);
}
--
2.43.5
^ permalink raw reply related [flat|nested] 13+ messages in thread
* Re: [PATCH v5 4/5] PM: hibernate: add new api pm_hibernate_is_recovering()
2025-07-09 10:05 ` [PATCH v5 4/5] PM: hibernate: add new api pm_hibernate_is_recovering() Samuel Zhang
@ 2025-07-09 10:14 ` Rafael J. Wysocki
2025-07-09 16:11 ` Mario Limonciello
1 sibling, 0 replies; 13+ messages in thread
From: Rafael J. Wysocki @ 2025-07-09 10:14 UTC (permalink / raw)
To: Samuel Zhang
Cc: alexander.deucher, christian.koenig, rafael, len.brown, pavel,
gregkh, dakr, airlied, simona, ray.huang, matthew.auld,
matthew.brost, maarten.lankhorst, mripard, tzimmermann,
mario.limonciello, lijo.lazar, victor.zhao, haijun.chang, Qing.Ma,
Owen.Zhang2, linux-pm, linux-kernel, amd-gfx, dri-devel
On Wed, Jul 9, 2025 at 12:05 PM Samuel Zhang <guoqing.zhang@amd.com> wrote:
>
> dev_pm_ops.thaw() is called in following cases:
> * normal case: after hibernation image has been created.
> * error case 1: creation of a hibernation image has failed.
> * error case 2: restoration from a hibernation image has failed.
>
> For normal case, it is called mainly for resume storage devices for
> saving the hibernation image. Other devices that are not involved
> in the image saving do not need to resume the device. But since there's
> no api to know which case thaw() is called, device drivers can't
> conditionally resume device in thaw().
>
> The new pm_hibernate_is_recovering() is such a api to query if thaw() is
> called in normal case.
>
> Signed-off-by: Samuel Zhang <guoqing.zhang@amd.com>
> ---
> drivers/base/power/main.c | 14 ++++++++++++++
> include/linux/pm.h | 2 ++
> 2 files changed, 16 insertions(+)
>
> diff --git a/drivers/base/power/main.c b/drivers/base/power/main.c
> index 40e1d8d8a589..ff78cf96f795 100644
> --- a/drivers/base/power/main.c
> +++ b/drivers/base/power/main.c
> @@ -63,6 +63,20 @@ static LIST_HEAD(dpm_noirq_list);
> static DEFINE_MUTEX(dpm_list_mtx);
> static pm_message_t pm_transition;
>
> +/**
> + * pm_hibernate_is_recovering - if recovering from hibernate due to error.
> + *
> + * Used to query if dev_pm_ops.thaw() is called for normal hibernation case or
> + * recovering from some error.
> + *
> + * Return: true for error case, false for normal case.
> + */
> +bool pm_hibernate_is_recovering(void)
> +{
> + return pm_transition.event == PM_EVENT_RECOVER;
> +}
> +EXPORT_SYMBOL_GPL(pm_hibernate_is_recovering);
> +
> static int async_error;
>
> static const char *pm_verb(int event)
> diff --git a/include/linux/pm.h b/include/linux/pm.h
> index 78855d794342..f54a803f2afb 100644
> --- a/include/linux/pm.h
> +++ b/include/linux/pm.h
> @@ -657,6 +657,8 @@ struct pm_subsys_data {
> #define DPM_FLAG_SMART_SUSPEND BIT(2)
> #define DPM_FLAG_MAY_SKIP_RESUME BIT(3)
>
> +bool pm_hibernate_is_recovering(void);
> +
Please add this to suspend.h instead (preferably after the
is_hibernate_resume_dev definition).
> struct dev_pm_info {
> pm_message_t power_state;
> bool can_wakeup:1;
> --
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH v5 3/5] PM: hibernate: shrink shmem pages after dev_pm_ops.prepare()
2025-07-09 10:05 ` [PATCH v5 3/5] PM: hibernate: shrink shmem pages after dev_pm_ops.prepare() Samuel Zhang
@ 2025-07-09 16:08 ` Mario Limonciello
0 siblings, 0 replies; 13+ messages in thread
From: Mario Limonciello @ 2025-07-09 16:08 UTC (permalink / raw)
To: Samuel Zhang, alexander.deucher, christian.koenig, rafael,
len.brown, pavel, gregkh, dakr, airlied, simona, ray.huang,
matthew.auld, matthew.brost, maarten.lankhorst, mripard,
tzimmermann
Cc: lijo.lazar, victor.zhao, haijun.chang, Qing.Ma, Owen.Zhang2,
linux-pm, linux-kernel, amd-gfx, dri-devel
On 7/9/2025 6:05 AM, Samuel Zhang wrote:
> When hibernate with data center dGPUs, huge number of VRAM data will be
> moved to shmem during dev_pm_ops.prepare(). These shmem pages take a lot
> of system memory so that there's no enough free memory for creating the
> hibernation image. This will cause hibernation fail and abort.
>
> After dev_pm_ops.prepare(), call shrink_all_memory() to force move shmem
> pages to swap disk and reclaim the pages, so that there's enough system
> memory for hibernation image and less pages needed to copy to the image.
>
> This patch can only flush and free about half shmem pages. It will be
> better to flush and free more pages, even all of shmem pages, so that
> there're less pages to be copied to the hibernation image and the overall
> hibernation time can be reduced.
>
> Signed-off-by: Samuel Zhang <guoqing.zhang@amd.com>
> Acked-by: Rafael J. Wysocki <rafael@kernel.org>
What is your base for this patch? I wanted to get it tested but I tried
on top of the latest 6.16-rc as well as linux-next but couldn't apply it
on either.
I suspect you're missing both 12ffc3b1513ebc1f11ae77d053948504a94a68a6
and e9cec4487cb789645a8c84b13a9ce54c2d89e3bb in your base.
Could you please rebase on something newer?
> ---
> kernel/power/hibernate.c | 26 ++++++++++++++++++++++++++
> 1 file changed, 26 insertions(+)
>
> diff --git a/kernel/power/hibernate.c b/kernel/power/hibernate.c
> index 10a01af63a80..7ae9d9a7aa1d 100644
> --- a/kernel/power/hibernate.c
> +++ b/kernel/power/hibernate.c
> @@ -370,6 +370,23 @@ static int create_image(int platform_mode)
> return error;
> }
>
> +static void shrink_shmem_memory(void)
> +{
> + struct sysinfo info;
> + unsigned long nr_shmem_pages, nr_freed_pages;
> +
> + si_meminfo(&info);
> + nr_shmem_pages = info.sharedram; /* current page count used for shmem */
> + /*
> + * The intent is to reclaim all shmem pages. Though shrink_all_memory() can
> + * only reclaim about half of them, it's enough for creating the hibernation
> + * image.
> + */
> + nr_freed_pages = shrink_all_memory(nr_shmem_pages);
> + pr_debug("requested to reclaim %lu shmem pages, actually freed %lu pages\n",
> + nr_shmem_pages, nr_freed_pages);
> +}
> +
> /**
> * hibernation_snapshot - Quiesce devices and create a hibernation image.
> * @platform_mode: If set, use platform driver to prepare for the transition.
> @@ -411,6 +428,15 @@ int hibernation_snapshot(int platform_mode)
> goto Thaw;
> }
>
> + /*
> + * Device drivers may move lots of data to shmem in dpm_prepare(). The shmem
> + * pages will use lots of system memory, causing hibernation image creation
> + * fail due to insufficient free memory.
> + * This call is to force flush the shmem pages to swap disk and reclaim
> + * the system memory so that image creation can succeed.
> + */
> + shrink_shmem_memory();
> +
> suspend_console();
> pm_restrict_gfp_mask();
>
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH v5 4/5] PM: hibernate: add new api pm_hibernate_is_recovering()
2025-07-09 10:05 ` [PATCH v5 4/5] PM: hibernate: add new api pm_hibernate_is_recovering() Samuel Zhang
2025-07-09 10:14 ` Rafael J. Wysocki
@ 2025-07-09 16:11 ` Mario Limonciello
1 sibling, 0 replies; 13+ messages in thread
From: Mario Limonciello @ 2025-07-09 16:11 UTC (permalink / raw)
To: Samuel Zhang, alexander.deucher, christian.koenig, rafael,
len.brown, pavel, gregkh, dakr, airlied, simona, ray.huang,
matthew.auld, matthew.brost, maarten.lankhorst, mripard,
tzimmermann
Cc: lijo.lazar, victor.zhao, haijun.chang, Qing.Ma, Owen.Zhang2,
linux-pm, linux-kernel, amd-gfx, dri-devel
On 7/9/2025 6:05 AM, Samuel Zhang wrote:
> dev_pm_ops.thaw() is called in following cases:
> * normal case: after hibernation image has been created.
> * error case 1: creation of a hibernation image has failed.
> * error case 2: restoration from a hibernation image has failed.
>
> For normal case, it is called mainly for resume storage devices for
> saving the hibernation image. Other devices that are not involved
> in the image saving do not need to resume the device. But since there's
> no api to know which case thaw() is called, device drivers can't
> conditionally resume device in thaw().
>
> The new pm_hibernate_is_recovering() is such a api to query if thaw() is
> called in normal case.
>
> Signed-off-by: Samuel Zhang <guoqing.zhang@amd.com>
This patch also doesn't apply to linux-next. Please rebase it.
Applying: PM: hibernate: add new api pm_hibernate_is_recovering()
error: patch failed: drivers/base/power/main.c:63
error: drivers/base/power/main.c: patch does not apply
Patch failed at 0004 PM: hibernate: add new api pm_hibernate_is_recovering()
hint: Use 'git am --show-current-patch=diff' to see the failed patch
> ---
> drivers/base/power/main.c | 14 ++++++++++++++
> include/linux/pm.h | 2 ++
> 2 files changed, 16 insertions(+)
>
> diff --git a/drivers/base/power/main.c b/drivers/base/power/main.c
> index 40e1d8d8a589..ff78cf96f795 100644
> --- a/drivers/base/power/main.c
> +++ b/drivers/base/power/main.c
> @@ -63,6 +63,20 @@ static LIST_HEAD(dpm_noirq_list);
> static DEFINE_MUTEX(dpm_list_mtx);
> static pm_message_t pm_transition;
>
> +/**
> + * pm_hibernate_is_recovering - if recovering from hibernate due to error.
> + *
> + * Used to query if dev_pm_ops.thaw() is called for normal hibernation case or
> + * recovering from some error.
> + *
> + * Return: true for error case, false for normal case.
> + */
> +bool pm_hibernate_is_recovering(void)
> +{
> + return pm_transition.event == PM_EVENT_RECOVER;
> +}
> +EXPORT_SYMBOL_GPL(pm_hibernate_is_recovering);
> +
> static int async_error;
>
> static const char *pm_verb(int event)
> diff --git a/include/linux/pm.h b/include/linux/pm.h
> index 78855d794342..f54a803f2afb 100644
> --- a/include/linux/pm.h
> +++ b/include/linux/pm.h
> @@ -657,6 +657,8 @@ struct pm_subsys_data {
> #define DPM_FLAG_SMART_SUSPEND BIT(2)
> #define DPM_FLAG_MAY_SKIP_RESUME BIT(3)
>
> +bool pm_hibernate_is_recovering(void);
> +
> struct dev_pm_info {
> pm_message_t power_state;
> bool can_wakeup:1;
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH v5 1/5] drm/ttm: add new api ttm_device_prepare_hibernation()
2025-07-09 10:05 ` [PATCH v5 1/5] drm/ttm: add new api ttm_device_prepare_hibernation() Samuel Zhang
@ 2025-07-09 16:41 ` Mario Limonciello
0 siblings, 0 replies; 13+ messages in thread
From: Mario Limonciello @ 2025-07-09 16:41 UTC (permalink / raw)
To: Samuel Zhang, alexander.deucher, christian.koenig, rafael,
len.brown, pavel, gregkh, dakr, airlied, simona, ray.huang,
matthew.auld, matthew.brost, maarten.lankhorst, mripard,
tzimmermann
Cc: lijo.lazar, victor.zhao, haijun.chang, Qing.Ma, Owen.Zhang2,
linux-pm, linux-kernel, amd-gfx, dri-devel
On 7/9/2025 6:05 AM, Samuel Zhang wrote:
> This new api is used for hibernation to move GTT BOs to shmem after
> VRAM eviction. shmem will be flushed to swap disk later to reduce
> the system memory usage for hibernation.
>
> Signed-off-by: Samuel Zhang <guoqing.zhang@amd.com>
> Reviewed-by: Christian König <christian.koenig@amd.com>
> ---
> drivers/gpu/drm/ttm/ttm_device.c | 23 +++++++++++++++++++++++
> include/drm/ttm/ttm_device.h | 1 +
> 2 files changed, 24 insertions(+)
>
> diff --git a/drivers/gpu/drm/ttm/ttm_device.c b/drivers/gpu/drm/ttm/ttm_device.c
> index 02e797fd1891..9c9ab1903919 100644
> --- a/drivers/gpu/drm/ttm/ttm_device.c
> +++ b/drivers/gpu/drm/ttm/ttm_device.c
> @@ -123,6 +123,29 @@ static int ttm_global_init(void)
> return ret;
> }
>
> +/**
> + * ttm_device_prepare_hibernation - move GTT BOs to shmem for hibernation.
> + *
> + * @bdev: A pointer to a struct ttm_device to prepare hibernation for.
> + *
> + * Return: 0 on success, negative number on failure.
> + */
> +int ttm_device_prepare_hibernation(struct ttm_device *bdev)
> +{
> + struct ttm_operation_ctx ctx = {
> + .interruptible = false,
> + .no_wait_gpu = false,
> + .force_alloc = true
On linux-next (next-20250709):
drivers/gpu/drm/ttm/ttm_device.c: In function
‘ttm_device_prepare_hibernation’:
drivers/gpu/drm/ttm/ttm_device.c:140:18: error: ‘struct
ttm_operation_ctx’ has no member named ‘force_alloc’
140 | .force_alloc = true
| ^~~~~~~~~~~
> + };
> + int ret;
> +
> + do {
> + ret = ttm_device_swapout(bdev, &ctx, GFP_KERNEL);
> + } while (ret > 0);
> + return ret;
> +}
> +EXPORT_SYMBOL(ttm_device_prepare_hibernation);
> +
> /*
> * A buffer object shrink method that tries to swap out the first
> * buffer object on the global::swap_lru list.
> diff --git a/include/drm/ttm/ttm_device.h b/include/drm/ttm/ttm_device.h
> index 39b8636b1845..592b5f802859 100644
> --- a/include/drm/ttm/ttm_device.h
> +++ b/include/drm/ttm/ttm_device.h
> @@ -272,6 +272,7 @@ struct ttm_device {
> int ttm_global_swapout(struct ttm_operation_ctx *ctx, gfp_t gfp_flags);
> int ttm_device_swapout(struct ttm_device *bdev, struct ttm_operation_ctx *ctx,
> gfp_t gfp_flags);
> +int ttm_device_prepare_hibernation(struct ttm_device *bdev);
>
> static inline struct ttm_resource_manager *
> ttm_manager_type(struct ttm_device *bdev, int mem_type)
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH v5 5/5] drm/amdgpu: do not resume device in thaw for normal hibernation
2025-07-09 10:05 ` [PATCH v5 5/5] drm/amdgpu: do not resume device in thaw for normal hibernation Samuel Zhang
@ 2025-07-09 19:50 ` Mario Limonciello
2025-07-10 4:18 ` Lazar, Lijo
0 siblings, 1 reply; 13+ messages in thread
From: Mario Limonciello @ 2025-07-09 19:50 UTC (permalink / raw)
To: Samuel Zhang, alexander.deucher, christian.koenig, rafael,
len.brown, pavel, gregkh, dakr, airlied, simona, ray.huang,
matthew.auld, matthew.brost, maarten.lankhorst, mripard,
tzimmermann
Cc: lijo.lazar, victor.zhao, haijun.chang, Qing.Ma, Owen.Zhang2,
linux-pm, linux-kernel, amd-gfx, dri-devel
On 7/9/2025 6:05 AM, Samuel Zhang wrote:
> For normal hibernation, GPU do not need to be resumed in thaw since it is
> not involved in writing the hibernation image. Skip resume in this case
> can reduce the hibernation time.
>
> On VM with 8 * 192GB VRAM dGPUs, 98% VRAM usage and 1.7TB system memory,
> this can save 50 minutes.
>
> Signed-off-by: Samuel Zhang <guoqing.zhang@amd.com>
I hand modified the patches for other changes missing from linux-next in
your base.
I checked on an APU with an eDP display connected and from a VT
hibernate does keep the display off now so this is definitely an
improvement there too.
Tested-by: Mario Limonciello <mario.limonciello@amd.com>
> ---
> drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c | 17 +++++++++++++++++
> 1 file changed, 17 insertions(+)
>
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
> index 4f8632737574..b24c420983ef 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
> @@ -2541,6 +2541,10 @@ amdgpu_pci_shutdown(struct pci_dev *pdev)
> if (amdgpu_ras_intr_triggered())
> return;
>
> + /* device maybe not resumed here, return immediately in this case */
> + if (adev->in_s4 && adev->in_suspend)
> + return;
> +
> /* if we are running in a VM, make sure the device
> * torn down properly on reboot/shutdown.
> * unfortunately we can't detect certain
> @@ -2557,6 +2561,10 @@ static int amdgpu_pmops_prepare(struct device *dev)
> struct drm_device *drm_dev = dev_get_drvdata(dev);
> struct amdgpu_device *adev = drm_to_adev(drm_dev);
>
> + /* device maybe not resumed here, return immediately in this case */
> + if (adev->in_s4 && adev->in_suspend)
> + return 0;
> +
Is this one right? Don't we still want to call prepare() for all the HW
IP blocks? The eviction call that happens in prepare() is a no-op but
there are other IP blocks with an prepare_suspend() callback like DCN.
That is I think you're destroying the optimization from commit
50e0bae34fa6b ("drm/amd/display: Add and use new dm_prepare_suspend()
callback") by adding this code here.
> /* Return a positive number here so
> * DPM_FLAG_SMART_SUSPEND works properly
> */
> @@ -2655,12 +2663,21 @@ static int amdgpu_pmops_thaw(struct device *dev)
> {
> struct drm_device *drm_dev = dev_get_drvdata(dev);
>
> + /* do not resume device if it's normal hibernation */
> + if (!pm_hibernate_is_recovering())
> + return 0;
> +
> return amdgpu_device_resume(drm_dev, true);
> }
>
> static int amdgpu_pmops_poweroff(struct device *dev)
> {
> struct drm_device *drm_dev = dev_get_drvdata(dev);
> + struct amdgpu_device *adev = drm_to_adev(drm_dev);
> +
> + /* device maybe not resumed here, return immediately in this case */
> + if (adev->in_s4 && adev->in_suspend)
> + return 0;
>
> return amdgpu_device_suspend(drm_dev, true);
> }
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH v5 5/5] drm/amdgpu: do not resume device in thaw for normal hibernation
2025-07-09 19:50 ` Mario Limonciello
@ 2025-07-10 4:18 ` Lazar, Lijo
2025-07-10 6:18 ` Zhang, GuoQing (Sam)
0 siblings, 1 reply; 13+ messages in thread
From: Lazar, Lijo @ 2025-07-10 4:18 UTC (permalink / raw)
To: Mario Limonciello, Samuel Zhang, alexander.deucher,
christian.koenig, rafael, len.brown, pavel, gregkh, dakr, airlied,
simona, ray.huang, matthew.auld, matthew.brost, maarten.lankhorst,
mripard, tzimmermann
Cc: victor.zhao, haijun.chang, Qing.Ma, Owen.Zhang2, linux-pm,
linux-kernel, amd-gfx, dri-devel
On 7/10/2025 1:20 AM, Mario Limonciello wrote:
> On 7/9/2025 6:05 AM, Samuel Zhang wrote:
>> For normal hibernation, GPU do not need to be resumed in thaw since it is
>> not involved in writing the hibernation image. Skip resume in this case
>> can reduce the hibernation time.
>>
>> On VM with 8 * 192GB VRAM dGPUs, 98% VRAM usage and 1.7TB system memory,
>> this can save 50 minutes.
>>
>> Signed-off-by: Samuel Zhang <guoqing.zhang@amd.com>
>
> I hand modified the patches for other changes missing from linux-next in
> your base.
>
> I checked on an APU with an eDP display connected and from a VT
> hibernate does keep the display off now so this is definitely an
> improvement there too.
>
> Tested-by: Mario Limonciello <mario.limonciello@amd.com>
>
>> ---
>> drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c | 17 +++++++++++++++++
>> 1 file changed, 17 insertions(+)
>>
>> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c b/drivers/gpu/
>> drm/amd/amdgpu/amdgpu_drv.c
>> index 4f8632737574..b24c420983ef 100644
>> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
>> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
>> @@ -2541,6 +2541,10 @@ amdgpu_pci_shutdown(struct pci_dev *pdev)
>> if (amdgpu_ras_intr_triggered())
>> return;
>> + /* device maybe not resumed here, return immediately in this
>> case */
>> + if (adev->in_s4 && adev->in_suspend)
>> + return;
>> +
>> /* if we are running in a VM, make sure the device
>> * torn down properly on reboot/shutdown.
>> * unfortunately we can't detect certain
>> @@ -2557,6 +2561,10 @@ static int amdgpu_pmops_prepare(struct device
>> *dev)
>> struct drm_device *drm_dev = dev_get_drvdata(dev);
>> struct amdgpu_device *adev = drm_to_adev(drm_dev);
>> + /* device maybe not resumed here, return immediately in this
>> case */
>> + if (adev->in_s4 && adev->in_suspend)
>> + return 0;
>> +
>
> Is this one right? Don't we still want to call prepare() for all the HW
> IP blocks? The eviction call that happens in prepare() is a no-op but
> there are other IP blocks with an prepare_suspend() callback like DCN.
>
> That is I think you're destroying the optimization from commit
> 50e0bae34fa6b ("drm/amd/display: Add and use new dm_prepare_suspend()
> callback") by adding this code here.
>
I guess this takes care of the prepare() before a power_off(). For the
hibernate prepare() call, in_suspend flag will remain false and it
should get executed. If the device is runtime-suspended already, then
the path won't be taken. Assuming that's fine.
Thanks,
Lijo
>
>> /* Return a positive number here so
>> * DPM_FLAG_SMART_SUSPEND works properly
>> */
>> @@ -2655,12 +2663,21 @@ static int amdgpu_pmops_thaw(struct device *dev)
>> {
>> struct drm_device *drm_dev = dev_get_drvdata(dev);
>> + /* do not resume device if it's normal hibernation */
>> + if (!pm_hibernate_is_recovering())
>> + return 0;
>> +
>> return amdgpu_device_resume(drm_dev, true);
>> }
>> static int amdgpu_pmops_poweroff(struct device *dev)
>> {
>> struct drm_device *drm_dev = dev_get_drvdata(dev);
>> + struct amdgpu_device *adev = drm_to_adev(drm_dev);
>> +
>> + /* device maybe not resumed here, return immediately in this case */
>> + if (adev->in_s4 && adev->in_suspend)
>> + return 0;
>> return amdgpu_device_suspend(drm_dev, true);
>> }
>
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH v5 5/5] drm/amdgpu: do not resume device in thaw for normal hibernation
2025-07-10 4:18 ` Lazar, Lijo
@ 2025-07-10 6:18 ` Zhang, GuoQing (Sam)
0 siblings, 0 replies; 13+ messages in thread
From: Zhang, GuoQing (Sam) @ 2025-07-10 6:18 UTC (permalink / raw)
To: Lazar, Lijo, Mario Limonciello, Samuel Zhang, alexander.deucher,
christian.koenig, rafael, len.brown, pavel, gregkh, dakr, airlied,
simona, ray.huang, matthew.auld, matthew.brost, maarten.lankhorst,
mripard, tzimmermann
Cc: victor.zhao, haijun.chang, Qing.Ma, Owen.Zhang2, linux-pm,
linux-kernel, amd-gfx, dri-devel
On 2025/7/10 12:18, Lazar, Lijo wrote:
>
> On 7/10/2025 1:20 AM, Mario Limonciello wrote:
>> On 7/9/2025 6:05 AM, Samuel Zhang wrote:
>>> For normal hibernation, GPU do not need to be resumed in thaw since it is
>>> not involved in writing the hibernation image. Skip resume in this case
>>> can reduce the hibernation time.
>>>
>>> On VM with 8 * 192GB VRAM dGPUs, 98% VRAM usage and 1.7TB system memory,
>>> this can save 50 minutes.
>>>
>>> Signed-off-by: Samuel Zhang <guoqing.zhang@amd.com>
>> I hand modified the patches for other changes missing from linux-next in
>> your base.
>>
>> I checked on an APU with an eDP display connected and from a VT
>> hibernate does keep the display off now so this is definitely an
>> improvement there too.
>>
>> Tested-by: Mario Limonciello <mario.limonciello@amd.com>
Thank you, Mario!
>>
>>> ---
>>> drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c | 17 +++++++++++++++++
>>> 1 file changed, 17 insertions(+)
>>>
>>> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c b/drivers/gpu/
>>> drm/amd/amdgpu/amdgpu_drv.c
>>> index 4f8632737574..b24c420983ef 100644
>>> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
>>> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
>>> @@ -2541,6 +2541,10 @@ amdgpu_pci_shutdown(struct pci_dev *pdev)
>>> if (amdgpu_ras_intr_triggered())
>>> return;
>>> + /* device maybe not resumed here, return immediately in this
>>> case */
>>> + if (adev->in_s4 && adev->in_suspend)
>>> + return;
>>> +
>>> /* if we are running in a VM, make sure the device
>>> * torn down properly on reboot/shutdown.
>>> * unfortunately we can't detect certain
>>> @@ -2557,6 +2561,10 @@ static int amdgpu_pmops_prepare(struct device
>>> *dev)
>>> struct drm_device *drm_dev = dev_get_drvdata(dev);
>>> struct amdgpu_device *adev = drm_to_adev(drm_dev);
>>> + /* device maybe not resumed here, return immediately in this
>>> case */
>>> + if (adev->in_s4 && adev->in_suspend)
>>> + return 0;
>>> +
>> Is this one right? Don't we still want to call prepare() for all the HW
>> IP blocks? The eviction call that happens in prepare() is a no-op but
>> there are other IP blocks with an prepare_suspend() callback like DCN.
>>
>> That is I think you're destroying the optimization from commit
>> 50e0bae34fa6b ("drm/amd/display: Add and use new dm_prepare_suspend()
>> callback") by adding this code here.
>>
> I guess this takes care of the prepare() before a power_off(). For the
> hibernate prepare() call, in_suspend flag will remain false and it
> should get executed. If the device is runtime-suspended already, then
> the path won't be taken. Assuming that's fine.
>
> Thanks,
> Lijo
That's right. Thank you for the clarification, Lijo.
Rafael reminded me yesterday that there are 2 hibernation mode, controlled by `/sys/power/disk`.
The 2 mode will call different callbacks after saving the image:
shutdown mode, hibernate will go through following steps:
1. amdgpu_pmops_prepare
2. amdgpu_pmops_freeze
3. create image
4. amdgpu_pmops_thaw
5. amdgpu_pmops_complete
6. save image
7. amdgpu_pci_shutdown
platform mode, hibernate will go through following steps:
1. amdgpu_pmops_prepare
2. amdgpu_pmops_freeze
3. create image
4. amdgpu_pmops_thaw
5. amdgpu_pmops_complete
6. save image
7. amdgpu_pmops_prepare
8. amdgpu_pmops_poweroff
This code is just to skip the step 7 of platform mode hibernation,
prepare to power off.
adev->in_suspend is false in step 2, so it will not return in new the check.
adev->in_suspend is true in step 7, it will return in new the check.
Regards
Sam
>
>>> /* Return a positive number here so
>>> * DPM_FLAG_SMART_SUSPEND works properly
>>> */
>>> @@ -2655,12 +2663,21 @@ static int amdgpu_pmops_thaw(struct device *dev)
>>> {
>>> struct drm_device *drm_dev = dev_get_drvdata(dev);
>>> + /* do not resume device if it's normal hibernation */
>>> + if (!pm_hibernate_is_recovering())
>>> + return 0;
>>> +
>>> return amdgpu_device_resume(drm_dev, true);
>>> }
>>> static int amdgpu_pmops_poweroff(struct device *dev)
>>> {
>>> struct drm_device *drm_dev = dev_get_drvdata(dev);
>>> + struct amdgpu_device *adev = drm_to_adev(drm_dev);
>>> +
>>> + /* device maybe not resumed here, return immediately in this case */
>>> + if (adev->in_s4 && adev->in_suspend)
>>> + return 0;
>>> return amdgpu_device_suspend(drm_dev, true);
>>> }
^ permalink raw reply [flat|nested] 13+ messages in thread
end of thread, other threads:[~2025-07-10 6:18 UTC | newest]
Thread overview: 13+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-07-09 10:05 [PATCH v5 0/5] reduce system memory requirement for hibernation Samuel Zhang
2025-07-09 10:05 ` [PATCH v5 1/5] drm/ttm: add new api ttm_device_prepare_hibernation() Samuel Zhang
2025-07-09 16:41 ` Mario Limonciello
2025-07-09 10:05 ` [PATCH v5 2/5] drm/amdgpu: move GTT to shmem after eviction for hibernation Samuel Zhang
2025-07-09 10:05 ` [PATCH v5 3/5] PM: hibernate: shrink shmem pages after dev_pm_ops.prepare() Samuel Zhang
2025-07-09 16:08 ` Mario Limonciello
2025-07-09 10:05 ` [PATCH v5 4/5] PM: hibernate: add new api pm_hibernate_is_recovering() Samuel Zhang
2025-07-09 10:14 ` Rafael J. Wysocki
2025-07-09 16:11 ` Mario Limonciello
2025-07-09 10:05 ` [PATCH v5 5/5] drm/amdgpu: do not resume device in thaw for normal hibernation Samuel Zhang
2025-07-09 19:50 ` Mario Limonciello
2025-07-10 4:18 ` Lazar, Lijo
2025-07-10 6:18 ` Zhang, GuoQing (Sam)
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).