Interrupts which are not marked per CPU increment not only the per CPU statistics, but also the accumulation counter irq_desc::tot_count. Change the counter to type unsigned long so it does not produce sporadic zeros due to wrap arounds on 64-bit machines and do a quick check for non per CPU interrupts. If the counter is zero, then simply emit a full set of zero strings. That spares the evaluation of the per CPU counters completely for interrupts with zero events.
Showing the changes to kernel (1 of 2 files). Show all
Unified · Split
| @@ -523,7 +523,16 @@ int show_interrupts(struct seq_file *p, void *v) · 522 unmodified lines | |||
| 523 | return 0; | 523 | return 0; |
| 524 | 524 | ||
| 525 | seq_printf(p, "%*d:", prec, i); | 525 | seq_printf(p, "%*d:", prec, i); |
| 526 | irq_proc_emit_counts(p, &desc->kstat_irqs->cnt); | 526 | |
| 527 | /* | ||
| 528 | * Always output per CPU interrupts. Output device interrupts only when | ||
| 529 | * desc::tot_count is not zero. | ||
| 530 | */ | ||
| 531 | if (irq_settings_is_per_cpu(desc) || irq_settings_is_per_cpu_devid(desc) || | ||
| 532 | data_race(desc->tot_count)) | ||
| 533 | irq_proc_emit_counts(p, &desc->kstat_irqs->cnt); | ||
| 534 | else | ||
| 535 | irq_proc_emit_zero_counts(p, num_online_cpus()); | ||
| 527 | seq_putc(p, ' '); | 536 | seq_putc(p, ' '); |
| 528 | 537 | ||
| 529 | guard(raw_spinlock_irq)(&desc->lock); | 538 | guard(raw_spinlock_irq)(&desc->lock); |