diff options
Diffstat (limited to 'common/recipes-kernel/linux/files/0273-drm-amdgpu-add-proper-job-alloc-free-functions.patch')
-rw-r--r-- | common/recipes-kernel/linux/files/0273-drm-amdgpu-add-proper-job-alloc-free-functions.patch | 362 |
1 files changed, 362 insertions, 0 deletions
diff --git a/common/recipes-kernel/linux/files/0273-drm-amdgpu-add-proper-job-alloc-free-functions.patch b/common/recipes-kernel/linux/files/0273-drm-amdgpu-add-proper-job-alloc-free-functions.patch new file mode 100644 index 00000000..fa77af5d --- /dev/null +++ b/common/recipes-kernel/linux/files/0273-drm-amdgpu-add-proper-job-alloc-free-functions.patch @@ -0,0 +1,362 @@ +From 6a50fb95f903bb73e062477399a1170de608c35c Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Christian=20K=C3=B6nig?= <christian.koenig@amd.com> +Date: Wed, 3 Feb 2016 13:44:52 +0100 +Subject: [PATCH 0273/1110] drm/amdgpu: add proper job alloc/free functions +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +And use them in the CS instead of allocating IBs and jobs separately. + +Signed-off-by: Christian König <christian.koenig@amd.com> +Reviewed-by: Alex Deucher <alexander.deucer@amd.com> +Signed-off-by: Alex Deucher <alexander.deucher@amd.com> +Signed-off-by: Kalyan Alle <kalyan.alle@amd.com> +--- + drivers/gpu/drm/amd/amdgpu/amdgpu.h | 14 ++++--- + drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c | 63 +++++++++++-------------------- + drivers/gpu/drm/amd/amdgpu/amdgpu_sched.c | 33 ++++++++++++++++ + drivers/gpu/drm/amd/amdgpu/amdgpu_trace.h | 4 +- + drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.c | 6 +-- + drivers/gpu/drm/amd/amdgpu/amdgpu_vce.c | 2 +- + 6 files changed, 69 insertions(+), 53 deletions(-) + +diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h b/drivers/gpu/drm/amd/amdgpu/amdgpu.h +index e4f6069..1dbd2d7 100644 +--- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h ++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h +@@ -755,7 +755,9 @@ enum amdgpu_ring_type { + }; + + extern struct amd_sched_backend_ops amdgpu_sched_ops; +- ++int amdgpu_job_alloc(struct amdgpu_device *adev, unsigned num_ibs, ++ struct amdgpu_job **job); ++void amdgpu_job_free(struct amdgpu_job *job); + int amdgpu_sched_ib_submit_kernel_helper(struct amdgpu_device *adev, + struct amdgpu_ring *ring, + struct amdgpu_ib *ibs, +@@ -1181,9 +1183,9 @@ struct amdgpu_cs_parser { + /* chunks */ + unsigned nchunks; + struct amdgpu_cs_chunk *chunks; +- /* indirect buffers */ +- uint32_t num_ibs; +- struct amdgpu_ib *ibs; ++ ++ /* scheduler job object */ ++ struct amdgpu_job *job; + + /* buffer objects */ + struct ww_acquire_ctx ticket; +@@ -1214,14 +1216,14 @@ struct amdgpu_job { + static inline u32 amdgpu_get_ib_value(struct amdgpu_cs_parser *p, + uint32_t ib_idx, int idx) + { +- return p->ibs[ib_idx].ptr[idx]; ++ return p->job->ibs[ib_idx].ptr[idx]; + } + + static inline void amdgpu_set_ib_value(struct amdgpu_cs_parser *p, + uint32_t ib_idx, int idx, + uint32_t value) + { +- p->ibs[ib_idx].ptr[idx] = value; ++ p->job->ibs[ib_idx].ptr[idx] = value; + } + + /* +diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c +index 58e115a..f1fd4ed 100644 +--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c ++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c +@@ -163,6 +163,7 @@ int amdgpu_cs_parser_init(struct amdgpu_cs_parser *p, void *data) + uint64_t *chunk_array; + struct amdgpu_fpriv *fpriv = p->filp->driver_priv; + unsigned size; ++ unsigned size, num_ibs = 0; + int i; + int ret; + +@@ -255,16 +256,9 @@ int amdgpu_cs_parser_init(struct amdgpu_cs_parser *p, void *data) + } + } + +- if (p->num_ibs == 0) { +- ret = -EINVAL; ++ ret = amdgpu_job_alloc(p->adev, num_ibs, &p->job); ++ if (ret) + goto free_all_kdata; +- } +- +- p->ibs = kcalloc(p->num_ibs, sizeof(struct amdgpu_ib), GFP_KERNEL); +- if (!p->ibs) { +- ret = -ENOMEM; +- goto free_all_kdata; +- } + + kfree(chunk_array); + return 0; +@@ -460,7 +454,7 @@ static int amdgpu_cs_sync_rings(struct amdgpu_cs_parser *p) + + list_for_each_entry(e, &p->validated, tv.head) { + struct reservation_object *resv = e->robj->tbo.resv; +- r = amdgpu_sync_resv(p->adev, &p->ibs[0].sync, resv, p->filp); ++ r = amdgpu_sync_resv(p->adev, &p->job->ibs[0].sync, resv, p->filp); + + if (r) + return r; +@@ -520,10 +514,8 @@ 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); +- if (parser->ibs) +- for (i = 0; i < parser->num_ibs; i++) +- amdgpu_ib_free(parser->adev, &parser->ibs[i]); +- kfree(parser->ibs); ++ if (parser->job) ++ amdgpu_job_free(parser->job); + amdgpu_bo_unref(&parser->uf.bo); + amdgpu_bo_unref(&parser->uf_entry.robj); + } +@@ -540,7 +532,7 @@ 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); ++ r = amdgpu_sync_fence(adev, &p->job->ibs[0].sync, vm->page_directory_fence); + if (r) + return r; + +@@ -566,14 +558,14 @@ static int amdgpu_bo_vm_update_pte(struct amdgpu_cs_parser *p, + return r; + + f = bo_va->last_pt_update; +- r = amdgpu_sync_fence(adev, &p->ibs[0].sync, f); ++ r = amdgpu_sync_fence(adev, &p->job->ibs[0].sync, f); + if (r) + return r; + } + + } + +- r = amdgpu_vm_clear_invalids(adev, vm, &p->ibs[0].sync); ++ r = amdgpu_vm_clear_invalids(adev, vm, &p->job->ibs[0].sync); + + if (amdgpu_vm_debug && p->bo_list) { + /* Invalidate all BOs to test for userspace bugs */ +@@ -599,8 +591,8 @@ static int amdgpu_cs_ib_vm_chunk(struct amdgpu_device *adev, + int i, r; + + /* Only for UVD/VCE VM emulation */ +- for (i = 0; i < parser->num_ibs; i++) { +- ring = parser->ibs[i].ring; ++ for (i = 0; i < parser->job->num_ibs; i++) { ++ ring = parser->job->ibs[i].ring; + if (ring->funcs->parse_cs) { + r = amdgpu_ring_parse_cs(ring, parser, i); + if (r) +@@ -633,14 +625,14 @@ static int amdgpu_cs_ib_fill(struct amdgpu_device *adev, + int i, j; + int r; + +- for (i = 0, j = 0; i < parser->nchunks && j < parser->num_ibs; i++) { ++ for (i = 0, j = 0; i < parser->nchunks && j < parser->job->num_ibs; i++) { + struct amdgpu_cs_chunk *chunk; + struct amdgpu_ib *ib; + struct drm_amdgpu_cs_chunk_ib *chunk_ib; + struct amdgpu_ring *ring; + + chunk = &parser->chunks[i]; +- ib = &parser->ibs[j]; ++ ib = &parser->job->ibs[j]; + chunk_ib = (struct drm_amdgpu_cs_chunk_ib *)chunk->kdata; + + if (chunk->chunk_id != AMDGPU_CHUNK_ID_IB) +@@ -709,7 +701,7 @@ static int amdgpu_cs_ib_fill(struct amdgpu_device *adev, + struct amdgpu_bo *gds = parser->bo_list->gds_obj; + struct amdgpu_bo *gws = parser->bo_list->gws_obj; + struct amdgpu_bo *oa = parser->bo_list->oa_obj; +- struct amdgpu_ib *ib = &parser->ibs[0]; ++ struct amdgpu_ib *ib = &parser->job->ibs[0]; + + if (gds) { + ib->gds_base = amdgpu_bo_gpu_offset(gds); +@@ -726,7 +718,7 @@ static int amdgpu_cs_ib_fill(struct amdgpu_device *adev, + } + /* wrap the last IB with user fence */ + if (parser->uf.bo) { +- struct amdgpu_ib *ib = &parser->ibs[parser->num_ibs - 1]; ++ struct amdgpu_ib *ib = &parser->job->ibs[parser->job->num_ibs - 1]; + + /* UVD & VCE fw doesn't support user fences */ + if (ib->ring->type == AMDGPU_RING_TYPE_UVD || +@@ -747,7 +739,7 @@ static int amdgpu_cs_dependencies(struct amdgpu_device *adev, + int i, j, r; + + /* Add dependencies to first IB */ +- ib = &p->ibs[0]; ++ ib = &p->job->ibs[0]; + for (i = 0; i < p->nchunks; ++i) { + struct drm_amdgpu_cs_chunk_dep *deps; + struct amdgpu_cs_chunk *chunk; +@@ -799,26 +791,20 @@ static int amdgpu_cs_dependencies(struct amdgpu_device *adev, + + static int amdgpu_cs_free_job(struct amdgpu_job *job) + { +- int i; +- if (job->ibs) +- for (i = 0; i < job->num_ibs; i++) +- amdgpu_ib_free(job->adev, &job->ibs[i]); +- kfree(job->ibs); +- if (job->uf.bo) +- amdgpu_bo_unref(&job->uf.bo); ++ amdgpu_job_free(job); + return 0; + } + + static int amdgpu_cs_submit(struct amdgpu_cs_parser *p, + union drm_amdgpu_cs *cs) + { +- struct amdgpu_ring * ring = p->ibs->ring; ++ struct amdgpu_ring * ring = p->job->ibs->ring; + struct amd_sched_fence *fence; + struct amdgpu_job *job; + +- job = kzalloc(sizeof(struct amdgpu_job), GFP_KERNEL); +- if (!job) +- return -ENOMEM; ++ job = p->job; ++ p->job = NULL; ++ + + job->base.sched = &ring->sched; + job->base.s_entity = &p->ctx->rings[ring->idx].entity; +@@ -826,11 +812,6 @@ static int amdgpu_cs_submit(struct amdgpu_cs_parser *p, + job->owner = p->filp; + job->free_job = amdgpu_cs_free_job; + +- job->ibs = p->ibs; +- job->num_ibs = p->num_ibs; +- p->ibs = NULL; +- p->num_ibs = 0; +- + if (job->ibs[job->num_ibs - 1].user) { + job->uf = p->uf; + job->ibs[job->num_ibs - 1].user = &job->uf; +@@ -897,7 +878,7 @@ int amdgpu_cs_ioctl(struct drm_device *dev, void *data, struct drm_file *filp) + if (r) + goto out; + +- for (i = 0; i < parser.num_ibs; i++) ++ for (i = 0; i < parser.job->num_ibs; i++) + trace_amdgpu_cs(&parser, i); + + r = amdgpu_cs_ib_vm_chunk(adev, &parser); +diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_sched.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_sched.c +index 76a1f82..91b4862 100644 +--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_sched.c ++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_sched.c +@@ -28,6 +28,39 @@ + #include "amdgpu.h" + #include "amdgpu_trace.h" + ++int amdgpu_job_alloc(struct amdgpu_device *adev, unsigned num_ibs, ++ struct amdgpu_job **job) ++{ ++ size_t size = sizeof(struct amdgpu_job); ++ ++ if (num_ibs == 0) ++ return -EINVAL; ++ ++ size += sizeof(struct amdgpu_ib) * num_ibs; ++ ++ *job = kzalloc(size, GFP_KERNEL); ++ if (!*job) ++ return -ENOMEM; ++ ++ (*job)->adev = adev; ++ (*job)->ibs = (void *)&(*job)[1]; ++ (*job)->num_ibs = num_ibs; ++ (*job)->free_job = NULL; ++ ++ return 0; ++} ++ ++void amdgpu_job_free(struct amdgpu_job *job) ++{ ++ unsigned i; ++ ++ for (i = 0; i < job->num_ibs; ++i) ++ amdgpu_ib_free(job->adev, &job->ibs[i]); ++ ++ amdgpu_bo_unref(&job->uf.bo); ++ /* TODO: Free the job structure here as well */ ++} ++ + static struct fence *amdgpu_sched_dependency(struct amd_sched_job *sched_job) + { + struct amdgpu_job *job = to_amdgpu_job(sched_job); +diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_trace.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_trace.h +index e7d2676..9c15284 100644 +--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_trace.h ++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_trace.h +@@ -39,9 +39,9 @@ TRACE_EVENT(amdgpu_cs, + TP_fast_assign( + __entry->bo_list = p->bo_list; + __entry->ring = p->ibs[i].ring->idx; +- __entry->dw = p->ibs[i].length_dw; ++ __entry->dw = p->job->ibs[i].length_dw; + __entry->fences = amdgpu_fence_count_emitted( +- p->ibs[i].ring); ++ p->job->ibs[i].ring); + ), + TP_printk("bo_list=%p, ring=%u, dw=%u, fences=%u", + __entry->bo_list, __entry->ring, __entry->dw, +diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.c +index 2a20b66..520ad02 100644 +--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.c ++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.c +@@ -707,7 +707,7 @@ static int amdgpu_uvd_cs_pass2(struct amdgpu_uvd_cs_ctx *ctx) + static int amdgpu_uvd_cs_reg(struct amdgpu_uvd_cs_ctx *ctx, + int (*cb)(struct amdgpu_uvd_cs_ctx *ctx)) + { +- struct amdgpu_ib *ib = &ctx->parser->ibs[ctx->ib_idx]; ++ struct amdgpu_ib *ib = &ctx->parser->job->ibs[ctx->ib_idx]; + int i, r; + + ctx->idx++; +@@ -753,7 +753,7 @@ static int amdgpu_uvd_cs_reg(struct amdgpu_uvd_cs_ctx *ctx, + static int amdgpu_uvd_cs_packets(struct amdgpu_uvd_cs_ctx *ctx, + int (*cb)(struct amdgpu_uvd_cs_ctx *ctx)) + { +- struct amdgpu_ib *ib = &ctx->parser->ibs[ctx->ib_idx]; ++ struct amdgpu_ib *ib = &ctx->parser->job->ibs[ctx->ib_idx]; + int r; + + for (ctx->idx = 0 ; ctx->idx < ib->length_dw; ) { +@@ -795,7 +795,7 @@ int amdgpu_uvd_ring_parse_cs(struct amdgpu_cs_parser *parser, uint32_t ib_idx) + [0x00000003] = 2048, + [0x00000004] = 0xFFFFFFFF, + }; +- struct amdgpu_ib *ib = &parser->ibs[ib_idx]; ++ struct amdgpu_ib *ib = &parser->job->ibs[ib_idx]; + int r; + + if (ib->length_dw % 16) { +diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vce.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_vce.c +index d80e12c..420b610 100644 +--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vce.c ++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vce.c +@@ -604,7 +604,7 @@ static int amdgpu_vce_validate_handle(struct amdgpu_cs_parser *p, + */ + int amdgpu_vce_ring_parse_cs(struct amdgpu_cs_parser *p, uint32_t ib_idx) + { +- struct amdgpu_ib *ib = &p->ibs[ib_idx]; ++ struct amdgpu_ib *ib = &p->job->ibs[ib_idx]; + unsigned fb_idx = 0, bs_idx = 0; + int session_idx = -1; + bool destroyed = false; +-- +2.7.4 + |