drm/amd: Propagate failures in dc_set_power_state()
authorMario Limonciello <mario.limonciello@amd.com>
Thu, 21 Sep 2023 14:50:04 +0000 (09:50 -0500)
committerAlex Deucher <alexander.deucher@amd.com>
Tue, 26 Sep 2023 21:00:22 +0000 (17:00 -0400)
During the suspend process dc_set_power_state() will use kzalloc
to allocate memory, but this potentially fails with memory pressure.
If it fails, the suspend should be aborted.

Link: https://gitlab.freedesktop.org/drm/amd/-/issues/2362
Signed-off-by: Mario Limonciello <mario.limonciello@amd.com>
Reviewed-by: Christian König <christian.koenig@amd.com>
Cc: Harry.Wentland@amd.com
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
drivers/gpu/drm/amd/display/dc/core/dc.c
drivers/gpu/drm/amd/display/dc/dc.h

index a0023d1..3480a02 100644 (file)
@@ -2671,9 +2671,7 @@ static int dm_suspend(void *handle)
 
        hpd_rx_irq_work_suspend(dm);
 
-       dc_set_power_state(dm->dc, DC_ACPI_CM_POWER_STATE_D3);
-
-       return 0;
+       return dc_set_power_state(dm->dc, DC_ACPI_CM_POWER_STATE_D3);
 }
 
 struct amdgpu_dm_connector *
@@ -2867,7 +2865,10 @@ static int dm_resume(void *handle)
                if (r)
                        DRM_ERROR("DMUB interface failed to initialize: status=%d\n", r);
 
-               dc_set_power_state(dm->dc, DC_ACPI_CM_POWER_STATE_D0);
+               r = dc_set_power_state(dm->dc, DC_ACPI_CM_POWER_STATE_D0);
+               if (r)
+                       return r;
+
                dc_resume(dm->dc);
 
                amdgpu_dm_irq_resume_early(adev);
@@ -2916,7 +2917,9 @@ static int dm_resume(void *handle)
        }
 
        /* power on hardware */
-       dc_set_power_state(dm->dc, DC_ACPI_CM_POWER_STATE_D0);
+       r = dc_set_power_state(dm->dc, DC_ACPI_CM_POWER_STATE_D0);
+       if (r)
+               return r;
 
        /* program HPD filter */
        dc_resume(dm->dc);
index c5a74b2..3b060e0 100644 (file)
@@ -4723,7 +4723,7 @@ void dc_power_down_on_boot(struct dc *dc)
                dc->hwss.power_down_on_boot(dc);
 }
 
-void dc_set_power_state(
+int dc_set_power_state(
        struct dc *dc,
        enum dc_acpi_cm_power_state power_state)
 {
@@ -4731,7 +4731,7 @@ void dc_set_power_state(
        struct display_mode_lib *dml;
 
        if (!dc->current_state)
-               return;
+               return 0;
 
        switch (power_state) {
        case DC_ACPI_CM_POWER_STATE_D0:
@@ -4758,7 +4758,7 @@ void dc_set_power_state(
 
                ASSERT(dml);
                if (!dml)
-                       return;
+                       return -ENOMEM;
 
                /* Preserve refcount */
                refcount = dc->current_state->refcount;
@@ -4776,6 +4776,8 @@ void dc_set_power_state(
 
                break;
        }
+
+       return 0;
 }
 
 void dc_resume(struct dc *dc)
index 0e09785..eec4592 100644 (file)
@@ -2283,7 +2283,7 @@ void dc_notify_vsync_int_state(struct dc *dc, struct dc_stream_state *stream, bo
 
 /* Power Interfaces */
 
-void dc_set_power_state(
+int dc_set_power_state(
                struct dc *dc,
                enum dc_acpi_cm_power_state power_state);
 void dc_resume(struct dc *dc);