Skip to content

Commit f920d1b

Browse files
changzhualexdeucher
authored andcommitted
drm/amdgpu: invalidate mmhub semaphore workaround in gmc9/gmc10
It may lose gpuvm invalidate acknowldege state across power-gating off cycle. To avoid this issue in gmc9/gmc10 invalidation, add semaphore acquire before invalidation and semaphore release after invalidation. After adding semaphore acquire before invalidation, the semaphore register become read-only if another process try to acquire semaphore. Then it will not be able to release this semaphore. Then it may cause deadlock problem. If this deadlock problem happens, it needs a semaphore firmware fix. Signed-off-by: changzhu <[email protected]> Acked-by: Huang Rui <[email protected]> Signed-off-by: Alex Deucher <[email protected]> Cc: [email protected]
1 parent 6c2c897 commit f920d1b

File tree

3 files changed

+116
-2
lines changed

3 files changed

+116
-2
lines changed

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

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -235,6 +235,29 @@ static void gmc_v10_0_flush_vm_hub(struct amdgpu_device *adev, uint32_t vmid,
235235
const unsigned eng = 17;
236236
unsigned int i;
237237

238+
spin_lock(&adev->gmc.invalidate_lock);
239+
/*
240+
* It may lose gpuvm invalidate acknowldege state across power-gating
241+
* off cycle, add semaphore acquire before invalidation and semaphore
242+
* release after invalidation to avoid entering power gated state
243+
* to WA the Issue
244+
*/
245+
246+
/* TODO: It needs to continue working on debugging with semaphore for GFXHUB as well. */
247+
if (vmhub == AMDGPU_MMHUB_0 ||
248+
vmhub == AMDGPU_MMHUB_1) {
249+
for (i = 0; i < adev->usec_timeout; i++) {
250+
/* a read return value of 1 means semaphore acuqire */
251+
tmp = RREG32_NO_KIQ(hub->vm_inv_eng0_sem + eng);
252+
if (tmp & 0x1)
253+
break;
254+
udelay(1);
255+
}
256+
257+
if (i >= adev->usec_timeout)
258+
DRM_ERROR("Timeout waiting for sem acquire in VM flush!\n");
259+
}
260+
238261
WREG32_NO_KIQ(hub->vm_inv_eng0_req + eng, tmp);
239262

240263
/*
@@ -254,6 +277,17 @@ static void gmc_v10_0_flush_vm_hub(struct amdgpu_device *adev, uint32_t vmid,
254277
udelay(1);
255278
}
256279

280+
/* TODO: It needs to continue working on debugging with semaphore for GFXHUB as well. */
281+
if (vmhub == AMDGPU_MMHUB_0 ||
282+
vmhub == AMDGPU_MMHUB_1)
283+
/*
284+
* add semaphore release after invalidation,
285+
* write with 0 means semaphore release
286+
*/
287+
WREG32_NO_KIQ(hub->vm_inv_eng0_sem + eng, 0);
288+
289+
spin_unlock(&adev->gmc.invalidate_lock);
290+
257291
if (i < adev->usec_timeout)
258292
return;
259293

@@ -338,6 +372,20 @@ static uint64_t gmc_v10_0_emit_flush_gpu_tlb(struct amdgpu_ring *ring,
338372
uint32_t req = gmc_v10_0_get_invalidate_req(vmid, 0);
339373
unsigned eng = ring->vm_inv_eng;
340374

375+
/*
376+
* It may lose gpuvm invalidate acknowldege state across power-gating
377+
* off cycle, add semaphore acquire before invalidation and semaphore
378+
* release after invalidation to avoid entering power gated state
379+
* to WA the Issue
380+
*/
381+
382+
/* TODO: It needs to continue working on debugging with semaphore for GFXHUB as well. */
383+
if (ring->funcs->vmhub == AMDGPU_MMHUB_0 ||
384+
ring->funcs->vmhub == AMDGPU_MMHUB_1)
385+
/* a read return value of 1 means semaphore acuqire */
386+
amdgpu_ring_emit_reg_wait(ring,
387+
hub->vm_inv_eng0_sem + eng, 0x1, 0x1);
388+
341389
amdgpu_ring_emit_wreg(ring, hub->ctx0_ptb_addr_lo32 + (2 * vmid),
342390
lower_32_bits(pd_addr));
343391

@@ -348,6 +396,15 @@ static uint64_t gmc_v10_0_emit_flush_gpu_tlb(struct amdgpu_ring *ring,
348396
hub->vm_inv_eng0_ack + eng,
349397
req, 1 << vmid);
350398

399+
/* TODO: It needs to continue working on debugging with semaphore for GFXHUB as well. */
400+
if (ring->funcs->vmhub == AMDGPU_MMHUB_0 ||
401+
ring->funcs->vmhub == AMDGPU_MMHUB_1)
402+
/*
403+
* add semaphore release after invalidation,
404+
* write with 0 means semaphore release
405+
*/
406+
amdgpu_ring_emit_wreg(ring, hub->vm_inv_eng0_sem + eng, 0);
407+
351408
return pd_addr;
352409
}
353410

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

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -459,6 +459,29 @@ static void gmc_v9_0_flush_gpu_tlb(struct amdgpu_device *adev, uint32_t vmid,
459459
}
460460

461461
spin_lock(&adev->gmc.invalidate_lock);
462+
463+
/*
464+
* It may lose gpuvm invalidate acknowldege state across power-gating
465+
* off cycle, add semaphore acquire before invalidation and semaphore
466+
* release after invalidation to avoid entering power gated state
467+
* to WA the Issue
468+
*/
469+
470+
/* TODO: It needs to continue working on debugging with semaphore for GFXHUB as well. */
471+
if (vmhub == AMDGPU_MMHUB_0 ||
472+
vmhub == AMDGPU_MMHUB_1) {
473+
for (j = 0; j < adev->usec_timeout; j++) {
474+
/* a read return value of 1 means semaphore acuqire */
475+
tmp = RREG32_NO_KIQ(hub->vm_inv_eng0_sem + eng);
476+
if (tmp & 0x1)
477+
break;
478+
udelay(1);
479+
}
480+
481+
if (j >= adev->usec_timeout)
482+
DRM_ERROR("Timeout waiting for sem acquire in VM flush!\n");
483+
}
484+
462485
WREG32_NO_KIQ(hub->vm_inv_eng0_req + eng, tmp);
463486

464487
/*
@@ -474,7 +497,18 @@ static void gmc_v9_0_flush_gpu_tlb(struct amdgpu_device *adev, uint32_t vmid,
474497
break;
475498
udelay(1);
476499
}
500+
501+
/* TODO: It needs to continue working on debugging with semaphore for GFXHUB as well. */
502+
if (vmhub == AMDGPU_MMHUB_0 ||
503+
vmhub == AMDGPU_MMHUB_1)
504+
/*
505+
* add semaphore release after invalidation,
506+
* write with 0 means semaphore release
507+
*/
508+
WREG32_NO_KIQ(hub->vm_inv_eng0_sem + eng, 0);
509+
477510
spin_unlock(&adev->gmc.invalidate_lock);
511+
478512
if (j < adev->usec_timeout)
479513
return;
480514

@@ -489,6 +523,20 @@ static uint64_t gmc_v9_0_emit_flush_gpu_tlb(struct amdgpu_ring *ring,
489523
uint32_t req = gmc_v9_0_get_invalidate_req(vmid, 0);
490524
unsigned eng = ring->vm_inv_eng;
491525

526+
/*
527+
* It may lose gpuvm invalidate acknowldege state across power-gating
528+
* off cycle, add semaphore acquire before invalidation and semaphore
529+
* release after invalidation to avoid entering power gated state
530+
* to WA the Issue
531+
*/
532+
533+
/* TODO: It needs to continue working on debugging with semaphore for GFXHUB as well. */
534+
if (ring->funcs->vmhub == AMDGPU_MMHUB_0 ||
535+
ring->funcs->vmhub == AMDGPU_MMHUB_1)
536+
/* a read return value of 1 means semaphore acuqire */
537+
amdgpu_ring_emit_reg_wait(ring,
538+
hub->vm_inv_eng0_sem + eng, 0x1, 0x1);
539+
492540
amdgpu_ring_emit_wreg(ring, hub->ctx0_ptb_addr_lo32 + (2 * vmid),
493541
lower_32_bits(pd_addr));
494542

@@ -499,6 +547,15 @@ static uint64_t gmc_v9_0_emit_flush_gpu_tlb(struct amdgpu_ring *ring,
499547
hub->vm_inv_eng0_ack + eng,
500548
req, 1 << vmid);
501549

550+
/* TODO: It needs to continue working on debugging with semaphore for GFXHUB as well. */
551+
if (ring->funcs->vmhub == AMDGPU_MMHUB_0 ||
552+
ring->funcs->vmhub == AMDGPU_MMHUB_1)
553+
/*
554+
* add semaphore release after invalidation,
555+
* write with 0 means semaphore release
556+
*/
557+
amdgpu_ring_emit_wreg(ring, hub->vm_inv_eng0_sem + eng, 0);
558+
502559
return pd_addr;
503560
}
504561

drivers/gpu/drm/amd/amdgpu/soc15.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,8 +28,8 @@
2828
#include "nbio_v7_0.h"
2929
#include "nbio_v7_4.h"
3030

31-
#define SOC15_FLUSH_GPU_TLB_NUM_WREG 4
32-
#define SOC15_FLUSH_GPU_TLB_NUM_REG_WAIT 1
31+
#define SOC15_FLUSH_GPU_TLB_NUM_WREG 6
32+
#define SOC15_FLUSH_GPU_TLB_NUM_REG_WAIT 3
3333

3434
extern const struct amd_ip_funcs soc15_common_ip_funcs;
3535

0 commit comments

Comments
 (0)