Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > linux.kernel > #1627761 > unrolled thread

[PATCH] sched/deadline: fix switching to -deadline

Started byluca abeni <luca.abeni@santannapisa.it>
First post2017-04-20 21:40 +0200
Last post2017-04-21 15:50 +0200
Articles 14 — 5 participants

Back to article view | Back to linux.kernel


Contents

  [PATCH] sched/deadline: fix switching to -deadline luca abeni <luca.abeni@santannapisa.it> - 2017-04-20 21:40 +0200
    Re: [PATCH] sched/deadline: fix switching to -deadline Juri Lelli <juri.lelli@arm.com> - 2017-04-21 11:50 +0200
      Re: [PATCH] sched/deadline: fix switching to -deadline Juri Lelli <juri.lelli@arm.com> - 2017-04-21 11:50 +0200
        Re: [PATCH] sched/deadline: fix switching to -deadline luca abeni <luca.abeni@santannapisa.it> - 2017-04-21 12:00 +0200
          Re: [PATCH] sched/deadline: fix switching to -deadline Peter Zijlstra <peterz@infradead.org> - 2017-04-21 12:20 +0200
          Re: [PATCH] sched/deadline: fix switching to -deadline Juri Lelli <juri.lelli@arm.com> - 2017-04-21 12:30 +0200
            Re: [PATCH] sched/deadline: fix switching to -deadline luca abeni <luca.abeni@santannapisa.it> - 2017-04-21 21:10 +0200
              Re: [PATCH] sched/deadline: fix switching to -deadline Juri Lelli <juri.lelli@arm.com> - 2017-04-24 12:20 +0200
                Re: [PATCH] sched/deadline: fix switching to -deadline Luca Abeni <luca.abeni@santannapisa.it> - 2017-04-24 12:40 +0200
                  Re: [PATCH] sched/deadline: fix switching to -deadline Juri Lelli <juri.lelli@arm.com> - 2017-04-24 13:00 +0200
        Re: [PATCH] sched/deadline: fix switching to -deadline Peter Zijlstra <peterz@infradead.org> - 2017-04-21 12:20 +0200
      Re: [PATCH] sched/deadline: fix switching to -deadline luca abeni <luca.abeni@santannapisa.it> - 2017-04-21 11:50 +0200
        Re: [PATCH] sched/deadline: fix switching to -deadline luca abeni <luca.abeni@santannapisa.it> - 2017-04-21 12:00 +0200
          Re: [PATCH] sched/deadline: fix switching to -deadline Steven Rostedt <rostedt@goodmis.org> - 2017-04-21 15:50 +0200

#1627761 — [PATCH] sched/deadline: fix switching to -deadline

Fromluca abeni <luca.abeni@santannapisa.it>
Date2017-04-20 21:40 +0200
Subject[PATCH] sched/deadline: fix switching to -deadline
Message-ID<tyq5Q-4y2-11@gated-at.bofh.it>
From: Luca Abeni <luca.abeni@santannapisa.it>

When switching to -deadline, if the scheduling deadline of a task is
in the past then switched_to_dl() calls setup_new_entity() to properly
initialize the scheduling deadline and runtime.

The problem is that the task is enqueued _before_ having its parameters
initialized by setup_new_entity(), and this can cause problems.
For example, a task with its out-of-date deadline in the past will
potentially be enqueued as the highest priority one; however, its
adjusted deadline may not be the earliest one.

This patch fixes the problem by initializing the task's parameters before
enqueuing it.

Signed-off-by: Luca Abeni <luca.abeni@santannapisa.it>
Reviewed-by: Daniel Bristot de Oliveira <bristot@redhat.com>
---
 kernel/sched/deadline.c | 12 ++++--------
 1 file changed, 4 insertions(+), 8 deletions(-)

diff --git a/kernel/sched/deadline.c b/kernel/sched/deadline.c
index a2ce590..ec53d24 100644
--- a/kernel/sched/deadline.c
+++ b/kernel/sched/deadline.c
@@ -950,6 +950,10 @@ enqueue_dl_entity(struct sched_dl_entity *dl_se,
 		update_dl_entity(dl_se, pi_se);
 	else if (flags & ENQUEUE_REPLENISH)
 		replenish_dl_entity(dl_se, pi_se);
+	else if ((flags & ENQUEUE_RESTORE) &&
+		  dl_time_before(dl_se->deadline,
+				 rq_clock(rq_of_dl_rq(dl_rq_of_se(dl_se)))))
+		setup_new_dl_entity(dl_se);
 
 	__enqueue_dl_entity(dl_se);
 }
@@ -1767,14 +1771,6 @@ static void switched_to_dl(struct rq *rq, struct task_struct *p)
 	if (!task_on_rq_queued(p))
 		return;
 
-	/*
-	 * If p is boosted we already updated its params in
-	 * rt_mutex_setprio()->enqueue_task(..., ENQUEUE_REPLENISH),
-	 * p's deadline being now already after rq_clock(rq).
-	 */
-	if (dl_time_before(p->dl.deadline, rq_clock(rq)))
-		setup_new_dl_entity(&p->dl);
-
 	if (rq->curr != p) {
 #ifdef CONFIG_SMP
 		if (p->nr_cpus_allowed > 1 && rq->dl.overloaded)
-- 
2.7.4

[toc] | [next] | [standalone]


#1628091

FromJuri Lelli <juri.lelli@arm.com>
Date2017-04-21 11:50 +0200
Message-ID<tyDmq-4ci-23@gated-at.bofh.it>
In reply to#1627761
Hi Luca,

On 20/04/17 21:30, Luca Abeni wrote:
> From: Luca Abeni <luca.abeni@santannapisa.it>
> 
> When switching to -deadline, if the scheduling deadline of a task is
> in the past then switched_to_dl() calls setup_new_entity() to properly
> initialize the scheduling deadline and runtime.
> 
> The problem is that the task is enqueued _before_ having its parameters
> initialized by setup_new_entity(), and this can cause problems.
> For example, a task with its out-of-date deadline in the past will
> potentially be enqueued as the highest priority one; however, its
> adjusted deadline may not be the earliest one.
> 
> This patch fixes the problem by initializing the task's parameters before
> enqueuing it.
> 
> Signed-off-by: Luca Abeni <luca.abeni@santannapisa.it>
> Reviewed-by: Daniel Bristot de Oliveira <bristot@redhat.com>
> ---
>  kernel/sched/deadline.c | 12 ++++--------
>  1 file changed, 4 insertions(+), 8 deletions(-)
> 
> diff --git a/kernel/sched/deadline.c b/kernel/sched/deadline.c
> index a2ce590..ec53d24 100644
> --- a/kernel/sched/deadline.c
> +++ b/kernel/sched/deadline.c
> @@ -950,6 +950,10 @@ enqueue_dl_entity(struct sched_dl_entity *dl_se,
>  		update_dl_entity(dl_se, pi_se);
>  	else if (flags & ENQUEUE_REPLENISH)
>  		replenish_dl_entity(dl_se, pi_se);
> +	else if ((flags & ENQUEUE_RESTORE) &&

Not sure I understand how this works. AFAICT we are doing
__sched_setscheduler() when we want to catch the case of a new dl_entity
(SCHED_{OTHER,FIFO} -> SCHED_DEADLINE}, but queue_flags (which are
passed to enqueue_task()) don't seem to have ENQUEUE_RESTORE set?

Thanks,

- Juri

[toc] | [prev] | [next] | [standalone]


#1628092

FromJuri Lelli <juri.lelli@arm.com>
Date2017-04-21 11:50 +0200
Message-ID<tyDmq-4ci-25@gated-at.bofh.it>
In reply to#1628091
On 21/04/17 11:42, Luca Abeni wrote:
> On Fri, 21 Apr 2017 10:39:26 +0100
> Juri Lelli <juri.lelli@arm.com> wrote:
> 
> > Hi Luca,
> > 
> > On 20/04/17 21:30, Luca Abeni wrote:
> > > From: Luca Abeni <luca.abeni@santannapisa.it>
> > > 
> > > When switching to -deadline, if the scheduling deadline of a task is
> > > in the past then switched_to_dl() calls setup_new_entity() to
> > > properly initialize the scheduling deadline and runtime.
> > > 
> > > The problem is that the task is enqueued _before_ having its
> > > parameters initialized by setup_new_entity(), and this can cause
> > > problems. For example, a task with its out-of-date deadline in the
> > > past will potentially be enqueued as the highest priority one;
> > > however, its adjusted deadline may not be the earliest one.
> > > 
> > > This patch fixes the problem by initializing the task's parameters
> > > before enqueuing it.
> > > 
> > > Signed-off-by: Luca Abeni <luca.abeni@santannapisa.it>
> > > Reviewed-by: Daniel Bristot de Oliveira <bristot@redhat.com>
> > > ---
> > >  kernel/sched/deadline.c | 12 ++++--------
> > >  1 file changed, 4 insertions(+), 8 deletions(-)
> > > 
> > > diff --git a/kernel/sched/deadline.c b/kernel/sched/deadline.c
> > > index a2ce590..ec53d24 100644
> > > --- a/kernel/sched/deadline.c
> > > +++ b/kernel/sched/deadline.c
> > > @@ -950,6 +950,10 @@ enqueue_dl_entity(struct sched_dl_entity
> > > *dl_se, update_dl_entity(dl_se, pi_se);
> > >  	else if (flags & ENQUEUE_REPLENISH)
> > >  		replenish_dl_entity(dl_se, pi_se);
> > > +	else if ((flags & ENQUEUE_RESTORE) &&  
> > 
> > Not sure I understand how this works. AFAICT we are doing
> > __sched_setscheduler() when we want to catch the case of a new
> > dl_entity (SCHED_{OTHER,FIFO} -> SCHED_DEADLINE}, but queue_flags
> > (which are passed to enqueue_task()) don't seem to have
> > ENQUEUE_RESTORE set?
> 
> I was under the impression sched_setscheduler() sets ENQUEUE_RESTORE...
> 

Oh, I think it works "by coincidence", as ENQUEUE_RESTORE == DEQUEUE_SAVE
== 0x02 ? :)

[toc] | [prev] | [next] | [standalone]


#1628095

Fromluca abeni <luca.abeni@santannapisa.it>
Date2017-04-21 12:00 +0200
Message-ID<tyDw5-4fF-11@gated-at.bofh.it>
In reply to#1628092
On Fri, 21 Apr 2017 10:47:29 +0100
Juri Lelli <juri.lelli@arm.com> wrote:
[...]
> > > > *dl_se, update_dl_entity(dl_se, pi_se);
> > > >  	else if (flags & ENQUEUE_REPLENISH)
> > > >  		replenish_dl_entity(dl_se, pi_se);
> > > > +	else if ((flags & ENQUEUE_RESTORE) &&    
> > > 
> > > Not sure I understand how this works. AFAICT we are doing
> > > __sched_setscheduler() when we want to catch the case of a new
> > > dl_entity (SCHED_{OTHER,FIFO} -> SCHED_DEADLINE}, but queue_flags
> > > (which are passed to enqueue_task()) don't seem to have
> > > ENQUEUE_RESTORE set?  
> > 
> > I was under the impression sched_setscheduler() sets
> > ENQUEUE_RESTORE... 
> 
> Oh, I think it works "by coincidence", as ENQUEUE_RESTORE ==
> DEQUEUE_SAVE == 0x02 ? :)

Not sure if this is a conincidence... By looking at the comments in
sched/sched.h I got the impression the two values match by design (and
__sched_setscheduler() is using this property to simplify the code :)



			Luca

[toc] | [prev] | [next] | [standalone]


#1628111

FromPeter Zijlstra <peterz@infradead.org>
Date2017-04-21 12:20 +0200
Message-ID<tyDPr-4B9-7@gated-at.bofh.it>
In reply to#1628095
On Fri, Apr 21, 2017 at 11:59:07AM +0200, luca abeni wrote:

> Not sure if this is a conincidence... By looking at the comments in
> sched/sched.h I got the impression the two values match by design (and
> __sched_setscheduler() is using this property to simplify the code :)

Exactly. Makes things simpler if they line up properly, because then you
can use the same flags for dequeue and enqueue.

[toc] | [prev] | [next] | [standalone]


#1628114

FromJuri Lelli <juri.lelli@arm.com>
Date2017-04-21 12:30 +0200
Message-ID<tyDZ8-4E7-1@gated-at.bofh.it>
In reply to#1628095
On 21/04/17 11:59, Luca Abeni wrote:
> On Fri, 21 Apr 2017 10:47:29 +0100
> Juri Lelli <juri.lelli@arm.com> wrote:
> [...]
> > > > > *dl_se, update_dl_entity(dl_se, pi_se);
> > > > >  	else if (flags & ENQUEUE_REPLENISH)
> > > > >  		replenish_dl_entity(dl_se, pi_se);
> > > > > +	else if ((flags & ENQUEUE_RESTORE) &&    
> > > > 
> > > > Not sure I understand how this works. AFAICT we are doing
> > > > __sched_setscheduler() when we want to catch the case of a new
> > > > dl_entity (SCHED_{OTHER,FIFO} -> SCHED_DEADLINE}, but queue_flags
> > > > (which are passed to enqueue_task()) don't seem to have
> > > > ENQUEUE_RESTORE set?  
> > > 
> > > I was under the impression sched_setscheduler() sets
> > > ENQUEUE_RESTORE... 
> > 
> > Oh, I think it works "by coincidence", as ENQUEUE_RESTORE ==
> > DEQUEUE_SAVE == 0x02 ? :)
> 
> Not sure if this is a conincidence... By looking at the comments in
> sched/sched.h I got the impression the two values match by design (and
> __sched_setscheduler() is using this property to simplify the code :)
> 

Yep, right.

Do you think we might get into trouble with do_set_cpus_allowed()?
Can it happen that we change a task affinity while its deadline is in
the past?

[toc] | [prev] | [next] | [standalone]


#1628514

Fromluca abeni <luca.abeni@santannapisa.it>
Date2017-04-21 21:10 +0200
Message-ID<tyM6l-1aE-15@gated-at.bofh.it>
In reply to#1628114
On Fri, 21 Apr 2017 11:26:59 +0100
Juri Lelli <juri.lelli@arm.com> wrote:
> On 21/04/17 11:59, Luca Abeni wrote:
> > On Fri, 21 Apr 2017 10:47:29 +0100
> > Juri Lelli <juri.lelli@arm.com> wrote:
> > [...]  
> > > > > > *dl_se, update_dl_entity(dl_se, pi_se);
> > > > > >  	else if (flags & ENQUEUE_REPLENISH)
> > > > > >  		replenish_dl_entity(dl_se, pi_se);
> > > > > > +	else if ((flags & ENQUEUE_RESTORE) &&      
> > > > > 
> > > > > Not sure I understand how this works. AFAICT we are doing
> > > > > __sched_setscheduler() when we want to catch the case of a new
> > > > > dl_entity (SCHED_{OTHER,FIFO} -> SCHED_DEADLINE}, but
> > > > > queue_flags (which are passed to enqueue_task()) don't seem
> > > > > to have ENQUEUE_RESTORE set?    
> > > > 
> > > > I was under the impression sched_setscheduler() sets
> > > > ENQUEUE_RESTORE...   
> > > 
> > > Oh, I think it works "by coincidence", as ENQUEUE_RESTORE ==
> > > DEQUEUE_SAVE == 0x02 ? :)  
> > 
> > Not sure if this is a conincidence... By looking at the comments in
> > sched/sched.h I got the impression the two values match by design
> > (and __sched_setscheduler() is using this property to simplify the
> > code :) 
> 
> Yep, right.
> 
> Do you think we might get into trouble with do_set_cpus_allowed()?
> Can it happen that we change a task affinity while its deadline is in
> the past?

Well, double thinking about it, this is an interesting problem... What
do we want to do with do_set_cpus_allowed()? (I mean: what is the
expected behaviour?)

With this patch, if a task is moved to a different runqueue when its
deadline is in the past (because we are doing gEDF, or because of timer
granularity issues) its scheduling deadline is reinitialized to current
time + relative deadline... I think this makes perfect sense, doesn't
it?


				Luca

[toc] | [prev] | [next] | [standalone]


#1629391

FromJuri Lelli <juri.lelli@arm.com>
Date2017-04-24 12:20 +0200
Message-ID<tzJg6-5J2-25@gated-at.bofh.it>
In reply to#1628514
On 21/04/17 21:08, Luca Abeni wrote:
> On Fri, 21 Apr 2017 11:26:59 +0100
> Juri Lelli <juri.lelli@arm.com> wrote:
> > On 21/04/17 11:59, Luca Abeni wrote:
> > > On Fri, 21 Apr 2017 10:47:29 +0100
> > > Juri Lelli <juri.lelli@arm.com> wrote:
> > > [...]  
> > > > > > > *dl_se, update_dl_entity(dl_se, pi_se);
> > > > > > >  	else if (flags & ENQUEUE_REPLENISH)
> > > > > > >  		replenish_dl_entity(dl_se, pi_se);
> > > > > > > +	else if ((flags & ENQUEUE_RESTORE) &&      
> > > > > > 
> > > > > > Not sure I understand how this works. AFAICT we are doing
> > > > > > __sched_setscheduler() when we want to catch the case of a new
> > > > > > dl_entity (SCHED_{OTHER,FIFO} -> SCHED_DEADLINE}, but
> > > > > > queue_flags (which are passed to enqueue_task()) don't seem
> > > > > > to have ENQUEUE_RESTORE set?    
> > > > > 
> > > > > I was under the impression sched_setscheduler() sets
> > > > > ENQUEUE_RESTORE...   
> > > > 
> > > > Oh, I think it works "by coincidence", as ENQUEUE_RESTORE ==
> > > > DEQUEUE_SAVE == 0x02 ? :)  
> > > 
> > > Not sure if this is a conincidence... By looking at the comments in
> > > sched/sched.h I got the impression the two values match by design
> > > (and __sched_setscheduler() is using this property to simplify the
> > > code :) 
> > 
> > Yep, right.
> > 
> > Do you think we might get into trouble with do_set_cpus_allowed()?
> > Can it happen that we change a task affinity while its deadline is in
> > the past?
> 
> Well, double thinking about it, this is an interesting problem... What
> do we want to do with do_set_cpus_allowed()? (I mean: what is the
> expected behaviour?)
> 
> With this patch, if a task is moved to a different runqueue when its
> deadline is in the past (because we are doing gEDF, or because of timer
> granularity issues) its scheduling deadline is reinitialized to current
> time + relative deadline... I think this makes perfect sense, doesn't
> it?
> 

Mmm, I don't think we will (with this patch) actually reinitialize the
deadline when a "normal" gEDF migration happen (push/pull), as
(de)activate_task() have no flag set. Which brings the question, should
we actually take care of this corner case (as what you say makes sense
to me too)?

[toc] | [prev] | [next] | [standalone]


#1629410

FromLuca Abeni <luca.abeni@santannapisa.it>
Date2017-04-24 12:40 +0200
Message-ID<tzJzs-5R1-19@gated-at.bofh.it>
In reply to#1629391
On Mon, 24 Apr 2017 11:16:24 +0100
Juri Lelli <juri.lelli@arm.com> wrote:

> On 21/04/17 21:08, Luca Abeni wrote:
> > On Fri, 21 Apr 2017 11:26:59 +0100
> > Juri Lelli <juri.lelli@arm.com> wrote:  
> > > On 21/04/17 11:59, Luca Abeni wrote:  
> > > > On Fri, 21 Apr 2017 10:47:29 +0100
> > > > Juri Lelli <juri.lelli@arm.com> wrote:
> > > > [...]    
> > > > > > > > *dl_se, update_dl_entity(dl_se, pi_se);
> > > > > > > >  	else if (flags & ENQUEUE_REPLENISH)
> > > > > > > >  		replenish_dl_entity(dl_se, pi_se);
> > > > > > > > +	else if ((flags & ENQUEUE_RESTORE) &&        
> > > > > > > 
> > > > > > > Not sure I understand how this works. AFAICT we are doing
> > > > > > > __sched_setscheduler() when we want to catch the case of
> > > > > > > a new dl_entity (SCHED_{OTHER,FIFO} -> SCHED_DEADLINE},
> > > > > > > but queue_flags (which are passed to enqueue_task())
> > > > > > > don't seem to have ENQUEUE_RESTORE set?      
> > > > > > 
> > > > > > I was under the impression sched_setscheduler() sets
> > > > > > ENQUEUE_RESTORE...     
> > > > > 
> > > > > Oh, I think it works "by coincidence", as ENQUEUE_RESTORE ==
> > > > > DEQUEUE_SAVE == 0x02 ? :)    
> > > > 
> > > > Not sure if this is a conincidence... By looking at the
> > > > comments in sched/sched.h I got the impression the two values
> > > > match by design (and __sched_setscheduler() is using this
> > > > property to simplify the code :)   
> > > 
> > > Yep, right.
> > > 
> > > Do you think we might get into trouble with do_set_cpus_allowed()?
> > > Can it happen that we change a task affinity while its deadline
> > > is in the past?  
> > 
> > Well, double thinking about it, this is an interesting problem...
> > What do we want to do with do_set_cpus_allowed()? (I mean: what is
> > the expected behaviour?)
> > 
> > With this patch, if a task is moved to a different runqueue when its
> > deadline is in the past (because we are doing gEDF, or because of
> > timer granularity issues) its scheduling deadline is reinitialized
> > to current time + relative deadline... I think this makes perfect
> > sense, doesn't it?
> >   
> 
> Mmm, I don't think we will (with this patch) actually reinitialize the
> deadline when a "normal" gEDF migration happen (push/pull), as
> (de)activate_task() have no flag set. Which brings the question,
> should we actually take care of this corner case (as what you say
> makes sense to me too)?

I might be misunderstanding the problem, here... Are you talking about
do_set_cpus_allowed()? Or about push/pull migrations happening because
of the gEDF algorithm?

If you are referring to do_set_cpus_allowed, this is my understanding:
1) If do_set_cpus_allowed() is called on a queued task, then
   dequeue_task() with DEQUEUE_SAVE is called, followed by
   enqueue_task() with ENQUEUE_RESTORE... So, if the deadline is in the
   past it is correctly reinitialized
2) If do_set_cpus_allowed() is called on a non-queued task, this means
   the task is blocked, no? So, when it will wake up enqueue_dl_entity()
   will invoke update_dl_entity() that will check if the deadline is in
   the past.

If you are referring to push/pull migrations due to gEDF, then
enqueue_dl_entity() will be invoked with "flags" = 0, so the deadline
will not be changed (and this is correct: we do not want to
initialize / change tasks' deadlines during gEDF migrations).

In my previous email, with "a task is moved to a different runqueue" I
wanted to say that the taks is forced to moved to a different runqueue
because its affinity is changed; I did not want to talk about "regular
migrations" due to the push/pull (gEDF) mechanism.


				Luca

[toc] | [prev] | [next] | [standalone]


#1629425

FromJuri Lelli <juri.lelli@arm.com>
Date2017-04-24 13:00 +0200
Message-ID<tzJSO-5YI-21@gated-at.bofh.it>
In reply to#1629410
On 24/04/17 12:36, Luca Abeni wrote:
> On Mon, 24 Apr 2017 11:16:24 +0100
> Juri Lelli <juri.lelli@arm.com> wrote:
> 
> > On 21/04/17 21:08, Luca Abeni wrote:

[...]

> > > 
> > > Well, double thinking about it, this is an interesting problem...
> > > What do we want to do with do_set_cpus_allowed()? (I mean: what is
> > > the expected behaviour?)
> > > 
> > > With this patch, if a task is moved to a different runqueue when its
> > > deadline is in the past (because we are doing gEDF, or because of
> > > timer granularity issues) its scheduling deadline is reinitialized
> > > to current time + relative deadline... I think this makes perfect
> > > sense, doesn't it?
> > >   
> > 
> > Mmm, I don't think we will (with this patch) actually reinitialize the
> > deadline when a "normal" gEDF migration happen (push/pull), as
> > (de)activate_task() have no flag set. Which brings the question,
> > should we actually take care of this corner case (as what you say
> > makes sense to me too)?
> 
> I might be misunderstanding the problem, here... Are you talking about
> do_set_cpus_allowed()? Or about push/pull migrations happening because
> of the gEDF algorithm?
> 

My concern was about do_set_cpus_allowed(), but then you mentioned
"because we are doing gEDF" and that made me think of what happens when
we do push/pull. :)

> If you are referring to do_set_cpus_allowed, this is my understanding:
> 1) If do_set_cpus_allowed() is called on a queued task, then
>    dequeue_task() with DEQUEUE_SAVE is called, followed by
>    enqueue_task() with ENQUEUE_RESTORE... So, if the deadline is in the
>    past it is correctly reinitialized
> 2) If do_set_cpus_allowed() is called on a non-queued task, this means
>    the task is blocked, no? So, when it will wake up enqueue_dl_entity()
>    will invoke update_dl_entity() that will check if the deadline is in
>    the past.
> 

OK. I think it makes sense, and your patch should cure the problem.
Maybe add a comment to note this down.

> If you are referring to push/pull migrations due to gEDF, then
> enqueue_dl_entity() will be invoked with "flags" = 0, so the deadline
> will not be changed (and this is correct: we do not want to
> initialize / change tasks' deadlines during gEDF migrations).
> 

Ok, but I was wondering about the (admittedly) corner case in which we
migrate (via push/pull) a task on a rq, the rq_clock of which is after
the task's deadline (because clocks on src_rq and dst_rq are not in
sync). Anyway, maybe it's so corner case that we don't really want to
deal with it right now? I guess bigger things to fix first. :)

> In my previous email, with "a task is moved to a different runqueue" I
> wanted to say that the taks is forced to moved to a different runqueue
> because its affinity is changed; I did not want to talk about "regular
> migrations" due to the push/pull (gEDF) mechanism.
> 

Thanks for claryfing. As said, I just got distracted by what you
mentioned as examples between parenthesis.

[toc] | [prev] | [next] | [standalone]


#1628112

FromPeter Zijlstra <peterz@infradead.org>
Date2017-04-21 12:20 +0200
Message-ID<tyDPs-4B9-15@gated-at.bofh.it>
In reply to#1628092
On Fri, Apr 21, 2017 at 10:47:29AM +0100, Juri Lelli wrote:

> Oh, I think it works "by coincidence", as ENQUEUE_RESTORE == DEQUEUE_SAVE
> == 0x02 ? :)

That's very much on purpose, also see:

#define DEQUEUE_SAVE            0x02 /* matches ENQUEUE_RESTORE */

[toc] | [prev] | [next] | [standalone]


#1628093

Fromluca abeni <luca.abeni@santannapisa.it>
Date2017-04-21 11:50 +0200
Message-ID<tyDmq-4ci-27@gated-at.bofh.it>
In reply to#1628091
On Fri, 21 Apr 2017 10:39:26 +0100
Juri Lelli <juri.lelli@arm.com> wrote:

> Hi Luca,
> 
> On 20/04/17 21:30, Luca Abeni wrote:
> > From: Luca Abeni <luca.abeni@santannapisa.it>
> > 
> > When switching to -deadline, if the scheduling deadline of a task is
> > in the past then switched_to_dl() calls setup_new_entity() to
> > properly initialize the scheduling deadline and runtime.
> > 
> > The problem is that the task is enqueued _before_ having its
> > parameters initialized by setup_new_entity(), and this can cause
> > problems. For example, a task with its out-of-date deadline in the
> > past will potentially be enqueued as the highest priority one;
> > however, its adjusted deadline may not be the earliest one.
> > 
> > This patch fixes the problem by initializing the task's parameters
> > before enqueuing it.
> > 
> > Signed-off-by: Luca Abeni <luca.abeni@santannapisa.it>
> > Reviewed-by: Daniel Bristot de Oliveira <bristot@redhat.com>
> > ---
> >  kernel/sched/deadline.c | 12 ++++--------
> >  1 file changed, 4 insertions(+), 8 deletions(-)
> > 
> > diff --git a/kernel/sched/deadline.c b/kernel/sched/deadline.c
> > index a2ce590..ec53d24 100644
> > --- a/kernel/sched/deadline.c
> > +++ b/kernel/sched/deadline.c
> > @@ -950,6 +950,10 @@ enqueue_dl_entity(struct sched_dl_entity
> > *dl_se, update_dl_entity(dl_se, pi_se);
> >  	else if (flags & ENQUEUE_REPLENISH)
> >  		replenish_dl_entity(dl_se, pi_se);
> > +	else if ((flags & ENQUEUE_RESTORE) &&  
> 
> Not sure I understand how this works. AFAICT we are doing
> __sched_setscheduler() when we want to catch the case of a new
> dl_entity (SCHED_{OTHER,FIFO} -> SCHED_DEADLINE}, but queue_flags
> (which are passed to enqueue_task()) don't seem to have
> ENQUEUE_RESTORE set?

I was under the impression sched_setscheduler() sets ENQUEUE_RESTORE...


				Luca

[toc] | [prev] | [next] | [standalone]


#1628097

Fromluca abeni <luca.abeni@santannapisa.it>
Date2017-04-21 12:00 +0200
Message-ID<tyDw5-4fF-13@gated-at.bofh.it>
In reply to#1628093
On Fri, 21 Apr 2017 11:42:40 +0200
luca abeni <luca.abeni@santannapisa.it> wrote:
[...]
> > > diff --git a/kernel/sched/deadline.c b/kernel/sched/deadline.c
> > > index a2ce590..ec53d24 100644
> > > --- a/kernel/sched/deadline.c
> > > +++ b/kernel/sched/deadline.c
> > > @@ -950,6 +950,10 @@ enqueue_dl_entity(struct sched_dl_entity
> > > *dl_se, update_dl_entity(dl_se, pi_se);
> > >  	else if (flags & ENQUEUE_REPLENISH)
> > >  		replenish_dl_entity(dl_se, pi_se);
> > > +	else if ((flags & ENQUEUE_RESTORE) &&    
> > 
> > Not sure I understand how this works. AFAICT we are doing
> > __sched_setscheduler() when we want to catch the case of a new
> > dl_entity (SCHED_{OTHER,FIFO} -> SCHED_DEADLINE}, but queue_flags
> > (which are passed to enqueue_task()) don't seem to have
> > ENQUEUE_RESTORE set?  
> 
> I was under the impression sched_setscheduler() sets
> ENQUEUE_RESTORE...

__sched_setscheduler() sets queue_flags to DEQUEUE_SAVE, which matches
ENQUEUE_RESTORE (see comments in sched/sched.h), so things should work
correctly, right?



				Luca

[toc] | [prev] | [next] | [standalone]


#1628266

FromSteven Rostedt <rostedt@goodmis.org>
Date2017-04-21 15:50 +0200
Message-ID<tyH6G-6q7-23@gated-at.bofh.it>
In reply to#1628097
On Fri, 21 Apr 2017 11:54:21 +0200
luca abeni <luca.abeni@santannapisa.it> wrote:

> On Fri, 21 Apr 2017 11:42:40 +0200
> luca abeni <luca.abeni@santannapisa.it> wrote:
> [...]
> > > > diff --git a/kernel/sched/deadline.c b/kernel/sched/deadline.c
> > > > index a2ce590..ec53d24 100644
> > > > --- a/kernel/sched/deadline.c
> > > > +++ b/kernel/sched/deadline.c
> > > > @@ -950,6 +950,10 @@ enqueue_dl_entity(struct sched_dl_entity
> > > > *dl_se, update_dl_entity(dl_se, pi_se);
> > > >  	else if (flags & ENQUEUE_REPLENISH)
> > > >  		replenish_dl_entity(dl_se, pi_se);
> > > > +	else if ((flags & ENQUEUE_RESTORE) &&      
> > > 
> > > Not sure I understand how this works. AFAICT we are doing
> > > __sched_setscheduler() when we want to catch the case of a new
> > > dl_entity (SCHED_{OTHER,FIFO} -> SCHED_DEADLINE}, but queue_flags
> > > (which are passed to enqueue_task()) don't seem to have
> > > ENQUEUE_RESTORE set?    
> > 
> > I was under the impression sched_setscheduler() sets
> > ENQUEUE_RESTORE...  
> 
> __sched_setscheduler() sets queue_flags to DEQUEUE_SAVE, which matches
> ENQUEUE_RESTORE (see comments in sched/sched.h), so things should work
> correctly, right?

I was tripping over this too, but missed the comments in sched/sched.h.

Probably want to stick a comment about this in here as well.

-- Steve

[toc] | [prev] | [standalone]


Back to top | Article view | linux.kernel


csiph-web