aboutsummaryrefslogtreecommitdiffstats
path: root/common/recipes-kernel/linux/files/0273-drm-amdgpu-add-proper-job-alloc-free-functions.patch
diff options
context:
space:
mode:
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.patch362
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
+