Skip to content

Commit 4021a6d

Browse files
committed
x86/irq: Cleanup posted MSI code
Make code and comments readable and use __this_cpu..() as this is guaranteed to be invoked with interrupts disabled. Signed-off-by: Thomas Gleixner <tglx@linutronix.de> Link: https://patch.msgid.link/20251125214631.108458942@linutronix.de
1 parent 0edc78b commit 4021a6d

File tree

1 file changed

+13
-18
lines changed

1 file changed

+13
-18
lines changed

arch/x86/kernel/irq.c

Lines changed: 13 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -401,11 +401,9 @@ static DEFINE_PER_CPU_CACHE_HOT(bool, posted_msi_handler_active);
401401

402402
void intel_posted_msi_init(void)
403403
{
404-
u32 destination;
405-
u32 apic_id;
404+
u32 destination, apic_id;
406405

407406
this_cpu_write(posted_msi_pi_desc.nv, POSTED_MSI_NOTIFICATION_VECTOR);
408-
409407
/*
410408
* APIC destination ID is stored in bit 8:15 while in XAPIC mode.
411409
* VT-d spec. CH 9.11
@@ -449,8 +447,8 @@ static __always_inline bool handle_pending_pir(unsigned long *pir, struct pt_reg
449447
}
450448

451449
/*
452-
* Performance data shows that 3 is good enough to harvest 90+% of the benefit
453-
* on high IRQ rate workload.
450+
* Performance data shows that 3 is good enough to harvest 90+% of the
451+
* benefit on high interrupt rate workloads.
454452
*/
455453
#define MAX_POSTED_MSI_COALESCING_LOOP 3
456454

@@ -460,37 +458,34 @@ static __always_inline bool handle_pending_pir(unsigned long *pir, struct pt_reg
460458
*/
461459
DEFINE_IDTENTRY_SYSVEC(sysvec_posted_msi_notification)
462460
{
461+
struct pi_desc *pid = this_cpu_ptr(&posted_msi_pi_desc);
463462
struct pt_regs *old_regs = set_irq_regs(regs);
464-
struct pi_desc *pid;
465-
int i = 0;
466-
467-
pid = this_cpu_ptr(&posted_msi_pi_desc);
468463

469464
/* Mark the handler active for intel_ack_posted_msi_irq() */
470465
__this_cpu_write(posted_msi_handler_active, true);
471466
inc_irq_stat(posted_msi_notification_count);
472467
irq_enter();
473468

474469
/*
475-
* Max coalescing count includes the extra round of handle_pending_pir
476-
* after clearing the outstanding notification bit. Hence, at most
477-
* MAX_POSTED_MSI_COALESCING_LOOP - 1 loops are executed here.
470+
* Loop only MAX_POSTED_MSI_COALESCING_LOOP - 1 times here to take
471+
* the final handle_pending_pir() invocation after clearing the
472+
* outstanding notification bit into account.
478473
*/
479-
while (++i < MAX_POSTED_MSI_COALESCING_LOOP) {
474+
for (int i = 1; i < MAX_POSTED_MSI_COALESCING_LOOP; i++) {
480475
if (!handle_pending_pir(pid->pir, regs))
481476
break;
482477
}
483478

484479
/*
485-
* Clear outstanding notification bit to allow new IRQ notifications,
486-
* do this last to maximize the window of interrupt coalescing.
480+
* Clear the outstanding notification bit to rearm the notification
481+
* mechanism.
487482
*/
488483
pi_clear_on(pid);
489484

490485
/*
491-
* There could be a race of PI notification and the clearing of ON bit,
492-
* process PIR bits one last time such that handling the new interrupts
493-
* are not delayed until the next IRQ.
486+
* Clearing the ON bit can race with a notification. Process the
487+
* PIR bits one last time so that handling the new interrupts is
488+
* not delayed until the next notification happens.
494489
*/
495490
handle_pending_pir(pid->pir, regs);
496491

0 commit comments

Comments
 (0)