隐式类型转化导致Panic

Posted by Fei Wu on March 15, 2024

问题

在分析sophgo sg2042性能时执行以下命令导致系统panic

1
perf record -e branches

原因

1
2
3
4
5
6
        unsigned long overflow;
        unsigned long overflowed_ctrs = 0;

        if (!(overflow & (1 << hidx)))
        ...
        overflowed_ctrs |= 1 << lidx;

解决方法

1
2
3
4
5
6
7
8
9
commit 34b567868777e9fd39ec5333969728a7f0cf179c
Author: Fei Wu <fei2.wu@intel.com>
Date:   Wed Feb 28 19:54:25 2024 +0800

    perf: RISCV: Fix panic on pmu overflow handler
    
    (1 << idx) of int is not desired when setting bits in unsigned long
    overflowed_ctrs, use BIT() instead. This panic happens when running
    'perf record -e branches' on sophgo sg2042.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
@@ -731,14 +731,14 @@ static irqreturn_t pmu_sbi_ovf_handler(int irq, void *dev)
                /* compute hardware counter index */
                hidx = info->csr - CSR_CYCLE;
                /* check if the corresponding bit is set in sscountovf */
-               if (!(overflow & (1 << hidx)))
+               if (!(overflow & BIT(hidx)))
                        continue;
 
                /*
                 * Keep a track of overflowed counters so that they can be started
                 * with updated initial value.
                 */
-               overflowed_ctrs |= 1 << lidx;
+               overflowed_ctrs |= BIT(lidx);
                hw_evt = &event->hw;
                riscv_pmu_event_update(event);
                perf_sample_data_init(&data, 0, hw_evt->last_period);

内核代码里面应该还有一些类似问题,需要系统修复一下。