]> www.infradead.org Git - users/dwmw2/linux.git/commitdiff
drm/amd: Split up UVD suspend into prepare and suspend steps
authorMario Limonciello <mario.limonciello@amd.com>
Fri, 6 Oct 2023 18:50:22 +0000 (13:50 -0500)
committerAlex Deucher <alexander.deucher@amd.com>
Fri, 13 Oct 2023 15:01:04 +0000 (11:01 -0400)
amdgpu_uvd_suspend() allocates memory and copies objects into that
allocated memory.  This fails under memory pressure.  Instead move
majority of this code into a prepare step when swap can still be
allocated.

Reviewed-by: Christian König <christian.koenig@amd.com>
Signed-off-by: Mario Limonciello <mario.limonciello@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.c
drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.h
drivers/gpu/drm/amd/amdgpu/uvd_v3_1.c
drivers/gpu/drm/amd/amdgpu/uvd_v4_2.c
drivers/gpu/drm/amd/amdgpu/uvd_v5_0.c
drivers/gpu/drm/amd/amdgpu/uvd_v6_0.c
drivers/gpu/drm/amd/amdgpu/uvd_v7_0.c

index b7441654e6fa730c344753eb0e121564449c7a40..815b7c34ed33c0e6c4d52ffdace24641b5da083d 100644 (file)
@@ -418,12 +418,11 @@ int amdgpu_uvd_entity_init(struct amdgpu_device *adev)
        return 0;
 }
 
-int amdgpu_uvd_suspend(struct amdgpu_device *adev)
+int amdgpu_uvd_prepare_suspend(struct amdgpu_device *adev)
 {
        unsigned int size;
        void *ptr;
        int i, j, idx;
-       bool in_ras_intr = amdgpu_ras_intr_triggered();
 
        cancel_delayed_work_sync(&adev->uvd.idle_work);
 
@@ -452,7 +451,7 @@ int amdgpu_uvd_suspend(struct amdgpu_device *adev)
 
                if (drm_dev_enter(adev_to_drm(adev), &idx)) {
                        /* re-write 0 since err_event_athub will corrupt VCPU buffer */
-                       if (in_ras_intr)
+                       if (amdgpu_ras_intr_triggered())
                                memset(adev->uvd.inst[j].saved_bo, 0, size);
                        else
                                memcpy_fromio(adev->uvd.inst[j].saved_bo, ptr, size);
@@ -461,7 +460,12 @@ int amdgpu_uvd_suspend(struct amdgpu_device *adev)
                }
        }
 
