diff options
Diffstat (limited to 'drivers/gpu/drm/scheduler/sched_main.c')
-rw-r--r-- | drivers/gpu/drm/scheduler/sched_main.c | 36 |
1 files changed, 36 insertions, 0 deletions
diff --git a/drivers/gpu/drm/scheduler/sched_main.c b/drivers/gpu/drm/scheduler/sched_main.c index f4ac38b435f7..a18eabf692e4 100644 --- a/drivers/gpu/drm/scheduler/sched_main.c +++ b/drivers/gpu/drm/scheduler/sched_main.c @@ -697,6 +697,42 @@ drm_sched_get_cleanup_job(struct drm_gpu_scheduler *sched) } /** + * drm_sched_pick_best - Get a drm sched from a sched_list with the least load + * @sched_list: list of drm_gpu_schedulers + * @num_sched_list: number of drm_gpu_schedulers in the sched_list + * + * Returns pointer of the sched with the least load or NULL if none of the + * drm_gpu_schedulers are ready + */ +struct drm_gpu_scheduler * +drm_sched_pick_best(struct drm_gpu_scheduler **sched_list, + unsigned int num_sched_list) +{ + struct drm_gpu_scheduler *sched, *picked_sched = NULL; + int i; + unsigned int min_jobs = UINT_MAX, num_jobs; + + for (i = 0; i < num_sched_list; ++i) { + sched = sched_list[i]; + + if (!sched->ready) { + DRM_WARN("scheduler %s is not ready, skipping", + sched->name); + continue; + } + + num_jobs = atomic_read(&sched->num_jobs); + if (num_jobs < min_jobs) { + min_jobs = num_jobs; + picked_sched = sched; + } + } + + return picked_sched; +} +EXPORT_SYMBOL(drm_sched_pick_best); + +/** * drm_sched_blocked - check if the scheduler is blocked * * @sched: scheduler instance |