diff mbox series

[1/2] drm/sched: adding a new scheduling policy

Message ID 20241011062136.1019695-1-jesse.zhang@amd.com (mailing list archive)
State New, archived
Headers show
Series [1/2] drm/sched: adding a new scheduling policy | expand

Commit Message

Zhang, Jesse(Jie) Oct. 11, 2024, 6:21 a.m. UTC
From: "Jesse.zhang@amd.com" <jesse.zhang@amd.com>

Added ring ID scheduling.
In some cases, userspace needs to run a job on a specific ring.
Instead of selecting the best ring to run based on the ring score.
For example, The user want to run a bad job on a specific ring to check
whether the ring can recover from a queue reset.

Signed-off-by: Jesse Zhang <Jesse.Zhang@amd.com>
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c   |  2 +-
 drivers/gpu/drm/amd/amdgpu/amdgpu_job.c  |  2 +-
 drivers/gpu/drm/etnaviv/etnaviv_sched.c  |  2 +-
 drivers/gpu/drm/imagination/pvr_queue.c  |  2 +-
 drivers/gpu/drm/lima/lima_sched.c        |  2 +-
 drivers/gpu/drm/msm/msm_gem_submit.c     |  2 +-
 drivers/gpu/drm/nouveau/nouveau_sched.c  |  2 +-
 drivers/gpu/drm/panfrost/panfrost_job.c  |  2 +-
 drivers/gpu/drm/scheduler/sched_entity.c | 11 +++++++++--
 drivers/gpu/drm/scheduler/sched_main.c   |  4 ++--
 drivers/gpu/drm/v3d/v3d_submit.c         |  2 +-
 include/drm/gpu_scheduler.h              |  4 ++--
 12 files changed, 22 insertions(+), 15 deletions(-)

Comments

Christian König Oct. 11, 2024, 8:40 a.m. UTC | #1
Am 11.10.24 um 08:21 schrieb jesse.zhang@amd.com:
> From: "Jesse.zhang@amd.com" <jesse.zhang@amd.com>
>
> Added ring ID scheduling.
> In some cases, userspace needs to run a job on a specific ring.
> Instead of selecting the best ring to run based on the ring score.
> For example, The user want to run a bad job on a specific ring to check
> whether the ring can recover from a queue reset.

Absolutely clearly a NAK, we don't want to expose the different HW rings 
directly to userspace.

Regards,
Christian.

