[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <87cyvjun3z.ffs@tglx>
Date: Wed, 06 Dec 2023 20:50:24 +0100
From: Thomas Gleixner <tglx@...utronix.de>
To: Peter Zijlstra <peterz@...radead.org>,
Jacob Pan <jacob.jun.pan@...ux.intel.com>
Cc: LKML <linux-kernel@...r.kernel.org>, X86 Kernel <x86@...nel.org>,
iommu@...ts.linux.dev, Lu Baolu <baolu.lu@...ux.intel.com>,
kvm@...r.kernel.org, Dave Hansen <dave.hansen@...el.com>,
Joerg Roedel <joro@...tes.org>,
"H. Peter Anvin" <hpa@...or.com>, Borislav Petkov <bp@...en8.de>,
Ingo Molnar <mingo@...hat.com>,
Raj Ashok <ashok.raj@...el.com>,
"Tian, Kevin" <kevin.tian@...el.com>, maz@...nel.org,
seanjc@...gle.com, Robin Murphy <robin.murphy@....com>
Subject: Re: [PATCH RFC 09/13] x86/irq: Install posted MSI notification handler
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? :)
Powered by blists - more mailing lists