From 3ccec53c294cbec2af44b6b24f70349637c45428 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Marek=20Ol=C5=A1=C3=A1k?= Date: Tue, 2 Jun 2015 17:44:49 +0200 Subject: [PATCH] drm/amdgpu: only support IBs in the buffer list (v2) MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit amdgpu_cs_find_mapping doesn't work without all buffers being validated, so the TTM validation must be done first. v2: only use amdgpu_cs_find_mapping for UVD/VCE VM emulation Signed-off-by: Marek Olšák Reviewed-by: Christian König --- drivers/gpu/drm/amd/amdgpu/amdgpu.h | 1 - drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c | 95 +++++++------------------- include/uapi/drm/amdgpu_drm.h | 6 +- 3 files changed, 25 insertions(+), 77 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h b/drivers/gpu/drm/amd/amdgpu/amdgpu.h index 149b76913091..c33c1af36fa2 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h @@ -1191,7 +1191,6 @@ struct amdgpu_cs_parser { struct amdgpu_cs_chunk *chunks; /* relocations */ struct amdgpu_bo_list_entry *vm_bos; - struct amdgpu_bo_list_entry *ib_bos; struct list_head validated; struct amdgpu_ib *ibs; diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c index fefa48a59a7d..f6b224a69b3a 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c @@ -230,11 +230,6 @@ int amdgpu_cs_parser_init(struct amdgpu_cs_parser *p, void *data) goto out; } - p->ib_bos = kcalloc(p->num_ibs, sizeof(struct amdgpu_bo_list_entry), - GFP_KERNEL); - if (!p->ib_bos) - r = -ENOMEM; - out: kfree(chunk_array); return r; @@ -373,13 +368,6 @@ static int amdgpu_cs_parser_relocs(struct amdgpu_cs_parser *p) p->vm_bos = amdgpu_vm_get_bos(p->adev, &fpriv->vm, &p->validated); - for (i = 0; i < p->num_ibs; i++) { - if (!p->ib_bos[i].robj) - continue; - - list_add(&p->ib_bos[i].tv.head, &p->validated); - } - if (need_mmap_lock) down_read(¤t->mm->mmap_sem); @@ -457,15 +445,9 @@ static void amdgpu_cs_parser_fini(struct amdgpu_cs_parser *parser, int error, bo for (i = 0; i < parser->nchunks; i++) drm_free_large(parser->chunks[i].kdata); kfree(parser->chunks); - for (i = 0; i < parser->num_ibs; i++) { - struct amdgpu_bo *bo = parser->ib_bos[i].robj; + for (i = 0; i < parser->num_ibs; i++) amdgpu_ib_free(parser->adev, &parser->ibs[i]); - - if (bo) - drm_gem_object_unreference_unlocked(&bo->gem_base); - } kfree(parser->ibs); - kfree(parser->ib_bos); if (parser->uf.bo) drm_gem_object_unreference_unlocked(&parser->uf.bo->gem_base); } @@ -505,21 +487,6 @@ static int amdgpu_bo_vm_update_pte(struct amdgpu_cs_parser *p, } } - for (i = 0; i < p->num_ibs; i++) { - bo = p->ib_bos[i].robj; - if (!bo) - continue; - - bo_va = p->ib_bos[i].bo_va; - if (!bo_va) - continue; - - r = amdgpu_vm_bo_update(adev, bo_va, &bo->tbo.mem); - if (r) - return r; - - amdgpu_sync_fence(&p->ibs[0].sync, bo_va->last_pt_update); - } return amdgpu_vm_clear_invalids(adev, vm, &p->ibs[0].sync); } @@ -581,11 +548,7 @@ static int amdgpu_cs_ib_fill(struct amdgpu_device *adev, struct amdgpu_cs_chunk *chunk; struct amdgpu_ib *ib; struct drm_amdgpu_cs_chunk_ib *chunk_ib; - struct amdgpu_bo_list_entry *ib_bo; struct amdgpu_ring *ring; - struct drm_gem_object *gobj; - struct amdgpu_bo *aobj; - void *kptr; chunk = &parser->chunks[i]; ib = &parser->ibs[j]; @@ -594,66 +557,49 @@ static int amdgpu_cs_ib_fill(struct amdgpu_device *adev, if (chunk->chunk_id != AMDGPU_CHUNK_ID_IB) continue; - gobj = drm_gem_object_lookup(adev->ddev, parser->filp, chunk_ib->handle); - if (gobj == NULL) - return -ENOENT; - aobj = gem_to_amdgpu_bo(gobj); - r = amdgpu_cs_get_ring(adev, chunk_ib->ip_type, chunk_ib->ip_instance, chunk_ib->ring, &ring); - if (r) { - drm_gem_object_unreference_unlocked(gobj); + if (r) return r; - } if (ring->funcs->parse_cs) { - r = amdgpu_bo_reserve(aobj, false); - if (r) { - drm_gem_object_unreference_unlocked(gobj); - return r; + struct amdgpu_bo *aobj = NULL; + void *kptr; + + amdgpu_cs_find_mapping(parser, chunk_ib->va_start, &aobj); + if (!aobj) { + DRM_ERROR("IB va_start is invalid\n"); + return -EINVAL; } + /* the IB should be reserved at this point */ r = amdgpu_bo_kmap(aobj, &kptr); if (r) { - amdgpu_bo_unreserve(aobj); - drm_gem_object_unreference_unlocked(gobj); return r; } r = amdgpu_ib_get(ring, NULL, chunk_ib->ib_bytes, ib); if (r) { DRM_ERROR("Failed to get ib !\n"); - amdgpu_bo_unreserve(aobj); - drm_gem_object_unreference_unlocked(gobj); return r; } memcpy(ib->ptr, kptr, chunk_ib->ib_bytes); amdgpu_bo_kunmap(aobj); - amdgpu_bo_unreserve(aobj); } else { r = amdgpu_ib_get(ring, vm, 0, ib); if (r) { DRM_ERROR("Failed to get ib !\n"); - drm_gem_object_unreference_unlocked(gobj); return r; } ib->gpu_addr = chunk_ib->va_start; } - ib->length_dw = chunk_ib->ib_bytes / 4; + ib->length_dw = chunk_ib->ib_bytes / 4; ib->flags = chunk_ib->flags; ib->ctx = parser->ctx; - - ib_bo = &parser->ib_bos[j]; - ib_bo->robj = aobj; - ib_bo->prefered_domains = aobj->initial_domain; - ib_bo->allowed_domains = aobj->initial_domain; - ib_bo->priority = 0; - ib_bo->tv.bo = &aobj->tbo; - ib_bo->tv.shared = true; j++; } @@ -702,6 +648,7 @@ int amdgpu_cs_ioctl(struct drm_device *dev, void *data, struct drm_file *filp) union drm_amdgpu_cs *cs = data; struct amdgpu_cs_parser parser; int r, i; + bool reserved_buffers = false; down_read(&adev->exclusive_lock); if (!adev->accel_working) { @@ -721,15 +668,21 @@ int amdgpu_cs_ioctl(struct drm_device *dev, void *data, struct drm_file *filp) return r; } - r = amdgpu_cs_ib_fill(adev, &parser); - if (!r) { - r = amdgpu_cs_parser_relocs(&parser); - if (r && r != -ERESTARTSYS) - DRM_ERROR("Failed to parse relocation %d!\n", r); + r = amdgpu_cs_parser_relocs(&parser); + if (r) { + if (r != -ERESTARTSYS) { + if (r == -ENOMEM) + DRM_ERROR("Not enough memory for command submission!\n"); + else + DRM_ERROR("Failed to process the buffer list %d!\n", r); + } + } else { + reserved_buffers = true; + r = amdgpu_cs_ib_fill(adev, &parser); } if (r) { - amdgpu_cs_parser_fini(&parser, r, false); + amdgpu_cs_parser_fini(&parser, r, reserved_buffers); up_read(&adev->exclusive_lock); r = amdgpu_cs_handle_lockup(adev, r); return r; diff --git a/include/uapi/drm/amdgpu_drm.h b/include/uapi/drm/amdgpu_drm.h index c90f4f0d059e..780a5815fb12 100644 --- a/include/uapi/drm/amdgpu_drm.h +++ b/include/uapi/drm/amdgpu_drm.h @@ -378,11 +378,7 @@ union drm_amdgpu_cs { #define AMDGPU_IB_FLAG_PREAMBLE (1<<2) struct drm_amdgpu_cs_chunk_ib { - /** - * Handle of GEM object to be used as IB or 0 if it is already in - * residency list. - */ - uint32_t handle; + uint32_t _pad; uint32_t flags; /* IB Flags */ uint64_t va_start; /* Virtual address to begin IB execution */ uint32_t ib_bytes; /* Size of submission */ -- 2.39.2