genirq: Convert kstat_irqs to a struct
authorBitao Hu <yaoma@linux.alibaba.com>
Thu, 11 Apr 2024 07:41:30 +0000 (15:41 +0800)
committerThomas Gleixner <tglx@linutronix.de>
Fri, 12 Apr 2024 15:08:05 +0000 (17:08 +0200)
The irq_desc::kstat_irqs member is a per-CPU variable of type int, which is
only capable of counting. A snapshot mechanism for interrupt statistics
will be added soon, which requires an additional variable to store the
snapshot.

To facilitate expansion, convert kstat_irqs here to a struct containing
only the count.

Originally-by: Thomas Gleixner <tglx@linutronix.de>
Signed-off-by: Bitao Hu <yaoma@linux.alibaba.com>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Link: https://lore.kernel.org/r/20240411074134.30922-2-yaoma@linux.alibaba.com
arch/mips/dec/setup.c
arch/parisc/kernel/smp.c
arch/powerpc/kvm/book3s_hv_rm_xics.c
include/linux/irqdesc.h
kernel/irq/internals.h
kernel/irq/irqdesc.c
kernel/irq/proc.c
scripts/gdb/linux/interrupts.py

index 6c3704f51d0de40fee5f851dcc76420bec39123b..87f0a1436bf9cc78bed11a708d49c20741ad51ea 100644 (file)
@@ -756,7 +756,7 @@ void __init arch_init_irq(void)
                                NULL))
                        pr_err("Failed to register fpu interrupt\n");
                desc_fpu = irq_to_desc(irq_fpu);
