All of lore.kernel.org
 help / color / mirror / Atom feed
From: Wanpeng Li <wanpeng.li@linux.intel.com>
To: Peter Zijlstra <peterz@infradead.org>, Juri Lelli <juri.lelli@arm.com>
Cc: Wanpeng Li <wanpeng.li@linux.intel.com>,
	Ingo Molnar <mingo@redhat.com>,
	linux-kernel@vger.kernel.org
Subject: Re: [PATCH] sched/deadline: Use IPI to trigger DL task push migration instead of pulling
Date: Wed, 1 Apr 2015 07:18:36 +0800	[thread overview]
Message-ID: <20150331231836.GA10760@kernel> (raw)
In-Reply-To: <20150330094140.31dcc1cf@gandalf.local.home>

On Mon, Mar 30, 2015 at 09:41:40AM -0400, Steven Rostedt wrote:
>On Mon, 30 Mar 2015 07:07:10 +0800
>Wanpeng Li <wanpeng.li@linux.intel.com> wrote:
>
>> +static int find_next_push_cpu(struct rq *rq)
>> +{
>> +	struct rq *next_rq;
>> +	int cpu;
>> +
>> +	while (1) {
>> +		cpu = dlo_next_cpu(rq);
>> +		if (cpu >= nr_cpu_ids)
>> +			break;
>> +		next_rq = cpu_rq(cpu);
>> +
>> +		/* Make sure the next rq can push to this rq */
>> +		if (dl_time_before(next_rq->dl.earliest_dl.next,
>> +			rq->dl.earliest_dl.curr))
>> +			break;
>> +	}
>> +
>> +	return cpu;
>> +}
>> +
>
>Is it possible that we don't duplicate the code and that we can find a
>way to share the code between rt and dl? It's not that trivial to just
>cut and paste. If a bug is found in one, it most likely wont be ported
>to the other.
>
>The best is if we can share the code here some way. Perhaps have a
>single IPI that checks both rt and dl?

Peter, Juri, what's your ideas? ;)

Regards,
Wanpeng Li 

