2007-06-10 09:33:43

by Thomas Gleixner

[permalink] [raw]
Subject: [patch-mm 07/23] Tick management: spread timer interrupt

From: john stultz <[email protected]>

After discussing w/ Thomas over IRC, it seems the issue is the sched
tick fires on every cpu at the same time, causing extra lock contention.

This smaller change, adds an extra offset per cpu so the ticks don't
line up. This patch also drops the idle latency from 40us down to under
20us.

Signed-off-by: john stultz <[email protected]>
Signed-off-by: Thomas Gleixner <[email protected]>

---
kernel/time/tick-sched.c | 7 ++++++-
1 file changed, 6 insertions(+), 1 deletion(-)

Index: linux-2.6.22-rc4-mm/kernel/time/tick-sched.c
===================================================================
--- linux-2.6.22-rc4-mm.orig/kernel/time/tick-sched.c 2007-06-10 10:44:37.000000000 +0200
+++ linux-2.6.22-rc4-mm/kernel/time/tick-sched.c 2007-06-10 10:44:38.000000000 +0200
@@ -573,6 +573,7 @@ void tick_setup_sched_timer(void)
{
struct tick_sched *ts = &__get_cpu_var(tick_cpu_sched);
ktime_t now = ktime_get();
+ u64 offset;

/*
* Emulate tick processing via per-CPU hrtimers:
@@ -581,8 +582,12 @@ void tick_setup_sched_timer(void)
ts->sched_timer.function = tick_sched_timer;
ts->sched_timer.cb_mode = HRTIMER_CB_IRQSAFE_NO_SOFTIRQ;

- /* Get the next period */
+ /* Get the next period (per cpu)*/
ts->sched_timer.expires = tick_init_jiffy_update();
+ offset = ktime_to_ns(tick_period) >> 1;
+ do_div(offset, NR_CPUS);
+ offset *= smp_processor_id();
+ ts->sched_timer.expires = ktime_add_ns(ts->sched_timer.expires, offset);

for (;;) {
hrtimer_forward(&ts->sched_timer, now, tick_period);

--


2007-06-10 14:16:27

by Andreas Mohr

[permalink] [raw]
Subject: Re: [patch-mm 07/23] Tick management: spread timer interrupt

Hi,

On Sun, Jun 10, 2007 at 09:44:05AM -0000, Thomas Gleixner wrote:
> From: john stultz <[email protected]>
>
> After discussing w/ Thomas over IRC, it seems the issue is the sched
> tick fires on every cpu at the same time, causing extra lock contention.

Hmm, the cpu-specific offset calculation isn't too expensive, hopefully?
(div/mul in patch, maybe this could be done differently)

And is it granted that the do_div() compiles into a nice plain void
on non-SMP? Would be good to verify this.

And calculation order? Do multiply before division to minimize calculation
error?
(for a timer tick it probably doesn't matter, however)
And of course OTOH doing it the other way might lead to overflows...

> This smaller change, adds an extra offset per cpu so the ticks don't
> line up. This patch also drops the idle latency from 40us down to under
> 20us.

Very nice, thanks!

> + /* Get the next period (per cpu)*/
> ts->sched_timer.expires = tick_init_jiffy_update();
> + offset = ktime_to_ns(tick_period) >> 1;
> + do_div(offset, NR_CPUS);
> + offset *= smp_processor_id();

Andreas Mohr

2007-06-10 14:31:20

by Thomas Gleixner

[permalink] [raw]
Subject: Re: [patch-mm 07/23] Tick management: spread timer interrupt

On Sun, 2007-06-10 at 16:16 +0200, Andreas Mohr wrote:
> Hi,
>
> On Sun, Jun 10, 2007 at 09:44:05AM -0000, Thomas Gleixner wrote:
> > From: john stultz <[email protected]>
> >
> > After discussing w/ Thomas over IRC, it seems the issue is the sched
> > tick fires on every cpu at the same time, causing extra lock contention.
>
> Hmm, the cpu-specific offset calculation isn't too expensive, hopefully?
> (div/mul in patch, maybe this could be done differently)

That's one time during setup, no hot path.

tglx


2007-06-10 14:35:40

by Andreas Mohr

[permalink] [raw]
Subject: Re: [patch-mm 07/23] Tick management: spread timer interrupt

Hi,

On Sun, Jun 10, 2007 at 04:31:03PM +0200, Thomas Gleixner wrote:
> That's one time during setup, no hot path.

Urks, should have looked at actual file then instead of patch context only,
sorry!

Andreas Mohr