From 91e1a5207edec9e4f888e44478a9a254186e0ba8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christian=20K=C3=B6nig?= Date: Mon, 6 Jul 2015 22:06:40 +0200 Subject: drm/amdgpu: deal with foreign fences in amdgpu_sync MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This also requires some error handling from the callers of that function. Signed-off-by: Christian König Reviewed-by: Jammy Zhou Reviewed-by: Chunming Zhou --- drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 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 1f040d85ac47..53e6a10fe9f9 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c @@ -482,6 +482,8 @@ 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 fence *f; + /* ignore duplicates */ bo = p->bo_list->array[i].robj; if (!bo) @@ -495,7 +497,10 @@ static int amdgpu_bo_vm_update_pte(struct amdgpu_cs_parser *p, if (r) return r; - amdgpu_sync_fence(&p->ibs[0].sync, bo_va->last_pt_update); + f = &bo_va->last_pt_update->base; + r = amdgpu_sync_fence(adev, &p->ibs[0].sync, f); + if (r) + return r; } } @@ -715,9 +720,12 @@ static int amdgpu_cs_dependencies(struct amdgpu_device *adev, return r; } - amdgpu_sync_fence(&ib->sync, fence); + r = amdgpu_sync_fence(adev, &ib->sync, &fence->base); amdgpu_fence_unref(&fence); amdgpu_ctx_put(ctx); + + if (r) + return r; } } -- cgit v1.2.2 From 21c16bf634e62cf9673946f509b469e7f0953ecf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christian=20K=C3=B6nig?= Date: Tue, 7 Jul 2015 17:24:49 +0200 Subject: drm/amdgpu: add user fence context map v2 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This is a prerequisite for the GPU scheduler to make the order of submission independent from the order of execution. v2: properly implement the locking Signed-off-by: Christian König Reviewed-by: Jammy Zhou Reviewed-by: Chunming Zhou --- drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c | 60 ++++++++++++++++++---------------- 1 file changed, 32 insertions(+), 28 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 53e6a10fe9f9..cef8360698be 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c @@ -698,9 +698,9 @@ static int amdgpu_cs_dependencies(struct amdgpu_device *adev, sizeof(struct drm_amdgpu_cs_chunk_dep); for (j = 0; j < num_deps; ++j) { - struct amdgpu_fence *fence; struct amdgpu_ring *ring; struct amdgpu_ctx *ctx; + struct fence *fence; r = amdgpu_cs_get_ring(adev, deps[j].ip_type, deps[j].ip_instance, @@ -712,20 +712,20 @@ static int amdgpu_cs_dependencies(struct amdgpu_device *adev, if (ctx == NULL) return -EINVAL; - r = amdgpu_fence_recreate(ring, p->filp, - deps[j].handle, - &fence); - if (r) { + fence = amdgpu_ctx_get_fence(ctx, ring, + deps[j].handle); + if (IS_ERR(fence)) { + r = PTR_ERR(fence); amdgpu_ctx_put(ctx); return r; - } - - r = amdgpu_sync_fence(adev, &ib->sync, &fence->base); - amdgpu_fence_unref(&fence); - amdgpu_ctx_put(ctx); - if (r) - return r; + } else if (fence) { + r = amdgpu_sync_fence(adev, &ib->sync, fence); + fence_put(fence); + amdgpu_ctx_put(ctx); + if (r) + return r; + } } } @@ -773,8 +773,11 @@ int amdgpu_cs_ioctl(struct drm_device *dev, void *data, struct drm_file *filp) r = amdgpu_cs_ib_fill(adev, &parser); } - if (!r) + if (!r) { r = amdgpu_cs_dependencies(adev, &parser); + if (r) + DRM_ERROR("Failed in the dependencies handling %d!\n", r); + } if (r) { amdgpu_cs_parser_fini(&parser, r, reserved_buffers); @@ -791,7 +794,7 @@ int amdgpu_cs_ioctl(struct drm_device *dev, void *data, struct drm_file *filp) goto out; } - cs->out.handle = parser.ibs[parser.num_ibs - 1].fence->seq; + cs->out.handle = parser.uf.sequence; out: amdgpu_cs_parser_fini(&parser, r, true); up_read(&adev->exclusive_lock); @@ -814,30 +817,31 @@ int amdgpu_cs_wait_ioctl(struct drm_device *dev, void *data, union drm_amdgpu_wait_cs *wait = data; struct amdgpu_device *adev = dev->dev_private; unsigned long timeout = amdgpu_gem_timeout(wait->in.timeout); - struct amdgpu_fence *fence = NULL; struct amdgpu_ring *ring = NULL; struct amdgpu_ctx *ctx; + struct fence *fence; long r; + r = amdgpu_cs_get_ring(adev, wait->in.ip_type, wait->in.ip_instance, + wait->in.ring, &ring); + if (r) + return r; + ctx = amdgpu_ctx_get(filp->driver_priv, wait->in.ctx_id); if (ctx == NULL) return -EINVAL; - r = amdgpu_cs_get_ring(adev, wait->in.ip_type, wait->in.ip_instance, - wait->in.ring, &ring); - if (r) { - amdgpu_ctx_put(ctx); - return r; - } + fence = amdgpu_ctx_get_fence(ctx, ring, wait->in.handle); + if (IS_ERR(fence)) + r = PTR_ERR(fence); - r = amdgpu_fence_recreate(ring, filp, wait->in.handle, &fence); - if (r) { - amdgpu_ctx_put(ctx); - return r; - } + else if (fence) { + r = fence_wait_timeout(fence, true, timeout); + fence_put(fence); + + } else + r = 1; - r = fence_wait_timeout(&fence->base, true, timeout); - amdgpu_fence_unref(&fence); amdgpu_ctx_put(ctx); if (r < 0) return r; -- cgit v1.2.2 From 5430a3ffb0b1902e8aea4ed2ba256b1263126e8d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christian=20K=C3=B6nig?= Date: Tue, 21 Jul 2015 18:02:21 +0200 Subject: drm/amdgpu: fix UVD/VCE fence handling MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We need to return the sequence number to userspace even when we don't use user fences. Signed-off-by: Christian König Reviewed-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (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 cef8360698be..4794e14976ca 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c @@ -794,7 +794,7 @@ int amdgpu_cs_ioctl(struct drm_device *dev, void *data, struct drm_file *filp) goto out; } - cs->out.handle = parser.uf.sequence; + cs->out.handle = parser.ibs[parser.num_ibs - 1].sequence; out: amdgpu_cs_parser_fini(&parser, r, true); up_read(&adev->exclusive_lock); -- cgit v1.2.2 From e60b344f6c0eff03362b5083db746ef5442c4b36 Mon Sep 17 00:00:00 2001 From: "monk.liu" Date: Fri, 17 Jul 2015 18:39:25 +0800 Subject: drm/amdgpu: optimize amdgpu_parser_init MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit use kmalloc_array instead of kcalloc where appropriate and other cleanups. Signed-off-by: monk.liu Reviewed-by: Christian König --- drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 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 4794e14976ca..bc0a70415485 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c @@ -147,13 +147,13 @@ int amdgpu_cs_parser_init(struct amdgpu_cs_parser *p, void *data) /* get chunks */ INIT_LIST_HEAD(&p->validated); - chunk_array = kcalloc(cs->in.num_chunks, sizeof(uint64_t), GFP_KERNEL); + chunk_array = kmalloc_array(cs->in.num_chunks, sizeof(uint64_t), GFP_KERNEL); if (chunk_array == NULL) { r = -ENOMEM; goto out; } - chunk_array_user = (uint64_t *)(unsigned long)(cs->in.chunks); + chunk_array_user = (uint64_t __user *)(cs->in.chunks); if (copy_from_user(chunk_array, chunk_array_user, sizeof(uint64_t)*cs->in.num_chunks)) { r = -EFAULT; @@ -161,7 +161,7 @@ int amdgpu_cs_parser_init(struct amdgpu_cs_parser *p, void *data) } p->nchunks = cs->in.num_chunks; - p->chunks = kcalloc(p->nchunks, sizeof(struct amdgpu_cs_chunk), + p->chunks = kmalloc_array(p->nchunks, sizeof(struct amdgpu_cs_chunk), GFP_KERNEL); if (p->chunks == NULL) { r = -ENOMEM; @@ -173,7 +173,7 @@ int amdgpu_cs_parser_init(struct amdgpu_cs_parser *p, void *data) struct drm_amdgpu_cs_chunk user_chunk; uint32_t __user *cdata; - chunk_ptr = (void __user *)(unsigned long)chunk_array[i]; + chunk_ptr = (void __user *)chunk_array[i]; if (copy_from_user(&user_chunk, chunk_ptr, sizeof(struct drm_amdgpu_cs_chunk))) { r = -EFAULT; @@ -183,7 +183,7 @@ int amdgpu_cs_parser_init(struct amdgpu_cs_parser *p, void *data) p->chunks[i].length_dw = user_chunk.length_dw; size = p->chunks[i].length_dw; - cdata = (void __user *)(unsigned long)user_chunk.chunk_data; + cdata = (void __user *)user_chunk.chunk_data; p->chunks[i].user_ptr = cdata; p->chunks[i].kdata = drm_malloc_ab(size, sizeof(uint32_t)); @@ -235,11 +235,10 @@ int amdgpu_cs_parser_init(struct amdgpu_cs_parser *p, void *data) } } - p->ibs = kcalloc(p->num_ibs, sizeof(struct amdgpu_ib), GFP_KERNEL); - if (!p->ibs) { + + p->ibs = kmalloc_array(p->num_ibs, sizeof(struct amdgpu_ib), GFP_KERNEL); + if (!p->ibs) r = -ENOMEM; - goto out; - } out: kfree(chunk_array); -- cgit v1.2.2 From 049fc527b4641f99e573b26f1a726a3eadd0cc25 Mon Sep 17 00:00:00 2001 From: Chunming Zhou Date: Tue, 21 Jul 2015 14:36:51 +0800 Subject: drm/amdgpu: dispatch jobs in cs BO validation is moved to scheduler except usrptr which must be validated in user process Signed-off-by: Chunming Zhou Acked-by: Christian K?nig Reviewed-by: Jammy Zhou --- drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c | 256 +++++++++++++++++++++++++-------- 1 file changed, 199 insertions(+), 57 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 bc0a70415485..f9d4fe985668 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c @@ -41,6 +41,11 @@ struct amdgpu_cs_buckets { struct list_head bucket[AMDGPU_CS_NUM_BUCKETS]; }; +static void amdgpu_cs_parser_fini(struct amdgpu_cs_parser *parser, + int error, bool backoff); +static void amdgpu_cs_parser_fini_early(struct amdgpu_cs_parser *parser, int error, bool backoff); +static void amdgpu_cs_parser_fini_late(struct amdgpu_cs_parser *parser); + static void amdgpu_cs_buckets_init(struct amdgpu_cs_buckets *b) { unsigned i; @@ -126,12 +131,52 @@ int amdgpu_cs_get_ring(struct amdgpu_device *adev, u32 ip_type, return 0; } +static void amdgpu_job_work_func(struct work_struct *work) +{ + struct amdgpu_cs_parser *sched_job = + container_of(work, struct amdgpu_cs_parser, + job_work); + mutex_lock(&sched_job->job_lock); + sched_job->free_job(sched_job); + mutex_unlock(&sched_job->job_lock); + /* after processing job, free memory */ + kfree(sched_job); +} +struct amdgpu_cs_parser *amdgpu_cs_parser_create(struct amdgpu_device *adev, + struct drm_file *filp, + struct amdgpu_ctx *ctx, + struct amdgpu_ib *ibs, + uint32_t num_ibs) +{ + struct amdgpu_cs_parser *parser; + int i; + + parser = kzalloc(sizeof(struct amdgpu_cs_parser), GFP_KERNEL); + if (!parser) + return NULL; + + parser->adev = adev; + parser->filp = filp; + parser->ctx = ctx; + parser->ibs = ibs; + parser->num_ibs = num_ibs; + if (amdgpu_enable_scheduler) { + mutex_init(&parser->job_lock); + INIT_WORK(&parser->job_work, amdgpu_job_work_func); + } + for (i = 0; i < num_ibs; i++) + ibs[i].ctx = ctx; + + return parser; +} + int amdgpu_cs_parser_init(struct amdgpu_cs_parser *p, void *data) { union drm_amdgpu_cs *cs = data; uint64_t *chunk_array_user; uint64_t *chunk_array = NULL; struct amdgpu_fpriv *fpriv = p->filp->driver_priv; + struct amdgpu_bo_list *bo_list = NULL; unsigned size, i; int r = 0; @@ -143,7 +188,17 @@ int amdgpu_cs_parser_init(struct amdgpu_cs_parser *p, void *data) r = -EINVAL; goto out; } - p->bo_list = amdgpu_bo_list_get(fpriv, cs->in.bo_list_handle); + bo_list = amdgpu_bo_list_get(fpriv, cs->in.bo_list_handle); + if (bo_list && !bo_list->has_userptr) { + p->bo_list = kzalloc(sizeof(struct amdgpu_bo_list), GFP_KERNEL); + if (!p->bo_list) + return -ENOMEM; + amdgpu_bo_list_copy(p->adev, p->bo_list, bo_list); + amdgpu_bo_list_put(bo_list); + } else if (bo_list && bo_list->has_userptr) + p->bo_list = bo_list; + else + p->bo_list = NULL; /* get chunks */ INIT_LIST_HEAD(&p->validated); @@ -424,8 +479,26 @@ static int cmp_size_smaller_first(void *priv, struct list_head *a, **/ static void amdgpu_cs_parser_fini(struct amdgpu_cs_parser *parser, int error, bool backoff) { - unsigned i; + amdgpu_cs_parser_fini_early(parser, error, backoff); + amdgpu_cs_parser_fini_late(parser); +} +static int amdgpu_cs_parser_run_job( + struct amdgpu_cs_parser *sched_job) +{ + amdgpu_cs_parser_fini_early(sched_job, 0, true); + return 0; +} + +static int amdgpu_cs_parser_free_job( + struct amdgpu_cs_parser *sched_job) +{ + amdgpu_cs_parser_fini_late(sched_job); + return 0; +} + +static void amdgpu_cs_parser_fini_early(struct amdgpu_cs_parser *parser, int error, bool backoff) +{ if (!error) { /* Sort the buffer list from the smallest to largest buffer, * which affects the order of buffers in the LRU list. @@ -446,11 +519,19 @@ static void amdgpu_cs_parser_fini(struct amdgpu_cs_parser *parser, int error, bo ttm_eu_backoff_reservation(&parser->ticket, &parser->validated); } +} +static void amdgpu_cs_parser_fini_late(struct amdgpu_cs_parser *parser) +{ + unsigned i; if (parser->ctx) amdgpu_ctx_put(parser->ctx); - if (parser->bo_list) - amdgpu_bo_list_put(parser->bo_list); + if (parser->bo_list) { + if (!parser->bo_list->has_userptr) + amdgpu_bo_list_free(parser->bo_list); + else + amdgpu_bo_list_put(parser->bo_list); + } drm_free_large(parser->vm_bos); for (i = 0; i < parser->nchunks; i++) drm_free_large(parser->chunks[i].kdata); @@ -461,6 +542,9 @@ static void amdgpu_cs_parser_fini(struct amdgpu_cs_parser *parser, int error, bo kfree(parser->ibs); if (parser->uf.bo) drm_gem_object_unreference_unlocked(&parser->uf.bo->gem_base); + + if (!amdgpu_enable_scheduler) + kfree(parser); } static int amdgpu_bo_vm_update_pte(struct amdgpu_cs_parser *p, @@ -533,9 +617,9 @@ static int amdgpu_cs_ib_vm_chunk(struct amdgpu_device *adev, goto out; } amdgpu_cs_sync_rings(parser); - - r = amdgpu_ib_schedule(adev, parser->num_ibs, parser->ibs, - parser->filp); + if (!amdgpu_enable_scheduler) + r = amdgpu_ib_schedule(adev, parser->num_ibs, parser->ibs, + parser->filp); out: mutex_unlock(&vm->mutex); @@ -731,35 +815,16 @@ static int amdgpu_cs_dependencies(struct amdgpu_device *adev, return 0; } -int amdgpu_cs_ioctl(struct drm_device *dev, void *data, struct drm_file *filp) +static int amdgpu_cs_parser_prepare_job(struct amdgpu_cs_parser *sched_job) { - struct amdgpu_device *adev = dev->dev_private; - 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) { - up_read(&adev->exclusive_lock); - return -EBUSY; - } - /* initialize parser */ - memset(&parser, 0, sizeof(struct amdgpu_cs_parser)); - parser.filp = filp; - parser.adev = adev; - r = amdgpu_cs_parser_init(&parser, data); - if (r) { - DRM_ERROR("Failed to initialize parser !\n"); - amdgpu_cs_parser_fini(&parser, r, false); - up_read(&adev->exclusive_lock); - r = amdgpu_cs_handle_lockup(adev, r); - return r; - } - - r = amdgpu_cs_parser_relocs(&parser); - if (r) { - if (r != -ERESTARTSYS) { + int r, i; + struct amdgpu_cs_parser *parser = sched_job; + struct amdgpu_device *adev = sched_job->adev; + bool reserved_buffers = false; + + r = amdgpu_cs_parser_relocs(parser); + if (r) { + if (r != -ERESTARTSYS) { if (r == -ENOMEM) DRM_ERROR("Not enough memory for command submission!\n"); else @@ -769,33 +834,104 @@ int amdgpu_cs_ioctl(struct drm_device *dev, void *data, struct drm_file *filp) if (!r) { reserved_buffers = true; - r = amdgpu_cs_ib_fill(adev, &parser); + r = amdgpu_cs_ib_fill(adev, parser); } - if (!r) { - r = amdgpu_cs_dependencies(adev, &parser); + r = amdgpu_cs_dependencies(adev, parser); if (r) DRM_ERROR("Failed in the dependencies handling %d!\n", r); } + if (r) { + amdgpu_cs_parser_fini(parser, r, reserved_buffers); + return r; + } + + for (i = 0; i < parser->num_ibs; i++) + trace_amdgpu_cs(parser, i); + + r = amdgpu_cs_ib_vm_chunk(adev, parser); + return r; +} + +static struct amdgpu_ring *amdgpu_cs_parser_get_ring( + struct amdgpu_device *adev, + struct amdgpu_cs_parser *parser) +{ + int i, r; + + struct amdgpu_cs_chunk *chunk; + struct drm_amdgpu_cs_chunk_ib *chunk_ib; + struct amdgpu_ring *ring; + for (i = 0; i < parser->nchunks; i++) { + chunk = &parser->chunks[i]; + chunk_ib = (struct drm_amdgpu_cs_chunk_ib *)chunk->kdata; + + if (chunk->chunk_id != AMDGPU_CHUNK_ID_IB) + continue; + + r = amdgpu_cs_get_ring(adev, chunk_ib->ip_type, + chunk_ib->ip_instance, chunk_ib->ring, + &ring); + if (r) + return NULL; + break; + } + return ring; +} + +int amdgpu_cs_ioctl(struct drm_device *dev, void *data, struct drm_file *filp) +{ + struct amdgpu_device *adev = dev->dev_private; + union drm_amdgpu_cs *cs = data; + struct amdgpu_cs_parser *parser; + int r; + + down_read(&adev->exclusive_lock); + if (!adev->accel_working) { + up_read(&adev->exclusive_lock); + return -EBUSY; + } + parser = amdgpu_cs_parser_create(adev, filp, NULL, NULL, 0); + if (!parser) + return -ENOMEM; + r = amdgpu_cs_parser_init(parser, data); if (r) { - amdgpu_cs_parser_fini(&parser, r, reserved_buffers); + DRM_ERROR("Failed to initialize parser !\n"); + amdgpu_cs_parser_fini(parser, r, false); up_read(&adev->exclusive_lock); r = amdgpu_cs_handle_lockup(adev, r); return r; } - for (i = 0; i < parser.num_ibs; i++) - trace_amdgpu_cs(&parser, i); - - r = amdgpu_cs_ib_vm_chunk(adev, &parser); - if (r) { - goto out; + if (amdgpu_enable_scheduler && parser->num_ibs) { + struct amdgpu_ring * ring = + amdgpu_cs_parser_get_ring(adev, parser); + parser->uf.sequence = atomic64_inc_return( + &parser->ctx->rings[ring->idx].c_entity.last_queued_v_seq); + if ((parser->bo_list && parser->bo_list->has_userptr)) { + r = amdgpu_cs_parser_prepare_job(parser); + if (r) + goto out; + } else + parser->prepare_job = amdgpu_cs_parser_prepare_job; + + parser->run_job = amdgpu_cs_parser_run_job; + parser->free_job = amdgpu_cs_parser_free_job; + amd_sched_push_job(ring->scheduler, + &parser->ctx->rings[ring->idx].c_entity, + parser); + cs->out.handle = parser->uf.sequence; + up_read(&adev->exclusive_lock); + return 0; } + r = amdgpu_cs_parser_prepare_job(parser); + if (r) + goto out; - cs->out.handle = parser.ibs[parser.num_ibs - 1].sequence; + cs->out.handle = parser->ibs[parser->num_ibs - 1].sequence; out: - amdgpu_cs_parser_fini(&parser, r, true); + amdgpu_cs_parser_fini(parser, r, true); up_read(&adev->exclusive_lock); r = amdgpu_cs_handle_lockup(adev, r); return r; @@ -829,18 +965,24 @@ int amdgpu_cs_wait_ioctl(struct drm_device *dev, void *data, ctx = amdgpu_ctx_get(filp->driver_priv, wait->in.ctx_id); if (ctx == NULL) return -EINVAL; - - fence = amdgpu_ctx_get_fence(ctx, ring, wait->in.handle); - if (IS_ERR(fence)) - r = PTR_ERR(fence); - - else if (fence) { - r = fence_wait_timeout(fence, true, timeout); - fence_put(fence); - - } else + if (amdgpu_enable_scheduler) { + r = amd_sched_wait_ts(&ctx->rings[ring->idx].c_entity, + wait->in.handle, true, timeout); + if (r) + return r; r = 1; + } else { + fence = amdgpu_ctx_get_fence(ctx, ring, wait->in.handle); + if (IS_ERR(fence)) + r = PTR_ERR(fence); + else if (fence) { + r = fence_wait_timeout(fence, true, timeout); + fence_put(fence); + + } else + r = 1; + } amdgpu_ctx_put(ctx); if (r < 0) return r; -- cgit v1.2.2 From 4b559c90bc1870313f02cceef680884519af6b2b Mon Sep 17 00:00:00 2001 From: Chunming Zhou Date: Tue, 21 Jul 2015 15:53:04 +0800 Subject: drm/amdgpu: make sure the fence is emitted before ring to get it. Signed-off-by: Chunming Zhou Acked-by: Christian K?nig Reviewed-by: Jammy Zhou --- drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c | 26 +++++++++----------------- 1 file changed, 9 insertions(+), 17 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 f9d4fe985668..5f2403898b06 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c @@ -915,7 +915,7 @@ int amdgpu_cs_ioctl(struct drm_device *dev, void *data, struct drm_file *filp) goto out; } else parser->prepare_job = amdgpu_cs_parser_prepare_job; - + parser->ring = ring; parser->run_job = amdgpu_cs_parser_run_job; parser->free_job = amdgpu_cs_parser_free_job; amd_sched_push_job(ring->scheduler, @@ -965,24 +965,16 @@ int amdgpu_cs_wait_ioctl(struct drm_device *dev, void *data, ctx = amdgpu_ctx_get(filp->driver_priv, wait->in.ctx_id); if (ctx == NULL) return -EINVAL; - if (amdgpu_enable_scheduler) { - r = amd_sched_wait_ts(&ctx->rings[ring->idx].c_entity, - wait->in.handle, true, timeout); - if (r) - return r; - r = 1; - } else { - fence = amdgpu_ctx_get_fence(ctx, ring, wait->in.handle); - if (IS_ERR(fence)) - r = PTR_ERR(fence); - else if (fence) { - r = fence_wait_timeout(fence, true, timeout); - fence_put(fence); + fence = amdgpu_ctx_get_fence(ctx, ring, wait->in.handle); + if (IS_ERR(fence)) + r = PTR_ERR(fence); + else if (fence) { + r = fence_wait_timeout(fence, true, timeout); + fence_put(fence); + } else + r = 1; - } else - r = 1; - } amdgpu_ctx_put(ctx); if (r < 0) return r; -- cgit v1.2.2 From 4274f5d45cf11f88d7380702a7147b70553ddd6e Mon Sep 17 00:00:00 2001 From: Chunming Zhou Date: Tue, 21 Jul 2015 16:04:39 +0800 Subject: drm/amdgpu: prepare job before push to sw queue for pte ring user mode will still use pte ring as a normal ring. if the prepare job generates another command(update pte) on its ring in scheduler, then will kill scheduler which is going to waiting later job but pending running job. Signed-off-by: Chunming Zhou Acked-by: Christian K?nig Reviewed-by: Jammy Zhou --- drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (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 5f2403898b06..9ff4d2756a6f 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c @@ -909,7 +909,7 @@ int amdgpu_cs_ioctl(struct drm_device *dev, void *data, struct drm_file *filp) amdgpu_cs_parser_get_ring(adev, parser); parser->uf.sequence = atomic64_inc_return( &parser->ctx->rings[ring->idx].c_entity.last_queued_v_seq); - if ((parser->bo_list && parser->bo_list->has_userptr)) { + if (ring->is_pte_ring || (parser->bo_list && parser->bo_list->has_userptr)) { r = amdgpu_cs_parser_prepare_job(parser); if (r) goto out; -- cgit v1.2.2 From afe10081498fdf2c5b92c7fcc534e49544218fb9 Mon Sep 17 00:00:00 2001 From: Chunming Zhou Date: Tue, 28 Jul 2015 16:11:52 +0800 Subject: drm/amdgpu: add check for callback it is possible that the callback isn't defined sometimes. Signed-off-by: Chunming Zhou Reviewed-by: Christian K?nig --- drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (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 9ff4d2756a6f..c41360e443be 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c @@ -137,7 +137,8 @@ static void amdgpu_job_work_func(struct work_struct *work) container_of(work, struct amdgpu_cs_parser, job_work); mutex_lock(&sched_job->job_lock); - sched_job->free_job(sched_job); + if (sched_job->free_job) + sched_job->free_job(sched_job); mutex_unlock(&sched_job->job_lock); /* after processing job, free memory */ kfree(sched_job); -- cgit v1.2.2 From d1ff9086c1b8e67390161599006a34056b437a72 Mon Sep 17 00:00:00 2001 From: Chunming Zhou Date: Thu, 30 Jul 2015 17:59:43 +0800 Subject: drm/amdgpu: fix seq in ctx_add_fence if enabling scheduler, then the queued seq is assigned when pushing job before emitting job. Signed-off-by: Chunming Zhou Reviewed-by: Christian K?nig --- drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c | 5 ++--- 1 file changed, 2 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 c41360e443be..40e85bfcdf91 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c @@ -739,7 +739,6 @@ static int amdgpu_cs_ib_fill(struct amdgpu_device *adev, ib->oa_size = amdgpu_bo_size(oa); } } - /* wrap the last IB with user fence */ if (parser->uf.bo) { struct amdgpu_ib *ib = &parser->ibs[parser->num_ibs - 1]; @@ -908,7 +907,7 @@ int amdgpu_cs_ioctl(struct drm_device *dev, void *data, struct drm_file *filp) if (amdgpu_enable_scheduler && parser->num_ibs) { struct amdgpu_ring * ring = amdgpu_cs_parser_get_ring(adev, parser); - parser->uf.sequence = atomic64_inc_return( + parser->ibs[parser->num_ibs - 1].sequence = atomic64_inc_return( &parser->ctx->rings[ring->idx].c_entity.last_queued_v_seq); if (ring->is_pte_ring || (parser->bo_list && parser->bo_list->has_userptr)) { r = amdgpu_cs_parser_prepare_job(parser); @@ -922,7 +921,7 @@ int amdgpu_cs_ioctl(struct drm_device *dev, void *data, struct drm_file *filp) amd_sched_push_job(ring->scheduler, &parser->ctx->rings[ring->idx].c_entity, parser); - cs->out.handle = parser->uf.sequence; + cs->out.handle = parser->ibs[parser->num_ibs - 1].sequence; up_read(&adev->exclusive_lock); return 0; } -- cgit v1.2.2 From 7fc11959018f8ba2d92025679a72339da18a74ad Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christian=20K=C3=B6nig?= Date: Thu, 30 Jul 2015 11:53:42 +0200 Subject: drm/amdgpu: stop using addr to check for BO move v3 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit It is theoretically possible that a swapped out BO gets the same GTT address, but different backing pages while being swapped in. Instead just use another VA state to note updated areas. Ported from not upstream yet radeon commit with the same name. v2: fix some bugs in the original implementation found in the radeon code. v3: squash in VCE/UVD fix Signed-off-by: Christian König Reviewed-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) (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 40e85bfcdf91..fe81b46266d9 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c @@ -1009,7 +1009,16 @@ amdgpu_cs_find_mapping(struct amdgpu_cs_parser *parser, if (!reloc->bo_va) continue; - list_for_each_entry(mapping, &reloc->bo_va->mappings, list) { + list_for_each_entry(mapping, &reloc->bo_va->valids, list) { + if (mapping->it.start > addr || + addr > mapping->it.last) + continue; + + *bo = reloc->bo_va->bo; + return mapping; + } + + list_for_each_entry(mapping, &reloc->bo_va->invalids, list) { if (mapping->it.start > addr || addr > mapping->it.last) continue; -- cgit v1.2.2 From bb1e38a4bead5025ecca90544f0f733f59996b13 Mon Sep 17 00:00:00 2001 From: Chunming Zhou Date: Mon, 3 Aug 2015 18:19:38 +0800 Subject: drm/amdgpu: use kernel fence for last_pt_update Signed-off-by: Chunming Zhou Reviewed-by: Christian K?nig Reviewed-by: Jammy Zhou --- drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (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 fe81b46266d9..aee59110735f 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c @@ -581,7 +581,7 @@ static int amdgpu_bo_vm_update_pte(struct amdgpu_cs_parser *p, if (r) return r; - f = &bo_va->last_pt_update->base; + f = bo_va->last_pt_update; r = amdgpu_sync_fence(adev, &p->ibs[0].sync, f); if (r) return r; -- cgit v1.2.2 From dd01d071957ded58d9bae3d3bf6061ada1d84692 Mon Sep 17 00:00:00 2001 From: Jammy Zhou Date: Thu, 30 Jul 2015 17:19:52 +0800 Subject: drm/amdgpu: some code refinement v2 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fix the code alignment, etc. v2: rebase the code Signed-off-by: Jammy Zhou Reviewed-by: Christian König Reviewed-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 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 aee59110735f..fda7792d9e08 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c @@ -817,14 +817,14 @@ static int amdgpu_cs_dependencies(struct amdgpu_device *adev, static int amdgpu_cs_parser_prepare_job(struct amdgpu_cs_parser *sched_job) { - int r, i; + int r, i; struct amdgpu_cs_parser *parser = sched_job; struct amdgpu_device *adev = sched_job->adev; - bool reserved_buffers = false; + bool reserved_buffers = false; - r = amdgpu_cs_parser_relocs(parser); - if (r) { - if (r != -ERESTARTSYS) { + r = amdgpu_cs_parser_relocs(parser); + if (r) { + if (r != -ERESTARTSYS) { if (r == -ENOMEM) DRM_ERROR("Not enough memory for command submission!\n"); else @@ -841,16 +841,16 @@ static int amdgpu_cs_parser_prepare_job(struct amdgpu_cs_parser *sched_job) if (r) DRM_ERROR("Failed in the dependencies handling %d!\n", r); } - if (r) { - amdgpu_cs_parser_fini(parser, r, reserved_buffers); - return r; - } + if (r) { + amdgpu_cs_parser_fini(parser, r, reserved_buffers); + return r; + } - for (i = 0; i < parser->num_ibs; i++) - trace_amdgpu_cs(parser, i); + for (i = 0; i < parser->num_ibs; i++) + trace_amdgpu_cs(parser, i); - r = amdgpu_cs_ib_vm_chunk(adev, parser); - return r; + r = amdgpu_cs_ib_vm_chunk(adev, parser); + return r; } static struct amdgpu_ring *amdgpu_cs_parser_get_ring( -- cgit v1.2.2 From ea199cc9f825f3ef5aab3db5f00dcc639f8a8b02 Mon Sep 17 00:00:00 2001 From: Jammy Zhou Date: Fri, 31 Jul 2015 16:47:28 +0800 Subject: drm/amdgpu: return new seq_no for amd_sched_push_job MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit It is clean to update last_queued_v_seq in the scheduler module Signed-off-by: Jammy Zhou Reviewed-by: Christian König Reviewed-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c | 5 ++--- 1 file changed, 2 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 fda7792d9e08..468f884271b3 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c @@ -907,8 +907,6 @@ int amdgpu_cs_ioctl(struct drm_device *dev, void *data, struct drm_file *filp) if (amdgpu_enable_scheduler && parser->num_ibs) { struct amdgpu_ring * ring = amdgpu_cs_parser_get_ring(adev, parser); - parser->ibs[parser->num_ibs - 1].sequence = atomic64_inc_return( - &parser->ctx->rings[ring->idx].c_entity.last_queued_v_seq); if (ring->is_pte_ring || (parser->bo_list && parser->bo_list->has_userptr)) { r = amdgpu_cs_parser_prepare_job(parser); if (r) @@ -918,7 +916,8 @@ int amdgpu_cs_ioctl(struct drm_device *dev, void *data, struct drm_file *filp) parser->ring = ring; parser->run_job = amdgpu_cs_parser_run_job; parser->free_job = amdgpu_cs_parser_free_job; - amd_sched_push_job(ring->scheduler, + parser->ibs[parser->num_ibs - 1].sequence = + amd_sched_push_job(ring->scheduler, &parser->ctx->rings[ring->idx].c_entity, parser); cs->out.handle = parser->ibs[parser->num_ibs - 1].sequence; -- cgit v1.2.2 From 351dba73691fc632b269f531bbce80157f79c5b3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christian=20K=C3=B6nig?= Date: Mon, 3 Aug 2015 20:39:12 +0200 Subject: drm/amdgpu: reorder the code to avoid forward declerations MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Christian König Reviewed-by: Chunming Zhou --- drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c | 61 ++++++++++++++++------------------ 1 file changed, 28 insertions(+), 33 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 468f884271b3..d4cc232ccff3 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c @@ -41,11 +41,6 @@ struct amdgpu_cs_buckets { struct list_head bucket[AMDGPU_CS_NUM_BUCKETS]; }; -static void amdgpu_cs_parser_fini(struct amdgpu_cs_parser *parser, - int error, bool backoff); -static void amdgpu_cs_parser_fini_early(struct amdgpu_cs_parser *parser, int error, bool backoff); -static void amdgpu_cs_parser_fini_late(struct amdgpu_cs_parser *parser); - static void amdgpu_cs_buckets_init(struct amdgpu_cs_buckets *b) { unsigned i; @@ -470,34 +465,6 @@ static int cmp_size_smaller_first(void *priv, struct list_head *a, return (int)la->robj->tbo.num_pages - (int)lb->robj->tbo.num_pages; } -/** - * cs_parser_fini() - clean parser states - * @parser: parser structure holding parsing context. - * @error: error number - * - * If error is set than unvalidate buffer, otherwise just free memory - * used by parsing context. - **/ -static void amdgpu_cs_parser_fini(struct amdgpu_cs_parser *parser, int error, bool backoff) -{ - amdgpu_cs_parser_fini_early(parser, error, backoff); - amdgpu_cs_parser_fini_late(parser); -} - -static int amdgpu_cs_parser_run_job( - struct amdgpu_cs_parser *sched_job) -{ - amdgpu_cs_parser_fini_early(sched_job, 0, true); - return 0; -} - -static int amdgpu_cs_parser_free_job( - struct amdgpu_cs_parser *sched_job) -{ - amdgpu_cs_parser_fini_late(sched_job); - return 0; -} - static void amdgpu_cs_parser_fini_early(struct amdgpu_cs_parser *parser, int error, bool backoff) { if (!error) { @@ -548,6 +515,34 @@ static void amdgpu_cs_parser_fini_late(struct amdgpu_cs_parser *parser) kfree(parser); } +/** + * cs_parser_fini() - clean parser states + * @parser: parser structure holding parsing context. + * @error: error number + * + * If error is set than unvalidate buffer, otherwise just free memory + * used by parsing context. + **/ +static void amdgpu_cs_parser_fini(struct amdgpu_cs_parser *parser, int error, bool backoff) +{ + amdgpu_cs_parser_fini_early(parser, error, backoff); + amdgpu_cs_parser_fini_late(parser); +} + +static int amdgpu_cs_parser_run_job( + struct amdgpu_cs_parser *sched_job) +{ + amdgpu_cs_parser_fini_early(sched_job, 0, true); + return 0; +} + +static int amdgpu_cs_parser_free_job( + struct amdgpu_cs_parser *sched_job) +{ + amdgpu_cs_parser_fini_late(sched_job); + return 0; +} + static int amdgpu_bo_vm_update_pte(struct amdgpu_cs_parser *p, struct amdgpu_vm *vm) { -- cgit v1.2.2 From 34cb581a7d99401cad0e1c43b528690885435f5b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christian=20K=C3=B6nig?= Date: Tue, 4 Aug 2015 11:54:48 +0200 Subject: drm/amdgpu: fix bo list handling in CS MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We didn't initialized the mutex in the cloned bo list resulting in nice warnings from lockdep. Also fixes error handling in this function. Signed-off-by: Christian König Reviewed-by: Chunming Zhou --- drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c | 5 ++--- 1 file changed, 2 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 d4cc232ccff3..aa1bc24b7edb 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c @@ -186,11 +186,10 @@ int amdgpu_cs_parser_init(struct amdgpu_cs_parser *p, void *data) } bo_list = amdgpu_bo_list_get(fpriv, cs->in.bo_list_handle); if (bo_list && !bo_list->has_userptr) { - p->bo_list = kzalloc(sizeof(struct amdgpu_bo_list), GFP_KERNEL); + p->bo_list = amdgpu_bo_list_clone(bo_list); + amdgpu_bo_list_put(bo_list); if (!p->bo_list) return -ENOMEM; - amdgpu_bo_list_copy(p->adev, p->bo_list, bo_list); - amdgpu_bo_list_put(bo_list); } else if (bo_list && bo_list->has_userptr) p->bo_list = bo_list; else -- cgit v1.2.2 From 80de5913cf31c86d64547af0715de4822c9b1abe Mon Sep 17 00:00:00 2001 From: Chunming Zhou Date: Wed, 5 Aug 2015 19:07:08 +0800 Subject: Revert "drm/amdgpu: return new seq_no for amd_sched_push_job" This reverts commit d1d33da8eb86b8ca41dd9ed95738030df5267b95. Reviewed-by: Christian K?nig Conflicts: drivers/gpu/drm/amd/amdgpu/amdgpu_sched.c drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c --- drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c | 5 +++-- 1 file changed, 3 insertions(+), 2 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 aa1bc24b7edb..f72a8583b1a9 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c @@ -901,6 +901,8 @@ int amdgpu_cs_ioctl(struct drm_device *dev, void *data, struct drm_file *filp) if (amdgpu_enable_scheduler && parser->num_ibs) { struct amdgpu_ring * ring = amdgpu_cs_parser_get_ring(adev, parser); + parser->ibs[parser->num_ibs - 1].sequence = atomic64_inc_return( + &parser->ctx->rings[ring->idx].c_entity.last_queued_v_seq); if (ring->is_pte_ring || (parser->bo_list && parser->bo_list->has_userptr)) { r = amdgpu_cs_parser_prepare_job(parser); if (r) @@ -910,8 +912,7 @@ int amdgpu_cs_ioctl(struct drm_device *dev, void *data, struct drm_file *filp) parser->ring = ring; parser->run_job = amdgpu_cs_parser_run_job; parser->free_job = amdgpu_cs_parser_free_job; - parser->ibs[parser->num_ibs - 1].sequence = - amd_sched_push_job(ring->scheduler, + amd_sched_push_job(ring->scheduler, &parser->ctx->rings[ring->idx].c_entity, parser); cs->out.handle = parser->ibs[parser->num_ibs - 1].sequence; -- cgit v1.2.2 From 4cd7f42cf8f57512b13a13bb7dcbeabb644f5264 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christian=20K=C3=B6nig?= Date: Wed, 5 Aug 2015 18:18:52 +0200 Subject: drm/amdgpu: fix coding style in a couple of places MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Christian König Reviewed-by: Alex Deucher Reviewed-by: Chunming Zhou --- drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c | 6 ++---- 1 file changed, 2 insertions(+), 4 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 f72a8583b1a9..d26688ddaa20 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c @@ -528,15 +528,13 @@ static void amdgpu_cs_parser_fini(struct amdgpu_cs_parser *parser, int error, bo amdgpu_cs_parser_fini_late(parser); } -static int amdgpu_cs_parser_run_job( - struct amdgpu_cs_parser *sched_job) +static int amdgpu_cs_parser_run_job(struct amdgpu_cs_parser *sched_job) { amdgpu_cs_parser_fini_early(sched_job, 0, true); return 0; } -static int amdgpu_cs_parser_free_job( - struct amdgpu_cs_parser *sched_job) +static int amdgpu_cs_parser_free_job(struct amdgpu_cs_parser *sched_job) { amdgpu_cs_parser_fini_late(sched_job); return 0; -- cgit v1.2.2 From 91404fb20825418fd9ab8e6533bc336e1ffc748e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christian=20K=C3=B6nig?= Date: Wed, 5 Aug 2015 18:33:21 +0200 Subject: drm/amdgpu: merge amd_sched_entity and amd_context_entity v2 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Avoiding a couple of casts. v2: rename c_entity to entity as well Signed-off-by: Christian König Reviewed-by: Chunming Zhou --- drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c | 4 ++-- 1 file changed, 2 insertions(+), 2 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 d26688ddaa20..b1dc7e1ed271 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c @@ -900,7 +900,7 @@ int amdgpu_cs_ioctl(struct drm_device *dev, void *data, struct drm_file *filp) struct amdgpu_ring * ring = amdgpu_cs_parser_get_ring(adev, parser); parser->ibs[parser->num_ibs - 1].sequence = atomic64_inc_return( - &parser->ctx->rings[ring->idx].c_entity.last_queued_v_seq); + &parser->ctx->rings[ring->idx].entity.last_queued_v_seq); if (ring->is_pte_ring || (parser->bo_list && parser->bo_list->has_userptr)) { r = amdgpu_cs_parser_prepare_job(parser); if (r) @@ -911,7 +911,7 @@ int amdgpu_cs_ioctl(struct drm_device *dev, void *data, struct drm_file *filp) parser->run_job = amdgpu_cs_parser_run_job; parser->free_job = amdgpu_cs_parser_free_job; amd_sched_push_job(ring->scheduler, - &parser->ctx->rings[ring->idx].c_entity, + &parser->ctx->rings[ring->idx].entity, parser); cs->out.handle = parser->ibs[parser->num_ibs - 1].sequence; up_read(&adev->exclusive_lock); -- cgit v1.2.2 From f556cb0caeec1ba9b8e5e2aa85b47e76277f5d4b Mon Sep 17 00:00:00 2001 From: Chunming Zhou Date: Sun, 2 Aug 2015 11:18:04 +0800 Subject: drm/amd: add scheduler fence implementation (v2) scheduler fence is based on kernel fence framework. v2: squash in Christian's build fix Signed-off-by: Chunming Zhou Reviewed-by: Christian K?nig --- drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 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 b1dc7e1ed271..f428288d8363 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c @@ -899,8 +899,6 @@ int amdgpu_cs_ioctl(struct drm_device *dev, void *data, struct drm_file *filp) if (amdgpu_enable_scheduler && parser->num_ibs) { struct amdgpu_ring * ring = amdgpu_cs_parser_get_ring(adev, parser); - parser->ibs[parser->num_ibs - 1].sequence = atomic64_inc_return( - &parser->ctx->rings[ring->idx].entity.last_queued_v_seq); if (ring->is_pte_ring || (parser->bo_list && parser->bo_list->has_userptr)) { r = amdgpu_cs_parser_prepare_job(parser); if (r) @@ -910,10 +908,21 @@ int amdgpu_cs_ioctl(struct drm_device *dev, void *data, struct drm_file *filp) parser->ring = ring; parser->run_job = amdgpu_cs_parser_run_job; parser->free_job = amdgpu_cs_parser_free_job; - amd_sched_push_job(ring->scheduler, - &parser->ctx->rings[ring->idx].entity, - parser); - cs->out.handle = parser->ibs[parser->num_ibs - 1].sequence; + mutex_lock(&parser->job_lock); + r = amd_sched_push_job(ring->scheduler, + &parser->ctx->rings[ring->idx].entity, + parser, + &parser->s_fence); + if (r) { + mutex_unlock(&parser->job_lock); + goto out; + } + parser->ibs[parser->num_ibs - 1].sequence = + amdgpu_ctx_add_fence(parser->ctx, ring, + &parser->s_fence->base, + parser->s_fence->v_seq); + cs->out.handle = parser->s_fence->v_seq; + mutex_unlock(&parser->job_lock); up_read(&adev->exclusive_lock); return 0; } -- cgit v1.2.2 From 281b42230175608dec0cd8dab9908250e7aa36a9 Mon Sep 17 00:00:00 2001 From: Chunming Zhou Date: Wed, 12 Aug 2015 12:58:31 +0800 Subject: drm/amdgpu: add reference for **fence fix fence is released when pass to **fence sometimes. add reference for it. Signed-off-by: Chunming Zhou Reviewed-by: Christian K?nig --- drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c | 1 + 1 file changed, 1 insertion(+) (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 f428288d8363..8796938216d6 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c @@ -136,6 +136,7 @@ static void amdgpu_job_work_func(struct work_struct *work) sched_job->free_job(sched_job); mutex_unlock(&sched_job->job_lock); /* after processing job, free memory */ + fence_put(&sched_job->s_fence->base); kfree(sched_job); } struct amdgpu_cs_parser *amdgpu_cs_parser_create(struct amdgpu_device *adev, -- cgit v1.2.2 From 1939e3e265d2fb984b56829c51f5843bfc6d5292 Mon Sep 17 00:00:00 2001 From: "monk.liu" Date: Thu, 13 Aug 2015 16:19:54 +0800 Subject: drm/amdgpu: drop bo_list_clone when no scheduler bo_list_clone() will take a lot of time when bo_list hold too much elements, like above 7000 Signed-off-by: Monk.Liu Reviewed-by: Chunming Zhou Reviewed-by: Jammy Zhou --- drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c | 22 +++++++++++++--------- 1 file changed, 13 insertions(+), 9 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 8796938216d6..07e3380ee0f2 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c @@ -186,15 +186,19 @@ int amdgpu_cs_parser_init(struct amdgpu_cs_parser *p, void *data) goto out; } bo_list = amdgpu_bo_list_get(fpriv, cs->in.bo_list_handle); - if (bo_list && !bo_list->has_userptr) { - p->bo_list = amdgpu_bo_list_clone(bo_list); - amdgpu_bo_list_put(bo_list); - if (!p->bo_list) - return -ENOMEM; - } else if (bo_list && bo_list->has_userptr) + if (!amdgpu_enable_scheduler) p->bo_list = bo_list; - else - p->bo_list = NULL; + else { + if (bo_list && !bo_list->has_userptr) { + p->bo_list = amdgpu_bo_list_clone(bo_list); + amdgpu_bo_list_put(bo_list); + if (!p->bo_list) + return -ENOMEM; + } else if (bo_list && bo_list->has_userptr) + p->bo_list = bo_list; + else + p->bo_list = NULL; + } /* get chunks */ INIT_LIST_HEAD(&p->validated); @@ -495,7 +499,7 @@ static void amdgpu_cs_parser_fini_late(struct amdgpu_cs_parser *parser) if (parser->ctx) amdgpu_ctx_put(parser->ctx); if (parser->bo_list) { - if (!parser->bo_list->has_userptr) + if (amdgpu_enable_scheduler && !parser->bo_list->has_userptr) amdgpu_bo_list_free(parser->bo_list); else amdgpu_bo_list_put(parser->bo_list); -- cgit v1.2.2 From c3b95d4f9e460704e184ded7af60b9c4898f6181 Mon Sep 17 00:00:00 2001 From: Chunming Zhou Date: Fri, 14 Aug 2015 14:55:27 +0800 Subject: drm/amdgpu: move prepare work out of scheduler to cs_ioctl Signed-off-by: Chunming Zhou Reviewed-by: Christian K?nig --- drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c | 21 ++++++++------------- 1 file changed, 8 insertions(+), 13 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 07e3380ee0f2..11edac725210 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c @@ -533,12 +533,6 @@ static void amdgpu_cs_parser_fini(struct amdgpu_cs_parser *parser, int error, bo amdgpu_cs_parser_fini_late(parser); } -static int amdgpu_cs_parser_run_job(struct amdgpu_cs_parser *sched_job) -{ - amdgpu_cs_parser_fini_early(sched_job, 0, true); - return 0; -} - static int amdgpu_cs_parser_free_job(struct amdgpu_cs_parser *sched_job) { amdgpu_cs_parser_fini_late(sched_job); @@ -904,14 +898,10 @@ int amdgpu_cs_ioctl(struct drm_device *dev, void *data, struct drm_file *filp) if (amdgpu_enable_scheduler && parser->num_ibs) { struct amdgpu_ring * ring = amdgpu_cs_parser_get_ring(adev, parser); - if (ring->is_pte_ring || (parser->bo_list && parser->bo_list->has_userptr)) { - r = amdgpu_cs_parser_prepare_job(parser); - if (r) - goto out; - } else - parser->prepare_job = amdgpu_cs_parser_prepare_job; + r = amdgpu_cs_parser_prepare_job(parser); + if (r) + goto out; parser->ring = ring; - parser->run_job = amdgpu_cs_parser_run_job; parser->free_job = amdgpu_cs_parser_free_job; mutex_lock(&parser->job_lock); r = amd_sched_push_job(ring->scheduler, @@ -927,6 +917,11 @@ int amdgpu_cs_ioctl(struct drm_device *dev, void *data, struct drm_file *filp) &parser->s_fence->base, parser->s_fence->v_seq); cs->out.handle = parser->s_fence->v_seq; + list_sort(NULL, &parser->validated, cmp_size_smaller_first); + ttm_eu_fence_buffer_objects(&parser->ticket, + &parser->validated, + &parser->s_fence->base); + mutex_unlock(&parser->job_lock); up_read(&adev->exclusive_lock); return 0; -- cgit v1.2.2 From 05906dec7d7daf197b9b773295c95ad6b9af2a5a Mon Sep 17 00:00:00 2001 From: Bas Nieuwenhuizen Date: Fri, 14 Aug 2015 20:08:40 +0200 Subject: drm/amdgpu: wait on page directory changes. v2 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Pagetables can be moved and therefore the page directory update can be necessary for the current cs even if none of the the bo's are moved. In that scenario there is no fence between the sdma0 and gfx ring, so we add one. v2 (chk): rebased Signed-off-by: Bas Nieuwenhuizen Signed-off-by: Christian König Reviewed-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c | 4 ++++ 1 file changed, 4 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 11edac725210..e4424b4db5d3 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c @@ -551,6 +551,10 @@ static int amdgpu_bo_vm_update_pte(struct amdgpu_cs_parser *p, if (r) return r; + r = amdgpu_sync_fence(adev, &p->ibs[0].sync, vm->page_directory_fence); + if (r) + return r; + r = amdgpu_vm_clear_freed(adev, vm); if (r) return r; -- cgit v1.2.2