diff mbox series

[3/4] drm/scheduler: add new function to get least loaded sched

Message ID 20180731103736.7813-4-nayan26deshmukh@gmail.com (mailing list archive)
State New, archived
Headers show
Series drm/scheduler: add dynamic balancing | expand

Commit Message

Nayan Deshmukh July 31, 2018, 10:37 a.m. UTC
The function selects the run queue from the rq_list with the
least load. The load is decided by the number of jobs in a
scheduler.

Signed-off-by: Nayan Deshmukh <nayan26deshmukh@gmail.com>
---
 drivers/gpu/drm/scheduler/gpu_scheduler.c | 26 ++++++++++++++++++++++++++
 1 file changed, 26 insertions(+)

Comments

Christian König July 31, 2018, 11:27 a.m. UTC | #1
Am 31.07.2018 um 12:37 schrieb Nayan Deshmukh:
> The function selects the run queue from the rq_list with the
> least load. The load is decided by the number of jobs in a
> scheduler.
>
> Signed-off-by: Nayan Deshmukh <nayan26deshmukh@gmail.com>
> ---
>   drivers/gpu/drm/scheduler/gpu_scheduler.c | 26 ++++++++++++++++++++++++++
>   1 file changed, 26 insertions(+)
>
> diff --git a/drivers/gpu/drm/scheduler/gpu_scheduler.c b/drivers/gpu/drm/scheduler/gpu_scheduler.c
> index 375f6f7f6a93..c67f65ad8f15 100644
> --- a/drivers/gpu/drm/scheduler/gpu_scheduler.c
> +++ b/drivers/gpu/drm/scheduler/gpu_scheduler.c
> @@ -255,6 +255,32 @@ static bool drm_sched_entity_is_ready(struct drm_sched_entity *entity)
>   	return true;
>   }
>   
> +/**
> + * drm_sched_entity_get_free_sched - Get the rq from rq_list with least load
> + *
> + * @entity: scheduler entity
> + *
> + * Return the pointer to the rq with least load.
> + */
> +static struct drm_sched_rq *
> +drm_sched_entity_get_free_sched(struct drm_sched_entity *entity)
> +{
> +	struct drm_sched_rq *rq = NULL;
> +	unsigned int min_jobs = UINT_MAX;
> +	int i;
> +
> +	for (i = 0; i < entity->num_rq_list; ++i) {
> +		if (atomic_read(&entity->rq_list[i]->sched->num_jobs) <
> +				min_jobs) {
> +			min_jobs = atomic_read(
> +					&entity->rq_list[i]->sched->num_jobs);

When you use atomic_read twice you might get different results because 
the atomic has changed in the meantime.

In other words you need to store the result locally:

unsigned int num_jobs = atomic_read(....);

if (num_jobs < min_jobs) {
     min_jobs = num_jobs;
     .....

Christian.

> +			rq = entity->rq_list[i];
> +		}
> +	}
> +
> +	return rq;
> +}
> +
>   static void drm_sched_entity_kill_jobs_cb(struct dma_fence *f,
>   				    struct dma_fence_cb *cb)
>   {
Nayan Deshmukh July 31, 2018, 11:35 a.m. UTC | #2
I will take care of that in v2.

On Tue, Jul 31, 2018 at 4:57 PM Christian König <
ckoenig.leichtzumerken@gmail.com> wrote:

> Am 31.07.2018 um 12:37 schrieb Nayan Deshmukh:
> > The function selects the run queue from the rq_list with the
> > least load. The load is decided by the number of jobs in a
> > scheduler.
> >
> > Signed-off-by: Nayan Deshmukh <nayan26deshmukh@gmail.com>
> > ---
> >   drivers/gpu/drm/scheduler/gpu_scheduler.c | 26
> ++++++++++++++++++++++++++
> >   1 file changed, 26 insertions(+)
> >
> > diff --git a/drivers/gpu/drm/scheduler/gpu_scheduler.c
> b/drivers/gpu/drm/scheduler/gpu_scheduler.c
> > index 375f6f7f6a93..c67f65ad8f15 100644
> > --- a/drivers/gpu/drm/scheduler/gpu_scheduler.c
> > +++ b/drivers/gpu/drm/scheduler/gpu_scheduler.c
> > @@ -255,6 +255,32 @@ static bool drm_sched_entity_is_ready(struct
> drm_sched_entity *entity)
> >       return true;
> >   }
> >
> > +/**
> > + * drm_sched_entity_get_free_sched - Get the rq from rq_list with least
> load
> > + *
> > + * @entity: scheduler entity
> > + *
> > + * Return the pointer to the rq with least load.
> > + */
> > +static struct drm_sched_rq *
> > +drm_sched_entity_get_free_sched(struct drm_sched_entity *entity)
> > +{
> > +     struct drm_sched_rq *rq = NULL;
> > +     unsigned int min_jobs = UINT_MAX;
> > +     int i;
> > +
> > +     for (i = 0; i < entity->num_rq_list; ++i) {
> > +             if (atomic_read(&entity->rq_list[i]->sched->num_jobs) <
> > +                             min_jobs) {
> > +                     min_jobs = atomic_read(
> > +
>  &entity->rq_list[i]->sched->num_jobs);
>
> When you use atomic_read twice you might get different results because
> the atomic has changed in the meantime.
>
> In other words you need to store the result locally:
>
> unsigned int num_jobs = atomic_read(....);
>
> if (num_jobs < min_jobs) {
>      min_jobs = num_jobs;
>      .....
>
> Christian.
>
> > +                     rq = entity->rq_list[i];
> > +             }
> > +     }
> > +
> > +     return rq;
> > +}
> > +
> >   static void drm_sched_entity_kill_jobs_cb(struct dma_fence *f,
> >                                   struct dma_fence_cb *cb)
> >   {
>
>
<div dir="ltr">I will take care of that in v2.<br></div><br><div class="gmail_quote"><div dir="ltr">On Tue, Jul 31, 2018 at 4:57 PM Christian König &lt;<a href="mailto:ckoenig.leichtzumerken@gmail.com">ckoenig.leichtzumerken@gmail.com</a>&gt; wrote:<br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Am 31.07.2018 um 12:37 schrieb Nayan Deshmukh:<br>
&gt; The function selects the run queue from the rq_list with the<br>
&gt; least load. The load is decided by the number of jobs in a<br>
&gt; scheduler.<br>
&gt;<br>
&gt; Signed-off-by: Nayan Deshmukh &lt;<a href="mailto:nayan26deshmukh@gmail.com" target="_blank">nayan26deshmukh@gmail.com</a>&gt;<br>
&gt; ---<br>
&gt;   drivers/gpu/drm/scheduler/gpu_scheduler.c | 26 ++++++++++++++++++++++++++<br>
&gt;   1 file changed, 26 insertions(+)<br>
&gt;<br>
&gt; diff --git a/drivers/gpu/drm/scheduler/gpu_scheduler.c b/drivers/gpu/drm/scheduler/gpu_scheduler.c<br>
&gt; index 375f6f7f6a93..c67f65ad8f15 100644<br>
&gt; --- a/drivers/gpu/drm/scheduler/gpu_scheduler.c<br>
&gt; +++ b/drivers/gpu/drm/scheduler/gpu_scheduler.c<br>
&gt; @@ -255,6 +255,32 @@ static bool drm_sched_entity_is_ready(struct drm_sched_entity *entity)<br>
&gt;       return true;<br>
&gt;   }<br>
&gt;   <br>
&gt; +/**<br>
&gt; + * drm_sched_entity_get_free_sched - Get the rq from rq_list with least load<br>
&gt; + *<br>
&gt; + * @entity: scheduler entity<br>
&gt; + *<br>
&gt; + * Return the pointer to the rq with least load.<br>
&gt; + */<br>
&gt; +static struct drm_sched_rq *<br>
&gt; +drm_sched_entity_get_free_sched(struct drm_sched_entity *entity)<br>
&gt; +{<br>
&gt; +     struct drm_sched_rq *rq = NULL;<br>
&gt; +     unsigned int min_jobs = UINT_MAX;<br>
&gt; +     int i;<br>
&gt; +<br>
&gt; +     for (i = 0; i &lt; entity-&gt;num_rq_list; ++i) {<br>
&gt; +             if (atomic_read(&amp;entity-&gt;rq_list[i]-&gt;sched-&gt;num_jobs) &lt;<br>
&gt; +                             min_jobs) {<br>
&gt; +                     min_jobs = atomic_read(<br>
&gt; +                                     &amp;entity-&gt;rq_list[i]-&gt;sched-&gt;num_jobs);<br>
<br>
When you use atomic_read twice you might get different results because <br>
the atomic has changed in the meantime.<br>
<br>
In other words you need to store the result locally:<br>
<br>
unsigned int num_jobs = atomic_read(....);<br>
<br>
if (num_jobs &lt; min_jobs) {<br>
     min_jobs = num_jobs;<br>
     .....<br>
<br>
Christian.<br>
<br>
&gt; +                     rq = entity-&gt;rq_list[i];<br>
&gt; +             }<br>
&gt; +     }<br>
&gt; +<br>
&gt; +     return rq;<br>
&gt; +}<br>
&gt; +<br>
&gt;   static void drm_sched_entity_kill_jobs_cb(struct dma_fence *f,<br>
&gt;                                   struct dma_fence_cb *cb)<br>
&gt;   {<br>
<br>
</blockquote></div>
diff mbox series

Patch

diff --git a/drivers/gpu/drm/scheduler/gpu_scheduler.c b/drivers/gpu/drm/scheduler/gpu_scheduler.c
index 375f6f7f6a93..c67f65ad8f15 100644
--- a/drivers/gpu/drm/scheduler/gpu_scheduler.c
+++ b/drivers/gpu/drm/scheduler/gpu_scheduler.c
@@ -255,6 +255,32 @@  static bool drm_sched_entity_is_ready(struct drm_sched_entity *entity)
 	return true;
 }
 
+/**
+ * drm_sched_entity_get_free_sched - Get the rq from rq_list with least load
+ *
+ * @entity: scheduler entity
+ *
+ * Return the pointer to the rq with least load.
+ */
+static struct drm_sched_rq *
+drm_sched_entity_get_free_sched(struct drm_sched_entity *entity)
+{
+	struct drm_sched_rq *rq = NULL;
+	unsigned int min_jobs = UINT_MAX;
+	int i;
+
+	for (i = 0; i < entity->num_rq_list; ++i) {
+		if (atomic_read(&entity->rq_list[i]->sched->num_jobs) <
+				min_jobs) {
+			min_jobs = atomic_read(
+					&entity->rq_list[i]->sched->num_jobs);
+			rq = entity->rq_list[i];
+		}
+	}
+
+	return rq;
+}
+
 static void drm_sched_entity_kill_jobs_cb(struct dma_fence *f,
 				    struct dma_fence_cb *cb)
 {