>
> Signed-off-by: Jesse Zhang <Jesse.Zhang@amd.com>
> ---
>   drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c   |  2 +-
>   drivers/gpu/drm/amd/amdgpu/amdgpu_job.c  |  2 +-
>   drivers/gpu/drm/etnaviv/etnaviv_sched.c  |  2 +-
>   drivers/gpu/drm/imagination/pvr_queue.c  |  2 +-
>   drivers/gpu/drm/lima/lima_sched.c        |  2 +-
>   drivers/gpu/drm/msm/msm_gem_submit.c     |  2 +-
>   drivers/gpu/drm/nouveau/nouveau_sched.c  |  2 +-
>   drivers/gpu/drm/panfrost/panfrost_job.c  |  2 +-
>   drivers/gpu/drm/scheduler/sched_entity.c | 11 +++++++++--
>   drivers/gpu/drm/scheduler/sched_main.c   |  4 ++--
>   drivers/gpu/drm/v3d/v3d_submit.c         |  2 +-
>   include/drm/gpu_scheduler.h              |  4 ++--
>   12 files changed, 22 insertions(+), 15 deletions(-)
>
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
> index d891ab779ca7..18887128a973 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
> @@ -1286,7 +1286,7 @@ static int amdgpu_cs_submit(struct amdgpu_cs_parser *p,
>   	int r;
>   
>   	for (i = 0; i < p->gang_size; ++i)
> -		drm_sched_job_arm(&p->jobs[i]->base);
> +		drm_sched_job_arm(&p->jobs[i]->base, -1);
>   
>   	for (i = 0; i < p->gang_size; ++i) {
>   		struct dma_fence *fence;
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_job.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_job.c
> index 717adcedf096..8d75ffa9a097 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_job.c
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_job.c
> @@ -320,7 +320,7 @@ struct dma_fence *amdgpu_job_submit(struct amdgpu_job *job)
>   {
>   	struct dma_fence *f;
>   
> -	drm_sched_job_arm(&job->base);
> +	drm_sched_job_arm(&job->base, -1);
>   	f = dma_fence_get(&job->base.s_fence->finished);
>   	amdgpu_job_free_resources(job);
>   	drm_sched_entity_push_job(&job->base);
> diff --git a/drivers/gpu/drm/etnaviv/etnaviv_sched.c b/drivers/gpu/drm/etnaviv/etnaviv_sched.c
> index 62dcfdc7894d..98d003757af1 100644
> --- a/drivers/gpu/drm/etnaviv/etnaviv_sched.c
> +++ b/drivers/gpu/drm/etnaviv/etnaviv_sched.c
> @@ -107,7 +107,7 @@ int etnaviv_sched_push_job(struct etnaviv_gem_submit *submit)
>   	 */
>   	mutex_lock(&gpu->sched_lock);
>   
> -	drm_sched_job_arm(&submit->sched_job);
> +	drm_sched_job_arm(&submit->sched_job, -1);
>   
>   	submit->out_fence = dma_fence_get(&submit->sched_job.s_fence->finished);
>   	ret = xa_alloc_cyclic(&gpu->user_fences, &submit->out_fence_id,
> diff --git a/drivers/gpu/drm/imagination/pvr_queue.c b/drivers/gpu/drm/imagination/pvr_queue.c
> index 5ed9c98fb599..ed7398a0ff21 100644
> --- a/drivers/gpu/drm/imagination/pvr_queue.c
> +++ b/drivers/gpu/drm/imagination/pvr_queue.c
> @@ -1115,7 +1115,7 @@ int pvr_queue_job_init(struct pvr_job *job)
>    */
>   struct dma_fence *pvr_queue_job_arm(struct pvr_job *job)
>   {
> -	drm_sched_job_arm(&job->base);
> +	drm_sched_job_arm(&job->base, -1);
>   
>   	return &job->base.s_fence->finished;
>   }
> diff --git a/drivers/gpu/drm/lima/lima_sched.c b/drivers/gpu/drm/lima/lima_sched.c
> index bbf3f8feab94..cc83b2aab9ce 100644
> --- a/drivers/gpu/drm/lima/lima_sched.c
> +++ b/drivers/gpu/drm/lima/lima_sched.c
> @@ -130,7 +130,7 @@ int lima_sched_task_init(struct lima_sched_task *task,
>   		return err;
>   	}
>   
> -	drm_sched_job_arm(&task->base);
> +	drm_sched_job_arm(&task->base, -1);
>   
>   	task->num_bos = num_bos;
>   	task->vm = lima_vm_get(vm);
> diff --git a/drivers/gpu/drm/msm/msm_gem_submit.c b/drivers/gpu/drm/msm/msm_gem_submit.c
> index fba78193127d..74c4e1b4df78 100644
> --- a/drivers/gpu/drm/msm/msm_gem_submit.c
> +++ b/drivers/gpu/drm/msm/msm_gem_submit.c
> @@ -831,7 +831,7 @@ int msm_ioctl_gem_submit(struct drm_device *dev, void *data,
>   		goto out;
>   	}
>   
> -	drm_sched_job_arm(&submit->base);
> +	drm_sched_job_arm(&submit->base, -1);
>   
>   	submit->user_fence = dma_fence_get(&submit->base.s_fence->finished);
>   
> diff --git a/drivers/gpu/drm/nouveau/nouveau_sched.c b/drivers/gpu/drm/nouveau/nouveau_sched.c
> index 32fa2e273965..3ff8142b5370 100644
> --- a/drivers/gpu/drm/nouveau/nouveau_sched.c
> +++ b/drivers/gpu/drm/nouveau/nouveau_sched.c
> @@ -309,7 +309,7 @@ nouveau_job_submit(struct nouveau_job *job)
>   	list_add(&job->entry, &sched->job.list.head);
>   	spin_unlock(&sched->job.list.lock);
>   
> -	drm_sched_job_arm(&job->base);
> +	drm_sched_job_arm(&job->base, -1);
>   	job->done_fence = dma_fence_get(&job->base.s_fence->finished);
>   	if (job->sync)
>   		done_fence = dma_fence_get(job->done_fence);
> diff --git a/drivers/gpu/drm/panfrost/panfrost_job.c b/drivers/gpu/drm/panfrost/panfrost_job.c
> index a61ef0af9a4e..cc937420cd35 100644
> --- a/drivers/gpu/drm/panfrost/panfrost_job.c
> +++ b/drivers/gpu/drm/panfrost/panfrost_job.c
> @@ -301,7 +301,7 @@ int panfrost_job_push(struct panfrost_job *job)
>   		return ret;
>   
>   	mutex_lock(&pfdev->sched_lock);
> -	drm_sched_job_arm(&job->base);
> +	drm_sched_job_arm(&job->base, -1);
>   
>   	job->render_done_fence = dma_fence_get(&job->base.s_fence->finished);
>   
> diff --git a/drivers/gpu/drm/scheduler/sched_entity.c b/drivers/gpu/drm/scheduler/sched_entity.c
> index 58c8161289fe..f4669422b3f9 100644
> --- a/drivers/gpu/drm/scheduler/sched_entity.c
> +++ b/drivers/gpu/drm/scheduler/sched_entity.c
> @@ -525,7 +525,7 @@ struct drm_sched_job *drm_sched_entity_pop_job(struct drm_sched_entity *entity)
>   	return sched_job;
>   }
>   
> -void drm_sched_entity_select_rq(struct drm_sched_entity *entity)
> +void drm_sched_entity_select_rq(struct drm_sched_entity *entity, int ring)
>   {
>   	struct dma_fence *fence;
>   	struct drm_gpu_scheduler *sched;
> @@ -554,7 +554,14 @@ void drm_sched_entity_select_rq(struct drm_sched_entity *entity)
>   		return;
>   
>   	spin_lock(&entity->rq_lock);
> -	sched = drm_sched_pick_best(entity->sched_list, entity->num_sched_list);
> +	if(ring >= 0) {
> +		if(entity->sched_list[ring] && entity->sched_list[ring]->ready)
> +			sched = entity->sched_list[ring];
> +		else
> +			sched = drm_sched_pick_best(entity->sched_list, entity->num_sched_list);
> +	}
> +	else
> +		sched = drm_sched_pick_best(entity->sched_list, entity->num_sched_list);
>   	rq = sched ? sched->sched_rq[entity->priority] : NULL;
>   	if (rq != entity->rq) {
>   		drm_sched_rq_remove_entity(entity->rq, entity);
> diff --git a/drivers/gpu/drm/scheduler/sched_main.c b/drivers/gpu/drm/scheduler/sched_main.c
> index 7e90c9f95611..356adf510670 100644
> --- a/drivers/gpu/drm/scheduler/sched_main.c
> +++ b/drivers/gpu/drm/scheduler/sched_main.c
> @@ -833,13 +833,13 @@ EXPORT_SYMBOL(drm_sched_job_init);
>    *
>    * This can only be called if drm_sched_job_init() succeeded.
>    */
> -void drm_sched_job_arm(struct drm_sched_job *job)
> +void drm_sched_job_arm(struct drm_sched_job *job, int ring)
>   {
>   	struct drm_gpu_scheduler *sched;
>   	struct drm_sched_entity *entity = job->entity;
>   
>   	BUG_ON(!entity);
> -	drm_sched_entity_select_rq(entity);
> +	drm_sched_entity_select_rq(entity, ring);
>   	sched = entity->rq->sched;
>   
>   	job->sched = sched;
> diff --git a/drivers/gpu/drm/v3d/v3d_submit.c b/drivers/gpu/drm/v3d/v3d_submit.c
> index 88f63d526b22..d33749017f93 100644
> --- a/drivers/gpu/drm/v3d/v3d_submit.c
> +++ b/drivers/gpu/drm/v3d/v3d_submit.c
> @@ -211,7 +211,7 @@ v3d_job_init(struct v3d_dev *v3d, struct drm_file *file_priv,
>   static void
>   v3d_push_job(struct v3d_job *job)
>   {
> -	drm_sched_job_arm(&job->base);
> +	drm_sched_job_arm(&job->base, -1);
>   
>   	job->done_fence = dma_fence_get(&job->base.s_fence->finished);
>   
> diff --git a/include/drm/gpu_scheduler.h b/include/drm/gpu_scheduler.h
> index 5acc64954a88..0eab405a2683 100644
> --- a/include/drm/gpu_scheduler.h
> +++ b/include/drm/gpu_scheduler.h
> @@ -553,7 +553,7 @@ void drm_sched_fini(struct drm_gpu_scheduler *sched);
>   int drm_sched_job_init(struct drm_sched_job *job,
>   		       struct drm_sched_entity *entity,
>   		       u32 credits, void *owner);
> -void drm_sched_job_arm(struct drm_sched_job *job);
> +void drm_sched_job_arm(struct drm_sched_job *job, int ring);
>   int drm_sched_job_add_dependency(struct drm_sched_job *job,
>   				 struct dma_fence *fence);
>   int drm_sched_job_add_syncobj_dependency(struct drm_sched_job *job,
> @@ -603,7 +603,7 @@ int drm_sched_entity_init(struct drm_sched_entity *entity,
>   long drm_sched_entity_flush(struct drm_sched_entity *entity, long timeout);
>   void drm_sched_entity_fini(struct drm_sched_entity *entity);
>   void drm_sched_entity_destroy(struct drm_sched_entity *entity);
> -void drm_sched_entity_select_rq(struct drm_sched_entity *entity);
> +void drm_sched_entity_select_rq(struct drm_sched_entity *entity, int ring);
>   struct drm_sched_job *drm_sched_entity_pop_job(struct drm_sched_entity *entity);
>   void drm_sched_entity_push_job(struct drm_sched_job *sched_job);
>   void drm_sched_entity_set_priority(struct drm_sched_entity *entity,
Zhang, Jesse(Jie) Oct. 12, 2024, 1:45 a.m. UTC | #2
[AMD Official Use Only - AMD Internal Distribution Only]

Hi Christian,

-----Original Message-----
From: Koenig, Christian <Christian.Koenig@amd.com>
Sent: Friday, October 11, 2024 4:40 PM
To: Zhang, Jesse(Jie) <Jesse.Zhang@amd.com>; dri-devel@lists.freedesktop.org; amd-gfx@lists.freedesktop.org
Cc: Deucher, Alexander <Alexander.Deucher@amd.com>
Subject: Re: [PATCH 1/2] drm/sched: adding a new scheduling policy

Am 11.10.24 um 08:21 schrieb jesse.zhang@amd.com:
> From: "Jesse.zhang@amd.com" <jesse.zhang@amd.com>
>
> Added ring ID scheduling.
> In some cases, userspace needs to run a job on a specific ring.
> Instead of selecting the best ring to run based on the ring score.
> For example, The user want to run a bad job on a specific ring to
> check whether the ring can recover from a queue reset.

Absolutely clearly a NAK, we don't want to expose the different HW rings directly to userspace.

Thanks for the confirmation. It was a bit confusing.
But now userspace can get the number of hardware rings directly via amdgpu info ioctl.

Regards
Jesse

Regards,
Christian.

>
> Signed-off-by: Jesse Zhang <Jesse.Zhang@amd.com>
> ---
>   drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c   |  2 +-
>   drivers/gpu/drm/amd/amdgpu/amdgpu_job.c  |  2 +-
>   drivers/gpu/drm/etnaviv/etnaviv_sched.c  |  2 +-
>   drivers/gpu/drm/imagination/pvr_queue.c  |  2 +-
>   drivers/gpu/drm/lima/lima_sched.c        |  2 +-
>   drivers/gpu/drm/msm/msm_gem_submit.c     |  2 +-
>   drivers/gpu/drm/nouveau/nouveau_sched.c  |  2 +-
>   drivers/gpu/drm/panfrost/panfrost_job.c  |  2 +-
>   drivers/gpu/drm/scheduler/sched_entity.c | 11 +++++++++--
>   drivers/gpu/drm/scheduler/sched_main.c   |  4 ++--
>   drivers/gpu/drm/v3d/v3d_submit.c         |  2 +-
>   include/drm/gpu_scheduler.h              |  4 ++--
>   12 files changed, 22 insertions(+), 15 deletions(-)
>
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
> b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
> index d891ab779ca7..18887128a973 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
> @@ -1286,7 +1286,7 @@ static int amdgpu_cs_submit(struct amdgpu_cs_parser *p,
>       int r;
>
>       for (i = 0; i < p->gang_size; ++i)
> -             drm_sched_job_arm(&p->jobs[i]->base);
> +             drm_sched_job_arm(&p->jobs[i]->base, -1);
>
>       for (i = 0; i < p->gang_size; ++i) {
>               struct dma_fence *fence;
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_job.c
> b/drivers/gpu/drm/amd/amdgpu/amdgpu_job.c
> index 717adcedf096..8d75ffa9a097 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_job.c
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_job.c
> @@ -320,7 +320,7 @@ struct dma_fence *amdgpu_job_submit(struct amdgpu_job *job)
>   {
>       struct dma_fence *f;
>
> -     drm_sched_job_arm(&job->base);
> +     drm_sched_job_arm(&job->base, -1);
>       f = dma_fence_get(&job->base.s_fence->finished);
>       amdgpu_job_free_resources(job);
>       drm_sched_entity_push_job(&job->base);
> diff --git a/drivers/gpu/drm/etnaviv/etnaviv_sched.c
> b/drivers/gpu/drm/etnaviv/etnaviv_sched.c
> index 62dcfdc7894d..98d003757af1 100644
> --- a/drivers/gpu/drm/etnaviv/etnaviv_sched.c
> +++ b/drivers/gpu/drm/etnaviv/etnaviv_sched.c
> @@ -107,7 +107,7 @@ int etnaviv_sched_push_job(struct etnaviv_gem_submit *submit)
>        */
>       mutex_lock(&gpu->sched_lock);
>
> -     drm_sched_job_arm(&submit->sched_job);
> +     drm_sched_job_arm(&submit->sched_job, -1);
>
>       submit->out_fence = dma_fence_get(&submit->sched_job.s_fence->finished);
>       ret = xa_alloc_cyclic(&gpu->user_fences, &submit->out_fence_id,
> diff --git a/drivers/gpu/drm/imagination/pvr_queue.c
> b/drivers/gpu/drm/imagination/pvr_queue.c
> index 5ed9c98fb599..ed7398a0ff21 100644
> --- a/drivers/gpu/drm/imagination/pvr_queue.c
> +++ b/drivers/gpu/drm/imagination/pvr_queue.c
> @@ -1115,7 +1115,7 @@ int pvr_queue_job_init(struct pvr_job *job)
>    */
>   struct dma_fence *pvr_queue_job_arm(struct pvr_job *job)
>   {
> -     drm_sched_job_arm(&job->base);
> +     drm_sched_job_arm(&job->base, -1);
>
>       return &job->base.s_fence->finished;
>   }
> diff --git a/drivers/gpu/drm/lima/lima_sched.c
> b/drivers/gpu/drm/lima/lima_sched.c
> index bbf3f8feab94..cc83b2aab9ce 100644
> --- a/drivers/gpu/drm/lima/lima_sched.c
> +++ b/drivers/gpu/drm/lima/lima_sched.c
> @@ -130,7 +130,7 @@ int lima_sched_task_init(struct lima_sched_task *task,
>               return err;
>       }
>
> -     drm_sched_job_arm(&task->base);
> +     drm_sched_job_arm(&task->base, -1);
>
>       task->num_bos = num_bos;
>       task->vm = lima_vm_get(vm);
> diff --git a/drivers/gpu/drm/msm/msm_gem_submit.c
> b/drivers/gpu/drm/msm/msm_gem_submit.c
> index fba78193127d..74c4e1b4df78 100644
> --- a/drivers/gpu/drm/msm/msm_gem_submit.c
> +++ b/drivers/gpu/drm/msm/msm_gem_submit.c
> @@ -831,7 +831,7 @@ int msm_ioctl_gem_submit(struct drm_device *dev, void *data,
>               goto out;
>       }
>
> -     drm_sched_job_arm(&submit->base);
> +     drm_sched_job_arm(&submit->base, -1);
>
>       submit->user_fence =
> dma_fence_get(&submit->base.s_fence->finished);
>
> diff --git a/drivers/gpu/drm/nouveau/nouveau_sched.c
> b/drivers/gpu/drm/nouveau/nouveau_sched.c
> index 32fa2e273965..3ff8142b5370 100644
> --- a/drivers/gpu/drm/nouveau/nouveau_sched.c
> +++ b/drivers/gpu/drm/nouveau/nouveau_sched.c
> @@ -309,7 +309,7 @@ nouveau_job_submit(struct nouveau_job *job)
>       list_add(&job->entry, &sched->job.list.head);
>       spin_unlock(&sched->job.list.lock);
>
> -     drm_sched_job_arm(&job->base);
> +     drm_sched_job_arm(&job->base, -1);
>       job->done_fence = dma_fence_get(&job->base.s_fence->finished);
>       if (job->sync)
>               done_fence = dma_fence_get(job->done_fence); diff --git
> a/drivers/gpu/drm/panfrost/panfrost_job.c
> b/drivers/gpu/drm/panfrost/panfrost_job.c
> index a61ef0af9a4e..cc937420cd35 100644
> --- a/drivers/gpu/drm/panfrost/panfrost_job.c
> +++ b/drivers/gpu/drm/panfrost/panfrost_job.c
> @@ -301,7 +301,7 @@ int panfrost_job_push(struct panfrost_job *job)
>               return ret;
>
>       mutex_lock(&pfdev->sched_lock);
> -     drm_sched_job_arm(&job->base);
> +     drm_sched_job_arm(&job->base, -1);
>
>       job->render_done_fence =
> dma_fence_get(&job->base.s_fence->finished);
>
> diff --git a/drivers/gpu/drm/scheduler/sched_entity.c
> b/drivers/gpu/drm/scheduler/sched_entity.c
> index 58c8161289fe..f4669422b3f9 100644
> --- a/drivers/gpu/drm/scheduler/sched_entity.c
> +++ b/drivers/gpu/drm/scheduler/sched_entity.c
> @@ -525,7 +525,7 @@ struct drm_sched_job *drm_sched_entity_pop_job(struct drm_sched_entity *entity)
>       return sched_job;
>   }
>
> -void drm_sched_entity_select_rq(struct drm_sched_entity *entity)
> +void drm_sched_entity_select_rq(struct drm_sched_entity *entity, int
> +ring)
>   {
>       struct dma_fence *fence;
>       struct drm_gpu_scheduler *sched;
> @@ -554,7 +554,14 @@ void drm_sched_entity_select_rq(struct drm_sched_entity *entity)
>               return;
>
>       spin_lock(&entity->rq_lock);
> -     sched = drm_sched_pick_best(entity->sched_list, entity->num_sched_list);
> +     if(ring >= 0) {
> +             if(entity->sched_list[ring] && entity->sched_list[ring]->ready)
> +                     sched = entity->sched_list[ring];
> +             else
> +                     sched = drm_sched_pick_best(entity->sched_list, entity->num_sched_list);
> +     }
> +     else
> +             sched = drm_sched_pick_best(entity->sched_list,
> +entity->num_sched_list);
>       rq = sched ? sched->sched_rq[entity->priority] : NULL;
>       if (rq != entity->rq) {
>               drm_sched_rq_remove_entity(entity->rq, entity); diff --git
> a/drivers/gpu/drm/scheduler/sched_main.c
> b/drivers/gpu/drm/scheduler/sched_main.c
> index 7e90c9f95611..356adf510670 100644
> --- a/drivers/gpu/drm/scheduler/sched_main.c
> +++ b/drivers/gpu/drm/scheduler/sched_main.c
> @@ -833,13 +833,13 @@ EXPORT_SYMBOL(drm_sched_job_init);
>    *
>    * This can only be called if drm_sched_job_init() succeeded.
>    */
> -void drm_sched_job_arm(struct drm_sched_job *job)
> +void drm_sched_job_arm(struct drm_sched_job *job, int ring)
>   {
>       struct drm_gpu_scheduler *sched;
>       struct drm_sched_entity *entity = job->entity;
>
>       BUG_ON(!entity);
> -     drm_sched_entity_select_rq(entity);
> +     drm_sched_entity_select_rq(entity, ring);
>       sched = entity->rq->sched;
>
>       job->sched = sched;
> diff --git a/drivers/gpu/drm/v3d/v3d_submit.c
> b/drivers/gpu/drm/v3d/v3d_submit.c
> index 88f63d526b22..d33749017f93 100644
> --- a/drivers/gpu/drm/v3d/v3d_submit.c
> +++ b/drivers/gpu/drm/v3d/v3d_submit.c
> @@ -211,7 +211,7 @@ v3d_job_init(struct v3d_dev *v3d, struct drm_file *file_priv,
>   static void
>   v3d_push_job(struct v3d_job *job)
>   {
> -     drm_sched_job_arm(&job->base);
> +     drm_sched_job_arm(&job->base, -1);
>
>       job->done_fence = dma_fence_get(&job->base.s_fence->finished);
>
> diff --git a/include/drm/gpu_scheduler.h b/include/drm/gpu_scheduler.h
> index 5acc64954a88..0eab405a2683 100644
> --- a/include/drm/gpu_scheduler.h
> +++ b/include/drm/gpu_scheduler.h
> @@ -553,7 +553,7 @@ void drm_sched_fini(struct drm_gpu_scheduler *sched);
>   int drm_sched_job_init(struct drm_sched_job *job,
>                      struct drm_sched_entity *entity,
>                      u32 credits, void *owner);
> -void drm_sched_job_arm(struct drm_sched_job *job);
> +void drm_sched_job_arm(struct drm_sched_job *job, int ring);
>   int drm_sched_job_add_dependency(struct drm_sched_job *job,
>                                struct dma_fence *fence);
>   int drm_sched_job_add_syncobj_dependency(struct drm_sched_job *job,
> @@ -603,7 +603,7 @@ int drm_sched_entity_init(struct drm_sched_entity *entity,
>   long drm_sched_entity_flush(struct drm_sched_entity *entity, long timeout);
>   void drm_sched_entity_fini(struct drm_sched_entity *entity);
>   void drm_sched_entity_destroy(struct drm_sched_entity *entity);
> -void drm_sched_entity_select_rq(struct drm_sched_entity *entity);
> +void drm_sched_entity_select_rq(struct drm_sched_entity *entity, int
> +ring);
>   struct drm_sched_job *drm_sched_entity_pop_job(struct drm_sched_entity *entity);
>   void drm_sched_entity_push_job(struct drm_sched_job *sched_job);
>   void drm_sched_entity_set_priority(struct drm_sched_entity *entity,
kernel test robot Oct. 12, 2024, 10:44 a.m. UTC | #3
Hi,

kernel test robot noticed the following build errors:

[auto build test ERROR on drm-exynos/exynos-drm-next]
[also build test ERROR on drm-intel/for-linux-next drm-intel/for-linux-next-fixes drm-misc/drm-misc-next drm-tip/drm-tip linus/master v6.12-rc2 next-20241011]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]

url:    https://github.com/intel-lab-lkp/linux/commits/jesse-zhang-amd-com/drm-amdgpu-add-the-ring-id-schedule-module-parameter-for-amdgpu/20241011-142247
base:   https://git.kernel.org/pub/scm/linux/kernel/git/daeinki/drm-exynos.git exynos-drm-next
patch link:    https://lore.kernel.org/r/20241011062136.1019695-1-jesse.zhang%40amd.com
patch subject: [PATCH 1/2] drm/sched: adding a new scheduling policy
config: sparc64-randconfig-r073-20241012 (https://download.01.org/0day-ci/archive/20241012/202410121817.HUe5MN9d-lkp@intel.com/config)
compiler: sparc64-linux-gcc (GCC) 14.1.0
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20241012/202410121817.HUe5MN9d-lkp@intel.com/reproduce)

If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202410121817.HUe5MN9d-lkp@intel.com/

All error/warnings (new ones prefixed by >>):

   drivers/gpu/drm/panthor/panthor_drv.c: In function 'panthor_submit_ctx_add_deps_and_arm_jobs':
>> drivers/gpu/drm/panthor/panthor_drv.c:674:17: error: too few arguments to function 'drm_sched_job_arm'
     674 |                 drm_sched_job_arm(ctx->jobs[i].job);
         |                 ^~~~~~~~~~~~~~~~~
   In file included from drivers/gpu/drm/panthor/panthor_drv.c:20:
   include/drm/gpu_scheduler.h:556:6: note: declared here
     556 | void drm_sched_job_arm(struct drm_sched_job *job, int ring);
         |      ^~~~~~~~~~~~~~~~~
--
   drivers/gpu/drm/scheduler/sched_main.c:405: warning: Function parameter or struct member 'result' not described in 'drm_sched_job_done'
>> drivers/gpu/drm/scheduler/sched_main.c:828: warning: Function parameter or struct member 'ring' not described in 'drm_sched_job_arm'


vim +/drm_sched_job_arm +674 drivers/gpu/drm/panthor/panthor_drv.c

4bdca11507928a Boris Brezillon 2024-02-29  655  
4bdca11507928a Boris Brezillon 2024-02-29  656  /**
4bdca11507928a Boris Brezillon 2024-02-29  657   * panthor_submit_ctx_add_deps_and_arm_jobs() - Add jobs dependencies and arm jobs
4bdca11507928a Boris Brezillon 2024-02-29  658   * @ctx: Submit context.
4bdca11507928a Boris Brezillon 2024-02-29  659   *
4bdca11507928a Boris Brezillon 2024-02-29  660   * Must be called after the resv preparation has been taken care of.
4bdca11507928a Boris Brezillon 2024-02-29  661   *
4bdca11507928a Boris Brezillon 2024-02-29  662   * Return: 0 on success, a negative error code otherwise.
4bdca11507928a Boris Brezillon 2024-02-29  663   */
4bdca11507928a Boris Brezillon 2024-02-29  664  static int
4bdca11507928a Boris Brezillon 2024-02-29  665  panthor_submit_ctx_add_deps_and_arm_jobs(struct panthor_submit_ctx *ctx)
4bdca11507928a Boris Brezillon 2024-02-29  666  {
4bdca11507928a Boris Brezillon 2024-02-29  667  	for (u32 i = 0; i < ctx->job_count; i++) {
4bdca11507928a Boris Brezillon 2024-02-29  668  		int ret;
4bdca11507928a Boris Brezillon 2024-02-29  669  
4bdca11507928a Boris Brezillon 2024-02-29  670  		ret = panthor_submit_ctx_add_sync_deps_to_job(ctx, i);
4bdca11507928a Boris Brezillon 2024-02-29  671  		if (ret)
4bdca11507928a Boris Brezillon 2024-02-29  672  			return ret;
4bdca11507928a Boris Brezillon 2024-02-29  673  
4bdca11507928a Boris Brezillon 2024-02-29 @674  		drm_sched_job_arm(ctx->jobs[i].job);
4bdca11507928a Boris Brezillon 2024-02-29  675  
4bdca11507928a Boris Brezillon 2024-02-29  676  		ret = panthor_submit_ctx_update_job_sync_signal_fences(ctx, i);
4bdca11507928a Boris Brezillon 2024-02-29  677  		if (ret)
4bdca11507928a Boris Brezillon 2024-02-29  678  			return ret;
4bdca11507928a Boris Brezillon 2024-02-29  679  	}
4bdca11507928a Boris Brezillon 2024-02-29  680  
4bdca11507928a Boris Brezillon 2024-02-29  681  	return 0;
4bdca11507928a Boris Brezillon 2024-02-29  682  }
4bdca11507928a Boris Brezillon 2024-02-29  683
kernel test robot Oct. 12, 2024, 11:35 a.m. UTC | #4
Hi,

kernel test robot noticed the following build errors:

[auto build test ERROR on drm-exynos/exynos-drm-next]
[also build test ERROR on drm-intel/for-linux-next drm-intel/for-linux-next-fixes drm-misc/drm-misc-next drm-tip/drm-tip linus/master v6.12-rc2 next-20241011]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]

url:    https://github.com/intel-lab-lkp/linux/commits/jesse-zhang-amd-com/drm-amdgpu-add-the-ring-id-schedule-module-parameter-for-amdgpu/20241011-142247
base:   https://git.kernel.org/pub/scm/linux/kernel/git/daeinki/drm-exynos.git exynos-drm-next
patch link:    https://lore.kernel.org/r/20241011062136.1019695-1-jesse.zhang%40amd.com
patch subject: [PATCH 1/2] drm/sched: adding a new scheduling policy
config: i386-randconfig-141-20241012 (https://download.01.org/0day-ci/archive/20241012/202410121939.cZrBIAkO-lkp@intel.com/config)
compiler: gcc-12 (Debian 12.2.0-14) 12.2.0
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20241012/202410121939.cZrBIAkO-lkp@intel.com/reproduce)

If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202410121939.cZrBIAkO-lkp@intel.com/

All errors (new ones prefixed by >>):

   drivers/gpu/drm/xe/xe_sched_job.c: In function 'xe_sched_job_arm':
>> drivers/gpu/drm/xe/xe_sched_job.c:284:9: error: too few arguments to function 'drm_sched_job_arm'
     284 |         drm_sched_job_arm(&job->drm);
         |         ^~~~~~~~~~~~~~~~~
   In file included from drivers/gpu/drm/xe/xe_sched_job_types.h:11,
                    from drivers/gpu/drm/xe/xe_sched_job.h:9,
                    from drivers/gpu/drm/xe/xe_sched_job.c:6:
   include/drm/gpu_scheduler.h:556:6: note: declared here
     556 | void drm_sched_job_arm(struct drm_sched_job *job, int ring);
         |      ^~~~~~~~~~~~~~~~~


vim +/drm_sched_job_arm +284 drivers/gpu/drm/xe/xe_sched_job.c

dd08ebf6c3525a Matthew Brost             2023-03-30  239  
dd08ebf6c3525a Matthew Brost             2023-03-30  240  void xe_sched_job_arm(struct xe_sched_job *job)
dd08ebf6c3525a Matthew Brost             2023-03-30  241  {
4fc4899e86f7af Thomas Hellström          2024-03-27  242  	struct xe_exec_queue *q = job->q;
0ac7a2c745e8a4 Thomas Hellström          2024-05-27  243  	struct dma_fence *fence, *prev;
4fc4899e86f7af Thomas Hellström          2024-03-27  244  	struct xe_vm *vm = q->vm;
0ac7a2c745e8a4 Thomas Hellström          2024-05-27  245  	u64 seqno = 0;
0ac7a2c745e8a4 Thomas Hellström          2024-05-27  246  	int i;
0ac7a2c745e8a4 Thomas Hellström          2024-05-27  247  
0ac7a2c745e8a4 Thomas Hellström          2024-05-27  248  	/* Migration and kernel engines have their own locking */
0ac7a2c745e8a4 Thomas Hellström          2024-05-27  249  	if (IS_ENABLED(CONFIG_LOCKDEP) &&
0ac7a2c745e8a4 Thomas Hellström          2024-05-27  250  	    !(q->flags & (EXEC_QUEUE_FLAG_KERNEL | EXEC_QUEUE_FLAG_VM))) {
0ac7a2c745e8a4 Thomas Hellström          2024-05-27  251  		lockdep_assert_held(&q->vm->lock);
0ac7a2c745e8a4 Thomas Hellström          2024-05-27  252  		if (!xe_vm_in_lr_mode(q->vm))
0ac7a2c745e8a4 Thomas Hellström          2024-05-27  253  			xe_vm_assert_held(q->vm);
0ac7a2c745e8a4 Thomas Hellström          2024-05-27  254  	}
4fc4899e86f7af Thomas Hellström          2024-03-27  255  
4fc4899e86f7af Thomas Hellström          2024-03-27  256  	if (vm && !xe_sched_job_is_migration(q) && !xe_vm_in_lr_mode(vm) &&
4fc4899e86f7af Thomas Hellström          2024-03-27  257  	    (vm->batch_invalidate_tlb || vm->tlb_flush_seqno != q->tlb_flush_seqno)) {
4fc4899e86f7af Thomas Hellström          2024-03-27  258  		xe_vm_assert_held(vm);
4fc4899e86f7af Thomas Hellström          2024-03-27  259  		q->tlb_flush_seqno = vm->tlb_flush_seqno;
4fc4899e86f7af Thomas Hellström          2024-03-27  260  		job->ring_ops_flush_tlb = true;
4fc4899e86f7af Thomas Hellström          2024-03-27  261  	}
4fc4899e86f7af Thomas Hellström          2024-03-27  262  
0ac7a2c745e8a4 Thomas Hellström          2024-05-27  263  	/* Arm the pre-allocated fences */
0ac7a2c745e8a4 Thomas Hellström          2024-05-27  264  	for (i = 0; i < q->width; prev = fence, ++i) {
0ac7a2c745e8a4 Thomas Hellström          2024-05-27  265  		struct dma_fence_chain *chain;
0ac7a2c745e8a4 Thomas Hellström          2024-05-27  266  
0ac7a2c745e8a4 Thomas Hellström          2024-05-27  267  		fence = job->ptrs[i].lrc_fence;
264eecdba211bb Niranjana Vishwanathapura 2024-05-29  268  		xe_lrc_init_seqno_fence(q->lrc[i], fence);
0ac7a2c745e8a4 Thomas Hellström          2024-05-27  269  		job->ptrs[i].lrc_fence = NULL;
0ac7a2c745e8a4 Thomas Hellström          2024-05-27  270  		if (!i) {
0ac7a2c745e8a4 Thomas Hellström          2024-05-27  271  			job->lrc_seqno = fence->seqno;
0ac7a2c745e8a4 Thomas Hellström          2024-05-27  272  			continue;
0ac7a2c745e8a4 Thomas Hellström          2024-05-27  273  		} else {
0ac7a2c745e8a4 Thomas Hellström          2024-05-27  274  			xe_assert(gt_to_xe(q->gt), job->lrc_seqno == fence->seqno);
0ac7a2c745e8a4 Thomas Hellström          2024-05-27  275  		}
0ac7a2c745e8a4 Thomas Hellström          2024-05-27  276  
0ac7a2c745e8a4 Thomas Hellström          2024-05-27  277  		chain = job->ptrs[i - 1].chain_fence;
0ac7a2c745e8a4 Thomas Hellström          2024-05-27  278  		dma_fence_chain_init(chain, prev, fence, seqno++);
0ac7a2c745e8a4 Thomas Hellström          2024-05-27  279  		job->ptrs[i - 1].chain_fence = NULL;
0ac7a2c745e8a4 Thomas Hellström          2024-05-27  280  		fence = &chain->base;
0ac7a2c745e8a4 Thomas Hellström          2024-05-27  281  	}
0ac7a2c745e8a4 Thomas Hellström          2024-05-27  282  
0ac7a2c745e8a4 Thomas Hellström          2024-05-27  283  	job->fence = fence;
dd08ebf6c3525a Matthew Brost             2023-03-30 @284  	drm_sched_job_arm(&job->drm);
dd08ebf6c3525a Matthew Brost             2023-03-30  285  }
dd08ebf6c3525a Matthew Brost             2023-03-30  286
Alex Deucher Oct. 14, 2024, 9:56 p.m. UTC | #5
[AMD Official Use Only - AMD Internal Distribution Only]

> -----Original Message-----
> From: Zhang, Jesse(Jie) <Jesse.Zhang@amd.com>
> Sent: Friday, October 11, 2024 9:45 PM
> To: Koenig, Christian <Christian.Koenig@amd.com>; dri-
> devel@lists.freedesktop.org; amd-gfx@lists.freedesktop.org
> Cc: Deucher, Alexander <Alexander.Deucher@amd.com>
> Subject: RE: [PATCH 1/2] drm/sched: adding a new scheduling policy
>
> [AMD Official Use Only - AMD Internal Distribution Only]
>
> Hi Christian,
>
> -----Original Message-----
> From: Koenig, Christian <Christian.Koenig@amd.com>
> Sent: Friday, October 11, 2024 4:40 PM
> To: Zhang, Jesse(Jie) <Jesse.Zhang@amd.com>; dri-devel@lists.freedesktop.org;
> amd-gfx@lists.freedesktop.org
> Cc: Deucher, Alexander <Alexander.Deucher@amd.com>
> Subject: Re: [PATCH 1/2] drm/sched: adding a new scheduling policy
>
> Am 11.10.24 um 08:21 schrieb jesse.zhang@amd.com:
> > From: "Jesse.zhang@amd.com" <jesse.zhang@amd.com>
> >
> > Added ring ID scheduling.
> > In some cases, userspace needs to run a job on a specific ring.
> > Instead of selecting the best ring to run based on the ring score.
> > For example, The user want to run a bad job on a specific ring to
> > check whether the ring can recover from a queue reset.
>
> Absolutely clearly a NAK, we don't want to expose the different HW rings directly to
> userspace.
>
> Thanks for the confirmation. It was a bit confusing.
> But now userspace can get the number of hardware rings directly via amdgpu info
> ioctl.

That number does not align with the actual number of rings on the IP.  It's just used for allowing userspace to schedule things in parallel.  The kernel driver still decides which actual rings to use based on load.  If you want to target specific rings, you might want to consider doing something like this:
https://gitlab.freedesktop.org/agd5f/linux/-/commit/08c517d5a923628de50f93e8a9fedd647d3eefbb

Alex

>
> Regards
> Jesse
>
> Regards,
> Christian.
>
> >
> > Signed-off-by: Jesse Zhang <Jesse.Zhang@amd.com>
> > ---
> >   drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c   |  2 +-
> >   drivers/gpu/drm/amd/amdgpu/amdgpu_job.c  |  2 +-
> >   drivers/gpu/drm/etnaviv/etnaviv_sched.c  |  2 +-
> >   drivers/gpu/drm/imagination/pvr_queue.c  |  2 +-
> >   drivers/gpu/drm/lima/lima_sched.c        |  2 +-
> >   drivers/gpu/drm/msm/msm_gem_submit.c     |  2 +-
> >   drivers/gpu/drm/nouveau/nouveau_sched.c  |  2 +-
> >   drivers/gpu/drm/panfrost/panfrost_job.c  |  2 +-
> >   drivers/gpu/drm/scheduler/sched_entity.c | 11 +++++++++--
> >   drivers/gpu/drm/scheduler/sched_main.c   |  4 ++--
> >   drivers/gpu/drm/v3d/v3d_submit.c         |  2 +-
> >   include/drm/gpu_scheduler.h              |  4 ++--
> >   12 files changed, 22 insertions(+), 15 deletions(-)
> >
> > diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
> > b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
> > index d891ab779ca7..18887128a973 100644
> > --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
> > +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
> > @@ -1286,7 +1286,7 @@ static int amdgpu_cs_submit(struct amdgpu_cs_parser
> *p,
> >       int r;
> >
> >       for (i = 0; i < p->gang_size; ++i)
> > -             drm_sched_job_arm(&p->jobs[i]->base);
> > +             drm_sched_job_arm(&p->jobs[i]->base, -1);
> >
> >       for (i = 0; i < p->gang_size; ++i) {
> >               struct dma_fence *fence; diff --git
> > a/drivers/gpu/drm/amd/amdgpu/amdgpu_job.c
> > b/drivers/gpu/drm/amd/amdgpu/amdgpu_job.c
> > index 717adcedf096..8d75ffa9a097 100644
> > --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_job.c
> > +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_job.c
> > @@ -320,7 +320,7 @@ struct dma_fence *amdgpu_job_submit(struct
> amdgpu_job *job)
> >   {
> >       struct dma_fence *f;
> >
> > -     drm_sched_job_arm(&job->base);
> > +     drm_sched_job_arm(&job->base, -1);
> >       f = dma_fence_get(&job->base.s_fence->finished);
> >       amdgpu_job_free_resources(job);
> >       drm_sched_entity_push_job(&job->base);
> > diff --git a/drivers/gpu/drm/etnaviv/etnaviv_sched.c
> > b/drivers/gpu/drm/etnaviv/etnaviv_sched.c
> > index 62dcfdc7894d..98d003757af1 100644
> > --- a/drivers/gpu/drm/etnaviv/etnaviv_sched.c
> > +++ b/drivers/gpu/drm/etnaviv/etnaviv_sched.c
> > @@ -107,7 +107,7 @@ int etnaviv_sched_push_job(struct etnaviv_gem_submit
> *submit)
> >        */
> >       mutex_lock(&gpu->sched_lock);
> >
> > -     drm_sched_job_arm(&submit->sched_job);
> > +     drm_sched_job_arm(&submit->sched_job, -1);
> >
> >       submit->out_fence = dma_fence_get(&submit->sched_job.s_fence->finished);
> >       ret = xa_alloc_cyclic(&gpu->user_fences, &submit->out_fence_id,
> > diff --git a/drivers/gpu/drm/imagination/pvr_queue.c
> > b/drivers/gpu/drm/imagination/pvr_queue.c
> > index 5ed9c98fb599..ed7398a0ff21 100644
> > --- a/drivers/gpu/drm/imagination/pvr_queue.c
> > +++ b/drivers/gpu/drm/imagination/pvr_queue.c
> > @@ -1115,7 +1115,7 @@ int pvr_queue_job_init(struct pvr_job *job)
> >    */
> >   struct dma_fence *pvr_queue_job_arm(struct pvr_job *job)
> >   {
> > -     drm_sched_job_arm(&job->base);
> > +     drm_sched_job_arm(&job->base, -1);
> >
> >       return &job->base.s_fence->finished;
> >   }
> > diff --git a/drivers/gpu/drm/lima/lima_sched.c
> > b/drivers/gpu/drm/lima/lima_sched.c
> > index bbf3f8feab94..cc83b2aab9ce 100644
> > --- a/drivers/gpu/drm/lima/lima_sched.c
> > +++ b/drivers/gpu/drm/lima/lima_sched.c
> > @@ -130,7 +130,7 @@ int lima_sched_task_init(struct lima_sched_task *task,
> >               return err;
> >       }
> >
> > -     drm_sched_job_arm(&task->base);
> > +     drm_sched_job_arm(&task->base, -1);
> >
> >       task->num_bos = num_bos;
> >       task->vm = lima_vm_get(vm);
> > diff --git a/drivers/gpu/drm/msm/msm_gem_submit.c
> > b/drivers/gpu/drm/msm/msm_gem_submit.c
> > index fba78193127d..74c4e1b4df78 100644
> > --- a/drivers/gpu/drm/msm/msm_gem_submit.c
> > +++ b/drivers/gpu/drm/msm/msm_gem_submit.c
> > @@ -831,7 +831,7 @@ int msm_ioctl_gem_submit(struct drm_device *dev, void
> *data,
> >               goto out;
> >       }
> >
> > -     drm_sched_job_arm(&submit->base);
> > +     drm_sched_job_arm(&submit->base, -1);
> >
> >       submit->user_fence =
> > dma_fence_get(&submit->base.s_fence->finished);
> >
> > diff --git a/drivers/gpu/drm/nouveau/nouveau_sched.c
> > b/drivers/gpu/drm/nouveau/nouveau_sched.c
> > index 32fa2e273965..3ff8142b5370 100644
> > --- a/drivers/gpu/drm/nouveau/nouveau_sched.c
> > +++ b/drivers/gpu/drm/nouveau/nouveau_sched.c
> > @@ -309,7 +309,7 @@ nouveau_job_submit(struct nouveau_job *job)
> >       list_add(&job->entry, &sched->job.list.head);
> >       spin_unlock(&sched->job.list.lock);
> >
> > -     drm_sched_job_arm(&job->base);
> > +     drm_sched_job_arm(&job->base, -1);
> >       job->done_fence = dma_fence_get(&job->base.s_fence->finished);
> >       if (job->sync)
> >               done_fence = dma_fence_get(job->done_fence); diff --git
> > a/drivers/gpu/drm/panfrost/panfrost_job.c
> > b/drivers/gpu/drm/panfrost/panfrost_job.c
> > index a61ef0af9a4e..cc937420cd35 100644
> > --- a/drivers/gpu/drm/panfrost/panfrost_job.c
> > +++ b/drivers/gpu/drm/panfrost/panfrost_job.c
> > @@ -301,7 +301,7 @@ int panfrost_job_push(struct panfrost_job *job)
> >               return ret;
> >
> >       mutex_lock(&pfdev->sched_lock);
> > -     drm_sched_job_arm(&job->base);
> > +     drm_sched_job_arm(&job->base, -1);
> >
> >       job->render_done_fence =
> > dma_fence_get(&job->base.s_fence->finished);
> >
> > diff --git a/drivers/gpu/drm/scheduler/sched_entity.c
> > b/drivers/gpu/drm/scheduler/sched_entity.c
> > index 58c8161289fe..f4669422b3f9 100644
> > --- a/drivers/gpu/drm/scheduler/sched_entity.c
> > +++ b/drivers/gpu/drm/scheduler/sched_entity.c
> > @@ -525,7 +525,7 @@ struct drm_sched_job *drm_sched_entity_pop_job(struct
> drm_sched_entity *entity)
> >       return sched_job;
> >   }
> >
> > -void drm_sched_entity_select_rq(struct drm_sched_entity *entity)
> > +void drm_sched_entity_select_rq(struct drm_sched_entity *entity, int
> > +ring)
> >   {
> >       struct dma_fence *fence;
> >       struct drm_gpu_scheduler *sched; @@ -554,7 +554,14 @@ void
> > drm_sched_entity_select_rq(struct drm_sched_entity *entity)
> >               return;
> >
> >       spin_lock(&entity->rq_lock);
> > -     sched = drm_sched_pick_best(entity->sched_list, entity->num_sched_list);
> > +     if(ring >= 0) {
> > +             if(entity->sched_list[ring] && entity->sched_list[ring]->ready)
> > +                     sched = entity->sched_list[ring];
> > +             else
> > +                     sched = drm_sched_pick_best(entity->sched_list, entity-
> >num_sched_list);
> > +     }
> > +     else
> > +             sched = drm_sched_pick_best(entity->sched_list,
> > +entity->num_sched_list);
> >       rq = sched ? sched->sched_rq[entity->priority] : NULL;
> >       if (rq != entity->rq) {
> >               drm_sched_rq_remove_entity(entity->rq, entity); diff
> > --git a/drivers/gpu/drm/scheduler/sched_main.c
> > b/drivers/gpu/drm/scheduler/sched_main.c
> > index 7e90c9f95611..356adf510670 100644
> > --- a/drivers/gpu/drm/scheduler/sched_main.c
> > +++ b/drivers/gpu/drm/scheduler/sched_main.c
> > @@ -833,13 +833,13 @@ EXPORT_SYMBOL(drm_sched_job_init);
> >    *
> >    * This can only be called if drm_sched_job_init() succeeded.
> >    */
> > -void drm_sched_job_arm(struct drm_sched_job *job)
> > +void drm_sched_job_arm(struct drm_sched_job *job, int ring)
> >   {
> >       struct drm_gpu_scheduler *sched;
> >       struct drm_sched_entity *entity = job->entity;
> >
> >       BUG_ON(!entity);
> > -     drm_sched_entity_select_rq(entity);
> > +     drm_sched_entity_select_rq(entity, ring);
> >       sched = entity->rq->sched;
> >
> >       job->sched = sched;
> > diff --git a/drivers/gpu/drm/v3d/v3d_submit.c
> > b/drivers/gpu/drm/v3d/v3d_submit.c
> > index 88f63d526b22..d33749017f93 100644
> > --- a/drivers/gpu/drm/v3d/v3d_submit.c
> > +++ b/drivers/gpu/drm/v3d/v3d_submit.c
> > @@ -211,7 +211,7 @@ v3d_job_init(struct v3d_dev *v3d, struct drm_file *file_priv,
> >   static void
> >   v3d_push_job(struct v3d_job *job)
> >   {
> > -     drm_sched_job_arm(&job->base);
> > +     drm_sched_job_arm(&job->base, -1);
> >
> >       job->done_fence = dma_fence_get(&job->base.s_fence->finished);
> >
> > diff --git a/include/drm/gpu_scheduler.h b/include/drm/gpu_scheduler.h
> > index 5acc64954a88..0eab405a2683 100644
> > --- a/include/drm/gpu_scheduler.h
> > +++ b/include/drm/gpu_scheduler.h
> > @@ -553,7 +553,7 @@ void drm_sched_fini(struct drm_gpu_scheduler *sched);
> >   int drm_sched_job_init(struct drm_sched_job *job,
> >                      struct drm_sched_entity *entity,
> >                      u32 credits, void *owner); -void
> > drm_sched_job_arm(struct drm_sched_job *job);
> > +void drm_sched_job_arm(struct drm_sched_job *job, int ring);
> >   int drm_sched_job_add_dependency(struct drm_sched_job *job,
> >                                struct dma_fence *fence);
> >   int drm_sched_job_add_syncobj_dependency(struct drm_sched_job *job,
> > @@ -603,7 +603,7 @@ int drm_sched_entity_init(struct drm_sched_entity *entity,
> >   long drm_sched_entity_flush(struct drm_sched_entity *entity, long timeout);
> >   void drm_sched_entity_fini(struct drm_sched_entity *entity);
> >   void drm_sched_entity_destroy(struct drm_sched_entity *entity);
> > -void drm_sched_entity_select_rq(struct drm_sched_entity *entity);
> > +void drm_sched_entity_select_rq(struct drm_sched_entity *entity, int
> > +ring);
> >   struct drm_sched_job *drm_sched_entity_pop_job(struct drm_sched_entity
> *entity);
> >   void drm_sched_entity_push_job(struct drm_sched_job *sched_job);
> >   void drm_sched_entity_set_priority(struct drm_sched_entity *entity,
>
Christian König Oct. 16, 2024, 12:05 p.m. UTC | #6
Am 14.10.24 um 23:56 schrieb Deucher, Alexander:
> [AMD Official Use Only - AMD Internal Distribution Only]
>
>> -----Original Message-----
>> From: Zhang, Jesse(Jie) <Jesse.Zhang@amd.com>
>> Sent: Friday, October 11, 2024 9:45 PM
>> To: Koenig, Christian <Christian.Koenig@amd.com>; dri-
>> devel@lists.freedesktop.org; amd-gfx@lists.freedesktop.org
>> Cc: Deucher, Alexander <Alexander.Deucher@amd.com>
>> Subject: RE: [PATCH 1/2] drm/sched: adding a new scheduling policy
>>
>> [AMD Official Use Only - AMD Internal Distribution Only]
>>
>> Hi Christian,
>>
>> -----Original Message-----
>> From: Koenig, Christian <Christian.Koenig@amd.com>
>> Sent: Friday, October 11, 2024 4:40 PM
>> To: Zhang, Jesse(Jie) <Jesse.Zhang@amd.com>; dri-devel@lists.freedesktop.org;
>> amd-gfx@lists.freedesktop.org
>> Cc: Deucher, Alexander <Alexander.Deucher@amd.com>
>> Subject: Re: [PATCH 1/2] drm/sched: adding a new scheduling policy
>>
>> Am 11.10.24 um 08:21 schrieb jesse.zhang@amd.com:
>>> From: "Jesse.zhang@amd.com" <jesse.zhang@amd.com>
>>>
>>> Added ring ID scheduling.
>>> In some cases, userspace needs to run a job on a specific ring.
>>> Instead of selecting the best ring to run based on the ring score.
>>> For example, The user want to run a bad job on a specific ring to
>>> check whether the ring can recover from a queue reset.
>> Absolutely clearly a NAK, we don't want to expose the different HW rings directly to
>> userspace.
>>
>> Thanks for the confirmation. It was a bit confusing.
>> But now userspace can get the number of hardware rings directly via amdgpu info
>> ioctl.
> That number does not align with the actual number of rings on the IP.  It's just used for allowing userspace to schedule things in parallel.  The kernel driver still decides which actual rings to use based on load.  If you want to target specific rings, you might want to consider doing something like this:
> https://gitlab.freedesktop.org/agd5f/linux/-/commit/08c517d5a923628de50f93e8a9fedd647d3eefbb

Yeah that looks like a good solution to me as well.

Christian.

>
> Alex
>
>> Regards
>> Jesse
>>
>> Regards,
>> Christian.
>>
>>> Signed-off-by: Jesse Zhang <Jesse.Zhang@amd.com>
>>> ---
>>>    drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c   |  2 +-
>>>    drivers/gpu/drm/amd/amdgpu/amdgpu_job.c  |  2 +-
>>>    drivers/gpu/drm/etnaviv/etnaviv_sched.c  |  2 +-
>>>    drivers/gpu/drm/imagination/pvr_queue.c  |  2 +-
>>>    drivers/gpu/drm/lima/lima_sched.c        |  2 +-
>>>    drivers/gpu/drm/msm/msm_gem_submit.c     |  2 +-
>>>    drivers/gpu/drm/nouveau/nouveau_sched.c  |  2 +-
>>>    drivers/gpu/drm/panfrost/panfrost_job.c  |  2 +-
>>>    drivers/gpu/drm/scheduler/sched_entity.c | 11 +++++++++--
>>>    drivers/gpu/drm/scheduler/sched_main.c   |  4 ++--
>>>    drivers/gpu/drm/v3d/v3d_submit.c         |  2 +-
>>>    include/drm/gpu_scheduler.h              |  4 ++--
>>>    12 files changed, 22 insertions(+), 15 deletions(-)
>>>
>>> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
>>> b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
>>> index d891ab779ca7..18887128a973 100644
>>> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
>>> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
>>> @@ -1286,7 +1286,7 @@ static int amdgpu_cs_submit(struct amdgpu_cs_parser
>> *p,
>>>        int r;
>>>
>>>        for (i = 0; i < p->gang_size; ++i)
>>> -             drm_sched_job_arm(&p->jobs[i]->base);
>>> +             drm_sched_job_arm(&p->jobs[i]->base, -1);
>>>
>>>        for (i = 0; i < p->gang_size; ++i) {
>>>                struct dma_fence *fence; diff --git
>>> a/drivers/gpu/drm/amd/amdgpu/amdgpu_job.c
>>> b/drivers/gpu/drm/amd/amdgpu/amdgpu_job.c
>>> index 717adcedf096..8d75ffa9a097 100644
>>> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_job.c
>>> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_job.c
>>> @@ -320,7 +320,7 @@ struct dma_fence *amdgpu_job_submit(struct
>> amdgpu_job *job)
>>>    {
>>>        struct dma_fence *f;
>>>
>>> -     drm_sched_job_arm(&job->base);
>>> +     drm_sched_job_arm(&job->base, -1);
>>>        f = dma_fence_get(&job->base.s_fence->finished);
>>>        amdgpu_job_free_resources(job);
>>>        drm_sched_entity_push_job(&job->base);
>>> diff --git a/drivers/gpu/drm/etnaviv/etnaviv_sched.c
>>> b/drivers/gpu/drm/etnaviv/etnaviv_sched.c
>>> index 62dcfdc7894d..98d003757af1 100644
>>> --- a/drivers/gpu/drm/etnaviv/etnaviv_sched.c
>>> +++ b/drivers/gpu/drm/etnaviv/etnaviv_sched.c
>>> @@ -107,7 +107,7 @@ int etnaviv_sched_push_job(struct etnaviv_gem_submit
>> *submit)
>>>         */
>>>        mutex_lock(&gpu->sched_lock);
>>>
>>> -     drm_sched_job_arm(&submit->sched_job);
>>> +     drm_sched_job_arm(&submit->sched_job, -1);
>>>
>>>        submit->out_fence = dma_fence_get(&submit->sched_job.s_fence->finished);
>>>        ret = xa_alloc_cyclic(&gpu->user_fences, &submit->out_fence_id,
>>> diff --git a/drivers/gpu/drm/imagination/pvr_queue.c
>>> b/drivers/gpu/drm/imagination/pvr_queue.c
>>> index 5ed9c98fb599..ed7398a0ff21 100644
>>> --- a/drivers/gpu/drm/imagination/pvr_queue.c
>>> +++ b/drivers/gpu/drm/imagination/pvr_queue.c
>>> @@ -1115,7 +1115,7 @@ int pvr_queue_job_init(struct pvr_job *job)
>>>     */
>>>    struct dma_fence *pvr_queue_job_arm(struct pvr_job *job)
>>>    {
>>> -     drm_sched_job_arm(&job->base);
>>> +     drm_sched_job_arm(&job->base, -1);
>>>
>>>        return &job->base.s_fence->finished;
>>>    }
>>> diff --git a/drivers/gpu/drm/lima/lima_sched.c
>>> b/drivers/gpu/drm/lima/lima_sched.c
>>> index bbf3f8feab94..cc83b2aab9ce 100644
>>> --- a/drivers/gpu/drm/lima/lima_sched.c
>>> +++ b/drivers/gpu/drm/lima/lima_sched.c
>>> @@ -130,7 +130,7 @@ int lima_sched_task_init(struct lima_sched_task *task,
>>>                return err;
>>>        }
>>>
>>> -     drm_sched_job_arm(&task->base);
>>> +     drm_sched_job_arm(&task->base, -1);
>>>
>>>        task->num_bos = num_bos;
>>>        task->vm = lima_vm_get(vm);
>>> diff --git a/drivers/gpu/drm/msm/msm_gem_submit.c
>>> b/drivers/gpu/drm/msm/msm_gem_submit.c
>>> index fba78193127d..74c4e1b4df78 100644
>>> --- a/drivers/gpu/drm/msm/msm_gem_submit.c
>>> +++ b/drivers/gpu/drm/msm/msm_gem_submit.c
>>> @@ -831,7 +831,7 @@ int msm_ioctl_gem_submit(struct drm_device *dev, void
>> *data,
>>>                goto out;
>>>        }
>>>
>>> -     drm_sched_job_arm(&submit->base);
>>> +     drm_sched_job_arm(&submit->base, -1);
>>>
>>>        submit->user_fence =
>>> dma_fence_get(&submit->base.s_fence->finished);
>>>
>>> diff --git a/drivers/gpu/drm/nouveau/nouveau_sched.c
>>> b/drivers/gpu/drm/nouveau/nouveau_sched.c
>>> index 32fa2e273965..3ff8142b5370 100644
>>> --- a/drivers/gpu/drm/nouveau/nouveau_sched.c
>>> +++ b/drivers/gpu/drm/nouveau/nouveau_sched.c
>>> @@ -309,7 +309,7 @@ nouveau_job_submit(struct nouveau_job *job)
>>>        list_add(&job->entry, &sched->job.list.head);
>>>        spin_unlock(&sched->job.list.lock);
>>>
>>> -     drm_sched_job_arm(&job->base);
>>> +     drm_sched_job_arm(&job->base, -1);
>>>        job->done_fence = dma_fence_get(&job->base.s_fence->finished);
>>>        if (job->sync)
>>>                done_fence = dma_fence_get(job->done_fence); diff --git
>>> a/drivers/gpu/drm/panfrost/panfrost_job.c
>>> b/drivers/gpu/drm/panfrost/panfrost_job.c
>>> index a61ef0af9a4e..cc937420cd35 100644
>>> --- a/drivers/gpu/drm/panfrost/panfrost_job.c
>>> +++ b/drivers/gpu/drm/panfrost/panfrost_job.c
>>> @@ -301,7 +301,7 @@ int panfrost_job_push(struct panfrost_job *job)
>>>                return ret;
>>>
>>>        mutex_lock(&pfdev->sched_lock);
>>> -     drm_sched_job_arm(&job->base);
>>> +     drm_sched_job_arm(&job->base, -1);
>>>
>>>        job->render_done_fence =
>>> dma_fence_get(&job->base.s_fence->finished);
>>>
>>> diff --git a/drivers/gpu/drm/scheduler/sched_entity.c
>>> b/drivers/gpu/drm/scheduler/sched_entity.c
>>> index 58c8161289fe..f4669422b3f9 100644
>>> --- a/drivers/gpu/drm/scheduler/sched_entity.c
>>> +++ b/drivers/gpu/drm/scheduler/sched_entity.c
>>> @@ -525,7 +525,7 @@ struct drm_sched_job *drm_sched_entity_pop_job(struct
>> drm_sched_entity *entity)
>>>        return sched_job;
>>>    }
>>>
>>> -void drm_sched_entity_select_rq(struct drm_sched_entity *entity)
>>> +void drm_sched_entity_select_rq(struct drm_sched_entity *entity, int
>>> +ring)
>>>    {
>>>        struct dma_fence *fence;
>>>        struct drm_gpu_scheduler *sched; @@ -554,7 +554,14 @@ void
>>> drm_sched_entity_select_rq(struct drm_sched_entity *entity)
>>>                return;
>>>
>>>        spin_lock(&entity->rq_lock);
>>> -     sched = drm_sched_pick_best(entity->sched_list, entity->num_sched_list);
>>> +     if(ring >= 0) {
>>> +             if(entity->sched_list[ring] && entity->sched_list[ring]->ready)
>>> +                     sched = entity->sched_list[ring];
>>> +             else
>>> +                     sched = drm_sched_pick_best(entity->sched_list, entity-
>>> num_sched_list);
>>> +     }
>>> +     else
>>> +             sched = drm_sched_pick_best(entity->sched_list,
>>> +entity->num_sched_list);
>>>        rq = sched ? sched->sched_rq[entity->priority] : NULL;
>>>        if (rq != entity->rq) {
>>>                drm_sched_rq_remove_entity(entity->rq, entity); diff
>>> --git a/drivers/gpu/drm/scheduler/sched_main.c
>>> b/drivers/gpu/drm/scheduler/sched_main.c
>>> index 7e90c9f95611..356adf510670 100644
>>> --- a/drivers/gpu/drm/scheduler/sched_main.c
>>> +++ b/drivers/gpu/drm/scheduler/sched_main.c
>>> @@ -833,13 +833,13 @@ EXPORT_SYMBOL(drm_sched_job_init);
>>>     *
>>>     * This can only be called if drm_sched_job_init() succeeded.
>>>     */
>>> -void drm_sched_job_arm(struct drm_sched_job *job)
>>> +void drm_sched_job_arm(struct drm_sched_job *job, int ring)
>>>    {
>>>        struct drm_gpu_scheduler *sched;
>>>        struct drm_sched_entity *entity = job->entity;
>>>
>>>        BUG_ON(!entity);
>>> -     drm_sched_entity_select_rq(entity);
>>> +     drm_sched_entity_select_rq(entity, ring);
>>>        sched = entity->rq->sched;
>>>
>>>        job->sched = sched;
>>> diff --git a/drivers/gpu/drm/v3d/v3d_submit.c
>>> b/drivers/gpu/drm/v3d/v3d_submit.c
>>> index 88f63d526b22..d33749017f93 100644
>>> --- a/drivers/gpu/drm/v3d/v3d_submit.c
>>> +++ b/drivers/gpu/drm/v3d/v3d_submit.c
>>> @@ -211,7 +211,7 @@ v3d_job_init(struct v3d_dev *v3d, struct drm_file *file_priv,
>>>    static void
>>>    v3d_push_job(struct v3d_job *job)
>>>    {
>>> -     drm_sched_job_arm(&job->base);
>>> +     drm_sched_job_arm(&job->base, -1);
>>>
>>>        job->done_fence = dma_fence_get(&job->base.s_fence->finished);
>>>
>>> diff --git a/include/drm/gpu_scheduler.h b/include/drm/gpu_scheduler.h
>>> index 5acc64954a88..0eab405a2683 100644
>>> --- a/include/drm/gpu_scheduler.h
>>> +++ b/include/drm/gpu_scheduler.h
>>> @@ -553,7 +553,7 @@ void drm_sched_fini(struct drm_gpu_scheduler *sched);
>>>    int drm_sched_job_init(struct drm_sched_job *job,
>>>                       struct drm_sched_entity *entity,
>>>                       u32 credits, void *owner); -void
>>> drm_sched_job_arm(struct drm_sched_job *job);
>>> +void drm_sched_job_arm(struct drm_sched_job *job, int ring);
>>>    int drm_sched_job_add_dependency(struct drm_sched_job *job,
>>>                                 struct dma_fence *fence);
>>>    int drm_sched_job_add_syncobj_dependency(struct drm_sched_job *job,
>>> @@ -603,7 +603,7 @@ int drm_sched_entity_init(struct drm_sched_entity *entity,
>>>    long drm_sched_entity_flush(struct drm_sched_entity *entity, long timeout);
>>>    void drm_sched_entity_fini(struct drm_sched_entity *entity);
>>>    void drm_sched_entity_destroy(struct drm_sched_entity *entity);
>>> -void drm_sched_entity_select_rq(struct drm_sched_entity *entity);
>>> +void drm_sched_entity_select_rq(struct drm_sched_entity *entity, int
>>> +ring);
>>>    struct drm_sched_job *drm_sched_entity_pop_job(struct drm_sched_entity
>> *entity);
>>>    void drm_sched_entity_push_job(struct drm_sched_job *sched_job);
>>>    void drm_sched_entity_set_priority(struct drm_sched_entity *entity,
diff mbox series

Patch

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
index d891ab779ca7..18887128a973 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
@@ -1286,7 +1286,7 @@  static int amdgpu_cs_submit(struct amdgpu_cs_parser *p,
 	int r;
 
 	for (i = 0; i < p->gang_size; ++i)
-		drm_sched_job_arm(&p->jobs[i]->base);
+		drm_sched_job_arm(&p->jobs[i]->base, -1);
 
 	for (i = 0; i < p->gang_size; ++i) {
 		struct dma_fence *fence;
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_job.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_job.c
index 717adcedf096..8d75ffa9a097 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_job.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_job.c
@@ -320,7 +320,7 @@  struct dma_fence *amdgpu_job_submit(struct amdgpu_job *job)
 {
 	struct dma_fence *f;
 
-	drm_sched_job_arm(&job->base);
+	drm_sched_job_arm(&job->base, -1);
 	f = dma_fence_get(&job->base.s_fence->finished);
 	amdgpu_job_free_resources(job);
 	drm_sched_entity_push_job(&job->base);
diff --git a/drivers/gpu/drm/etnaviv/etnaviv_sched.c b/drivers/gpu/drm/etnaviv/etnaviv_sched.c
index 62dcfdc7894d..98d003757af1 100644
--- a/drivers/gpu/drm/etnaviv/etnaviv_sched.c
+++ b/drivers/gpu/drm/etnaviv/etnaviv_sched.c
@@ -107,7 +107,7 @@  int etnaviv_sched_push_job(struct etnaviv_gem_submit *submit)
 	 */
 	mutex_lock(&gpu->sched_lock);
 
-	drm_sched_job_arm(&submit->sched_job);
+	drm_sched_job_arm(&submit->sched_job, -1);
 
 	submit->out_fence = dma_fence_get(&submit->sched_job.s_fence->finished);
 	ret = xa_alloc_cyclic(&gpu->user_fences, &submit->out_fence_id,
diff --git a/drivers/gpu/drm/imagination/pvr_queue.c b/drivers/gpu/drm/imagination/pvr_queue.c
index 5ed9c98fb599..ed7398a0ff21 100644
--- a/drivers/gpu/drm/imagination/pvr_queue.c
+++ b/drivers/gpu/drm/imagination/pvr_queue.c
@@ -1115,7 +1115,7 @@  int pvr_queue_job_init(struct pvr_job *job)
  */
 struct dma_fence *pvr_queue_job_arm(struct pvr_job *job)
 {
-	drm_sched_job_arm(&job->base);
+	drm_sched_job_arm(&job->base, -1);
 
 	return &job->base.s_fence->finished;
 }
diff --git a/drivers/gpu/drm/lima/lima_sched.c b/drivers/gpu/drm/lima/lima_sched.c
index bbf3f8feab94..cc83b2aab9ce 100644
--- a/drivers/gpu/drm/lima/lima_sched.c
+++ b/drivers/gpu/drm/lima/lima_sched.c
@@ -130,7 +130,7 @@  int lima_sched_task_init(struct lima_sched_task *task,
 		return err;
 	}
 
-	drm_sched_job_arm(&task->base);
+	drm_sched_job_arm(&task->base, -1);
 
 	task->num_bos = num_bos;
 	task->vm = lima_vm_get(vm);
diff --git a/drivers/gpu/drm/msm/msm_gem_submit.c b/drivers/gpu/drm/msm/msm_gem_submit.c
index fba78193127d..74c4e1b4df78 100644
--- a/drivers/gpu/drm/msm/msm_gem_submit.c
+++ b/drivers/gpu/drm/msm/msm_gem_submit.c
@@ -831,7 +831,7 @@  int msm_ioctl_gem_submit(struct drm_device *dev, void *data,
 		goto out;
 	}
 
-	drm_sched_job_arm(&submit->base);
+	drm_sched_job_arm(&submit->base, -1);
 
 	submit->user_fence = dma_fence_get(&submit->base.s_fence->finished);
 
diff --git a/drivers/gpu/drm/nouveau/nouveau_sched.c b/drivers/gpu/drm/nouveau/nouveau_sched.c
index 32fa2e273965..3ff8142b5370 100644
--- a/drivers/gpu/drm/nouveau/nouveau_sched.c
+++ b/drivers/gpu/drm/nouveau/nouveau_sched.c
@@ -309,7 +309,7 @@  nouveau_job_submit(struct nouveau_job *job)
 	list_add(&job->entry, &sched->job.list.head);
 	spin_unlock(&sched->job.list.lock);
 
-	drm_sched_job_arm(&job->base);
+	drm_sched_job_arm(&job->base, -1);
 	job->done_fence = dma_fence_get(&job->base.s_fence->finished);
 	if (job->sync)
 		done_fence = dma_fence_get(job->done_fence);
diff --git a/drivers/gpu/drm/panfrost/panfrost_job.c b/drivers/gpu/drm/panfrost/panfrost_job.c
index a61ef0af9a4e..cc937420cd35 100644
--- a/drivers/gpu/drm/panfrost/panfrost_job.c
+++ b/drivers/gpu/drm/panfrost/panfrost_job.c
@@ -301,7 +301,7 @@  int panfrost_job_push(struct panfrost_job *job)
 		return ret;
 
 	mutex_lock(&pfdev->sched_lock);
-	drm_sched_job_arm(&job->base);
+	drm_sched_job_arm(&job->base, -1);
 
 	job->render_done_fence = dma_fence_get(&job->base.s_fence->finished);
 
diff --git a/drivers/gpu/drm/scheduler/sched_entity.c b/drivers/gpu/drm/scheduler/sched_entity.c
index 58c8161289fe..f4669422b3f9 100644
--- a/drivers/gpu/drm/scheduler/sched_entity.c
+++ b/drivers/gpu/drm/scheduler/sched_entity.c
@@ -525,7 +525,7 @@  struct drm_sched_job *drm_sched_entity_pop_job(struct drm_sched_entity *entity)
 	return sched_job;
 }
 
-void drm_sched_entity_select_rq(struct drm_sched_entity *entity)
+void drm_sched_entity_select_rq(struct drm_sched_entity *entity, int ring)
 {
 	struct dma_fence *fence;
 	struct drm_gpu_scheduler *sched;
@@ -554,7 +554,14 @@  void drm_sched_entity_select_rq(struct drm_sched_entity *entity)
 		return;
 
 	spin_lock(&entity->rq_lock);
-	sched = drm_sched_pick_best(entity->sched_list, entity->num_sched_list);
+	if(ring >= 0) {
+		if(entity->sched_list[ring] && entity->sched_list[ring]->ready)
+			sched = entity->sched_list[ring];
+		else
+			sched = drm_sched_pick_best(entity->sched_list, entity->num_sched_list);
+	}
+	else
+		sched = drm_sched_pick_best(entity->sched_list, entity->num_sched_list);
 	rq = sched ? sched->sched_rq[entity->priority] : NULL;
 	if (rq != entity->rq) {
 		drm_sched_rq_remove_entity(entity->rq, entity);
diff --git a/drivers/gpu/drm/scheduler/sched_main.c b/drivers/gpu/drm/scheduler/sched_main.c
index 7e90c9f95611..356adf510670 100644
--- a/drivers/gpu/drm/scheduler/sched_main.c
+++ b/drivers/gpu/drm/scheduler/sched_main.c
@@ -833,13 +833,13 @@  EXPORT_SYMBOL(drm_sched_job_init);
  *
  * This can only be called if drm_sched_job_init() succeeded.
  */
-void drm_sched_job_arm(struct drm_sched_job *job)
+void drm_sched_job_arm(struct drm_sched_job *job, int ring)
 {
 	struct drm_gpu_scheduler *sched;
 	struct drm_sched_entity *entity = job->entity;
 
 	BUG_ON(!entity);
-	drm_sched_entity_select_rq(entity);
+	drm_sched_entity_select_rq(entity, ring);
 	sched = entity->rq->sched;
 
 	job->sched = sched;
diff --git a/drivers/gpu/drm/v3d/v3d_submit.c b/drivers/gpu/drm/v3d/v3d_submit.c
index 88f63d526b22..d33749017f93 100644
--- a/drivers/gpu/drm/v3d/v3d_submit.c
+++ b/drivers/gpu/drm/v3d/v3d_submit.c
@@ -211,7 +211,7 @@  v3d_job_init(struct v3d_dev *v3d, struct drm_file *file_priv,
 static void
 v3d_push_job(struct v3d_job *job)
 {
-	drm_sched_job_arm(&job->base);
+	drm_sched_job_arm(&job->base, -1);
 
 	job->done_fence = dma_fence_get(&job->base.s_fence->finished);
 
diff --git a/include/drm/gpu_scheduler.h b/include/drm/gpu_scheduler.h
index 5acc64954a88..0eab405a2683 100644
--- a/include/drm/gpu_scheduler.h
+++ b/include/drm/gpu_scheduler.h
@@ -553,7 +553,7 @@  void drm_sched_fini(struct drm_gpu_scheduler *sched);
 int drm_sched_job_init(struct drm_sched_job *job,
 		       struct drm_sched_entity *entity,
 		       u32 credits, void *owner);
-void drm_sched_job_arm(struct drm_sched_job *job);
+void drm_sched_job_arm(struct drm_sched_job *job, int ring);
 int drm_sched_job_add_dependency(struct drm_sched_job *job,
 				 struct dma_fence *fence);
 int drm_sched_job_add_syncobj_dependency(struct drm_sched_job *job,
@@ -603,7 +603,7 @@  int drm_sched_entity_init(struct drm_sched_entity *entity,
 long drm_sched_entity_flush(struct drm_sched_entity *entity, long timeout);
 void drm_sched_entity_fini(struct drm_sched_entity *entity);
 void drm_sched_entity_destroy(struct drm_sched_entity *entity);
-void drm_sched_entity_select_rq(struct drm_sched_entity *entity);
+void drm_sched_entity_select_rq(struct drm_sched_entity *entity, int ring);
 struct drm_sched_job *drm_sched_entity_pop_job(struct drm_sched_entity *entity);
 void drm_sched_entity_push_job(struct drm_sched_job *sched_job);
 void drm_sched_entity_set_priority(struct drm_sched_entity *entity,