Commit db998890 authored by Mario Limonciello's avatar Mario Limonciello Committed by Alex Deucher

drm/amd: Split up UVD suspend into prepare and suspend steps

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: default avatarChristian König <christian.koenig@amd.com>
Signed-off-by: default avatarMario Limonciello <mario.limonciello@amd.com>
Signed-off-by: default avatarAlex Deucher <alexander.deucher@amd.com>
parent cb11ca32
...@@ -418,12 +418,11 @@ int amdgpu_uvd_entity_init(struct amdgpu_device *adev) ...@@ -418,12 +418,11 @@ int amdgpu_uvd_entity_init(struct amdgpu_device *adev)
return 0; return 0;
} }
int amdgpu_uvd_suspend(struct amdgpu_device *adev) int amdgpu_uvd_prepare_suspend(struct amdgpu_device *adev)
{ {
unsigned int size; unsigned int size;
void *ptr; void *ptr;
int i, j, idx; int i, j, idx;
bool in_ras_intr = amdgpu_ras_intr_triggered();
cancel_delayed_work_sync(&adev->uvd.idle_work); cancel_delayed_work_sync(&adev->uvd.idle_work);
...@@ -452,7 +451,7 @@ int amdgpu_uvd_suspend(struct amdgpu_device *adev) ...@@ -452,7 +451,7 @@ int amdgpu_uvd_suspend(struct amdgpu_device *adev)
if (drm_dev_enter(adev_to_drm(adev), &idx)) { if (drm_dev_enter(adev_to_drm(adev), &idx)) {
/* re-write 0 since err_event_athub will corrupt VCPU buffer */ /* 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); memset(adev->uvd.inst[j].saved_bo, 0, size);
else else
memcpy_fromio(adev->uvd.inst[j].saved_bo, ptr, size); memcpy_fromio(adev->uvd.inst[j].saved_bo, ptr, size);
...@@ -461,7 +460,12 @@ int amdgpu_uvd_suspend(struct amdgpu_device *adev) ...@@ -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"); DRM_WARN("UVD VCPU state may lost due to RAS ERREVENT_ATHUB_INTERRUPT\n");
return 0; return 0;
......
...@@ -74,6 +74,7 @@ struct amdgpu_uvd { ...@@ -74,6 +74,7 @@ struct amdgpu_uvd {
int amdgpu_uvd_sw_init(struct amdgpu_device *adev); int amdgpu_uvd_sw_init(struct amdgpu_device *adev);
int amdgpu_uvd_sw_fini(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_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_suspend(struct amdgpu_device *adev);
int amdgpu_uvd_resume(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, int amdgpu_uvd_get_create_msg(struct amdgpu_ring *ring, uint32_t handle,
......
...@@ -706,6 +706,13 @@ static int uvd_v3_1_hw_fini(void *handle) ...@@ -706,6 +706,13 @@ static int uvd_v3_1_hw_fini(void *handle)
return 0; 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) static int uvd_v3_1_suspend(void *handle)
{ {
int r; int r;
...@@ -806,6 +813,7 @@ static const struct amd_ip_funcs uvd_v3_1_ip_funcs = { ...@@ -806,6 +813,7 @@ static const struct amd_ip_funcs uvd_v3_1_ip_funcs = {
.sw_fini = uvd_v3_1_sw_fini, .sw_fini = uvd_v3_1_sw_fini,
.hw_init = uvd_v3_1_hw_init, .hw_init = uvd_v3_1_hw_init,
.hw_fini = uvd_v3_1_hw_fini, .hw_fini = uvd_v3_1_hw_fini,
.prepare_suspend = uvd_v3_1_prepare_suspend,
.suspend = uvd_v3_1_suspend, .suspend = uvd_v3_1_suspend,
.resume = uvd_v3_1_resume, .resume = uvd_v3_1_resume,
.is_idle = uvd_v3_1_is_idle, .is_idle = uvd_v3_1_is_idle,
......
...@@ -220,6 +220,13 @@ static int uvd_v4_2_hw_fini(void *handle) ...@@ -220,6 +220,13 @@ static int uvd_v4_2_hw_fini(void *handle)
return 0; 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) static int uvd_v4_2_suspend(void *handle)
{ {
int r; int r;
...@@ -756,6 +763,7 @@ static const struct amd_ip_funcs uvd_v4_2_ip_funcs = { ...@@ -756,6 +763,7 @@ static const struct amd_ip_funcs uvd_v4_2_ip_funcs = {
.sw_fini = uvd_v4_2_sw_fini, .sw_fini = uvd_v4_2_sw_fini,
.hw_init = uvd_v4_2_hw_init, .hw_init = uvd_v4_2_hw_init,
.hw_fini = uvd_v4_2_hw_fini, .hw_fini = uvd_v4_2_hw_fini,
.prepare_suspend = uvd_v4_2_prepare_suspend,
.suspend = uvd_v4_2_suspend, .suspend = uvd_v4_2_suspend,
.resume = uvd_v4_2_resume, .resume = uvd_v4_2_resume,
.is_idle = uvd_v4_2_is_idle, .is_idle = uvd_v4_2_is_idle,
......
...@@ -218,6 +218,13 @@ static int uvd_v5_0_hw_fini(void *handle) ...@@ -218,6 +218,13 @@ static int uvd_v5_0_hw_fini(void *handle)
return 0; 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) static int uvd_v5_0_suspend(void *handle)
{ {
int r; int r;
...@@ -863,6 +870,7 @@ static const struct amd_ip_funcs uvd_v5_0_ip_funcs = { ...@@ -863,6 +870,7 @@ static const struct amd_ip_funcs uvd_v5_0_ip_funcs = {
.sw_fini = uvd_v5_0_sw_fini, .sw_fini = uvd_v5_0_sw_fini,
.hw_init = uvd_v5_0_hw_init, .hw_init = uvd_v5_0_hw_init,
.hw_fini = uvd_v5_0_hw_fini, .hw_fini = uvd_v5_0_hw_fini,
.prepare_suspend = uvd_v5_0_prepare_suspend,
.suspend = uvd_v5_0_suspend, .suspend = uvd_v5_0_suspend,
.resume = uvd_v5_0_resume, .resume = uvd_v5_0_resume,
.is_idle = uvd_v5_0_is_idle, .is_idle = uvd_v5_0_is_idle,
......
...@@ -542,6 +542,13 @@ static int uvd_v6_0_hw_fini(void *handle) ...@@ -542,6 +542,13 @@ static int uvd_v6_0_hw_fini(void *handle)
return 0; 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) static int uvd_v6_0_suspend(void *handle)
{ {
int r; int r;
...@@ -1528,6 +1535,7 @@ static const struct amd_ip_funcs uvd_v6_0_ip_funcs = { ...@@ -1528,6 +1535,7 @@ static const struct amd_ip_funcs uvd_v6_0_ip_funcs = {
.sw_fini = uvd_v6_0_sw_fini, .sw_fini = uvd_v6_0_sw_fini,
.hw_init = uvd_v6_0_hw_init, .hw_init = uvd_v6_0_hw_init,
.hw_fini = uvd_v6_0_hw_fini, .hw_fini = uvd_v6_0_hw_fini,
.prepare_suspend = uvd_v6_0_prepare_suspend,
.suspend = uvd_v6_0_suspend, .suspend = uvd_v6_0_suspend,
.resume = uvd_v6_0_resume, .resume = uvd_v6_0_resume,
.is_idle = uvd_v6_0_is_idle, .is_idle = uvd_v6_0_is_idle,
......
...@@ -612,6 +612,13 @@ static int uvd_v7_0_hw_fini(void *handle) ...@@ -612,6 +612,13 @@ static int uvd_v7_0_hw_fini(void *handle)
return 0; 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) static int uvd_v7_0_suspend(void *handle)
{ {
int r; int r;
...@@ -1787,6 +1794,7 @@ const struct amd_ip_funcs uvd_v7_0_ip_funcs = { ...@@ -1787,6 +1794,7 @@ const struct amd_ip_funcs uvd_v7_0_ip_funcs = {
.sw_fini = uvd_v7_0_sw_fini, .sw_fini = uvd_v7_0_sw_fini,
.hw_init = uvd_v7_0_hw_init, .hw_init = uvd_v7_0_hw_init,
.hw_fini = uvd_v7_0_hw_fini, .hw_fini = uvd_v7_0_hw_fini,
.prepare_suspend = uvd_v7_0_prepare_suspend,
.suspend = uvd_v7_0_suspend, .suspend = uvd_v7_0_suspend,
.resume = uvd_v7_0_resume, .resume = uvd_v7_0_resume,
.is_idle = NULL /* uvd_v7_0_is_idle */, .is_idle = NULL /* uvd_v7_0_is_idle */,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment