winsys/amdgpu: use correct vm_timeline_point for userq creation
doorbell does not require va address mapping from userspace and hence amdgpu_bo_va_op_common() function is not called and therefore doorbell bo->vm_timeline_point is not updated. Currently to wait for all mappings to be ready doorbell vm_timeline_point is used which is incorrect. This patch updates vm_timeline_point to wait for all bos. The bos can be real bo or slab bo. slab bo can be from old buffer and hence there is a check to update vm_timeline_point to wait only if it is new. Reported-by: Zhang, ShanYi (Ken) <ShanYi.Zhang@amd.com> Reviewed-by: Marek Olšák <marek.olsak@amd.com> Reviewed-by: Pierre-Eric Pelloux-Prayer <pierre-eric.pelloux-prayer@amd.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/38059>
This commit is contained in:
committed by
Marge Bot
parent
45affb0e53
commit
53b9389563
@@ -9,8 +9,24 @@
|
||||
#include "ac_linux_drm.h"
|
||||
#include "sid.h"
|
||||
|
||||
static void
|
||||
update_vm_timeline_point_to_wait(uint64_t *vm_timeline_point_to_wait, struct pb_buffer_lean *_buf)
|
||||
{
|
||||
struct amdgpu_winsys_bo *bo = amdgpu_winsys_bo(_buf);
|
||||
struct amdgpu_bo_real *bo_real;
|
||||
|
||||
if (bo->type == AMDGPU_BO_SLAB_ENTRY)
|
||||
bo_real = get_slab_entry_real_bo(bo);
|
||||
else
|
||||
bo_real = get_real_bo(bo);
|
||||
|
||||
if (bo_real->vm_timeline_point > *vm_timeline_point_to_wait)
|
||||
*vm_timeline_point_to_wait = bo_real->vm_timeline_point;
|
||||
}
|
||||
|
||||
static bool
|
||||
amdgpu_userq_ring_init(struct amdgpu_winsys *aws, struct amdgpu_userq *userq)
|
||||
amdgpu_userq_ring_init(struct amdgpu_winsys *aws, struct amdgpu_userq *userq,
|
||||
uint64_t *vm_timeline_point_to_wait)
|
||||
{
|
||||
/* Allocate ring and user fence in one buffer. */
|
||||
uint32_t gtt_bo_size = AMDGPU_USERQ_RING_SIZE + aws->info.gart_page_size;
|
||||
@@ -49,6 +65,7 @@ amdgpu_userq_ring_init(struct amdgpu_winsys *aws, struct amdgpu_userq *userq)
|
||||
if (!userq->rptr_bo)
|
||||
return false;
|
||||
|
||||
update_vm_timeline_point_to_wait(vm_timeline_point_to_wait, userq->rptr_bo);
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -86,6 +103,10 @@ amdgpu_userq_init(struct amdgpu_winsys *aws, struct amdgpu_userq *userq, enum am
|
||||
{
|
||||
int r = -1;
|
||||
uint32_t hw_ip_type;
|
||||
/* The VA page table for ring, rtr, wptr buffer should be ready before job submission so that
|
||||
* the packets submitted can be read by gpu.
|
||||
*/
|
||||
uint64_t vm_timeline_point_to_wait = 0;
|
||||
struct drm_amdgpu_userq_mqd_gfx11 gfx_mqd;
|
||||
struct drm_amdgpu_userq_mqd_compute_gfx11 compute_mqd;
|
||||
struct drm_amdgpu_userq_mqd_sdma_gfx11 sdma_mqd;
|
||||
@@ -99,7 +120,7 @@ amdgpu_userq_init(struct amdgpu_winsys *aws, struct amdgpu_userq *userq, enum am
|
||||
}
|
||||
|
||||
userq->ip_type = ip_type;
|
||||
if (!amdgpu_userq_ring_init(aws, userq))
|
||||
if (!amdgpu_userq_ring_init(aws, userq, &vm_timeline_point_to_wait))
|
||||
goto fail;
|
||||
|
||||
switch (userq->ip_type) {
|
||||
@@ -123,6 +144,8 @@ amdgpu_userq_init(struct amdgpu_winsys *aws, struct amdgpu_userq *userq, enum am
|
||||
gfx_mqd.shadow_va = amdgpu_bo_get_va(userq->gfx_data.shadow_bo);
|
||||
gfx_mqd.csa_va = amdgpu_bo_get_va(userq->gfx_data.csa_bo);
|
||||
mqd = &gfx_mqd;
|
||||
update_vm_timeline_point_to_wait(&vm_timeline_point_to_wait, userq->gfx_data.csa_bo);
|
||||
update_vm_timeline_point_to_wait(&vm_timeline_point_to_wait, userq->gfx_data.shadow_bo);
|
||||
break;
|
||||
case AMD_IP_COMPUTE:
|
||||
hw_ip_type = AMDGPU_HW_IP_COMPUTE;
|
||||
@@ -134,6 +157,7 @@ amdgpu_userq_init(struct amdgpu_winsys *aws, struct amdgpu_userq *userq, enum am
|
||||
|
||||
compute_mqd.eop_va = amdgpu_bo_get_va(userq->compute_data.eop_bo);
|
||||
mqd = &compute_mqd;
|
||||
update_vm_timeline_point_to_wait(&vm_timeline_point_to_wait, userq->compute_data.eop_bo);
|
||||
break;
|
||||
case AMD_IP_SDMA:
|
||||
hw_ip_type = AMDGPU_HW_IP_DMA;
|
||||
@@ -146,6 +170,7 @@ amdgpu_userq_init(struct amdgpu_winsys *aws, struct amdgpu_userq *userq, enum am
|
||||
|
||||
sdma_mqd.csa_va = amdgpu_bo_get_va(userq->sdma_data.csa_bo);
|
||||
mqd = &sdma_mqd;
|
||||
update_vm_timeline_point_to_wait(&vm_timeline_point_to_wait, userq->sdma_data.csa_bo);
|
||||
break;
|
||||
default:
|
||||
fprintf(stderr, "amdgpu: userq unsupported for ip = %d\n", userq->ip_type);
|
||||
@@ -158,21 +183,14 @@ amdgpu_userq_init(struct amdgpu_winsys *aws, struct amdgpu_userq *userq, enum am
|
||||
if (!userq->doorbell_bo)
|
||||
goto fail;
|
||||
|
||||
/* doorbell map should be the last map call, it is used to wait for all mappings before
|
||||
* calling amdgpu_create_userqueue().
|
||||
*/
|
||||
userq->doorbell_bo_map = amdgpu_bo_map(&aws->dummy_sws.base, userq->doorbell_bo, NULL,
|
||||
PIPE_MAP_WRITE | PIPE_MAP_UNSYNCHRONIZED);
|
||||
if (!userq->doorbell_bo_map)
|
||||
goto fail;
|
||||
|
||||
/* The VA page table for ring buffer should be ready before job submission so that the packets
|
||||
* submitted can be read by gpu. The same applies to rptr, wptr buffers also.
|
||||
*/
|
||||
r = ac_drm_cs_syncobj_timeline_wait(aws->dev, &aws->vm_timeline_syncobj,
|
||||
&get_real_bo(amdgpu_winsys_bo(userq->doorbell_bo))
|
||||
->vm_timeline_point,
|
||||
1, INT64_MAX, DRM_SYNCOBJ_WAIT_FLAGS_WAIT_ALL |
|
||||
&vm_timeline_point_to_wait, 1,
|
||||
INT64_MAX, DRM_SYNCOBJ_WAIT_FLAGS_WAIT_ALL |
|
||||
DRM_SYNCOBJ_WAIT_FLAGS_WAIT_FOR_SUBMIT, NULL);
|
||||
if (r) {
|
||||
fprintf(stderr, "amdgpu: waiting for vm fences failed\n");
|
||||
|
||||
Reference in New Issue
Block a user