diff options
Diffstat (limited to 'drivers/gpu/drm/scheduler/sched_entity.c')
| -rw-r--r-- | drivers/gpu/drm/scheduler/sched_entity.c | 46 | 
1 files changed, 28 insertions, 18 deletions
| diff --git a/drivers/gpu/drm/scheduler/sched_entity.c b/drivers/gpu/drm/scheduler/sched_entity.c index 4463d3826ecb..35ddbec1375a 100644 --- a/drivers/gpu/drm/scheduler/sched_entity.c +++ b/drivers/gpu/drm/scheduler/sched_entity.c @@ -52,12 +52,12 @@ int drm_sched_entity_init(struct drm_sched_entity *entity,  {  	int i; -	if (!(entity && rq_list && num_rq_list > 0 && rq_list[0])) +	if (!(entity && rq_list && (num_rq_list == 0 || rq_list[0])))  		return -EINVAL;  	memset(entity, 0, sizeof(struct drm_sched_entity));  	INIT_LIST_HEAD(&entity->list); -	entity->rq = rq_list[0]; +	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 *), @@ -67,6 +67,10 @@ int drm_sched_entity_init(struct drm_sched_entity *entity,  	for (i = 0; i < num_rq_list; ++i)  		entity->rq_list[i] = rq_list[i]; + +	if (num_rq_list) +		entity->rq = rq_list[0]; +  	entity->last_scheduled = NULL;  	spin_lock_init(&entity->rq_lock); @@ -165,6 +169,9 @@ long drm_sched_entity_flush(struct drm_sched_entity *entity, long timeout)  	struct task_struct *last_user;  	long ret = timeout; +	if (!entity->rq) +		return 0; +  	sched = entity->rq->sched;  	/**  	 * The client will not queue more IBs during this fini, consume existing @@ -264,20 +271,24 @@ static void drm_sched_entity_kill_jobs(struct drm_sched_entity *entity)   */  void drm_sched_entity_fini(struct drm_sched_entity *entity)  { -	struct drm_gpu_scheduler *sched; +	struct drm_gpu_scheduler *sched = NULL; -	sched = entity->rq->sched; -	drm_sched_rq_remove_entity(entity->rq, entity); +	if (entity->rq) { +		sched = entity->rq->sched; +		drm_sched_rq_remove_entity(entity->rq, entity); +	}  	/* Consumption of existing IBs wasn't completed. Forcefully  	 * remove them here.  	 */  	if (spsc_queue_peek(&entity->job_queue)) { -		/* Park the kernel for a moment to make sure it isn't processing -		 * our enity. -		 */ -		kthread_park(sched->thread); -		kthread_unpark(sched->thread); +		if (sched) { +			/* Park the kernel for a moment to make sure it isn't processing +			 * our enity. +			 */ +			kthread_park(sched->thread); +			kthread_unpark(sched->thread); +		}  		if (entity->dependency) {  			dma_fence_remove_callback(entity->dependency,  						  &entity->cb); @@ -362,9 +373,11 @@ void drm_sched_entity_set_priority(struct drm_sched_entity *entity,  	for (i = 0; i < entity->num_rq_list; ++i)  		drm_sched_entity_set_rq_priority(&entity->rq_list[i], priority); -	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); +	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); +	}  	spin_unlock(&entity->rq_lock);  } @@ -440,13 +453,10 @@ struct drm_sched_job *drm_sched_entity_pop_job(struct drm_sched_entity *entity)  	while ((entity->dependency =  			sched->ops->dependency(sched_job, entity))) { +		trace_drm_sched_job_wait_dep(sched_job, entity->dependency); -		if (drm_sched_entity_add_dependency_cb(entity)) { - -			trace_drm_sched_job_wait_dep(sched_job, -						     entity->dependency); +		if (drm_sched_entity_add_dependency_cb(entity))  			return NULL; -		}  	}  	/* skip jobs from entity that marked guilty */ | 
