--- zzzz-none-000/linux-4.4.271/kernel/irq/irqdesc.c 2021-06-03 06:22:09.000000000 +0000 +++ hawkeye-5590-750/linux-4.4.271/kernel/irq/irqdesc.c 2023-04-19 10:22:30.000000000 +0000 @@ -15,14 +15,62 @@ #include #include #include +#include +#ifdef CONFIG_STOPWATCH_HARD_IRQ +#define __STOPWATCH_USE__ +#endif +#include #include "internals.h" +DEFINE_STOPWATCH_ARRAY(hardirq, NR_IRQS + 2); + /* * lockdep: we want to handle all irq_desc locks as a single lock-class: */ static struct lock_class_key irq_desc_lock_class; +#ifdef __STOPWATCH_USE__ +int stopwatch_hardirq_show(struct seq_file *f, void *v) +{ + struct irqaction *ap; + int irq = *((loff_t *) v); + struct irq_desc *desc = irq_to_desc(irq); + int cpu; + + if (irq == 0) + seq_printf(f, "%20s\tCPU\tmin(us)\tavg(us)\tmax(us)\n\n", ""); + + if (irq == (NR_IRQS + 1)) + seq_printf(f, "%-20s", "softirq"); + else { + ap = desc->action; + if (!ap || (desc->handle_irq == handle_bad_irq)) + return 0; + else + seq_printf(f, "%3d:%-17s", irq, ap->name); + } + + for_each_cpu(cpu, cpu_online_mask) { + if (!cpu) + seq_printf(f, "\t%d", cpu); + else + seq_printf(f, "%20s\t%d", "", cpu); + stopwatch_show(&STOPWATCH_INSTANCE_CPU(hardirq[irq], cpu), f, STOPWATCH_MICRO); + seq_printf(f, "\n"); + } + seq_printf(f, "\n"); + return 0; +} + +static int __init hardirq_stopwatch_init(void) +{ + INIT_STOPWATCH_ARRAY(hardirq, NR_IRQS + 2); + return stopwatch_register("hardirq", NR_IRQS + 2, stopwatch_hardirq_show); +} +module_init(hardirq_stopwatch_init) +#endif + #if defined(CONFIG_SMP) static void __init init_irq_default_affinity(void) { @@ -384,10 +432,24 @@ ack_bad_irq(irq); ret = -EINVAL; } else { +#ifndef __STOPWATCH_USE__ generic_handle_irq(irq); +#else + if (irq > NR_IRQS) { + STOPWATCH_START(hardirq[NR_IRQS]); + generic_handle_irq(irq); + STOPWATCH_STOP(hardirq[NR_IRQS]); + } else { + STOPWATCH_START(hardirq[irq]); + generic_handle_irq(irq); + STOPWATCH_STOP(hardirq[irq]); + } +#endif } + STOPWATCH_START(hardirq[NR_IRQS + 1]); irq_exit(); + STOPWATCH_STOP(hardirq[NR_IRQS + 1]); set_irq_regs(old_regs); return ret; }