drm/sched: Use completion to wait for sched->thread idle v2.
authorAndrey Grodzovsky <andrey.grodzovsky@amd.com>
Mon, 4 Nov 2019 21:30:05 +0000 (16:30 -0500)
committerAlex Deucher <alexander.deucher@amd.com>
Thu, 7 Nov 2019 23:08:07 +0000 (18:08 -0500)
Removes thread park/unpark hack from drm_sched_entity_fini and
by this fixes reactivation of scheduler thread while the thread
is supposed to be stopped.

v2: Per sched entity completion.

Signed-off-by: Andrey Grodzovsky <andrey.grodzovsky@amd.com>
Suggested-by: Christian König <christian.koenig@amd.com>
Reviewed-by: Christian König <christian.koenig@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
drivers/gpu/drm/scheduler/sched_entity.c
drivers/gpu/drm/scheduler/sched_main.c
include/drm/gpu_scheduler.h

index 1a51531..461a7a8 100644 (file)
@@ -23,6 +23,7 @@
 
 #include <linux/kthread.h>
 #include <linux/slab.h>
+#include <linux/completion.h>
 
 #include <drm/drm_print.h>
 #include <drm/gpu_scheduler.h>
@@ -68,6 +69,8 @@ int drm_sched_entity_init(struct drm_sched_entity *entity,
        if (!entity->rq_list)
                return -ENOMEM;
 
+       init_completion(&entity->entity_idle);
+
        for (i = 0; i < num_rq_list; ++i)
                entity->rq_list[i] = rq_list[i];
 
@@ -286,11 +289,12 @@ void drm_sched_entity_fini(struct drm_sched_entity *entity)
         */
        if (spsc_queue_count(&entity->job_queue)) {
                if (sched) {
-                       /* Park the kernel for a moment to make sure it isn't processing
-                        * our enity.
+                       /*
+                        * Wait for thread to idle to make sure it isn't processing
+                        * this entity.
                         */
-                       kthread_park(sched->thread);
-                       kthread_unpark(sched->thread);
+                       wait_for_completion(&entity->entity_idle);
+
                }
                if (entity->dependency) {
                        dma_fence_remove_callback(entity->dependency,
index fbb6446..362cf1a 100644 (file)
@@ -47,6 +47,7 @@
 #include <linux/kthread.h>
 #include <linux/wait.h>
 #include <linux/sched.h>
+#include <linux/completion.h>
 #include <uapi/linux/sched/types.h>
 
 #include <drm/drm_print.h>
@@ -134,6 +135,7 @@ drm_sched_rq_select_entity(struct drm_sched_rq *rq)
                list_for_each_entry_continue(entity, &rq->entities, list) {
                        if (drm_sched_entity_is_ready(entity)) {
                                rq->current_entity = entity;
+                               reinit_completion(&entity->entity_idle);
                                spin_unlock(&rq->lock);
                                return entity;
                        }
@@ -144,6 +146,7 @@ drm_sched_rq_select_entity(struct drm_sched_rq *rq)
 
                if (drm_sched_entity_is_ready(entity)) {
                        rq->current_entity = entity;
+                       reinit_completion(&entity->entity_idle);
                        spin_unlock(&rq->lock);
                        return entity;
                }
@@ -726,6 +729,9 @@ static int drm_sched_main(void *param)
                        continue;
 
                sched_job = drm_sched_entity_pop_job(entity);
+
+               complete(&entity->entity_idle);
+
                if (!sched_job)
                        continue;
 
index 57b4121..6619d2a 100644 (file)
@@ -71,6 +71,7 @@ enum drm_sched_priority {
  * @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.
+ * @entity_idle: Signals when enityt is not in use
  *
  * Entities will emit jobs in order to their corresponding hardware
  * ring, and the scheduler will alternate between entities based on
@@ -94,6 +95,7 @@ struct drm_sched_entity {
        struct dma_fence                *last_scheduled;
        struct task_struct              *last_user;
        bool                            stopped;
+       struct completion               entity_idle;
 };
 
 /**