[Top] [All Lists]

Re: [PATCH] MIPS: Enable interrupts in arch_cpu_idle()

To: Thomas Gleixner <>
Subject: Re: [PATCH] MIPS: Enable interrupts in arch_cpu_idle()
From: Ralf Baechle <>
Date: Thu, 2 May 2013 16:58:09 +0200
Cc: Linus Torvalds <>, Jonas Gorski <>,, "" <>, "" <>
In-reply-to: <alpine.LFD.2.02.1305021527010.3972@ionos>
List-archive: <>
List-help: <>
List-id: linux-mips <>
List-owner: <>
List-post: <>
List-software: Ecartis version 1.0.0
List-subscribe: <>
List-unsubscribe: <>
Original-recipient: rfc822;
References: <20522420.158691367384219315.JavaMail.weblogic@epml17> <> <alpine.LFD.2.02.1305021241040.3972@ionos> <> <alpine.LFD.2.02.1305021527010.3972@ionos>
User-agent: Mutt/1.5.21 (2010-09-15)
On Thu, May 02, 2013 at 04:33:52PM +0200, Thomas Gleixner wrote:

> commit cdbedc61c8 (mips: Use generic idle loop) broke MIPS as I did
> not realize that MIPS wants to invoke the wait instructions with
> interrupts enabled. Don't ask why that works correctly; Ralf suggested
> to get thoroughly drunk before even thinking about it. Looking sober
> at commit c65a5480 ([MIPS] Fix potential latency problem due to
> non-atomic cpu_wait) is not recommended.
> Enable interrupts in arch_cpu_idle() on mips to repair the issue.
> Reported-and-tested-by: Jonas Gorski <>
> Reported-by: EunBong Song <>
> Booze-recommended-by: Ralf Baechle <>
> Signed-off-by: Thomas Gleixner <>

A very sobering commit message ;-)

The underlying issue is that the WAIT instruction on MIPS is architecturally
defined as "[...] It is implementation-dependent whether the pipeline
restarts when a non-enabled interrupt is requested.  [...]"

arch_local_irq_disable() disables interrupts by clearing the IE bit in
the CPU status register, thus disabling all interrupts.  If no a WAIT
instruction is executed it's legal for a CPU to stop the pipeline for
good.  Which obviously is pretty stupidtastik behaviour.

For a while we just used to live with the race condition resulting from
not disabling interrupts in the idle loop.  Then c65a5480 fixed this by
checking if we're returning to the WAIT instruction in the idle loop
when returning from an interrupt and iff so, rolling back the
program counter to point to the if (test_thread_flag(TIF_NEED_RESCHED))
test at the beginning of rollback_r4k_wait.

Linux knows which CPUs have the problematic behaviour and uses this special
variant of the idle loop only where needed.


<Prev in Thread] Current Thread [Next in Thread>