From: Thomas Gleixner <tglx@linutronix.de>
To: Elias Oltmanns <eo@nebensachen.de>
Cc: Jiri Slaby <jirislaby@gmail.com>, linux-wireless@vger.kernel.org
Subject: Re: ath5k: kernel timing screwed - due to unserialised register access?
Date: Tue, 14 Oct 2008 21:00:07 +0200 (CEST) [thread overview]
Message-ID: <alpine.LFD.2.00.0810142054580.6848@apollo> (raw)
In-Reply-To: <87k5ceeuxy.fsf@denkblock.local>
On Sat, 11 Oct 2008, Elias Oltmanns wrote:
> > Compile the acpi_processor module in to the kernel
> > (CONFIG_ACPI_PROCESSOR=y) and add processor.max_cstate=1 to the kernel
> > command line. If I analysed the problem correctly this will make the
> > jiffies problem go away. I'm working on a fix.
>
> Spot on, it does go away regardless whether NO_HZ or HIGH_RES are
> enabled or disabled. Looking forward to testing your fix ;-).
Here you go.
tglx
---
diff --git a/include/linux/tick.h b/include/linux/tick.h
index 98921a3..cb271ce 100644
--- a/include/linux/tick.h
+++ b/include/linux/tick.h
@@ -96,9 +96,11 @@ extern cpumask_t *tick_get_broadcast_oneshot_mask(void);
extern void tick_clock_notify(void);
extern int tick_check_oneshot_change(int allow_nohz);
extern struct tick_sched *tick_get_tick_sched(int cpu);
+extern void tick_check_idle(int cpu);
# else
static inline void tick_clock_notify(void) { }
static inline int tick_check_oneshot_change(int allow_nohz) { return 0; }
+static inline void tick_check_idle(int cpu) { }
# endif
#else /* CONFIG_GENERIC_CLOCKEVENTS */
@@ -111,21 +113,17 @@ static inline int tick_check_oneshot_change(int allow_nohz) { return 0; }
# ifdef CONFIG_NO_HZ
extern void tick_nohz_stop_sched_tick(int inidle);
extern void tick_nohz_restart_sched_tick(void);
-extern void tick_nohz_update_jiffies(void);
extern ktime_t tick_nohz_get_sleep_length(void);
-extern void tick_nohz_stop_idle(int cpu);
extern u64 get_cpu_idle_time_us(int cpu, u64 *last_update_time);
# else
static inline void tick_nohz_stop_sched_tick(int inidle) { }
static inline void tick_nohz_restart_sched_tick(void) { }
-static inline void tick_nohz_update_jiffies(void) { }
static inline ktime_t tick_nohz_get_sleep_length(void)
{
ktime_t len = { .tv64 = NSEC_PER_SEC/HZ };
return len;
}
-static inline void tick_nohz_stop_idle(int cpu) { }
static inline u64 get_cpu_idle_time_us(int cpu, u64 *unused) { return -1; }
# endif /* !NO_HZ */
diff --git a/kernel/softirq.c b/kernel/softirq.c
index c506f26..6ad6aec 100644
--- a/kernel/softirq.c
+++ b/kernel/softirq.c
@@ -254,16 +254,12 @@ asmlinkage void do_softirq(void)
*/
void irq_enter(void)
{
-#ifdef CONFIG_NO_HZ
int cpu = smp_processor_id();
- if (idle_cpu(cpu) && !in_interrupt())
- tick_nohz_stop_idle(cpu);
-#endif
- __irq_enter();
-#ifdef CONFIG_NO_HZ
+
if (idle_cpu(cpu))
- tick_nohz_update_jiffies();
-#endif
+ tick_check_idle(cpu);
+
+ __irq_enter();
}
#ifdef __ARCH_IRQ_EXIT_IRQS_DISABLED
diff --git a/kernel/time/tick-broadcast.c b/kernel/time/tick-broadcast.c
index cb01cd8..f98a1b7 100644
--- a/kernel/time/tick-broadcast.c
+++ b/kernel/time/tick-broadcast.c
@@ -384,6 +384,19 @@ int tick_resume_broadcast_oneshot(struct clock_event_device *bc)
}
/*
+ * Called from irq_enter() when idle was interrupted to reenable the
+ * per cpu device.
+ */
+void tick_check_oneshot_broadcast(int cpu)
+{
+ if (cpu_isset(cpu, tick_broadcast_oneshot_mask)) {
+ struct tick_device *td = &per_cpu(tick_cpu_device, cpu);
+
+ clockevents_set_mode(td->evtdev, CLOCK_EVT_MODE_ONESHOT);
+ }
+}
+
+/*
* Handle oneshot mode broadcasting
*/
static void tick_handle_oneshot_broadcast(struct clock_event_device *dev)
diff --git a/kernel/time/tick-internal.h b/kernel/time/tick-internal.h
index 4692487..b1c05bf 100644
--- a/kernel/time/tick-internal.h
+++ b/kernel/time/tick-internal.h
@@ -36,6 +36,7 @@ extern void tick_broadcast_switch_to_oneshot(void);
extern void tick_shutdown_broadcast_oneshot(unsigned int *cpup);
extern int tick_resume_broadcast_oneshot(struct clock_event_device *bc);
extern int tick_broadcast_oneshot_active(void);
+extern void tick_check_oneshot_broadcast(int cpu);
# else /* BROADCAST */
static inline void tick_broadcast_setup_oneshot(struct clock_event_device *bc)
{
@@ -45,6 +46,7 @@ static inline void tick_broadcast_oneshot_control(unsigned long reason) { }
static inline void tick_broadcast_switch_to_oneshot(void) { }
static inline void tick_shutdown_broadcast_oneshot(unsigned int *cpup) { }
static inline int tick_broadcast_oneshot_active(void) { return 0; }
+static inline void tick_check_oneshot_broadcast(int cpu) { }
# endif /* !BROADCAST */
#else /* !ONESHOT */
diff --git a/kernel/time/tick-sched.c b/kernel/time/tick-sched.c
index a4d2193..d1b39e6 100644
--- a/kernel/time/tick-sched.c
+++ b/kernel/time/tick-sched.c
@@ -155,7 +155,7 @@ void tick_nohz_update_jiffies(void)
touch_softlockup_watchdog();
}
-void tick_nohz_stop_idle(int cpu)
+static void tick_nohz_stop_idle(int cpu)
{
struct tick_sched *ts = &per_cpu(tick_cpu_sched, cpu);
@@ -559,6 +559,20 @@ static inline void tick_nohz_switch_to_nohz(void) { }
#endif /* NO_HZ */
/*
+ * Called from irq_enter to notify about the possible interruption of idle()
+ */
+void tick_check_idle(int cpu)
+{
+#ifdef CONFIG_NO_HZ
+ if (!in_interrupt()) {
+ tick_nohz_stop_idle(cpu);
+ tick_nohz_update_jiffies();
+ }
+#endif
+ tick_check_oneshot_broadcast(cpu);
+}
+
+/*
* High resolution timer specific code
*/
#ifdef CONFIG_HIGH_RES_TIMERS
next prev parent reply other threads:[~2008-10-14 19:00 UTC|newest]
Thread overview: 27+ messages / expand[flat|nested] mbox.gz Atom feed top
2008-10-05 21:45 ath5k: kernel timing screwed - due to unserialised register access? Elias Oltmanns
2008-10-05 21:59 ` Thomas Gleixner
2008-10-06 14:04 ` Elias Oltmanns
2008-10-06 19:47 ` Thomas Gleixner
2008-10-07 15:27 ` Elias Oltmanns
2008-10-07 18:02 ` Thomas Gleixner
2008-10-07 18:44 ` Thomas Gleixner
2008-10-07 21:23 ` Elias Oltmanns
2008-10-08 11:39 ` Elias Oltmanns
2008-10-08 21:14 ` Thomas Gleixner
2008-10-09 11:15 ` Thomas Gleixner
2008-10-10 8:33 ` Elias Oltmanns
2008-10-10 10:13 ` Thomas Gleixner
2008-10-10 11:50 ` Elias Oltmanns
2008-10-10 12:34 ` Thomas Gleixner
2008-10-10 12:59 ` Elias Oltmanns
2008-10-10 21:32 ` Christoph Hellwig
2008-10-11 9:55 ` Thomas Gleixner
2008-10-10 19:24 ` Nick Kossifidis
2008-10-11 9:54 ` Thomas Gleixner
2008-10-11 20:30 ` Elias Oltmanns
2008-10-14 19:00 ` Thomas Gleixner [this message]
2008-10-14 22:01 ` Elias Oltmanns
2008-10-15 8:43 ` Thomas Gleixner
2008-10-15 16:32 ` Elias Oltmanns
2008-10-15 19:53 ` Thomas Gleixner
2008-10-17 21:03 ` Elias Oltmanns
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=alpine.LFD.2.00.0810142054580.6848@apollo \
--to=tglx@linutronix.de \
--cc=eo@nebensachen.de \
--cc=jirislaby@gmail.com \
--cc=linux-wireless@vger.kernel.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.