From 9d248517d4bd807c7690d55d0b6f54618fc60942 Mon Sep 17 00:00:00 2001 From: Christian König Date: Mon, 23 Jul 2018 16:01:39 +0200 Subject: drm/amdgpu: add support for inplace IB patching for MM engines v2 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We are going to need that for the second UVD instance on Vega20. v2: rename to patch_cs_in_place Signed-off-by: Christian König Reviewed-and-tested-by: James Zhu Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c | 22 +++++++++++++++------- 1 file changed, 15 insertions(+), 7 deletions(-) (limited to 'drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c') diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c index 178d9ce4eba1..533b2e7656c0 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c @@ -916,7 +916,7 @@ static int amdgpu_cs_ib_vm_chunk(struct amdgpu_device *adev, int r; /* Only for UVD/VCE VM emulation */ - if (p->ring->funcs->parse_cs) { + if (p->ring->funcs->parse_cs || p->ring->funcs->patch_cs_in_place) { unsigned i, j; for (i = 0, j = 0; i < p->nchunks && j < p->job->num_ibs; i++) { @@ -957,12 +957,20 @@ static int amdgpu_cs_ib_vm_chunk(struct amdgpu_device *adev, offset = m->start * AMDGPU_GPU_PAGE_SIZE; kptr += va_start - offset; - memcpy(ib->ptr, kptr, chunk_ib->ib_bytes); - amdgpu_bo_kunmap(aobj); - - r = amdgpu_ring_parse_cs(ring, p, j); - if (r) - return r; + if (p->ring->funcs->parse_cs) { + memcpy(ib->ptr, kptr, chunk_ib->ib_bytes); + amdgpu_bo_kunmap(aobj); + + r = amdgpu_ring_parse_cs(ring, p, j); + if (r) + return r; + } else { + ib->ptr = (uint32_t *)kptr; + r = amdgpu_ring_patch_cs_in_place(ring, p, j); + amdgpu_bo_kunmap(aobj); + if (r) + return r; + } j++; } -- cgit From 52c054caf83012fe9fe858ee86d90b4ea2cc3cca Mon Sep 17 00:00:00 2001 From: Christian König Date: Fri, 27 Jul 2018 15:32:04 +0200 Subject: drm/amdgpu: add proper error handling to amdgpu_bo_list_get MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Otherwise we silently don't use a BO list when the handle is invalid. Signed-off-by: Christian König Reviewed-by: Chunming Zhou Reviewed-by: Huang Rui Reviewed-by: Michel Dänzer Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) (limited to 'drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c') diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c index 533b2e7656c0..8a49c3b97bd4 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c @@ -572,11 +572,16 @@ static int amdgpu_cs_parser_bos(struct amdgpu_cs_parser *p, INIT_LIST_HEAD(&p->validated); /* p->bo_list could already be assigned if AMDGPU_CHUNK_ID_BO_HANDLES is present */ - if (!p->bo_list) - p->bo_list = amdgpu_bo_list_get(fpriv, cs->in.bo_list_handle); - else + if (p->bo_list) { mutex_lock(&p->bo_list->lock); + } else if (cs->in.bo_list_handle) { + r = amdgpu_bo_list_get(fpriv, cs->in.bo_list_handle, + &p->bo_list); + if (r) + return r; + } + if (p->bo_list) { amdgpu_bo_list_get_list(p->bo_list, &p->validated); if (p->bo_list->first_userptr != p->bo_list->num_entries) -- cgit From 0cb7c1f03bfb3991120313c5927c1749041ef800 Mon Sep 17 00:00:00 2001 From: Christian König Date: Mon, 30 Jul 2018 16:18:54 +0200 Subject: drm/amdgpu: return error if both BOs and bo_list handle is given MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Return -EINVAL when both the BOs as well as a list handle is provided in the IOCTL. Signed-off-by: Christian König Reviewed-by: Chunming Zhou Reviewed-by: Huang Rui Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) (limited to 'drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c') diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c index 8a49c3b97bd4..d41cea78e4aa 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c @@ -572,14 +572,17 @@ static int amdgpu_cs_parser_bos(struct amdgpu_cs_parser *p, INIT_LIST_HEAD(&p->validated); /* p->bo_list could already be assigned if AMDGPU_CHUNK_ID_BO_HANDLES is present */ - if (p->bo_list) { - mutex_lock(&p->bo_list->lock); + if (cs->in.bo_list_handle) { + if (p->bo_list) + return -EINVAL; - } else if (cs->in.bo_list_handle) { r = amdgpu_bo_list_get(fpriv, cs->in.bo_list_handle, &p->bo_list); if (r) return r; + + } else if (p->bo_list) { + mutex_lock(&p->bo_list->lock); } if (p->bo_list) { -- cgit From 8ab19ea619aeed8ca4a36c124e8edfd9b9491aba Mon Sep 17 00:00:00 2001 From: Christian König Date: Fri, 27 Jul 2018 16:56:34 +0200 Subject: drm/amdgpu: add new amdgpu_vm_bo_trace_cs() function v2 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This allows us to trace all VM ranges which should be valid inside a CS. v2: dump mappings without BO as well Signed-off-by: Christian König Reviewed-by: Chunming Zhou Reviewed-and-tested-by: Andrey Grodzovsky (v1) Reviewed-by: Huang Rui (v1) Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c') diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c index d41cea78e4aa..0295666968da 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c @@ -1223,6 +1223,7 @@ static void amdgpu_cs_post_dependencies(struct amdgpu_cs_parser *p) static int amdgpu_cs_submit(struct amdgpu_cs_parser *p, union drm_amdgpu_cs *cs) { + struct amdgpu_fpriv *fpriv = p->filp->driver_priv; struct amdgpu_ring *ring = p->ring; struct drm_sched_entity *entity = &p->ctx->rings[ring->idx].entity; enum drm_sched_priority priority; @@ -1275,6 +1276,7 @@ static int amdgpu_cs_submit(struct amdgpu_cs_parser *p, amdgpu_job_free_resources(job); trace_amdgpu_cs_ioctl(job); + amdgpu_vm_bo_trace_cs(&fpriv->vm, &p->ticket); priority = job->base.s_priority; drm_sched_entity_push_job(&job->base, entity); -- cgit From 81c6dabcc990c341793368db985ee8aca5713b16 Mon Sep 17 00:00:00 2001 From: Christian König Date: Mon, 30 Jul 2018 13:46:04 +0200 Subject: drm/amdgpu: always recreate bo_list MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The bo_list handle is allocated by OP_CREATE, so in OP_UPDATE here we just re-create the bo_list object and replace the handle. This way we don't need locking to protect the bo_list because it's always re-created when changed. Signed-off-by: Christian König Reviewed-by: Chunming Zhou Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c | 3 --- 1 file changed, 3 deletions(-) (limited to 'drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c') diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c index 0295666968da..f7154f3ed807 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c @@ -580,9 +580,6 @@ static int amdgpu_cs_parser_bos(struct amdgpu_cs_parser *p, &p->bo_list); if (r) return r; - - } else if (p->bo_list) { - mutex_lock(&p->bo_list->lock); } if (p->bo_list) { -- cgit From 39f7f69a6054bb9777b47b6afdb5ce2fae30dbee Mon Sep 17 00:00:00 2001 From: Christian König Date: Mon, 30 Jul 2018 15:37:46 +0200 Subject: drm/amdgpu: add bo_list iterators MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add helpers to iterate over all entries in a bo_list. Signed-off-by: Christian König Reviewed-by: Chunming Zhou Acked-by: Huang Rui Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c | 51 +++++++++++++++------------------- 1 file changed, 22 insertions(+), 29 deletions(-) (limited to 'drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c') diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c index f7154f3ed807..1d7292ab2b62 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c @@ -563,10 +563,10 @@ static int amdgpu_cs_parser_bos(struct amdgpu_cs_parser *p, struct amdgpu_fpriv *fpriv = p->filp->driver_priv; struct amdgpu_bo_list_entry *e; struct list_head duplicates; - unsigned i, tries = 10; struct amdgpu_bo *gds; struct amdgpu_bo *gws; struct amdgpu_bo *oa; + unsigned tries = 10; int r; INIT_LIST_HEAD(&p->validated); @@ -596,7 +596,6 @@ static int amdgpu_cs_parser_bos(struct amdgpu_cs_parser *p, while (1) { struct list_head need_pages; - unsigned i; r = ttm_eu_reserve_buffers(&p->ticket, &p->validated, true, &duplicates); @@ -611,12 +610,8 @@ static int amdgpu_cs_parser_bos(struct amdgpu_cs_parser *p, break; INIT_LIST_HEAD(&need_pages); - for (i = p->bo_list->first_userptr; - i < p->bo_list->num_entries; ++i) { - struct amdgpu_bo *bo; - - e = &p->bo_list->array[i]; - bo = e->robj; + amdgpu_bo_list_for_each_userptr_entry(e, p->bo_list) { + struct amdgpu_bo *bo = e->robj; if (amdgpu_ttm_tt_userptr_invalidated(bo->tbo.ttm, &e->user_invalidated) && e->user_pages) { @@ -710,16 +705,14 @@ static int amdgpu_cs_parser_bos(struct amdgpu_cs_parser *p, if (p->bo_list) { struct amdgpu_vm *vm = &fpriv->vm; - unsigned i; + struct amdgpu_bo_list_entry *e; gds = p->bo_list->gds_obj; gws = p->bo_list->gws_obj; oa = p->bo_list->oa_obj; - for (i = 0; i < p->bo_list->num_entries; i++) { - struct amdgpu_bo *bo = p->bo_list->array[i].robj; - p->bo_list->array[i].bo_va = amdgpu_vm_bo_find(vm, bo); - } + amdgpu_bo_list_for_each_entry(e, p->bo_list) + e->bo_va = amdgpu_vm_bo_find(vm, e->robj); } else { gds = p->adev->gds.gds_gfx_bo; gws = p->adev->gds.gws_gfx_bo; @@ -753,10 +746,7 @@ error_validate: error_free_pages: if (p->bo_list) { - for (i = p->bo_list->first_userptr; - i < p->bo_list->num_entries; ++i) { - e = &p->bo_list->array[i]; - + amdgpu_bo_list_for_each_userptr_entry(e, p->bo_list) { if (!e->user_pages) continue; @@ -830,7 +820,7 @@ static int amdgpu_bo_vm_update_pte(struct amdgpu_cs_parser *p) struct amdgpu_vm *vm = &fpriv->vm; struct amdgpu_bo_va *bo_va; struct amdgpu_bo *bo; - int i, r; + int r; r = amdgpu_vm_clear_freed(adev, vm, NULL); if (r) @@ -861,15 +851,17 @@ static int amdgpu_bo_vm_update_pte(struct amdgpu_cs_parser *p) } if (p->bo_list) { - for (i = 0; i < p->bo_list->num_entries; i++) { + struct amdgpu_bo_list_entry *e; + + amdgpu_bo_list_for_each_entry(e, p->bo_list) { struct dma_fence *f; /* ignore duplicates */ - bo = p->bo_list->array[i].robj; + bo = e->robj; if (!bo) continue; - bo_va = p->bo_list->array[i].bo_va; + bo_va = e->bo_va; if (bo_va == NULL) continue; @@ -898,14 +890,15 @@ static int amdgpu_bo_vm_update_pte(struct amdgpu_cs_parser *p) return r; if (amdgpu_vm_debug && p->bo_list) { + struct amdgpu_bo_list_entry *e; + /* Invalidate all BOs to test for userspace bugs */ - for (i = 0; i < p->bo_list->num_entries; i++) { + amdgpu_bo_list_for_each_entry(e, p->bo_list) { /* ignore duplicates */ - bo = p->bo_list->array[i].robj; - if (!bo) + if (!e->robj) continue; - amdgpu_vm_bo_invalidate(adev, bo, false); + amdgpu_vm_bo_invalidate(adev, e->robj, false); } } @@ -1225,16 +1218,16 @@ static int amdgpu_cs_submit(struct amdgpu_cs_parser *p, struct drm_sched_entity *entity = &p->ctx->rings[ring->idx].entity; enum drm_sched_priority priority; struct amdgpu_job *job; - unsigned i; uint64_t seq; int r; amdgpu_mn_lock(p->mn); if (p->bo_list) { - for (i = p->bo_list->first_userptr; - i < p->bo_list->num_entries; ++i) { - struct amdgpu_bo *bo = p->bo_list->array[i].robj; + struct amdgpu_bo_list_entry *e; + + amdgpu_bo_list_for_each_userptr_entry(e, p->bo_list) { + struct amdgpu_bo *bo = e->robj; if (amdgpu_ttm_tt_userptr_needs_pages(bo->tbo.ttm)) { amdgpu_mn_unlock(p->mn); -- cgit From 4a102ad4ba0daf886dcf0927ce2a7f6c3b3a615c Mon Sep 17 00:00:00 2001 From: Christian König Date: Mon, 30 Jul 2018 16:44:14 +0200 Subject: drm/amdgpu: create an empty bo_list if no handle is provided MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Instead of having extra handling just create an empty bo_list when no handle is provided. Signed-off-by: Christian König Reviewed-by: Chunming Zhou Reviewed-by: Huang Rui Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c | 111 ++++++++++++++------------------- 1 file changed, 46 insertions(+), 65 deletions(-) (limited to 'drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c') diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c index 1d7292ab2b62..502b94fb116a 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c @@ -561,6 +561,7 @@ static int amdgpu_cs_parser_bos(struct amdgpu_cs_parser *p, union drm_amdgpu_cs *cs) { struct amdgpu_fpriv *fpriv = p->filp->driver_priv; + struct amdgpu_vm *vm = &fpriv->vm; struct amdgpu_bo_list_entry *e; struct list_head duplicates; struct amdgpu_bo *gds; @@ -580,13 +581,17 @@ static int amdgpu_cs_parser_bos(struct amdgpu_cs_parser *p, &p->bo_list); if (r) return r; + } else if (!p->bo_list) { + /* Create a empty bo_list when no handle is provided */ + r = amdgpu_bo_list_create(p->adev, p->filp, NULL, 0, + &p->bo_list); + if (r) + return r; } - if (p->bo_list) { - amdgpu_bo_list_get_list(p->bo_list, &p->validated); - if (p->bo_list->first_userptr != p->bo_list->num_entries) - p->mn = amdgpu_mn_get(p->adev, AMDGPU_MN_TYPE_GFX); - } + amdgpu_bo_list_get_list(p->bo_list, &p->validated); + if (p->bo_list->first_userptr != p->bo_list->num_entries) + p->mn = amdgpu_mn_get(p->adev, AMDGPU_MN_TYPE_GFX); INIT_LIST_HEAD(&duplicates); amdgpu_vm_get_pd_bo(&fpriv->vm, &p->validated, &p->vm_pd); @@ -605,10 +610,6 @@ static int amdgpu_cs_parser_bos(struct amdgpu_cs_parser *p, goto error_free_pages; } - /* Without a BO list we don't have userptr BOs */ - if (!p->bo_list) - break; - INIT_LIST_HEAD(&need_pages); amdgpu_bo_list_for_each_userptr_entry(e, p->bo_list) { struct amdgpu_bo *bo = e->robj; @@ -703,21 +704,12 @@ static int amdgpu_cs_parser_bos(struct amdgpu_cs_parser *p, amdgpu_cs_report_moved_bytes(p->adev, p->bytes_moved, p->bytes_moved_vis); - if (p->bo_list) { - struct amdgpu_vm *vm = &fpriv->vm; - struct amdgpu_bo_list_entry *e; + gds = p->bo_list->gds_obj; + gws = p->bo_list->gws_obj; + oa = p->bo_list->oa_obj; - gds = p->bo_list->gds_obj; - gws = p->bo_list->gws_obj; - oa = p->bo_list->oa_obj; - - amdgpu_bo_list_for_each_entry(e, p->bo_list) - e->bo_va = amdgpu_vm_bo_find(vm, e->robj); - } else { - gds = p->adev->gds.gds_gfx_bo; - gws = p->adev->gds.gws_gfx_bo; - oa = p->adev->gds.oa_gfx_bo; - } + amdgpu_bo_list_for_each_entry(e, p->bo_list) + e->bo_va = amdgpu_vm_bo_find(vm, e->robj); if (gds) { p->job->gds_base = amdgpu_bo_gpu_offset(gds); @@ -745,15 +737,13 @@ error_validate: error_free_pages: - if (p->bo_list) { - amdgpu_bo_list_for_each_userptr_entry(e, p->bo_list) { - if (!e->user_pages) - continue; + amdgpu_bo_list_for_each_userptr_entry(e, p->bo_list) { + if (!e->user_pages) + continue; - release_pages(e->user_pages, - e->robj->tbo.ttm->num_pages); - kvfree(e->user_pages); - } + release_pages(e->user_pages, + e->robj->tbo.ttm->num_pages); + kvfree(e->user_pages); } return r; @@ -815,9 +805,10 @@ static void amdgpu_cs_parser_fini(struct amdgpu_cs_parser *parser, int error, static int amdgpu_bo_vm_update_pte(struct amdgpu_cs_parser *p) { - struct amdgpu_device *adev = p->adev; struct amdgpu_fpriv *fpriv = p->filp->driver_priv; + struct amdgpu_device *adev = p->adev; struct amdgpu_vm *vm = &fpriv->vm; + struct amdgpu_bo_list_entry *e; struct amdgpu_bo_va *bo_va; struct amdgpu_bo *bo; int r; @@ -850,31 +841,26 @@ static int amdgpu_bo_vm_update_pte(struct amdgpu_cs_parser *p) return r; } - if (p->bo_list) { - struct amdgpu_bo_list_entry *e; - - amdgpu_bo_list_for_each_entry(e, p->bo_list) { - struct dma_fence *f; - - /* ignore duplicates */ - bo = e->robj; - if (!bo) - continue; + amdgpu_bo_list_for_each_entry(e, p->bo_list) { + struct dma_fence *f; - bo_va = e->bo_va; - if (bo_va == NULL) - continue; + /* ignore duplicates */ + bo = e->robj; + if (!bo) + continue; - r = amdgpu_vm_bo_update(adev, bo_va, false); - if (r) - return r; + bo_va = e->bo_va; + if (bo_va == NULL) + continue; - f = bo_va->last_pt_update; - r = amdgpu_sync_fence(adev, &p->job->sync, f, false); - if (r) - return r; - } + r = amdgpu_vm_bo_update(adev, bo_va, false); + if (r) + return r; + f = bo_va->last_pt_update; + r = amdgpu_sync_fence(adev, &p->job->sync, f, false); + if (r) + return r; } r = amdgpu_vm_handle_moved(adev, vm); @@ -889,9 +875,7 @@ static int amdgpu_bo_vm_update_pte(struct amdgpu_cs_parser *p) if (r) return r; - if (amdgpu_vm_debug && p->bo_list) { - struct amdgpu_bo_list_entry *e; - + if (amdgpu_vm_debug) { /* Invalidate all BOs to test for userspace bugs */ amdgpu_bo_list_for_each_entry(e, p->bo_list) { /* ignore duplicates */ @@ -1217,22 +1201,19 @@ static int amdgpu_cs_submit(struct amdgpu_cs_parser *p, struct amdgpu_ring *ring = p->ring; struct drm_sched_entity *entity = &p->ctx->rings[ring->idx].entity; enum drm_sched_priority priority; + struct amdgpu_bo_list_entry *e; struct amdgpu_job *job; uint64_t seq; int r; amdgpu_mn_lock(p->mn); - if (p->bo_list) { - struct amdgpu_bo_list_entry *e; + amdgpu_bo_list_for_each_userptr_entry(e, p->bo_list) { + struct amdgpu_bo *bo = e->robj; - amdgpu_bo_list_for_each_userptr_entry(e, p->bo_list) { - struct amdgpu_bo *bo = e->robj; - - if (amdgpu_ttm_tt_userptr_needs_pages(bo->tbo.ttm)) { - amdgpu_mn_unlock(p->mn); - return -ERESTARTSYS; - } + if (amdgpu_ttm_tt_userptr_needs_pages(bo->tbo.ttm)) { + amdgpu_mn_unlock(p->mn); + return -ERESTARTSYS; } } -- cgit