]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
rcu/cpu_stall_cputime: fix the hardirq count for x86 architecture
authorYongliang Gao <leonylgao@tencent.com>
Sun, 16 Feb 2025 08:41:09 +0000 (16:41 +0800)
committerJoel Fernandes <joelagnelf@nvidia.com>
Fri, 16 May 2025 13:00:54 +0000 (09:00 -0400)
When counting the number of hardirqs in the x86 architecture,
it is essential to add arch_irq_stat_cpu to ensure accuracy.

For example, a CPU loop within the rcu_read_lock function.

Before:
[   70.910184] rcu: INFO: rcu_preempt self-detected stall on CPU
[   70.910436] rcu:     3-....: (4999 ticks this GP) idle=***
[   70.910711] rcu:              hardirqs   softirqs   csw/system
[   70.910870] rcu:      number:        0        657            0
[   70.911024] rcu:     cputime:        0          0         2498   ==> 2498(ms)
[   70.911278] rcu:     (t=5001 jiffies g=3677 q=29 ncpus=8)

After:
[   68.046132] rcu: INFO: rcu_preempt self-detected stall on CPU
[   68.046354] rcu:     2-....: (4999 ticks this GP) idle=***
[   68.046628] rcu:              hardirqs   softirqs   csw/system
[   68.046793] rcu:      number:     2498        663            0
[   68.046951] rcu:     cputime:        0          0         2496   ==> 2496(ms)
[   68.047244] rcu:     (t=5000 jiffies g=3825 q=4 ncpus=8)

Fixes: be42f00b73a0 ("rcu: Add RCU stall diagnosis information")
Reported-by: kernel test robot <lkp@intel.com>
Closes: https://lore.kernel.org/oe-kbuild-all/202501090842.SfI6QPGS-lkp@intel.com/
Signed-off-by: Yongliang Gao <leonylgao@tencent.com>
Reviewed-by: Neeraj Upadhyay <Neeraj.Upadhyay@amd.com>
Link: https://lore.kernel.org/r/20250216084109.3109837-1-leonylgao@gmail.com
Signed-off-by: Boqun Feng <boqun.feng@gmail.com>
Signed-off-by: Joel Fernandes <joelagnelf@nvidia.com>
kernel/rcu/tree.c
kernel/rcu/tree.h
kernel/rcu/tree_stall.h

index 1b8eee06183c93a0021bce2019f6499b81d06c8a..0b0dd9e1f0574af0241dc5e0edc494cc6f0ac8bc 100644 (file)
@@ -801,6 +801,10 @@ static int rcu_watching_snap_save(struct rcu_data *rdp)
        return 0;
 }
 
+#ifndef arch_irq_stat_cpu
+#define arch_irq_stat_cpu(cpu) 0
+#endif
+
 /*
  * Returns positive if the specified CPU has passed through a quiescent state
  * by virtue of being in or having passed through an dynticks idle state since
@@ -936,9 +940,9 @@ static int rcu_watching_snap_recheck(struct rcu_data *rdp)
                        rsrp->cputime_irq     = kcpustat_field(kcsp, CPUTIME_IRQ, cpu);
                        rsrp->cputime_softirq = kcpustat_field(kcsp, CPUTIME_SOFTIRQ, cpu);
                        rsrp->cputime_system  = kcpustat_field(kcsp, CPUTIME_SYSTEM, cpu);
-                       rsrp->nr_hardirqs = kstat_cpu_irqs_sum(rdp->cpu);
-                       rsrp->nr_softirqs = kstat_cpu_softirqs_sum(rdp->cpu);
-                       rsrp->nr_csw = nr_context_switches_cpu(rdp->cpu);
+                       rsrp->nr_hardirqs = kstat_cpu_irqs_sum(cpu) + arch_irq_stat_cpu(cpu);
+                       rsrp->nr_softirqs = kstat_cpu_softirqs_sum(cpu);
+                       rsrp->nr_csw = nr_context_switches_cpu(cpu);
                        rsrp->jiffies = jiffies;
                        rsrp->gp_seq = rdp->gp_seq;
                }
index a9a811d9d7a372abc80dc64e7cf3808e1e8f14fd..1bba2225e7448be347e654a9e77b8ababf1f5820 100644 (file)
@@ -168,7 +168,7 @@ struct rcu_snap_record {
        u64             cputime_irq;    /* Accumulated cputime of hard irqs */
        u64             cputime_softirq;/* Accumulated cputime of soft irqs */
        u64             cputime_system; /* Accumulated cputime of kernel tasks */
-       unsigned long   nr_hardirqs;    /* Accumulated number of hard irqs */
+       u64             nr_hardirqs;    /* Accumulated number of hard irqs */
        unsigned int    nr_softirqs;    /* Accumulated number of soft irqs */
        unsigned long long nr_csw;      /* Accumulated number of task switches */
        unsigned long   jiffies;        /* Track jiffies value */
index 925fcdad5dea22cfc8b0648546b78870cee485a6..56b21219442b65d4e37765ef802353c0fc6f9bfc 100644 (file)
@@ -435,8 +435,8 @@ static void print_cpu_stat_info(int cpu)
        rsr.cputime_system  = kcpustat_field(kcsp, CPUTIME_SYSTEM, cpu);
 
        pr_err("\t         hardirqs   softirqs   csw/system\n");
-       pr_err("\t number: %8ld %10d %12lld\n",
-               kstat_cpu_irqs_sum(cpu) - rsrp->nr_hardirqs,
+       pr_err("\t number: %8lld %10d %12lld\n",
+               kstat_cpu_irqs_sum(cpu) + arch_irq_stat_cpu(cpu) - rsrp->nr_hardirqs,
                kstat_cpu_softirqs_sum(cpu) - rsrp->nr_softirqs,
                nr_context_switches_cpu(cpu) - rsrp->nr_csw);
        pr_err("\tcputime: %8lld %10lld %12lld   ==> %d(ms)\n",