From: Thomas Gleixner <tglx@linutronix.de> To: LKML <linux-kernel@vger.kernel.org> Cc: LAK <linux-arm-kernel@lists.infradead.org>, John Stultz <john.stultz@linaro.org>, Arjan van de Veen <arjan@infradead.org>, Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>, Santosh Shilimkar <santosh.shilimkar@ti.com>, Jason Liu <liu.h.jason@gmail.com> Subject: [patch 3/7] tick: Avoid programming the local cpu timer if broadcast pending Date: Wed, 06 Mar 2013 11:18:35 -0000 [thread overview] Message-ID: <20130306111537.431082074@linutronix.de> (raw) In-Reply-To: 20130306111351.883117670@linutronix.de [-- Attachment #1: tick-avoid-programming-local-cpu-timer-if-broadcast-pending.patch --] [-- Type: text/plain, Size: 3693 bytes --] If the local cpu timer stops in deep idle, we arm the broadcast device and get woken by an IPI. Now when we return from deep idle we reenable the local cpu timer unconditionally before handling the IPI. But that's a pointless exercise: the timer is already expired and the IPI is on the way. And it's an expensive exercise as we use the forced reprogramming mode so that we do not lose a timer event. This forced reprogramming will loop at least once in the retry. To avoid this reprogramming, we mark the cpu in a pending bit mask before we send the IPI. Now when the IPI target cpu wakes up, it will see the pending bit set and skip the reprogramming. The reprogramming of the cpu local timer will happen in the IPI handler which runs the cpu local timer interrupt function. Reported-by: Jason Liu <liu.h.jason@gmail.com> Signed-off-by: Thomas Gleixner <tglx@linutronix.de> --- kernel/time/tick-broadcast.c | 33 +++++++++++++++++++++++++++++---- 1 file changed, 29 insertions(+), 4 deletions(-) Index: tip/kernel/time/tick-broadcast.c =================================================================== --- tip.orig/kernel/time/tick-broadcast.c +++ tip/kernel/time/tick-broadcast.c @@ -392,6 +392,7 @@ int tick_resume_broadcast(void) #ifdef CONFIG_TICK_ONESHOT static cpumask_var_t tick_broadcast_oneshot_mask; +static cpumask_var_t tick_broadcast_pending_mask; /* * Exposed for debugging: see timer_list.c @@ -448,10 +449,17 @@ again: /* Find all expired events */ for_each_cpu(cpu, tick_broadcast_oneshot_mask) { td = &per_cpu(tick_cpu_device, cpu); - if (td->evtdev->next_event.tv64 <= now.tv64) + if (td->evtdev->next_event.tv64 <= now.tv64) { cpumask_set_cpu(cpu, tmpmask); - else if (td->evtdev->next_event.tv64 < next_event.tv64) + /* + * Mark the remote cpu in the pending mask, so + * it can avoid reprogramming the cpu local + * timer in tick_broadcast_oneshot_control(). + */ + cpumask_set_cpu(cpu, tick_broadcast_pending_mask); + } else if (td->evtdev->next_event.tv64 < next_event.tv64) { next_event.tv64 = td->evtdev->next_event.tv64; + } } /* @@ -513,6 +521,7 @@ void tick_broadcast_oneshot_control(unsi raw_spin_lock_irqsave(&tick_broadcast_lock, flags); if (reason == CLOCK_EVT_NOTIFY_BROADCAST_ENTER) { + WARN_ON_ONCE(cpumask_test_cpu(cpu, tick_broadcast_pending_mask)); if (!cpumask_test_and_set_cpu(cpu, tick_broadcast_oneshot_mask)) { clockevents_set_mode(dev, CLOCK_EVT_MODE_SHUTDOWN); if (dev->next_event.tv64 < bc->next_event.tv64) @@ -521,10 +530,25 @@ void tick_broadcast_oneshot_control(unsi } else { if (cpumask_test_and_clear_cpu(cpu, tick_broadcast_oneshot_mask)) { clockevents_set_mode(dev, CLOCK_EVT_MODE_ONESHOT); - if (dev->next_event.tv64 != KTIME_MAX) - tick_program_event(dev->next_event, 1); + if (dev->next_event.tv64 == KTIME_MAX) + goto out; + /* + * The cpu which was handling the broadcast + * timer marked this cpu in the broadcast + * pending mask and fired the broadcast + * IPI. So we are going to handle the expired + * event anyway via the broadcast IPI + * handler. No need to reprogram the timer + * with an already expired event. + */ + if (cpumask_test_and_clear_cpu(cpu, + tick_broadcast_pending_mask)) + goto out; + + tick_program_event(dev->next_event, 1); } } +out: raw_spin_unlock_irqrestore(&tick_broadcast_lock, flags); } @@ -661,5 +685,6 @@ void tick_broadcast_init(void) alloc_cpumask_var(&tmpmask, GFP_NOWAIT); #ifdef CONFIG_TICK_ONESHOT alloc_cpumask_var(&tick_broadcast_oneshot_mask, GFP_NOWAIT); + alloc_cpumask_var(&tick_broadcast_pending_mask, GFP_NOWAIT); #endif }
WARNING: multiple messages have this Message-ID (diff)
From: tglx@linutronix.de (Thomas Gleixner) To: linux-arm-kernel@lists.infradead.org Subject: [patch 3/7] tick: Avoid programming the local cpu timer if broadcast pending Date: Wed, 06 Mar 2013 11:18:35 -0000 [thread overview] Message-ID: <20130306111537.431082074@linutronix.de> (raw) In-Reply-To: 20130306111351.883117670@linutronix.de An embedded and charset-unspecified text was scrubbed... Name: tick-avoid-programming-local-cpu-timer-if-broadcast-pending.patch URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20130306/52b75b8a/attachment.ksh>
next prev parent reply other threads:[~2013-03-06 11:21 UTC|newest] Thread overview: 31+ messages / expand[flat|nested] mbox.gz Atom feed top 2013-03-06 11:18 [patch 0/7] tick: Optimize broadcast handling and prevent expiry ping pong Thomas Gleixner 2013-03-06 11:18 ` Thomas Gleixner 2013-03-06 11:18 ` [patch 1/7] tick: Call tick_init late Thomas Gleixner 2013-03-06 11:18 ` Thomas Gleixner 2013-03-07 16:29 ` [tip:timers/core] " tip-bot for Thomas Gleixner 2013-03-06 11:18 ` [patch 2/7] tick: Convert broadcast cpu bitmaps to cpumask_var_t Thomas Gleixner 2013-03-06 11:18 ` Thomas Gleixner 2013-03-07 5:51 ` Rusty Russell 2013-03-07 5:51 ` Rusty Russell 2013-03-07 16:30 ` [tip:timers/core] " tip-bot for Thomas Gleixner 2013-03-06 11:18 ` Thomas Gleixner [this message] 2013-03-06 11:18 ` [patch 3/7] tick: Avoid programming the local cpu timer if broadcast pending Thomas Gleixner 2013-03-19 11:35 ` [tip:timers/core] " tip-bot for Thomas Gleixner 2013-03-06 11:18 ` [patch 4/7] tick: Handle broadcast wakeup of multiple cpus Thomas Gleixner 2013-03-06 11:18 ` Thomas Gleixner 2013-03-13 11:36 ` Lorenzo Pieralisi 2013-03-13 11:36 ` Lorenzo Pieralisi 2013-03-13 21:42 ` Thomas Gleixner 2013-03-13 21:42 ` Thomas Gleixner 2013-03-19 11:37 ` [tip:timers/core] " tip-bot for Thomas Gleixner 2013-03-06 11:18 ` [patch 5/7] tick: Provide a check for a forced broadcast pending Thomas Gleixner 2013-03-06 11:18 ` Thomas Gleixner 2013-03-19 11:38 ` [tip:timers/core] " tip-bot for Thomas Gleixner 2013-03-06 11:18 ` [patch 6/7] arm: Use tick broadcast expired check Thomas Gleixner 2013-03-06 11:18 ` Thomas Gleixner 2013-03-19 11:39 ` [tip:timers/core] " tip-bot for Thomas Gleixner 2013-03-06 11:18 ` [patch 7/7] x86: " Thomas Gleixner 2013-03-06 11:18 ` Thomas Gleixner 2013-03-19 11:40 ` [tip:timers/core] " tip-bot for Thomas Gleixner 2013-03-13 9:35 ` [patch 0/7] tick: Optimize broadcast handling and prevent expiry ping pong Santosh Shilimkar 2013-03-13 9:35 ` Santosh Shilimkar
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=20130306111537.431082074@linutronix.de \ --to=tglx@linutronix.de \ --cc=arjan@infradead.org \ --cc=john.stultz@linaro.org \ --cc=linux-arm-kernel@lists.infradead.org \ --cc=linux-kernel@vger.kernel.org \ --cc=liu.h.jason@gmail.com \ --cc=lorenzo.pieralisi@arm.com \ --cc=santosh.shilimkar@ti.com \ /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: linkBe 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.