From: Huang Rui Date: Thu, 13 Apr 2017 08:12:26 +0000 (+0800) Subject: drm/amdgpu: fix dead lock if any ip block resume failed in s3 X-Git-Tag: v4.12-rc1~9^2~2^2~102 X-Git-Url: https://git.karo-electronics.de/?a=commitdiff_plain;h=03161a6ecb7576492bb37e9bfc68a0330fc6a41d;p=karo-tx-linux.git drm/amdgpu: fix dead lock if any ip block resume failed in s3 Driver must free the console lock whether driver resuming successful or not. Otherwise, fb_console will be always waiting for the lock and then cause system stuck. [ 244.405541] INFO: task kworker/0:0:4 blocked for more than 120 seconds. [ 244.405543] Tainted: G OE 4.9.0-custom #1 [ 244.405544] "echo 0 > /proc/sys/kernel/hung_task_timeout_secs" disables this message. [ 244.405541] INFO: task kworker/0:0:4 blocked for more than 120 seconds. [ 244.405543] Tainted: G OE 4.9.0-custom #1 [ 244.405544] "echo 0 > /proc/sys/kernel/hung_task_timeout_secs" disables this message. [ 244.405550] kworker/0:0 D 0 4 2 0x00080000 [ 244.405559] Workqueue: events console_callback [ 244.405564] ffff88045a2cfc00 0000000000000000 ffff880462b75940 ffffffff81c0e500 [ 244.405568] ffff880476419280 ffffc900018f7c90 ffffffff817dcf62 000000000000003c [ 244.405572] 0000000100000000 0000000000000002 ffff880462b75940 ffff880462b75940 [ 244.405573] Call Trace: [ 244.405580] [] ? __schedule+0x222/0x6a0 [ 244.405584] [] schedule+0x36/0x80 [ 244.405588] [] schedule_timeout+0x1fc/0x390 [ 244.405592] [] __down_common+0xa5/0xf8 [ 244.405598] [] ? put_prev_entity+0x48/0x710 [ 244.405601] [] __down+0x1d/0x1f [ 244.405606] [] down+0x41/0x50 [ 244.405611] [] console_lock+0x1a/0x40 [ 244.405614] [] console_callback+0x13/0x160 [ 244.405617] [] ? __schedule+0x22a/0x6a0 [ 244.405623] [] process_one_work+0x153/0x3f0 [ 244.405628] [] worker_thread+0x12b/0x4b0 [ 244.405633] [] ? rescuer_thread+0x350/0x350 [ 244.405637] [] kthread+0xd3/0xf0 [ 244.405641] [] ? kthread_park+0x60/0x60 [ 244.405645] [] ? kthread_park+0x60/0x60 [ 244.405649] [] ret_from_fork+0x25/0x30 Signed-off-by: Huang Rui Reviewed-by: Michel Dänzer Reviewed-by: Alex Deucher Signed-off-by: Alex Deucher --- diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c index 724b4c1c80f6..fbda93a87648 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c @@ -2215,7 +2215,7 @@ int amdgpu_device_resume(struct drm_device *dev, bool resume, bool fbcon) struct drm_connector *connector; struct amdgpu_device *adev = dev->dev_private; struct drm_crtc *crtc; - int r; + int r = 0; if (dev->switch_power_state == DRM_SWITCH_POWER_OFF) return 0; @@ -2227,11 +2227,8 @@ int amdgpu_device_resume(struct drm_device *dev, bool resume, bool fbcon) pci_set_power_state(dev->pdev, PCI_D0); pci_restore_state(dev->pdev); r = pci_enable_device(dev->pdev); - if (r) { - if (fbcon) - console_unlock(); - return r; - } + if (r) + goto unlock; } if (adev->is_atom_fw) amdgpu_atomfirmware_scratch_regs_restore(adev); @@ -2248,7 +2245,7 @@ int amdgpu_device_resume(struct drm_device *dev, bool resume, bool fbcon) r = amdgpu_resume(adev); if (r) { DRM_ERROR("amdgpu_resume failed (%d).\n", r); - return r; + goto unlock; } amdgpu_fence_driver_resume(adev); @@ -2259,11 +2256,8 @@ int amdgpu_device_resume(struct drm_device *dev, bool resume, bool fbcon) } r = amdgpu_late_init(adev); - if (r) { - if (fbcon) - console_unlock(); - return r; - } + if (r) + goto unlock; /* pin cursors */ list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { @@ -2313,12 +2307,14 @@ int amdgpu_device_resume(struct drm_device *dev, bool resume, bool fbcon) dev->dev->power.disable_depth--; #endif - if (fbcon) { + if (fbcon) amdgpu_fbdev_set_suspend(adev, 0); + +unlock: + if (fbcon) console_unlock(); - } - return 0; + return r; } static bool amdgpu_check_soft_reset(struct amdgpu_device *adev)