Re: [PATCH RFC 09/13] x86/irq: Install posted MSI notification handler

From: Thomas Gleixner
Date: Wed Dec 06 2023 - 14:50:31 EST


On Wed, Nov 15 2023 at 13:56, Peter Zijlstra wrote:
>
> Would it not make more sense to write things something like:
>
> bool handle_pending_pir()
> {
> bool handled = false;
> u64 pir_copy[4];
>
> for (i = 0; i < 4; i++) {
> if (!pid-pir_l[i]) {
> pir_copy[i] = 0;
> continue;
> }
>
> pir_copy[i] = arch_xchg(&pir->pir_l[i], 0);
> handled |= true;
> }
>
> if (!handled)
> return handled;
>
> for_each_set_bit()
> ....
>
> return handled.
> }

I don't understand what the whole copy business is about. It's
absolutely not required.

static bool handle_pending_pir(unsigned long *pir)
{
unsigned int idx, vec;
bool handled = false;
unsigned long pend;

for (idx = 0; offs < 4; idx++) {
if (!pir[idx])
continue;
pend = arch_xchg(pir + idx, 0);
for_each_set_bit(vec, &pend, 64)
call_irq_handler(vec + idx * 64, NULL);
handled = true;
}
return handled;
}

No?

> sysvec_posted_blah_blah()
> {
> bool done = false;
> bool handled;
>
> for (;;) {
> handled = handle_pending_pir();
> if (done)
> break;
> if (!handled || ++loops > MAX_LOOPS) {

That does one loop too many. Should be ++loops == MAX_LOOPS. No?

> pi_clear_on(pid);
> /* once more after clear_on */
> done = true;
> }
> }
> }
>
>
> Hmm?

I think that can be done less convoluted.

{
struct pi_desc *pid = this_cpu_ptr(&posted_interrupt_desc);
struct pt_regs *old_regs = set_irq_regs(regs);
int loops;

for (loops = 0;;) {
bool handled = handle_pending_pir((unsigned long)pid->pir);

if (++loops > MAX_LOOPS)
break;

if (!handled || loops == MAX_LOOPS) {
pi_clear_on(pid);
/* Break the loop after handle_pending_pir()! */
loops = MAX_LOOPS;
}
}

...
set_irq_regs(old_regs);
}

Hmm? :)