Commit 83a7772b authored by Andrey Grodzovsky's avatar Andrey Grodzovsky Committed by Alex Deucher

drm/sched: Use completion to wait for sched->thread idle v2.

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: default avatarAndrey Grodzovsky <andrey.grodzovsky@amd.com>
Suggested-by: default avatarChristian König <christian.koenig@amd.com>
Reviewed-by: default avatarChristian König <christian.koenig@amd.com>
Signed-off-by: default avatarAlex Deucher <alexander.deucher@amd.com>
parent cb5932f8
...@@ -23,6 +23,7 @@ ...@@ -23,6 +23,7 @@
#include <linux/kthread.h> #include <linux/kthread.h>
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/completion.h>
#include <drm/drm_print.h> #include <drm/drm_print.h>
#include <drm/gpu_scheduler.h> #include <drm/gpu_scheduler.h>
...@@ -68,6 +69,8 @@ int drm_sched_entity_init(struct drm_sched_entity *entity, ...@@ -68,6 +69,8 @@ int drm_sched_entity_init(struct drm_sched_entity *entity,
if (!entity->rq_list) if (!entity->rq_list)
return -ENOMEM; return -ENOMEM;
init_completion(&entity->entity_idle);
for (i = 0; i < num_rq_list; ++i) for (i = 0; i < num_rq_list; ++i)
entity->rq_list[i] = rq_list[i]; entity->rq_list[i] = rq_list[i];
...@@ -286,11 +289,12 @@ void drm_sched_entity_fini(struct drm_sched_entity *entity) ...@@ -286,11 +289,12 @@ void drm_sched_entity_fini(struct drm_sched_entity *entity)
*/ */
if (spsc_queue_count(&entity->job_queue)) { if (spsc_queue_count(&entity->job_queue)) {
if (sched) { 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); wait_for_completion(&entity->entity_idle);
kthread_unpark(sched->thread);
} }
if (entity->dependency) { if (entity->dependency) {
dma_fence_remove_callback(entity->dependency, dma_fence_remove_callback(entity->dependency,
......
...@@ -47,6 +47,7 @@ ...@@ -47,6 +47,7 @@
#include <linux/kthread.h> #include <linux/kthread.h>
#include <linux/wait.h> #include <linux/wait.h>
#include <linux/sched.h> #include <linux/sched.h>
#include <linux/completion.h>
#include <uapi/linux/sched/types.h> #include <uapi/linux/sched/types.h>
#include <drm/drm_print.h> #include <drm/drm_print.h>
...@@ -134,6 +135,7 @@ drm_sched_rq_select_entity(struct drm_sched_rq *rq) ...@@ -134,6 +135,7 @@ drm_sched_rq_select_entity(struct drm_sched_rq *rq)
list_for_each_entry_continue(entity, &rq->entities, list) { list_for_each_entry_continue(entity, &rq->entities, list) {
if (drm_sched_entity_is_ready(entity)) { if (drm_sched_entity_is_ready(entity)) {
rq->current_entity = entity; rq->current_entity = entity;
reinit_completion(&entity->entity_idle);
spin_unlock(&rq->lock); spin_unlock(&rq->lock);
return entity; return entity;
} }
...@@ -144,6 +146,7 @@ drm_sched_rq_select_entity(struct drm_sched_rq *rq) ...@@ -144,6 +146,7 @@ drm_sched_rq_select_entity(struct drm_sched_rq *rq)
if (drm_sched_entity_is_ready(entity)) { if (drm_sched_entity_is_ready(entity)) {
rq->current_entity = entity; rq->current_entity = entity;
reinit_completion(&entity->entity_idle);
spin_unlock(&rq->lock); spin_unlock(&rq->lock);
return entity; return entity;
} }
...@@ -726,6 +729,9 @@ static int drm_sched_main(void *param) ...@@ -726,6 +729,9 @@ static int drm_sched_main(void *param)
continue; continue;
sched_job = drm_sched_entity_pop_job(entity); sched_job = drm_sched_entity_pop_job(entity);
complete(&entity->entity_idle);
if (!sched_job) if (!sched_job)
continue; continue;
......
...@@ -71,6 +71,7 @@ enum drm_sched_priority { ...@@ -71,6 +71,7 @@ enum drm_sched_priority {
* @last_scheduled: points to the finished fence of the last scheduled job. * @last_scheduled: points to the finished fence of the last scheduled job.
* @last_user: last group leader pushing a job into the entity. * @last_user: last group leader pushing a job into the entity.
* @stopped: Marks the enity as removed from rq and destined for termination. * @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 * Entities will emit jobs in order to their corresponding hardware
* ring, and the scheduler will alternate between entities based on * ring, and the scheduler will alternate between entities based on
...@@ -94,6 +95,7 @@ struct drm_sched_entity { ...@@ -94,6 +95,7 @@ struct drm_sched_entity {
struct dma_fence *last_scheduled; struct dma_fence *last_scheduled;
struct task_struct *last_user; struct task_struct *last_user;
bool stopped; bool stopped;
struct completion entity_idle;
}; };
/** /**
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment