2011-03-24 14:01:44

by Dario Faggioli

[permalink] [raw]
Subject: [PATCH] sched: leave sched_setscheduler earlier if possible.

sched_setscheduler (in sched.c) is called in order of changing the
scheduling policy and/or the real-time priority of a task. Thus,
if we find out that neither of those are actually being modified, it
is possible to return earlier and save the overhead of a full
deactivate+activate cycle of the task in question.

Beside that, if we have more than one SCHED_FIFO task with the same
priority on the same rq (which means they share the same priority queue)
having one of them changing its position in the priority queue because of
a sched_setscheduler (as it happens by means of the deactivate+activate)
that does not actually change the priority violates POSIX which states,
for SCHED_FIFO:

"If a thread whose policy or priority has been modified by
pthread_setschedprio() is a running thread or is runnable, the effect on
its position in the thread list depends on the direction of the
modification, as follows: a. <...> b. If the priority is unchanged, the
thread does not change position in the thread list. c. <...>"

(http://pubs.opengroup.org/onlinepubs/009695399/functions/xsh_chap02_08.html)

Signed-off-by: Dario Faggioli <[email protected]>
---
kernel/sched.c | 10 ++++++++++
1 files changed, 10 insertions(+), 0 deletions(-)

diff --git a/kernel/sched.c b/kernel/sched.c
index c5ae6bc..d73bbc5 100644
--- a/kernel/sched.c
+++ b/kernel/sched.c
@@ -4998,6 +4998,16 @@ recheck:
return -EINVAL;
}