-               fpu_kstat_irq = this_cpu_ptr(desc_fpu->kstat_irqs);
+               fpu_kstat_irq = this_cpu_ptr(&desc_fpu->kstat_irqs->cnt);
        }
        if (dec_interrupt[DEC_IRQ_CASCADE] >= 0) {
                if (request_irq(dec_interrupt[DEC_IRQ_CASCADE], no_action,
index 444154271f237040efc50360f98e6e86b8e3b0ef..800eb64e91ad0a313de74516f86e06ed638b06c9 100644 (file)
@@ -344,7 +344,7 @@ static int smp_boot_one_cpu(int cpuid, struct task_struct *idle)
                struct irq_desc *desc = irq_to_desc(i);
 
                if (desc && desc->kstat_irqs)
-                       *per_cpu_ptr(desc->kstat_irqs, cpuid) = 0;
+                       *per_cpu_ptr(desc->kstat_irqs, cpuid) = (struct irqstat) { };
        }
 #endif
 
index e429848785033c87eb0c3426d8900dae586a3957..f2636414d82a07fc63df152ea8e861eb43f7c94c 100644 (file)
@@ -837,7 +837,7 @@ static inline void this_cpu_inc_rm(unsigned int __percpu *addr)
  */
 static void kvmppc_rm_handle_irq_desc(struct irq_desc *desc)
 {
-       this_cpu_inc_rm(desc->kstat_irqs);
+       this_cpu_inc_rm(&desc->kstat_irqs->cnt);
        __this_cpu_inc(kstat.irqs_sum);
 }
 
index d9451d456a7333fe3b1af852bc3590bb179ce6dd..c28612674acbc32e607756588ed250a51646064f 100644 (file)
@@ -17,6 +17,14 @@ struct irq_desc;
 struct irq_domain;
 struct pt_regs;
 
+/**
+ * struct irqstat - interrupt statistics
+ * @cnt:       real-time interrupt count
+ */
+struct irqstat {
+       unsigned int    cnt;
+};
+
 /**
  * struct irq_desc - interrupt descriptor
  * @irq_common_data:   per irq and chip data passed down to chip functions
@@ -55,7 +63,7 @@ struct pt_regs;
 struct irq_desc {
        struct irq_common_data  irq_common_data;
        struct irq_data         irq_data;
-       unsigned int __percpu   *kstat_irqs;
+       struct irqstat __percpu *kstat_irqs;
        irq_flow_handler_t      handle_irq;
        struct irqaction        *action;        /* IRQ action list */
        unsigned int            status_use_accessors;
@@ -119,7 +127,7 @@ extern struct irq_desc irq_desc[NR_IRQS];
 static inline unsigned int irq_desc_kstat_cpu(struct irq_desc *desc,
                                              unsigned int cpu)
 {
-       return desc->kstat_irqs ? *per_cpu_ptr(desc->kstat_irqs, cpu) : 0;
+       return desc->kstat_irqs ? per_cpu(desc->kstat_irqs->cnt, cpu) : 0;
 }
 
 static inline struct irq_desc *irq_data_to_desc(struct irq_data *data)
index bcc7f21db9eeb34986957aad5b6a018854b71545..1d92532c2aaecefb80c59d6f8cdc33f990ff31a0 100644 (file)
@@ -258,7 +258,7 @@ static inline void irq_state_set_masked(struct irq_desc *desc)
 
 static inline void __kstat_incr_irqs_this_cpu(struct irq_desc *desc)
 {
-       __this_cpu_inc(*desc->kstat_irqs);
+       __this_cpu_inc(desc->kstat_irqs->cnt);
        __this_cpu_inc(kstat.irqs_sum);
 }
 
index 4c6b32318ce350a5fb831093424f7437f9f54cea..b59b79200ad7451014a2be1f672c7b02f9c60daf 100644 (file)
@@ -134,7 +134,7 @@ static void desc_set_defaults(unsigned int irq, struct irq_desc *desc, int node,
        desc->name = NULL;
        desc->owner = owner;
        for_each_possible_cpu(cpu)
-               *per_cpu_ptr(desc->kstat_irqs, cpu) = 0;
+               *per_cpu_ptr(desc->kstat_irqs, cpu) = (struct irqstat) { };
        desc_smp_init(desc, node, affinity);
 }
 
@@ -186,7 +186,7 @@ static int init_desc(struct irq_desc *desc, int irq, int node,
                     const struct cpumask *affinity,
                     struct module *owner)
 {
-       desc->kstat_irqs = alloc_percpu(unsigned int);
+       desc->kstat_irqs = alloc_percpu(struct irqstat);
        if (!desc->kstat_irqs)
                return -ENOMEM;
 
@@ -968,8 +968,7 @@ unsigned int kstat_irqs_cpu(unsigned int irq, int cpu)
 {
        struct irq_desc *desc = irq_to_desc(irq);
 
-       return desc && desc->kstat_irqs ?
-                       *per_cpu_ptr(desc->kstat_irqs, cpu) : 0;
+       return desc && desc->kstat_irqs ? per_cpu(desc->kstat_irqs->cnt, cpu) : 0;
 }
 
 static bool irq_is_nmi(struct irq_desc *desc)
@@ -991,7 +990,7 @@ static unsigned int kstat_irqs(unsigned int irq)
                return data_race(desc->tot_count);
 
        for_each_possible_cpu(cpu)
-               sum += data_race(*per_cpu_ptr(desc->kstat_irqs, cpu));
+               sum += data_race(per_cpu(desc->kstat_irqs->cnt, cpu));
        return sum;
 }
 
index 623b8136e9af3b86040102392e63c1ff4a5a04aa..6954e0a020475b863d9ba623dc515b674c42e3ce 100644 (file)
@@ -490,7 +490,7 @@ int show_interrupts(struct seq_file *p, void *v)
 
        if (desc->kstat_irqs) {
                for_each_online_cpu(j)
-                       any_count |= data_race(*per_cpu_ptr(desc->kstat_irqs, j));
+                       any_count |= data_race(per_cpu(desc->kstat_irqs->cnt, j));
        }
 
        if ((!desc->action || irq_desc_is_chained(desc)) && !any_count)
@@ -498,8 +498,7 @@ int show_interrupts(struct seq_file *p, void *v)
 
        seq_printf(p, "%*d: ", prec, i);
        for_each_online_cpu(j)
-               seq_printf(p, "%10u ", desc->kstat_irqs ?
-                                       *per_cpu_ptr(desc->kstat_irqs, j) : 0);
+               seq_printf(p, "%10u ", desc->kstat_irqs ? per_cpu(desc->kstat_irqs->cnt, j) : 0);
 
        raw_spin_lock_irqsave(&desc->lock, flags);
        if (desc->irq_data.chip) {
index 66ae5c7690cf1750eb0bbaf3a0942fafa3fe9868..616a5f26377a8cb63e4a81f44db4f490274f13f0 100644 (file)
@@ -37,7 +37,7 @@ def show_irq_desc(prec, irq):
     any_count = 0
     if desc['kstat_irqs']:
         for cpu in cpus.each_online_cpu():
-            any_count += cpus.per_cpu(desc['kstat_irqs'], cpu)
+            any_count += cpus.per_cpu(desc['kstat_irqs'], cpu)['cnt']
 
     if (desc['action'] == 0 or irq_desc_is_chained(desc)) and any_count == 0:
         return text;
@@ -45,7 +45,7 @@ def show_irq_desc(prec, irq):
     text += "%*d: " % (prec, irq)
     for cpu in cpus.each_online_cpu():
         if desc['kstat_irqs']:
-            count = cpus.per_cpu(desc['kstat_irqs'], cpu)
+            count = cpus.per_cpu(desc['kstat_irqs'], cpu)['cnt']
         else:
             count = 0
         text += "%10u" % (count)
@@ -177,7 +177,7 @@ def arm_common_show_interrupts(prec):
         if desc == 0:
             continue
         for cpu in cpus.each_online_cpu():
-            text += "%10u" % (cpus.per_cpu(desc['kstat_irqs'], cpu))
+            text += "%10u" % (cpus.per_cpu(desc['kstat_irqs'], cpu)['cnt'])
         text += "      %s" % (ipi_types[ipi].string())
         text += "\n"
     return text