summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristian König <christian.koenig@amd.com>2015-08-18 14:41:25 +0200
committerAlex Deucher <alexander.deucher@amd.com>2015-08-20 17:03:47 -0400
commit2b184d8dbc002d3ef26e4827dd5a80d57533dcae (patch)
tree5f652253374c0e1c81b290006b8e3a5ff03091e9
parenta3348bb801bac5c9a81fb3da4b1a2f0479e97923 (diff)
drm/amdgpu: use a spinlock instead of a mutex for the rq
More appropriate and fixes some nasty lockdep warnings. Signed-off-by: Christian König <christian.koenig@amd.com> Reviewed-by: Chunming Zhou <david1.zhou@amd.com>
-rw-r--r--drivers/gpu/drm/amd/scheduler/gpu_scheduler.c49
-rw-r--r--drivers/gpu/drm/amd/scheduler/gpu_scheduler.h2
2 files changed, 18 insertions, 33 deletions
diff --git a/drivers/gpu/drm/amd/scheduler/gpu_scheduler.c b/drivers/gpu/drm/amd/scheduler/gpu_scheduler.c
index 462c1617d56e..1125aa2e2a9a 100644
--- a/drivers/gpu/drm/amd/scheduler/gpu_scheduler.c
+++ b/drivers/gpu/drm/amd/scheduler/gpu_scheduler.c
@@ -30,27 +30,27 @@
/* Initialize a given run queue struct */
static void amd_sched_rq_init(struct amd_sched_rq *rq)
{
+ spin_lock_init(&rq->lock);
INIT_LIST_HEAD(&rq->entities);
- mutex_init(&rq->lock);
rq->current_entity = NULL;
}
static void amd_sched_rq_add_entity(struct amd_sched_rq *rq,
struct amd_sched_entity *entity)
{
- mutex_lock(&rq->lock);
+ spin_lock(&rq->lock);
list_add_tail(&entity->list, &rq->entities);
- mutex_unlock(&rq->lock);
+ spin_unlock(&rq->lock);
}
static void amd_sched_rq_remove_entity(struct amd_sched_rq *rq,
struct amd_sched_entity *entity)
{
- mutex_lock(&rq->lock);
+ spin_lock(&rq->lock);
list_del_init(&entity->list);
if (rq->current_entity == entity)
rq->current_entity = NULL;
- mutex_unlock(&rq->lock);
+ spin_unlock(&rq->lock);
}
/**
@@ -61,12 +61,16 @@ static void amd_sched_rq_remove_entity(struct amd_sched_rq *rq,
static struct amd_sched_entity *
amd_sched_rq_select_entity(struct amd_sched_rq *rq)
{
- struct amd_sched_entity *entity = rq->current_entity;
+ struct amd_sched_entity *entity;
+ spin_lock(&rq->lock);
+
+ entity = rq->current_entity;
if (entity) {
list_for_each_entry_continue(entity, &rq->entities, list) {
if (!kfifo_is_empty(&entity->job_queue)) {
rq->current_entity = entity;
+ spin_unlock(&rq->lock);
return rq->current_entity;
}
}
@@ -76,6 +80,7 @@ amd_sched_rq_select_entity(struct amd_sched_rq *rq)
if (!kfifo_is_empty(&entity->job_queue)) {
rq->current_entity = entity;
+ spin_unlock(&rq->lock);
return rq->current_entity;
}
@@ -83,6 +88,8 @@ amd_sched_rq_select_entity(struct amd_sched_rq *rq)
break;
}
+ spin_unlock(&rq->lock);
+
return NULL;
}
@@ -109,22 +116,6 @@ static bool is_scheduler_ready(struct amd_gpu_scheduler *sched)
}
/**
- * Select next entity from the kernel run queue, if not available,
- * return null.
-*/
-static struct amd_sched_entity *
-kernel_rq_select_context(struct amd_gpu_scheduler *sched)
-{
- struct amd_sched_entity *sched_entity;
- struct amd_sched_rq *rq = &sched->kernel_rq;
-
- mutex_lock(&rq->lock);
- sched_entity = amd_sched_rq_select_entity(rq);
- mutex_unlock(&rq->lock);
- return sched_entity;
-}
-
-/**
* Select next entity containing real IB submissions
*/
static struct amd_sched_entity *
@@ -132,21 +123,15 @@ select_context(struct amd_gpu_scheduler *sched)
{
struct amd_sched_entity *wake_entity = NULL;
struct amd_sched_entity *tmp;
- struct amd_sched_rq *rq;
if (!is_scheduler_ready(sched))
return NULL;
/* Kernel run queue has higher priority than normal run queue*/
- tmp = kernel_rq_select_context(sched);
- if (tmp != NULL)
- goto exit;
-
- rq = &sched->sched_rq;
- mutex_lock(&rq->lock);
- tmp = amd_sched_rq_select_entity(rq);
- mutex_unlock(&rq->lock);
-exit:
+ tmp = amd_sched_rq_select_entity(&sched->kernel_rq);
+ if (tmp == NULL)
+ tmp = amd_sched_rq_select_entity(&sched->sched_rq);
+
if (sched->current_entity && (sched->current_entity != tmp))
wake_entity = sched->current_entity;
sched->current_entity = tmp;
diff --git a/drivers/gpu/drm/amd/scheduler/gpu_scheduler.h b/drivers/gpu/drm/amd/scheduler/gpu_scheduler.h
index 25e38d030157..6597d61266e7 100644
--- a/drivers/gpu/drm/amd/scheduler/gpu_scheduler.h
+++ b/drivers/gpu/drm/amd/scheduler/gpu_scheduler.h
@@ -63,7 +63,7 @@ struct amd_sched_entity {
* the next entity to emit commands from.
*/
struct amd_sched_rq {
- struct mutex lock;
+ spinlock_t lock;
struct list_head entities;
struct amd_sched_entity *current_entity;
};