-       if (in_ras_intr)
+       return 0;
+}
+
+int amdgpu_uvd_suspend(struct amdgpu_device *adev)
+{
+       if (amdgpu_ras_intr_triggered())
                DRM_WARN("UVD VCPU state may lost due to RAS ERREVENT_ATHUB_INTERRUPT\n");
 
        return 0;
index 9f89bb7cd60b78f7cd81613172660c46b087a2fa..a9f342537c6834e8dea2af8566073690b2ab7bb6 100644 (file)
@@ -74,6 +74,7 @@ struct amdgpu_uvd {
 int amdgpu_uvd_sw_init(struct amdgpu_device *adev);
 int amdgpu_uvd_sw_fini(struct amdgpu_device *adev);
 int amdgpu_uvd_entity_init(struct amdgpu_device *adev);
+int amdgpu_uvd_prepare_suspend(struct amdgpu_device *adev);
 int amdgpu_uvd_suspend(struct amdgpu_device *adev);
 int amdgpu_uvd_resume(struct amdgpu_device *adev);
 int amdgpu_uvd_get_create_msg(struct amdgpu_ring *ring, uint32_t handle,
index 5534c769b655085f7d2dd97611ca0b1dd0892aa1..58a8f78c003c7a0634a3a5f1d2d6bcf6858fad20 100644 (file)
@@ -706,6 +706,13 @@ static int uvd_v3_1_hw_fini(void *handle)
        return 0;
 }
 
+static int uvd_v3_1_prepare_suspend(void *handle)
+{
+       struct amdgpu_device *adev = (struct amdgpu_device *)handle;
+
+       return amdgpu_uvd_prepare_suspend(adev);
+}
+
 static int uvd_v3_1_suspend(void *handle)
 {
        int r;
@@ -806,6 +813,7 @@ static const struct amd_ip_funcs uvd_v3_1_ip_funcs = {
        .sw_fini = uvd_v3_1_sw_fini,
        .hw_init = uvd_v3_1_hw_init,
        .hw_fini = uvd_v3_1_hw_fini,
+       .prepare_suspend = uvd_v3_1_prepare_suspend,
        .suspend = uvd_v3_1_suspend,
        .resume = uvd_v3_1_resume,
        .is_idle = uvd_v3_1_is_idle,
index c108b83817951b7e3b5be55cec9939b72eb3e636..d3b1e31f545032f97b96d2b836bab5bda8b989d8 100644 (file)
@@ -220,6 +220,13 @@ static int uvd_v4_2_hw_fini(void *handle)
        return 0;
 }
 
+static int uvd_v4_2_prepare_suspend(void *handle)
+{
+       struct amdgpu_device *adev = (struct amdgpu_device *)handle;
+
+       return amdgpu_uvd_prepare_suspend(adev);
+}
+
 static int uvd_v4_2_suspend(void *handle)
 {
        int r;
@@ -756,6 +763,7 @@ static const struct amd_ip_funcs uvd_v4_2_ip_funcs = {
        .sw_fini = uvd_v4_2_sw_fini,
        .hw_init = uvd_v4_2_hw_init,
        .hw_fini = uvd_v4_2_hw_fini,
+       .prepare_suspend = uvd_v4_2_prepare_suspend,
        .suspend = uvd_v4_2_suspend,
        .resume = uvd_v4_2_resume,
        .is_idle = uvd_v4_2_is_idle,
index d7e31e48a2b8de27e75fcbf703e9f6eb547b77a9..5a8116437abf6f95c69e3393887b8b3acc9cb733 100644 (file)
@@ -218,6 +218,13 @@ static int uvd_v5_0_hw_fini(void *handle)
        return 0;
 }
 
+static int uvd_v5_0_prepare_suspend(void *handle)
+{
+       struct amdgpu_device *adev = (struct amdgpu_device *)handle;
+
+       return amdgpu_uvd_prepare_suspend(adev);
+}
+
 static int uvd_v5_0_suspend(void *handle)
 {
        int r;
@@ -863,6 +870,7 @@ static const struct amd_ip_funcs uvd_v5_0_ip_funcs = {
        .sw_fini = uvd_v5_0_sw_fini,
        .hw_init = uvd_v5_0_hw_init,
        .hw_fini = uvd_v5_0_hw_fini,
+       .prepare_suspend = uvd_v5_0_prepare_suspend,
        .suspend = uvd_v5_0_suspend,
        .resume = uvd_v5_0_resume,
        .is_idle = uvd_v5_0_is_idle,
index 5fe872f4bea7e30c68207347e51ca7c318be0ca8..74c09230aeb32bd38b00551cfbd3c711f85d9294 100644 (file)
@@ -542,6 +542,13 @@ static int uvd_v6_0_hw_fini(void *handle)
        return 0;
 }
 
+static int uvd_v6_0_prepare_suspend(void *handle)
+{
+       struct amdgpu_device *adev = (struct amdgpu_device *)handle;
+
+       return amdgpu_uvd_prepare_suspend(adev);
+}
+
 static int uvd_v6_0_suspend(void *handle)
 {
        int r;
@@ -1528,6 +1535,7 @@ static const struct amd_ip_funcs uvd_v6_0_ip_funcs = {
        .sw_fini = uvd_v6_0_sw_fini,
        .hw_init = uvd_v6_0_hw_init,
        .hw_fini = uvd_v6_0_hw_fini,
+       .prepare_suspend = uvd_v6_0_prepare_suspend,
        .suspend = uvd_v6_0_suspend,
        .resume = uvd_v6_0_resume,
        .is_idle = uvd_v6_0_is_idle,
index 86d1d46e1e5ee3c3810b252e17b5b9e4ab7049d0..1c42cf10cc2937546d1e003e1b72bd25c1d563ab 100644 (file)
@@ -612,6 +612,13 @@ static int uvd_v7_0_hw_fini(void *handle)
        return 0;
 }
 
+static int uvd_v7_0_prepare_suspend(void *handle)
+{
+       struct amdgpu_device *adev = (struct amdgpu_device *)handle;
+
+       return amdgpu_uvd_prepare_suspend(adev);
+}
+
 static int uvd_v7_0_suspend(void *handle)
 {
        int r;
@@ -1787,6 +1794,7 @@ const struct amd_ip_funcs uvd_v7_0_ip_funcs = {
        .sw_fini = uvd_v7_0_sw_fini,
        .hw_init = uvd_v7_0_hw_init,
        .hw_fini = uvd_v7_0_hw_fini,
+       .prepare_suspend = uvd_v7_0_prepare_suspend,
        .suspend = uvd_v7_0_suspend,
        .resume = uvd_v7_0_resume,
        .is_idle = NULL /* uvd_v7_0_is_idle */,