drm/scheduler: Add stopped flag to drm_sched_entity
authorAndrey Grodzovsky <andrey.grodzovsky@amd.com>
Fri, 17 Aug 2018 14:32:50 +0000 (10:32 -0400)
committerAlex Deucher <alexander.deucher@amd.com>
Mon, 27 Aug 2018 16:11:10 +0000 (11:11 -0500)
The flag will prevent another thread from same process to
reinsert the entity queue into scheduler's rq after it was already
removewd from there by another thread during drm_sched_entity_flush.

Signed-off-by: Andrey Grodzovsky <andrey.grodzovsky@amd.com>
Reviewed-by: Chunming Zhou <david1.zhou@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
drivers/gpu/drm/scheduler/sched_entity.c
include/drm/gpu_scheduler.h

index 1416edb..812e353 100644 (file)
@@ -177,8 +177,12 @@ long drm_sched_entity_flush(struct drm_sched_entity *entity, long timeout)
        /* For killed process disable any more IBs enqueue right now */
        last_user = cmpxchg(&entity->last_user, current->group_leader, NULL);
        if ((!last_user || last_user == current->group_leader) &&
-           (current->flags & PF_EXITING) && (current->exit_code == SIGKILL))
+           (current->flags & PF_EXITING) && (current->exit_code == SIGKILL)) {
+               spin_lock(&entity->rq_lock);
+               entity->stopped = true;
                drm_sched_rq_remove_entity(entity->rq, entity);
+               spin_unlock(&entity->rq_lock);
+       }
 
        return ret;
 }
@@ -504,6 +508,12 @@ void drm_sched_entity_push_job(struct drm_sched_job *sched_job,
        if (first) {
                /* Add the entity to the run queue */
                spin_lock(&entity->rq_lock);
+               if (entity->stopped) {
+                       spin_unlock(&entity->rq_lock);
+
+                       DRM_ERROR("Trying to push to a killed entity\n");
+                       return;
+               }
                drm_sched_rq_add_entity(entity->rq, entity);
                spin_unlock(&entity->rq_lock);
                drm_sched_wakeup(entity->rq->sched);
index 919ae57..daec50f 100644 (file)
@@ -70,6 +70,7 @@ enum drm_sched_priority {
  * @fini_status: contains the exit status in case the process was signalled.
  * @last_scheduled: points to the finished fence of the last scheduled job.
  * @last_user: last group leader pushing a job into the entity.
+ * @stopped: Marks the enity as removed from rq and destined for termination.
  *
  * Entities will emit jobs in order to their corresponding hardware
  * ring, and the scheduler will alternate between entities based on
@@ -92,6 +93,7 @@ struct drm_sched_entity {
        atomic_t                        *guilty;
        struct dma_fence                *last_scheduled;
        struct task_struct              *last_user;
+       bool                            stopped;
 };
 
 /**