Skip to content

Commit e356d32

Browse files
ChristianKoenigAMDalexdeucher
authored andcommitted
drm/amdgpu: cleanup MES11 command submission
The approach of having a separate WB slot for each submission doesn't really work well and for example breaks GPU reset. Use a status query packet for the fence update instead since those should always succeed we can use the fence of the original packet to signal the state of the operation. While at it cleanup the coding style. Fixes: eef016b ("drm/amdgpu/mes11: Use a separate fence per transaction") Reviewed-by: Mukul Joshi <mukul.joshi@amd.com> Signed-off-by: Christian König <christian.koenig@amd.com> Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
1 parent f0d576f commit e356d32

File tree

1 file changed

+48
-28
lines changed

1 file changed

+48
-28
lines changed

drivers/gpu/drm/amd/amdgpu/mes_v11_0.c

Lines changed: 48 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -154,18 +154,18 @@ static int mes_v11_0_submit_pkt_and_poll_completion(struct amdgpu_mes *mes,
154154
void *pkt, int size,
155155
int api_status_off)
156156
{
157-
int ndw = size / 4;
158-
signed long r;
159-
union MESAPI__MISC *x_pkt = pkt;
160-
struct MES_API_STATUS *api_status;
157+
union MESAPI__QUERY_MES_STATUS mes_status_pkt;
158+
signed long timeout = 3000000; /* 3000 ms */
161159
struct amdgpu_device *adev = mes->adev;
162160
struct amdgpu_ring *ring = &mes->ring;
163-
unsigned long flags;
164-
signed long timeout = 3000000; /* 3000 ms */
161+
struct MES_API_STATUS *api_status;
162+
union MESAPI__MISC *x_pkt = pkt;
165163
const char *op_str, *misc_op_str;
166-
u32 fence_offset;
167-
u64 fence_gpu_addr;
168-
u64 *fence_ptr;
164+
unsigned long flags;
165+
u64 status_gpu_addr;
166+
u32 status_offset;
167+
u64 *status_ptr;
168+
signed long r;
169169
int ret;
170170

171171
if (x_pkt->header.opcode >= MES_SCH_API_MAX)
@@ -177,44 +177,55 @@ static int mes_v11_0_submit_pkt_and_poll_completion(struct amdgpu_mes *mes,
177177
/* Worst case in sriov where all other 15 VF timeout, each VF needs about 600ms */
178178
timeout = 15 * 600 * 1000;
179179
}
180-
BUG_ON(size % 4 != 0);
181180

182-
ret = amdgpu_device_wb_get(adev, &fence_offset);
181+
ret = amdgpu_device_wb_get(adev, &status_offset);
183182
if (ret)
184183
return ret;
185-
fence_gpu_addr =
186-
adev->wb.gpu_addr + (fence_offset * 4);
187-
fence_ptr = (u64 *)&adev->wb.wb[fence_offset];
188-
*fence_ptr = 0;
184+
185+
status_gpu_addr = adev->wb.gpu_addr + (status_offset * 4);
186+
status_ptr = (u64 *)&adev->wb.wb[status_offset];
187+
*status_ptr = 0;
189188

190189
spin_lock_irqsave(&mes->ring_lock, flags);
191-
if (amdgpu_ring_alloc(ring, ndw)) {
192-
spin_unlock_irqrestore(&mes->ring_lock, flags);
193-
amdgpu_device_wb_free(adev, fence_offset);
194-
return -ENOMEM;
195-
}
190+
r = amdgpu_ring_alloc(ring, (size + sizeof(mes_status_pkt)) / 4);
191+
if (r)
192+
goto error_unlock_free;
196193

197194
api_status = (struct MES_API_STATUS *)((char *)pkt + api_status_off);
198-
api_status->api_completion_fence_addr = fence_gpu_addr;
195+
api_status->api_completion_fence_addr = status_gpu_addr;
199196
api_status->api_completion_fence_value = 1;
200197

201-
amdgpu_ring_write_multiple(ring, pkt, ndw);
198+
amdgpu_ring_write_multiple(ring, pkt, size / 4);
199+
200+
memset(&mes_status_pkt, 0, sizeof(mes_status_pkt));
201+
mes_status_pkt.header.type = MES_API_TYPE_SCHEDULER;
202+
mes_status_pkt.header.opcode = MES_SCH_API_QUERY_SCHEDULER_STATUS;
203+
mes_status_pkt.header.dwsize = API_FRAME_SIZE_IN_DWORDS;
204+
mes_status_pkt.api_status.api_completion_fence_addr =
205+
ring->fence_drv.gpu_addr;
206+
mes_status_pkt.api_status.api_completion_fence_value =
207+
++ring->fence_drv.sync_seq;
208+
209+
amdgpu_ring_write_multiple(ring, &mes_status_pkt,
210+
sizeof(mes_status_pkt) / 4);
211+
202212
amdgpu_ring_commit(ring);
203213
spin_unlock_irqrestore(&mes->ring_lock, flags);
204214

205215
op_str = mes_v11_0_get_op_string(x_pkt);
206216
misc_op_str = mes_v11_0_get_misc_op_string(x_pkt);
207217

208218
if (misc_op_str)
209-
dev_dbg(adev->dev, "MES msg=%s (%s) was emitted\n", op_str, misc_op_str);
219+
dev_dbg(adev->dev, "MES msg=%s (%s) was emitted\n", op_str,
220+
misc_op_str);
210221
else if (op_str)
211222
dev_dbg(adev->dev, "MES msg=%s was emitted\n", op_str);
212223
else
213-
dev_dbg(adev->dev, "MES msg=%d was emitted\n", x_pkt->header.opcode);
224+
dev_dbg(adev->dev, "MES msg=%d was emitted\n",
225+
x_pkt->header.opcode);
214226

215-
r = amdgpu_mes_fence_wait_polling(fence_ptr, (u64)1, timeout);
216-
amdgpu_device_wb_free(adev, fence_offset);
217-
if (r < 1) {
227+
r = amdgpu_fence_wait_polling(ring, ring->fence_drv.sync_seq, timeout);
228+
if (r < 1 || !*status_ptr) {
218229

219230
if (misc_op_str)
220231
dev_err(adev->dev, "MES failed to respond to msg=%s (%s)\n",
@@ -229,10 +240,19 @@ static int mes_v11_0_submit_pkt_and_poll_completion(struct amdgpu_mes *mes,
229240
while (halt_if_hws_hang)
230241
schedule();
231242

232-
return -ETIMEDOUT;
243+
r = -ETIMEDOUT;
244+
goto error_wb_free;
233245
}
234246

247+
amdgpu_device_wb_free(adev, status_offset);
235248
return 0;
249+
250+
error_unlock_free:
251+
spin_unlock_irqrestore(&mes->ring_lock, flags);
252+
253+
error_wb_free:
254+
amdgpu_device_wb_free(adev, status_offset);
255+
return r;
236256
}
237257

238258
static int convert_to_mes_queue_type(int queue_type)

0 commit comments

Comments
 (0)