Re: [tip: irq/core] x86: Select HARDIRQS_SW_RESEND on x86

From: Hans de Goede
Date: Thu Mar 12 2020 - 09:49:46 EST


Hi,

On 3/12/20 2:31 PM, Linus Walleij wrote:
On Wed, Mar 11, 2020 at 10:42 PM tip-bot2 for Hans de Goede
<tip-bot2@xxxxxxxxxxxxx> wrote:

select GENERIC_GETTIMEOFDAY
select GENERIC_VDSO_TIME_NS
select GUP_GET_PTE_LOW_HIGH if X86_PAE
+ select HARDIRQS_SW_RESEND

Just help me understand the semantics of this thing...

According to the text in KConfig:

# Tasklet based software resend for pending interrupts on enable_irq()
config HARDIRQS_SW_RESEND
bool

According to
commit a4633adcdbc15ac51afcd0e1395de58cee27cf92

[PATCH] genirq: add genirq sw IRQ-retrigger

Enable platforms that do not have a hardware-assisted
hardirq-resend mechanism
to resend them via a softirq-driven IRQ emulation mechanism.

so when enable_irq() is called, if the IRQ is already asserted,
it will be distributed in the form of a software irq?

OK I give up I don't understand the semantics of this thing.

Maybe it's because I think of a register where the IRQ line
is just a level IRQ bit thing that stays high as long as the IRQ
is not handled.

So I suppose it is for any type of transient IRQ such as
edge triggered that happened before the system came back
online entirely and now the only remnant of it is a bit in
the irchip status register?

The way I understand it is like this:

1. We have an edge triggered IRQ from a peripheral to a
GPIO controller

2. We have a level triggered IRQ from the GPIO controller to the
"root" IRQ controller.

3. With modern x86 suspend, we do not really put the entire
system in a firmware-controller suspend state, instead the CPU is
halted until any IRQ happens; and there is a power-management
micro-controller which shuts various things down while the CPU
is halted leading to similar power consumption as old S3 suspend.

The combination of these 3 means that we must ack the edge
triggered IRQ at the GPIO controller level even while suspended
(we briefly wake up for this) to make the level-triggered IRQ
coming from the GPIO controller low so that we can go back to sleep.

When this happens we record in the kernel IRQ tracking data for
the edge-triggered IRQ tied to the GPIO (there are no "remnants"
of it in any chuip registers), that the IRQ needs to be replayed
on resume. Some IRQ controllers allow writing a register to
retrigger the IRQ without the level on the external GPIO actually
changing.

Some IRQ controllers do not allow this, in this case we need to
emulate this retriggering in software, this is what the
HARDIRQS_SW_RESEND option is for, this handles this in a generic
way, so that we do not have to add emulation to every IRQ-chip
driver where the hardware lacks a "retrigger" register.

I see that ARM and ARM64 simply just select this. What
happens if you do that and why is x86 not selecting it in general?

Erm, "selecting it in general" (well at least on x86) is what
this patch is doing. But I guess you mean why is this not
selected on all architectures? If I've understood tglx correctly
the HARDIRQS_SW_RESEND option is incompatible with some irq-chip
drivers. I think it was incompatible with using nested threaded
handlers are some such...

tglx can probably explain this way better then I can :)

Regards,

Hans