summaryrefslogtreecommitdiff
path: root/drivers/gpu/drm/amd/amdgpu
diff options
context:
space:
mode:
authorChunming Zhou <david1.zhou@amd.com>2015-08-02 11:18:04 +0800
committerAlex Deucher <alexander.deucher@amd.com>2015-08-17 16:51:07 -0400
commitf556cb0caeec1ba9b8e5e2aa85b47e76277f5d4b (patch)
tree1325c1eb049a5a85901437743ea0c3f499f73f2d /drivers/gpu/drm/amd/amdgpu
parent4af9f07ccdac96e16f7a0ddaf983891a29ebd11a (diff)
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 <david1.zhou@amd.com> Reviewed-by: Christian K?nig <christian.koenig@amd.com>
Diffstat (limited to 'drivers/gpu/drm/amd/amdgpu')
-rw-r--r--drivers/gpu/drm/amd/amdgpu/Makefile1
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu.h1
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c21
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c10
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_ib.c2
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_sched.c34
6 files changed, 35 insertions, 34 deletions
diff --git a/drivers/gpu/drm/amd/amdgpu/Makefile b/drivers/gpu/drm/amd/amdgpu/Makefile
index f1cb7d2fa411..04c270757030 100644
--- a/drivers/gpu/drm/amd/amdgpu/Makefile
+++ b/drivers/gpu/drm/amd/amdgpu/Makefile
@@ -86,6 +86,7 @@ amdgpu-y += amdgpu_cgs.o
# GPU scheduler
amdgpu-y += \
../scheduler/gpu_scheduler.o \
+ ../scheduler/sched_fence.o \
amdgpu_sched.o
amdgpu-$(CONFIG_COMPAT) += amdgpu_ioc32.o
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h b/drivers/gpu/drm/amd/amdgpu/amdgpu.h
index 987e3075a03f..2ba448ee948b 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h
@@ -1261,6 +1261,7 @@ struct amdgpu_cs_parser {
int (*prepare_job)(struct amdgpu_cs_parser *sched_job);
int (*run_job)(struct amdgpu_cs_parser *sched_job);
int (*free_job)(struct amdgpu_cs_parser *sched_job);
+ struct amd_sched_fence *s_fence;
};
static inline u32 amdgpu_get_ib_value(struct amdgpu_cs_parser *p, uint32_t ib_idx, int idx)
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;
}
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c
index 232e800eea56..1833f05c7e0b 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c
@@ -268,16 +268,6 @@ struct fence *amdgpu_ctx_get_fence(struct amdgpu_ctx *ctx,
struct amdgpu_ctx_ring *cring = & ctx->rings[ring->idx];
struct fence *fence;
uint64_t queued_seq;
- int r;
-
- if (amdgpu_enable_scheduler) {
- r = amd_sched_wait_emit(&cring->entity,
- seq,
- false,
- -1);
- if (r)
- return NULL;
- }
spin_lock(&ctx->ring_lock);
if (amdgpu_enable_scheduler)
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ib.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ib.c
index eed409c59492..5104e64e9ad8 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ib.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ib.c
@@ -218,7 +218,7 @@ int amdgpu_ib_schedule(struct amdgpu_device *adev, unsigned num_ibs,
sequence = amdgpu_enable_scheduler ? ib->sequence : 0;
- if (ib->ctx)
+ if (!amdgpu_enable_scheduler && ib->ctx)
ib->sequence = amdgpu_ctx_add_fence(ib->ctx, ring,
&ib->fence->base,
sequence);
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_sched.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_sched.c
index d82f2481bd0e..6a7e83edcaa7 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_sched.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_sched.c
@@ -118,7 +118,6 @@ int amdgpu_sched_ib_submit_kernel_helper(struct amdgpu_device *adev,
{
int r = 0;
if (amdgpu_enable_scheduler) {
- uint64_t v_seq;
struct amdgpu_cs_parser *sched_job =
amdgpu_cs_parser_create(adev, owner, &adev->kernel_ctx,
ibs, num_ibs);
@@ -126,22 +125,23 @@ int amdgpu_sched_ib_submit_kernel_helper(struct amdgpu_device *adev,
return -ENOMEM;
}
sched_job->free_job = free_job;
- v_seq = atomic64_inc_return(&adev->kernel_ctx.rings[ring->idx].entity.last_queued_v_seq);
- ibs[num_ibs - 1].sequence = v_seq;
- amd_sched_push_job(ring->scheduler,
- &adev->kernel_ctx.rings[ring->idx].entity,
- sched_job);
- r = amd_sched_wait_emit(
- &adev->kernel_ctx.rings[ring->idx].entity,
- v_seq,
- false,
- -1);
- if (r)
- WARN(true, "emit timeout\n");
- } else
+ mutex_lock(&sched_job->job_lock);
+ r = amd_sched_push_job(ring->scheduler,
+ &adev->kernel_ctx.rings[ring->idx].entity,
+ sched_job, &sched_job->s_fence);
+ if (r) {
+ mutex_unlock(&sched_job->job_lock);
+ kfree(sched_job);
+ return r;
+ }
+ ibs[num_ibs - 1].sequence = sched_job->s_fence->v_seq;
+ *f = &sched_job->s_fence->base;
+ mutex_unlock(&sched_job->job_lock);
+ } else {
r = amdgpu_ib_schedule(adev, num_ibs, ibs, owner);
- if (r)
- return r;
- *f = &ibs[num_ibs - 1].fence->base;
+ if (r)
+ return r;
+ *f = &ibs[num_ibs - 1].fence->base;
+ }
return 0;
}