>
>-- Steve
>
>> +#define RT_PUSH_IPI_EXECUTING		1
>> +#define RT_PUSH_IPI_RESTART		2
>> +
>> +static void tell_cpu_to_push(struct rq *rq)
>> +{
>> +	int cpu;
>> +
>> +	if (rq->dl.push_flags & RT_PUSH_IPI_EXECUTING) {
>> +		raw_spin_lock(&rq->dl.push_lock);
>> +		/* Make sure it's still executing */
>> +		if (rq->dl.push_flags & RT_PUSH_IPI_EXECUTING) {
>> +			/*
>> +			 * Tell the IPI to restart the loop as things have
>> +			 * changed since it started.
>> +			 */
>> +			rq->dl.push_flags |= RT_PUSH_IPI_RESTART;
>> +			raw_spin_unlock(&rq->dl.push_lock);
>> +			return;
>> +		}
>> +		raw_spin_unlock(&rq->dl.push_lock);
>> +	}
>> +
>> +	/* When here, there's no IPI going around */
>> +
>> +	rq->dl.push_cpu = rq->cpu;
>> +	cpu = find_next_push_cpu(rq);
>> +	if (cpu >= nr_cpu_ids)
>> +		return;
>> +
>> +	rq->dl.push_flags = RT_PUSH_IPI_EXECUTING;
>> +
>> +	irq_work_queue_on(&rq->dl.push_work, cpu);
>> +}
>> +
>> +/* Called from hardirq context */
>> +static void try_to_push_tasks(void *arg)
>> +{
>> +	struct dl_rq *dl_rq = arg;
>> +	struct rq *rq, *src_rq;
>> +	int this_cpu;
>> +	int cpu;
>> +
>> +	this_cpu = dl_rq->push_cpu;
>> +
>> +	/* Paranoid check */
>> +	BUG_ON(this_cpu != smp_processor_id());
>> +
>> +	rq = cpu_rq(this_cpu);
>> +	src_rq = rq_of_dl_rq(dl_rq);
>> +
>> +again:
>> +	if (has_pushable_dl_tasks(rq)) {
>> +		raw_spin_lock(&rq->lock);
>> +		push_dl_task(rq);
>> +		raw_spin_unlock(&rq->lock);
>> +	}
>> +
>> +	/* Pass the IPI to the next rt overloaded queue */
>> +	raw_spin_lock(&dl_rq->push_lock);
>> +	/*
>> +	 * If the source queue changed since the IPI went out,
>> +	 * we need to restart the search from that CPU again.
>> +	 */
>> +	if (dl_rq->push_flags & RT_PUSH_IPI_RESTART) {
>> +		dl_rq->push_flags &= ~RT_PUSH_IPI_RESTART;
>> +		dl_rq->push_cpu = src_rq->cpu;
>> +	}
>> +
>> +	cpu = find_next_push_cpu(src_rq);
>> +
>> +	if (cpu >= nr_cpu_ids)
>> +		dl_rq->push_flags &= ~RT_PUSH_IPI_EXECUTING;
>> +	raw_spin_unlock(&dl_rq->push_lock);
>> +
>> +	if (cpu >= nr_cpu_ids)
>> +		return;
>> +
>> +	/*
>> +	 * It is possible that a restart caused this CPU to be
>> +	 * chosen again. Don't bother with an IPI, just see if we
>> +	 * have more to push.
>> +	 */
>> +	if (unlikely(cpu == rq->cpu))
>> +		goto again;
>> +
>> +	/* Try the next RT overloaded CPU */
>> +	irq_work_queue_on(&dl_rq->push_work, cpu);
>> +}
>> +
>> +static void push_irq_work_func(struct irq_work *work)
>> +{
>> +	struct dl_rq *dl_rq = container_of(work, struct dl_rq, push_work);
>> +
>> +	try_to_push_tasks(dl_rq);
>> +}
>> +#endif /* HAVE_RT_PUSH_IPI */
>> +
>>  static int pull_dl_task(struct rq *this_rq)
>>  {
>>  	int this_cpu = this_rq->cpu, ret = 0, cpu;
>> @@ -1432,6 +1602,13 @@ static int pull_dl_task(struct rq *this_rq)
>>  	 */
>>  	smp_rmb();
>>  
>> +#ifdef HAVE_RT_PUSH_IPI
>> +	if (sched_feat(RT_PUSH_IPI)) {
>> +		tell_cpu_to_push(this_rq);
>> +		return 0;
>> +	}
>> +#endif
>> +
>>  	for_each_cpu(cpu, this_rq->rd->dlo_mask) {
>>  		if (this_cpu == cpu)
>>  			continue;
>> diff --git a/kernel/sched/sched.h b/kernel/sched/sched.h
>> index dd532c5..87a937c 100644
>> --- a/kernel/sched/sched.h
>> +++ b/kernel/sched/sched.h
>> @@ -500,6 +500,12 @@ struct dl_rq {
>>  	 */
>>  	struct rb_root pushable_dl_tasks_root;
>>  	struct rb_node *pushable_dl_tasks_leftmost;
>> +#ifdef HAVE_RT_PUSH_IPI
>> +	int push_flags;
>> +	int push_cpu;
>> +	struct irq_work push_work;
>> +	raw_spinlock_t push_lock;
>> +#endif
>>  #else
>>  	struct dl_bw dl_bw;
>>  #endif

  reply	other threads:[~2015-03-31 23:36 UTC|newest]

Thread overview: 4+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2015-03-29 23:07 [PATCH] sched/deadline: Use IPI to trigger DL task push migration instead of pulling Wanpeng Li
2015-03-30 13:41 ` Steven Rostedt
2015-03-31 23:18   ` Wanpeng Li [this message]
2015-03-31 23:21     ` Wanpeng Li

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20150331231836.GA10760@kernel \
    --to=wanpeng.li@linux.intel.com \
    --cc=juri.lelli@arm.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=mingo@redhat.com \
    --cc=peterz@infradead.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.