+ /*
+ * If not changing anything there's no need to proceed further
+ */
+ if (unlikely(policy == p->policy && (!rt_policy(policy) ||
+ param->sched_priority == p->rt_priority))) {
+ __task_rq_unlock(rq);
+ raw_spin_unlock_irqrestore(&p->pi_lock, flags);
+ return 0;
+ }
+
#ifdef CONFIG_RT_GROUP_SCHED
if (user) {
/*
--
1.7.4.1

--
<<This happens because I choose it to happen!>> (Raistlin Majere)
----------------------------------------------------------------------
Dario Faggioli, ReTiS Lab, Scuola Superiore Sant'Anna, Pisa (Italy)

http://retis.sssup.it/people/faggioli -- [email protected]


Attachments:
signature.asc (198.00 B)
This is a digitally signed message part

2011-03-24 14:22:04

by Steven Rostedt

[permalink] [raw]
Subject: Re: [PATCH] sched: leave sched_setscheduler earlier if possible.

On Thu, 2011-03-24 at 14:00 +0100, Dario Faggioli wrote:
> sched_setscheduler (in sched.c) is called in order of changing the
> scheduling policy and/or the real-time priority of a task. Thus,
> if we find out that neither of those are actually being modified, it
> is possible to return earlier and save the overhead of a full
> deactivate+activate cycle of the task in question.
>
> Beside that, if we have more than one SCHED_FIFO task with the same
> priority on the same rq (which means they share the same priority queue)
> having one of them changing its position in the priority queue because of
> a sched_setscheduler (as it happens by means of the deactivate+activate)
> that does not actually change the priority violates POSIX which states,
> for SCHED_FIFO:
>
> "If a thread whose policy or priority has been modified by
> pthread_setschedprio() is a running thread or is runnable, the effect on
> its position in the thread list depends on the direction of the
> modification, as follows: a. <...> b. If the priority is unchanged, the
> thread does not change position in the thread list. c. <...>"
>
> (http://pubs.opengroup.org/onlinepubs/009695399/functions/xsh_chap02_08.html)
>
> Signed-off-by: Dario Faggioli <[email protected]>

Acked-by: Steven Rostedt <[email protected]>

> ---
> kernel/sched.c | 10 ++++++++++
> 1 files changed, 10 insertions(+), 0 deletions(-)
>
> diff --git a/kernel/sched.c b/kernel/sched.c
> index c5ae6bc..d73bbc5 100644
> --- a/kernel/sched.c
> +++ b/kernel/sched.c


> @@ -4998,6 +4998,16 @@ recheck:

Peter, this is why I prefer:

recheck:
over
recheck:

-- Steve


> return -EINVAL;
> }
>
> + /*
> + * If not changing anything there's no need to proceed further
> + */
> + if (unlikely(policy == p->policy && (!rt_policy(policy) ||
> + param->sched_priority == p->rt_priority))) {
> + __task_rq_unlock(rq);
> + raw_spin_unlock_irqrestore(&p->pi_lock, flags);
> + return 0;
> + }
> +
> #ifdef CONFIG_RT_GROUP_SCHED
> if (user) {
> /*
> --
> 1.7.4.1
>

2011-03-25 10:26:27

by Peter Zijlstra

[permalink] [raw]
Subject: Re: [PATCH] sched: leave sched_setscheduler earlier if possible.

On Thu, 2011-03-24 at 10:21 -0400, Steven Rostedt wrote:
> > @@ -4998,6 +4998,16 @@ recheck:
>
> Peter, this is why I prefer:
>
> recheck:
> over
> recheck:
>
And you know I prefer to fix the tools ;-)

2011-03-25 12:52:58

by Steven Rostedt

[permalink] [raw]
Subject: Re: [PATCH] sched: leave sched_setscheduler earlier if possible.

On Fri, 2011-03-25 at 11:28 +0100, Peter Zijlstra wrote:
> On Thu, 2011-03-24 at 10:21 -0400, Steven Rostedt wrote:
> > > @@ -4998,6 +4998,16 @@ recheck:
> >
> > Peter, this is why I prefer:
> >
> > recheck:
> > over
> > recheck:
> >
> And you know I prefer to fix the tools ;-)

And when the tools are fixed, I'll also prefer

recheck:
over
recheck:

;-)

-- Steve

2011-03-25 13:05:06

by Peter Zijlstra

[permalink] [raw]
Subject: Re: [PATCH] sched: leave sched_setscheduler earlier if possible.

On Fri, 2011-03-25 at 08:52 -0400, Steven Rostedt wrote:
> > And you know I prefer to fix the tools ;-)
>
> And when the tools are fixed, I'll also prefer
>
So instead of complaining about it, tell people to use:

QUILT_DIFF_OPTS="-F ^[[:alpha:]\$_].*[^:]\$"

Just like you tell them about all your other patch style issues.

Junio, know of any way to make git-diff do the same? The purpose is to
skip labels as functions so that people stop doing stupid crap like
indenting labels, eg.:

void foo(void)
{
again:
/* do stuff */
if (retry)
goto again;
}

instead of the normal:

void foo(void)
{
again:
/* do stuff */
if (retry)
goto again;
}

2011-03-25 22:36:57

by Junio C Hamano

[permalink] [raw]
Subject: Re: [PATCH] sched: leave sched_setscheduler earlier if possible.

Peter Zijlstra <[email protected]> writes:

> Junio, know of any way to make git-diff do the same? The purpose is to
> skip labels as functions so that people stop doing stupid crap like
> indenting labels, eg.:
>
> void foo(void)
> {
> again:

Perhaps "git help attributes" and look for "funcname"?

2011-03-26 10:24:11

by Peter Zijlstra

[permalink] [raw]
Subject: Re: [PATCH] sched: leave sched_setscheduler earlier if possible.

On Fri, 2011-03-25 at 15:36 -0700, Junio C Hamano wrote:
> Peter Zijlstra <[email protected]> writes:
>
> > Junio, know of any way to make git-diff do the same? The purpose is to
> > skip labels as functions so that people stop doing stupid crap like
> > indenting labels, eg.:
> >
> > void foo(void)
> > {
> > again:
>
> Perhaps "git help attributes" and look for "funcname"?

Awesome so the diff.$foo.xfuncname is about what I want, except I seem
to need a .gitattributes file per repository.

Is there a way to over-ride the default in a global way so that I can
only change ~/.gitconfig and not bother with all various repos I have?

Another question, the built-in patterns consist of multiple regexes, can
custom patterns also have multiple?


So what worked for me was:

~/.gitconfig:

[diff "cpp"]
xfuncname = "^[[:alpha:]$_].*[^:]$"

and linux-2.6/.gitattributes:

*.h diff=cpp
*.c diff=cpp

What I tried was:

[diff]
xfuncname = "^[[:alpha:]$_].*[^:]$"

But that didn't seem to work.. I also tried ~/.gitattributes, but again,
no joy.


2011-03-26 10:28:19

by Peter Zijlstra

[permalink] [raw]
Subject: Re: [PATCH] sched: leave sched_setscheduler earlier if possible.

On Sat, 2011-03-26 at 11:26 +0100, Peter Zijlstra wrote:
> Awesome so the diff.$foo.xfuncname is about what I want, except I seem
> to need a .gitattributes file per repository.
>
> Is there a way to over-ride the default in a global way so that I can
> only change ~/.gitconfig and not bother with all various repos I have?
>
> Another question, the built-in patterns consist of multiple regexes, can
> custom patterns also have multiple?
>
>
> So what worked for me was:
>
> ~/.gitconfig:
>
> [diff "cpp"]
> xfuncname = "^[[:alpha:]$_].*[^:]$"
>
> and linux-2.6/.gitattributes:
>
> *.h diff=cpp
> *.c diff=cpp
>
> What I tried was:
>
> [diff]
> xfuncname = "^[[:alpha:]$_].*[^:]$"
>
> But that didn't seem to work.. I also tried ~/.gitattributes, but again,
> no joy.

D0'h, so what worked is:

# cat ~/.gitconfig
[diff "default"]
xfuncname = "^[[:alpha:]$_].*[^:]$"


2011-03-31 12:40:24

by Dario Faggioli

[permalink] [raw]
Subject: [tip:sched/urgent] sched: Leave sched_setscheduler() earlier if possible, do not disturb SCHED_FIFO tasks

Commit-ID: a51e91981870d013fcfcc08b0117997edbcbc7a7
Gitweb: http://git.kernel.org/tip/a51e91981870d013fcfcc08b0117997edbcbc7a7
Author: Dario Faggioli <[email protected]>
AuthorDate: Thu, 24 Mar 2011 14:00:18 +0100
Committer: Ingo Molnar <[email protected]>
CommitDate: Thu, 31 Mar 2011 13:00:34 +0200

sched: Leave sched_setscheduler() earlier if possible, do not disturb SCHED_FIFO tasks

sched_setscheduler() (in sched.c) is called in order of changing the
scheduling policy and/or the real-time priority of a task. Thus,
if we find out that neither of those are actually being modified, it
is possible to return earlier and save the overhead of a full
deactivate+activate cycle of the task in question.

Beside that, if we have more than one SCHED_FIFO task with the same
priority on the same rq (which means they share the same priority queue)
having one of them changing its position in the priority queue because of
a sched_setscheduler (as it happens by means of the deactivate+activate)
that does not actually change the priority violates POSIX which states,
for SCHED_FIFO:

"If a thread whose policy or priority has been modified by
pthread_setschedprio() is a running thread or is runnable, the effect on
its position in the thread list depends on the direction of the
modification, as follows: a. <...> b. If the priority is unchanged, the
thread does not change position in the thread list. c. <...>"

http://pubs.opengroup.org/onlinepubs/009695399/functions/xsh_chap02_08.html

(ed: And the POSIX specification here does, briefly and somewhat unexpectedly,
match what common sense tells us as well. )

Signed-off-by: Dario Faggioli <[email protected]>
Signed-off-by: Peter Zijlstra <[email protected]>
LKML-Reference: <1300971618.3960.82.camel@Palantir>
Signed-off-by: Ingo Molnar <[email protected]>
---
kernel/sched.c | 11 +++++++++++
1 files changed, 11 insertions(+), 0 deletions(-)

diff --git a/kernel/sched.c b/kernel/sched.c
index f592ce6..a884551 100644
--- a/kernel/sched.c
+++ b/kernel/sched.c
@@ -5011,6 +5011,17 @@ recheck:
return -EINVAL;
}

+ /*
+ * If not changing anything there's no need to proceed further:
+ */
+ if (unlikely(policy == p->policy && (!rt_policy(policy) ||
+ param->sched_priority == p->rt_priority))) {
+
+ __task_rq_unlock(rq);
+ raw_spin_unlock_irqrestore(&p->pi_lock, flags);
+ return 0;
+ }
+
#ifdef CONFIG_RT_GROUP_SCHED
if (user) {
/*