mirror of
https://github.com/Fishwaldo/Star64_linux.git
synced 2025-04-21 22:03:58 +00:00
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: 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>
This commit is contained in:
parent
cb5932f866
commit
83a7772ba2
3 changed files with 16 additions and 4 deletions
|
@ -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,
|
||||||
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)
|
||||||
*/
|
*/
|
||||||
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 @@
|
||||||
#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)
|
||||||
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)
|
||||||
|
|
||||||
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)
|
||||||
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 {
|
||||||
* @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 {
|
||||||
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;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
Loading…
Add table
Reference in a new issue