drm/scheduler: rework entity creation
Entity currently keeps a copy of run_queue list and modify it in drm_sched_entity_set_priority(). Entities shouldn't modify run_queue list. Use drm_gpu_scheduler list instead of drm_sched_rq list in drm_sched_entity struct. In this way we can select a runqueue based on entity/ctx's priority for a drm scheduler. Signed-off-by: Nirmoy Das <nirmoy.das@amd.com> Reviewed-by: Christian König <christian.koenig@amd.com> Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
This commit is contained in:
@@ -38,9 +38,10 @@
|
||||
* submit to HW ring.
|
||||
*
|
||||
* @entity: scheduler entity to init
|
||||
* @rq_list: the list of run queue on which jobs from this
|
||||
* @priority: priority of the entity
|
||||
* @sched_list: the list of drm scheds on which jobs from this
|
||||
* entity can be submitted
|
||||
* @num_rq_list: number of run queue in rq_list
|
||||
* @num_sched_list: number of drm sched in sched_list
|
||||
* @guilty: atomic_t set to 1 when a job on this queue
|
||||
* is found to be guilty causing a timeout
|
||||
*
|
||||
@@ -50,32 +51,35 @@
|
||||
* Returns 0 on success or a negative error code on failure.
|
||||
*/
|
||||
int drm_sched_entity_init(struct drm_sched_entity *entity,
|
||||
struct drm_sched_rq **rq_list,
|
||||
unsigned int num_rq_list,
|
||||
enum drm_sched_priority priority,
|
||||
struct drm_gpu_scheduler **sched_list,
|
||||
unsigned int num_sched_list,
|
||||
atomic_t *guilty)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (!(entity && rq_list && (num_rq_list == 0 || rq_list[0])))
|
||||
if (!(entity && sched_list && (num_sched_list == 0 || sched_list[0])))
|
||||
return -EINVAL;
|
||||
|
||||
memset(entity, 0, sizeof(struct drm_sched_entity));
|
||||
INIT_LIST_HEAD(&entity->list);
|
||||
entity->rq = NULL;
|
||||
entity->guilty = guilty;
|
||||
entity->num_rq_list = num_rq_list;
|
||||
entity->rq_list = kcalloc(num_rq_list, sizeof(struct drm_sched_rq *),
|
||||
GFP_KERNEL);
|
||||
if (!entity->rq_list)
|
||||
entity->num_sched_list = num_sched_list;
|
||||
entity->priority = priority;
|
||||
entity->sched_list = kcalloc(num_sched_list,
|
||||
sizeof(struct drm_gpu_scheduler *), GFP_KERNEL);
|
||||
|
||||
if(!entity->sched_list)
|
||||
return -ENOMEM;
|
||||
|
||||
init_completion(&entity->entity_idle);
|
||||
|
||||
for (i = 0; i < num_rq_list; ++i)
|
||||
entity->rq_list[i] = rq_list[i];
|
||||
for (i = 0; i < num_sched_list; i++)
|
||||
entity->sched_list[i] = sched_list[i];
|
||||
|
||||
if (num_rq_list)
|
||||
entity->rq = rq_list[0];
|
||||
if (num_sched_list)
|
||||
entity->rq = &entity->sched_list[0]->sched_rq[entity->priority];
|
||||
|
||||
entity->last_scheduled = NULL;
|
||||
|
||||
@@ -139,10 +143,10 @@ drm_sched_entity_get_free_sched(struct drm_sched_entity *entity)
|
||||
unsigned int min_jobs = UINT_MAX, num_jobs;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < entity->num_rq_list; ++i) {
|
||||
struct drm_gpu_scheduler *sched = entity->rq_list[i]->sched;
|
||||
for (i = 0; i < entity->num_sched_list; ++i) {
|
||||
struct drm_gpu_scheduler *sched = entity->sched_list[i];
|
||||
|
||||
if (!entity->rq_list[i]->sched->ready) {
|
||||
if (!entity->sched_list[i]->ready) {
|
||||
DRM_WARN("sched%s is not ready, skipping", sched->name);
|
||||
continue;
|
||||
}
|
||||
@@ -150,7 +154,7 @@ drm_sched_entity_get_free_sched(struct drm_sched_entity *entity)
|
||||
num_jobs = atomic_read(&sched->num_jobs);
|
||||
if (num_jobs < min_jobs) {
|
||||
min_jobs = num_jobs;
|
||||
rq = entity->rq_list[i];
|
||||
rq = &entity->sched_list[i]->sched_rq[entity->priority];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -308,7 +312,7 @@ void drm_sched_entity_fini(struct drm_sched_entity *entity)
|
||||
|
||||
dma_fence_put(entity->last_scheduled);
|
||||
entity->last_scheduled = NULL;
|
||||
kfree(entity->rq_list);
|
||||
kfree(entity->sched_list);
|
||||
}
|
||||
EXPORT_SYMBOL(drm_sched_entity_fini);
|
||||
|
||||
@@ -353,15 +357,6 @@ static void drm_sched_entity_wakeup(struct dma_fence *f,
|
||||
drm_sched_wakeup(entity->rq->sched);
|
||||
}
|
||||
|
||||
/**
|
||||
* drm_sched_entity_set_rq_priority - helper for drm_sched_entity_set_priority
|
||||
*/
|
||||
static void drm_sched_entity_set_rq_priority(struct drm_sched_rq **rq,
|
||||
enum drm_sched_priority priority)
|
||||
{
|
||||
*rq = &(*rq)->sched->sched_rq[priority];
|
||||
}
|
||||
|
||||
/**
|
||||
* drm_sched_entity_set_priority - Sets priority of the entity
|
||||
*
|
||||
@@ -373,19 +368,8 @@ static void drm_sched_entity_set_rq_priority(struct drm_sched_rq **rq,
|
||||
void drm_sched_entity_set_priority(struct drm_sched_entity *entity,
|
||||
enum drm_sched_priority priority)
|
||||
{
|
||||
unsigned int i;
|
||||
|
||||
spin_lock(&entity->rq_lock);
|
||||
|
||||
for (i = 0; i < entity->num_rq_list; ++i)
|
||||
drm_sched_entity_set_rq_priority(&entity->rq_list[i], priority);
|
||||
|
||||
if (entity->rq) {
|
||||
drm_sched_rq_remove_entity(entity->rq, entity);
|
||||
drm_sched_entity_set_rq_priority(&entity->rq, priority);
|
||||
drm_sched_rq_add_entity(entity->rq, entity);
|
||||
}
|
||||
|
||||
entity->priority = priority;
|
||||
spin_unlock(&entity->rq_lock);
|
||||
}
|
||||
EXPORT_SYMBOL(drm_sched_entity_set_priority);
|
||||
@@ -490,20 +474,20 @@ void drm_sched_entity_select_rq(struct drm_sched_entity *entity)
|
||||
struct dma_fence *fence;
|
||||
struct drm_sched_rq *rq;
|
||||
|
||||
if (spsc_queue_count(&entity->job_queue) || entity->num_rq_list <= 1)
|
||||
if (spsc_queue_count(&entity->job_queue) || entity->num_sched_list <= 1)
|
||||
return;
|
||||
|
||||
fence = READ_ONCE(entity->last_scheduled);
|
||||
if (fence && !dma_fence_is_signaled(fence))
|
||||
return;
|
||||
|
||||
rq = drm_sched_entity_get_free_sched(entity);
|
||||
if (rq == entity->rq)
|
||||
return;
|
||||
|
||||
spin_lock(&entity->rq_lock);
|
||||
drm_sched_rq_remove_entity(entity->rq, entity);
|
||||
entity->rq = rq;
|
||||
rq = drm_sched_entity_get_free_sched(entity);
|
||||
if (rq != entity->rq) {
|
||||
drm_sched_rq_remove_entity(entity->rq, entity);
|
||||
entity->rq = rq;
|
||||
}
|
||||
|
||||
spin_unlock(&entity->rq_lock);
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user