mirror of
https://github.com/torvalds/linux.git
synced 2024-09-20 06:53:04 +00:00
drm/amdgpu/mes: fix mes ring buffer overflow
wait memory room until enough before writing mes packets to avoid ring buffer overflow. v2: squash in sched_hw_submission fix Fixes:de32462541
("drm/amdgpu: cleanup MES11 command submission") Fixes:fffe347e14
("drm/amdgpu: cleanup MES12 command submission") Signed-off-by: Jack Xiao <Jack.Xiao@amd.com> Acked-by: Alex Deucher <alexander.deucher@amd.com> Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
This commit is contained in:
parent
46142cc1b9
commit
34e087e892
|
@ -214,6 +214,8 @@ int amdgpu_ring_init(struct amdgpu_device *adev, struct amdgpu_ring *ring,
|
|||
*/
|
||||
if (ring->funcs->type == AMDGPU_RING_TYPE_KIQ)
|
||||
sched_hw_submission = max(sched_hw_submission, 256);
|
||||
if (ring->funcs->type == AMDGPU_RING_TYPE_MES)
|
||||
sched_hw_submission = 8;
|
||||
else if (ring == &adev->sdma.instance[0].page)
|
||||
sched_hw_submission = 256;
|
||||
|
||||
|
|
|
@ -168,7 +168,7 @@ static int mes_v11_0_submit_pkt_and_poll_completion(struct amdgpu_mes *mes,
|
|||
const char *op_str, *misc_op_str;
|
||||
unsigned long flags;
|
||||
u64 status_gpu_addr;
|
||||
u32 status_offset;
|
||||
u32 seq, status_offset;
|
||||
u64 *status_ptr;
|
||||
signed long r;
|
||||
int ret;
|
||||
|
@ -196,6 +196,13 @@ static int mes_v11_0_submit_pkt_and_poll_completion(struct amdgpu_mes *mes,
|
|||
if (r)
|
||||
goto error_unlock_free;
|
||||
|
||||
seq = ++ring->fence_drv.sync_seq;
|
||||
r = amdgpu_fence_wait_polling(ring,
|
||||
seq - ring->fence_drv.num_fences_mask,
|
||||
timeout);
|
||||
if (r < 1)
|
||||
goto error_undo;
|
||||
|
||||
api_status = (struct MES_API_STATUS *)((char *)pkt + api_status_off);
|
||||
api_status->api_completion_fence_addr = status_gpu_addr;
|
||||
api_status->api_completion_fence_value = 1;
|
||||
|
@ -208,8 +215,7 @@ static int mes_v11_0_submit_pkt_and_poll_completion(struct amdgpu_mes *mes,
|
|||
mes_status_pkt.header.dwsize = API_FRAME_SIZE_IN_DWORDS;
|
||||
mes_status_pkt.api_status.api_completion_fence_addr =
|
||||
ring->fence_drv.gpu_addr;
|
||||
mes_status_pkt.api_status.api_completion_fence_value =
|
||||
++ring->fence_drv.sync_seq;
|
||||
mes_status_pkt.api_status.api_completion_fence_value = seq;
|
||||
|
||||
amdgpu_ring_write_multiple(ring, &mes_status_pkt,
|
||||
sizeof(mes_status_pkt) / 4);
|
||||
|
@ -229,7 +235,7 @@ static int mes_v11_0_submit_pkt_and_poll_completion(struct amdgpu_mes *mes,
|
|||
dev_dbg(adev->dev, "MES msg=%d was emitted\n",
|
||||
x_pkt->header.opcode);
|
||||
|
||||
r = amdgpu_fence_wait_polling(ring, ring->fence_drv.sync_seq, timeout);
|
||||
r = amdgpu_fence_wait_polling(ring, seq, timeout);
|
||||
if (r < 1 || !*status_ptr) {
|
||||
|
||||
if (misc_op_str)
|
||||
|
@ -252,6 +258,10 @@ static int mes_v11_0_submit_pkt_and_poll_completion(struct amdgpu_mes *mes,
|
|||
amdgpu_device_wb_free(adev, status_offset);
|
||||
return 0;
|
||||
|
||||
error_undo:
|
||||
dev_err(adev->dev, "MES ring buffer is full.\n");
|
||||
amdgpu_ring_undo(ring);
|
||||
|
||||
error_unlock_free:
|
||||
spin_unlock_irqrestore(&mes->ring_lock, flags);
|
||||
|
||||
|
|
|
@ -154,7 +154,7 @@ static int mes_v12_0_submit_pkt_and_poll_completion(struct amdgpu_mes *mes,
|
|||
const char *op_str, *misc_op_str;
|
||||
unsigned long flags;
|
||||
u64 status_gpu_addr;
|
||||
u32 status_offset;
|
||||
u32 seq, status_offset;
|
||||
u64 *status_ptr;
|
||||
signed long r;
|
||||
int ret;
|
||||
|
@ -182,6 +182,13 @@ static int mes_v12_0_submit_pkt_and_poll_completion(struct amdgpu_mes *mes,
|
|||
if (r)
|
||||
goto error_unlock_free;
|
||||
|
||||
seq = ++ring->fence_drv.sync_seq;
|
||||
r = amdgpu_fence_wait_polling(ring,
|
||||
seq - ring->fence_drv.num_fences_mask,
|
||||
timeout);
|
||||
if (r < 1)
|
||||
goto error_undo;
|
||||
|
||||
api_status = (struct MES_API_STATUS *)((char *)pkt + api_status_off);
|
||||
api_status->api_completion_fence_addr = status_gpu_addr;
|
||||
api_status->api_completion_fence_value = 1;
|
||||
|
@ -194,8 +201,7 @@ static int mes_v12_0_submit_pkt_and_poll_completion(struct amdgpu_mes *mes,
|
|||
mes_status_pkt.header.dwsize = API_FRAME_SIZE_IN_DWORDS;
|
||||
mes_status_pkt.api_status.api_completion_fence_addr =
|
||||
ring->fence_drv.gpu_addr;
|
||||
mes_status_pkt.api_status.api_completion_fence_value =
|
||||
++ring->fence_drv.sync_seq;
|
||||
mes_status_pkt.api_status.api_completion_fence_value = seq;
|
||||
|
||||
amdgpu_ring_write_multiple(ring, &mes_status_pkt,
|
||||
sizeof(mes_status_pkt) / 4);
|
||||
|
@ -215,7 +221,7 @@ static int mes_v12_0_submit_pkt_and_poll_completion(struct amdgpu_mes *mes,
|
|||
dev_dbg(adev->dev, "MES msg=%d was emitted\n",
|
||||
x_pkt->header.opcode);
|
||||
|
||||
r = amdgpu_fence_wait_polling(ring, ring->fence_drv.sync_seq, timeout);
|
||||
r = amdgpu_fence_wait_polling(ring, seq, timeout);
|
||||
if (r < 1 || !*status_ptr) {
|
||||
|
||||
if (misc_op_str)
|
||||
|
@ -238,6 +244,10 @@ static int mes_v12_0_submit_pkt_and_poll_completion(struct amdgpu_mes *mes,
|
|||
amdgpu_device_wb_free(adev, status_offset);
|
||||
return 0;
|
||||
|
||||
error_undo:
|
||||
dev_err(adev->dev, "MES ring buffer is full.\n");
|
||||
amdgpu_ring_undo(ring);
|
||||
|
||||
error_unlock_free:
|
||||
spin_unlock_irqrestore(&mes->ring_lock, flags);
|
||||
|
||||
|
|
Loading…
Reference in New Issue
Block a user