Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

drm/amdgpu/jpeg: fix race condition issue for jpeg start

Fix race condition issue when multiple jpeg starts are called.

Signed-off-by: James Zhu <James.Zhu@amd.com>
Acked-by: Nirmoy Das <nirmoy.das@amd.com>
Reviewed-by: Leo Liu <leo.liu@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>

authored by

James Zhu and committed by
Alex Deucher
651a1465 7ef869ef

+14 -4
+12 -4
drivers/gpu/drm/amd/amdgpu/amdgpu_jpeg.c
··· 37 37 int amdgpu_jpeg_sw_init(struct amdgpu_device *adev) 38 38 { 39 39 INIT_DELAYED_WORK(&adev->jpeg.idle_work, amdgpu_jpeg_idle_work_handler); 40 + mutex_init(&adev->jpeg.jpeg_pg_lock); 41 + atomic_set(&adev->jpeg.total_submission_cnt, 0); 40 42 41 43 return 0; 42 44 } ··· 55 53 56 54 amdgpu_ring_fini(&adev->jpeg.inst[i].ring_dec); 57 55 } 56 + 57 + mutex_destroy(&adev->jpeg.jpeg_pg_lock); 58 58 59 59 return 0; 60 60 } ··· 87 83 fences += amdgpu_fence_count_emitted(&adev->jpeg.inst[i].ring_dec); 88 84 } 89 85 90 - if (fences == 0) 86 + if (!fences && !atomic_read(&adev->jpeg.total_submission_cnt)) 91 87 amdgpu_device_ip_set_powergating_state(adev, AMD_IP_BLOCK_TYPE_JPEG, 92 88 AMD_PG_STATE_GATE); 93 89 else ··· 97 93 void amdgpu_jpeg_ring_begin_use(struct amdgpu_ring *ring) 98 94 { 99 95 struct amdgpu_device *adev = ring->adev; 100 - bool set_clocks = !cancel_delayed_work_sync(&adev->jpeg.idle_work); 101 96 102 - if (set_clocks) 103 - amdgpu_device_ip_set_powergating_state(adev, AMD_IP_BLOCK_TYPE_JPEG, 97 + atomic_inc(&adev->jpeg.total_submission_cnt); 98 + cancel_delayed_work_sync(&adev->jpeg.idle_work); 99 + 100 + mutex_lock(&adev->jpeg.jpeg_pg_lock); 101 + amdgpu_device_ip_set_powergating_state(adev, AMD_IP_BLOCK_TYPE_JPEG, 104 102 AMD_PG_STATE_UNGATE); 103 + mutex_unlock(&adev->jpeg.jpeg_pg_lock); 105 104 } 106 105 107 106 void amdgpu_jpeg_ring_end_use(struct amdgpu_ring *ring) 108 107 { 108 + atomic_dec(&ring->adev->jpeg.total_submission_cnt); 109 109 schedule_delayed_work(&ring->adev->jpeg.idle_work, JPEG_IDLE_TIMEOUT); 110 110 } 111 111
+2
drivers/gpu/drm/amd/amdgpu/amdgpu_jpeg.h
··· 46 46 unsigned harvest_config; 47 47 struct delayed_work idle_work; 48 48 enum amd_powergating_state cur_state; 49 + struct mutex jpeg_pg_lock; 50 + atomic_t total_submission_cnt; 49 51 }; 50 52 51 53 int amdgpu_jpeg_sw_init(struct amdgpu_device *adev);