• Jisheng Zhang's avatar
    clockevents/drivers/dw_apb_timer: Add dynamic irq flag to the timer · 8b5f0010
    Jisheng Zhang authored
    Commit d2348fb6 ("tick: Dynamically set broadcast irq affinity")
    adds one excellent feature CLOCK_EVT_FEAT_DYNIRQ to let the core set the
    interrupt affinity of the broadcast interrupt to the cpu which has the
    earliest expiry time. This patch adds CLOCK_EVT_FEAT_DYNIRQ flag to
    avoid unnecessary wakeups and IPIs when the dw_apb_timer is used as
    broadcast timer.
    
    A simple test:
    ~ # rm /tmp/test.sh
    ~ # cat > /tmp/test.sh
    cat /proc/interrupts
    for i in `seq 10` ; do sleep $i; done
    cat /proc/interrupts
    ~ # chmod +x /tmp/test.sh
    ~ # taskset 0x2 /tmp/test.sh
    
    without the patch:
    
               CPU0       CPU1
     27:        115         36       GIC  27  arch_timer
     45:         62          0       GIC  45  mmc0
    160:         88          0  interrupt-controller   8  timer
    227:          0          0  interrupt-controller   4  f7e81400.i2c
    228:          0          0  interrupt-controller   5  f7e81800.i2c
    229:          0          0  interrupt-controller   7  dw_spi65535
    230:          0          0  interrupt-controller  21  f7e84000.i2c
    231:          0          0  interrupt-controller  20  f7e84800.i2c
    265:        445          0  interrupt-controller   8  serial
    IPI0:          0          0  CPU wakeup interrupts
    IPI1:          0         11  Timer broadcast interrupts
    IPI2:         56        104  Rescheduling interrupts
    IPI3:          0          0  Function call interrupts
    IPI4:          0          4  Single function call interrupts
    IPI5:          0          0  CPU stop interrupts
    IPI6:         25         27  IRQ work interrupts
    IPI7:          0          0  completion interrupts
    IPI8:          0          0  CPU backtrace
    Err:          0
               CPU0       CPU1
     27:        115         38       GIC  27  arch_timer
     45:         62          0       GIC  45  mmc0
    160:        160          0  interrupt-controller   8  timer
    227:          0          0  interrupt-controller   4  f7e81400.i2c
    228:          0          0  interrupt-controller   5  f7e81800.i2c
    229:          0          0  interrupt-controller   7  dw_spi65535
    230:          0          0  interrupt-controller  21  f7e84000.i2c
    231:          0          0  interrupt-controller  20  f7e84800.i2c
    265:        514          0  interrupt-controller   8  serial
    IPI0:          0          0  CPU wakeup interrupts
    IPI1:          0         83  Timer broadcast interrupts
    IPI2:         56        104  Rescheduling interrupts
    IPI3:          0          0  Function call interrupts
    IPI4:          0          4  Single function call interrupts
    IPI5:          0          0  CPU stop interrupts
    IPI6:         25         46  IRQ work interrupts
    IPI7:          0          0  completion interrupts
    IPI8:          0          0  CPU backtrace
    Err:          0
    
    cpu0 get 160-88=72 timer interrupts, CPU1 got 83-11=72 broadcast timer
    IPIs
    So, overall system got 72+72=144 wake ups and 72 broadcast timer IPIs
    
    With the patch:
               CPU0       CPU1
     27:        107         37       GIC  27  arch_timer
     45:         62          0       GIC  45  mmc0
    160:         66          7  interrupt-controller   8  timer
    227:          0          0  interrupt-controller   4  f7e81400.i2c
    228:          0          0  interrupt-controller   5  f7e81800.i2c
    229:          0          0  interrupt-controller   7  dw_spi65535
    230:          0          0  interrupt-controller  21  f7e84000.i2c
    231:          0          0  interrupt-controller  20  f7e84800.i2c
    265:        311          0  interrupt-controller   8  serial
    IPI0:          0          0  CPU wakeup interrupts
    IPI1:          2          4  Timer broadcast interrupts
    IPI2:         58        100  Rescheduling interrupts
    IPI3:          0          0  Function call interrupts
    IPI4:          0          4  Single function call interrupts
    IPI5:          0          0  CPU stop interrupts
    IPI6:         21         24  IRQ work interrupts
    IPI7:          0          0  completion interrupts
    IPI8:          0          0  CPU backtrace
    Err:          0
               CPU0       CPU1
     27:        107         39       GIC  27  arch_timer
     45:         62          0       GIC  45  mmc0
    160:         69         75  interrupt-controller   8  timer
    227:          0          0  interrupt-controller   4  f7e81400.i2c
    228:          0          0  interrupt-controller   5  f7e81800.i2c
    229:          0          0  interrupt-controller   7  dw_spi65535
    230:          0          0  interrupt-controller  21  f7e84000.i2c
    231:          0          0  interrupt-controller  20  f7e84800.i2c
    265:        380          0  interrupt-controller   8  serial
    IPI0:          0          0  CPU wakeup interrupts
    IPI1:          3          6  Timer broadcast interrupts
    IPI2:         60        100  Rescheduling interrupts
    IPI3:          0          0  Function call interrupts
    IPI4:          0          4  Single function call interrupts
    IPI5:          0          0  CPU stop interrupts
    IPI6:         21         45  IRQ work interrupts
    IPI7:          0          0  completion interrupts
    IPI8:          0          0  CPU backtrace
    Err:          0
    
    cpu0 got 69-66=3, cpu1 got 75-7=68 timer interrupts. cpu0 got 3-2=1
    broadcast timer IPIs, cpu1 got 6-4=2 broadcast timer IPIs.
    So, overall system got 3+68+1+2=74 wakeups and 1+2=3 broadcast timer
    IPIs
    
    This patch removes 50% wakeups and almost 100% broadcast timer IPIs!
    Signed-off-by: default avatarJisheng Zhang <jszhang@marvell.com>
    Signed-off-by: default avatarDaniel Lezcano <daniel.lezcano@linaro.org>
    8b5f0010
dw_apb_timer.c 11.6 KB