[PATCH v8 4/4] arm64: switch to irq_stack during softirq
Catalin Marinas
catalin.marinas at arm.com
Fri Dec 4 10:40:39 PST 2015
On Fri, Dec 04, 2015 at 02:39:44PM +0000, James Morse wrote:
> On 04/12/15 14:01, Catalin Marinas wrote:
> > On Fri, Dec 04, 2015 at 11:02:28AM +0000, James Morse wrote:
> >> +ENTRY(__do_softirq_on_irqstack)
> >> + push x19, lr
> >> + push x25, x26
> >> +
> >> + irq_stack_entry lr
> >> +
> >> + /* irq_stack_entry leaves irq_count in x25 */
> >> + ldr x1, [x25]
> >> + add x1, x1, #1
> >> + str x1, [x25]
> >> +
> >> + bl __do_softirq
> >> +
> >> + ldr x1, [x25]
> >> + sub x1, x1, #1
> >> + str x1, [x25]
> >> +
> >> + irq_stack_exit
> >> +
> >> + pop x25, x26
> >> + pop x19, lr
> >> + ret
> >> +ENDPROC(__do_softirq_on_irqstack)
> >
> > I was thinking of doing do_softirq_own_stack() entirely in assembly
> > without the need to check for on_irq_stack() check in C, just a test of
> > the irq_count value.
>
> I tried that, but couldn't get it to work - maybe I'm missing a trick:
>
> There are at least two ways into do_softirq_own_stack():
> el1_irq() -> __irq_exit() -> do_softirq_own_stack(),
> as well as:
> cpu_switch_to(ksoftirqd) -> do_softirq_own_stack()
If it was only these two cases, I think it would have been easier as in
both scenarios the stack is nearly empty. But there is another call to
do_softirq() from netif_rx_ni() and I'm not sure how the stack looks
like at this point. That's why I suggested that we always switch to a
different stack for softirqs.
> In both cases irq_count == 0 because do_softirq_own_stack() is where we
> update irq_count [0]. I can only see two ways to tell them apart,
> increment irq_count in el1_irq(), (which we don't like), or have that
> bounds checking.
I now see the problem. Looking at x86, they increment irq_count for
every interrupt (as per Jungseok's early patch).
> (We could increase hardirq_count() in el?_irq(), which would mean
> in_irq()/in_interrupt() always returns true when on the irq_stack, which
> would stop softirqs being processed here... but that is a fairly
> significant change in behaviour.)
So I think the options are (a) irq_count increment in el?_irq or (b)
check the current stack before switching. I'll think about it until
Monday ;).
BTW, at which point does in_irq() return true for an interrupt (and when
it ceases to do so)?
--
Catalin
More information about the linux-arm-kernel
mailing list