]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/blob - queue-6.6/drm-amd-evict-resources-during-pm-ops-prepare-callba.patch
2e22e361c4935b09fa13d135f0df78a80a899709
[thirdparty/kernel/stable-queue.git] / queue-6.6 / drm-amd-evict-resources-during-pm-ops-prepare-callba.patch
1 From fb3b984cfc3edbbb2c040c67a93f7a5b04775ad2 Mon Sep 17 00:00:00 2001
2 From: Sasha Levin <sashal@kernel.org>
3 Date: Fri, 6 Oct 2023 13:50:20 -0500
4 Subject: drm/amd: Evict resources during PM ops prepare() callback
5 MIME-Version: 1.0
6 Content-Type: text/plain; charset=UTF-8
7 Content-Transfer-Encoding: 8bit
8
9 From: Mario Limonciello <mario.limonciello@amd.com>
10
11 [ Upstream commit 5095d5418193eb2748c7d8553c7150b8f1c44696 ]
12
13 Linux PM core has a prepare() callback run before suspend.
14
15 If the system is under high memory pressure, the resources may need
16 to be evicted into swap instead. If the storage backing for swap
17 is offlined during the suspend() step then such a call may fail.
18
19 So move this step into prepare() to move evict majority of
20 resources and update all non-pmops callers to call the same callback.
21
22 Link: https://gitlab.freedesktop.org/drm/amd/-/issues/2362
23 Reviewed-by: Christian König <christian.koenig@amd.com>
24 Reviewed-by: Alex Deucher <alexander.deucher@amd.com>
25 Signed-off-by: Mario Limonciello <mario.limonciello@amd.com>
26 Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
27 Stable-dep-of: ca299b4512d4 ("drm/amd: Flush GFXOFF requests in prepare stage")
28 Signed-off-by: Sasha Levin <sashal@kernel.org>
29 ---
30 drivers/gpu/drm/amd/amdgpu/amdgpu.h | 1 +
31 drivers/gpu/drm/amd/amdgpu/amdgpu_device.c | 31 ++++++++++++++++++----
32 drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c | 10 ++++---
33 3 files changed, 34 insertions(+), 8 deletions(-)
34
35 diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h b/drivers/gpu/drm/amd/amdgpu/amdgpu.h
36 index 85efd686e538d..d59e8536192ca 100644
37 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h
38 +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h
39 @@ -1369,6 +1369,7 @@ void amdgpu_driver_postclose_kms(struct drm_device *dev,
40 void amdgpu_driver_release_kms(struct drm_device *dev);
41
42 int amdgpu_device_ip_suspend(struct amdgpu_device *adev);
43 +int amdgpu_device_prepare(struct drm_device *dev);
44 int amdgpu_device_suspend(struct drm_device *dev, bool fbcon);
45 int amdgpu_device_resume(struct drm_device *dev, bool fbcon);
46 u32 amdgpu_get_vblank_counter_kms(struct drm_crtc *crtc);
47 diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
48 index 79261bec26542..707c17641c757 100644
49 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
50 +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
51 @@ -1549,6 +1549,7 @@ static void amdgpu_switcheroo_set_state(struct pci_dev *pdev,
52 } else {
53 pr_info("switched off\n");
54 dev->switch_power_state = DRM_SWITCH_POWER_CHANGING;
55 + amdgpu_device_prepare(dev);
56 amdgpu_device_suspend(dev, true);
57 amdgpu_device_cache_pci_state(pdev);
58 /* Shut down the device */
59 @@ -4094,6 +4095,31 @@ static int amdgpu_device_evict_resources(struct amdgpu_device *adev)
60 /*
61 * Suspend & resume.
62 */
63 +/**
64 + * amdgpu_device_prepare - prepare for device suspend
65 + *
66 + * @dev: drm dev pointer
67 + *
68 + * Prepare to put the hw in the suspend state (all asics).
69 + * Returns 0 for success or an error on failure.
70 + * Called at driver suspend.
71 + */
72 +int amdgpu_device_prepare(struct drm_device *dev)
73 +{
74 + struct amdgpu_device *adev = drm_to_adev(dev);
75 + int r;
76 +
77 + if (dev->switch_power_state == DRM_SWITCH_POWER_OFF)
78 + return 0;
79 +
80 + /* Evict the majority of BOs before starting suspend sequence */
81 + r = amdgpu_device_evict_resources(adev);
82 + if (r)
83 + return r;
84 +
85 + return 0;
86 +}
87 +
88 /**
89 * amdgpu_device_suspend - initiate device suspend
90 *
91 @@ -4114,11 +4140,6 @@ int amdgpu_device_suspend(struct drm_device *dev, bool fbcon)
92
93 adev->in_suspend = true;
94
95 - /* Evict the majority of BOs before grabbing the full access */
96 - r = amdgpu_device_evict_resources(adev);
97 - if (r)
98 - return r;
99 -
100 if (amdgpu_sriov_vf(adev)) {
101 amdgpu_virt_fini_data_exchange(adev);
102 r = amdgpu_virt_request_full_gpu(adev, false);
103 diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
104 index 3204c3a42f2a3..f9bc38d20ce3e 100644
105 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
106 +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
107 @@ -2386,8 +2386,9 @@ static int amdgpu_pmops_prepare(struct device *dev)
108 /* Return a positive number here so
109 * DPM_FLAG_SMART_SUSPEND works properly
110 */
111 - if (amdgpu_device_supports_boco(drm_dev))
112 - return pm_runtime_suspended(dev);
113 + if (amdgpu_device_supports_boco(drm_dev) &&
114 + pm_runtime_suspended(dev))
115 + return 1;
116
117 /* if we will not support s3 or s2i for the device
118 * then skip suspend
119 @@ -2396,7 +2397,7 @@ static int amdgpu_pmops_prepare(struct device *dev)
120 !amdgpu_acpi_is_s3_active(adev))
121 return 1;
122
123 - return 0;
124 + return amdgpu_device_prepare(drm_dev);
125 }
126
127 static void amdgpu_pmops_complete(struct device *dev)
128 @@ -2598,6 +2599,9 @@ static int amdgpu_pmops_runtime_suspend(struct device *dev)
129 if (amdgpu_device_supports_boco(drm_dev))
130 adev->mp1_state = PP_MP1_STATE_UNLOAD;
131
132 + ret = amdgpu_device_prepare(drm_dev);
133 + if (ret)
134 + return ret;
135 ret = amdgpu_device_suspend(drm_dev, false);
136 if (ret) {
137 adev->in_runpm = false;
138 --
139 2.43.0
140