[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <20160916105135.GM5012@twins.programming.kicks-ass.net>
Date: Fri, 16 Sep 2016 12:51:35 +0200
From: Peter Zijlstra <peterz@...radead.org>
To: Vincent Guittot <vincent.guittot@...aro.org>
Cc: mingo@...nel.org, linux-kernel@...r.kernel.org,
yuyang.du@...el.com, Morten.Rasmussen@....com,
linaro-kernel@...ts.linaro.org, dietmar.eggemann@....com,
pjt@...gle.com, bsegall@...gle.com
Subject: Re: [PATCH 7/7 v3] sched: fix wrong utilization accounting when
switching to fair class
On Mon, Sep 12, 2016 at 09:47:52AM +0200, Vincent Guittot wrote:
> -dequeue task
> -put task
> -change the property
> -enqueue task
> -set task as current task
> diff --git a/kernel/sched/core.c b/kernel/sched/core.c
> index 3e52d08..7a9c9b9 100644
> --- a/kernel/sched/core.c
> +++ b/kernel/sched/core.c
> @@ -1105,10 +1105,10 @@ void do_set_cpus_allowed(struct task_struct *p, const struct cpumask *new_mask)
>
> p->sched_class->set_cpus_allowed(p, new_mask);
>
> - if (running)
> - p->sched_class->set_curr_task(rq);
> if (queued)
> enqueue_task(rq, p, ENQUEUE_RESTORE);
> + if (running)
> + p->sched_class->set_curr_task(rq);
> }
>
> /*
So one thing that I've wanted to do for a while, but never managed to
come up with a sensible way to do is encapsulate this pattern.
The two options I came up with are:
#define FOO(p, stmt)
({
struct rq *rq = task_rq(p);
bool queued = task_on_rq_queued(p);
bool running = task_current(rq);
int queue_flags = DEQUEUE_SAVE; /* also ENQUEUE_RESTORE */
if (queued)
dequeue_task(rq, p, queue_flags);
if (running)
put_prev_task(rq, p);
stmt;
if (queued)
enqueue_task(rq, p, queue_flags);
if (running)
set_curr_task(rq, p);
})
and
void foo(struct task_struct *p, void (*func)(struct task_struct *, int *))
{
struct rq *rq = task_rq(p);
bool queued = task_on_rq_queued(p);
bool running = task_current(rq);
int queue_flags = DEQUEUE_SAVE; /* also ENQUEUE_RESTORE */
if (queued)
dequeue_task(rq, p, queue_flags);
if (running)
put_prev_task(rq, p);
func(p, &queue_flags);
if (queued)
enqueue_task(rq, p, queue_flags);
if (running)
set_curr_task(rq, p);
}
Neither results in particularly pretty code. Although I suppose if I'd
have to pick one I'd go for the macro variant.
Opinions? I'm fine with leaving the code as is, just wanted to throw
this out there.
Powered by blists - more mailing lists