From: Bixuan Cui cuibixuan@huawei.com
ascend inclusion category: bugfix bugzilla: NA CVE: NA
---------------------------------------------
There is an anomalous statistics in itrace irqsoff: max_time:3945(us) caller:__do_softirq+0x8c/0x310 max_time:7996(us) caller:__do_softirq+0x8c/0x310
Use function tracer to trace: stress-ng-cpu-3723 [011] d... 2817.510377: rcu_nmi_exit <-rcu_irq_exit stress-ng-cpu-3723 [011] d... 2817.510377: rcu_dynticks_curr_cpu_in_eqs <-rcu_nmi_exit stress-ng-cpu-3723 [011] d... 2817.514356: gic_handle_irq <-el0_irq_naked stress-ng-cpu-3723 [011] d... 2817.514356: __handle_domain_irq <-gic_handle_irq ...
The per-cpu interrupt is enabled after irq_handler in el0_irq_naked() is executed. However, the itrace does not add the irqsoff monitoring to el0_irq_naked. And the same omission appears in the following files: arch/arm64/include/asm/daifflags.h arch/arm64/kernel/entry.S arch/arm64/kernel/syscall.c arch/arm64/mm/fault.c
Add missing itrace_hardirqs_ignore() calls into it.
Signed-off-by: Bixuan Cui cuibixuan@huawei.com Reviewed-by: Ding Tianhong dingtianhong@huawei.com Signed-off-by: Yang Yingliang yangyingliang@huawei.com --- arch/arm64/include/asm/daifflags.h | 3 +++ arch/arm64/kernel/entry.S | 9 +++++++++ arch/arm64/kernel/syscall.c | 3 +++ arch/arm64/mm/fault.c | 6 +++++- 4 files changed, 20 insertions(+), 1 deletion(-)
diff --git a/arch/arm64/include/asm/daifflags.h b/arch/arm64/include/asm/daifflags.h index 1230923b032dd..1d832814eae8f 100644 --- a/arch/arm64/include/asm/daifflags.h +++ b/arch/arm64/include/asm/daifflags.h @@ -72,6 +72,9 @@ static inline void local_daif_restore(unsigned long flags)
if (!irq_disabled) { trace_hardirqs_on(); +#ifdef CONFIG_ITRACE_IRQSOFF + itrace_hardirqs_ignore(); +#endif
if (system_uses_irq_prio_masking()) { gic_write_pmr(GIC_PRIO_IRQON); diff --git a/arch/arm64/kernel/entry.S b/arch/arm64/kernel/entry.S index 2eb1b657de2fb..2c9b8d94d3677 100644 --- a/arch/arm64/kernel/entry.S +++ b/arch/arm64/kernel/entry.S @@ -718,6 +718,9 @@ alternative_else_nop_endif #endif bl trace_hardirqs_on 1: +#endif +#ifdef CONFIG_ITRACE_IRQSOFF + bl itrace_hardirqs_ignore #endif
kernel_exit 1 @@ -954,6 +957,9 @@ el0_irq_naked:
#ifdef CONFIG_TRACE_IRQFLAGS bl trace_hardirqs_on +#endif +#ifdef CONFIG_ITRACE_IRQSOFF + bl itrace_hardirqs_ignore #endif b ret_to_user ENDPROC(el0_irq) @@ -989,6 +995,9 @@ work_pending: bl do_notify_resume #ifdef CONFIG_TRACE_IRQFLAGS bl trace_hardirqs_on // enabled while in userspace +#endif +#ifdef CONFIG_ITRACE_IRQSOFF + bl itrace_hardirqs_ignore #endif ldr x1, [tsk, #TSK_TI_FLAGS] // re-check for single-step b finish_ret_to_user diff --git a/arch/arm64/kernel/syscall.c b/arch/arm64/kernel/syscall.c index f2d2dbbbfca20..964df44d7429a 100644 --- a/arch/arm64/kernel/syscall.c +++ b/arch/arm64/kernel/syscall.c @@ -131,6 +131,9 @@ static void el0_svc_common(struct pt_regs *regs, int scno, int sc_nr, * the SPSR. */ trace_hardirqs_on(); +#ifdef CONFIG_ITRACE_IRQSOFF + itrace_hardirqs_ignore(); +#endif return; } local_daif_restore(DAIF_PROCCTX); diff --git a/arch/arm64/mm/fault.c b/arch/arm64/mm/fault.c index 08040fe73199a..4e7aaa658d636 100644 --- a/arch/arm64/mm/fault.c +++ b/arch/arm64/mm/fault.c @@ -1094,8 +1094,12 @@ asmlinkage int __exception do_debug_exception(unsigned long addr_if_watchpoint, rv = 0; }
- if (interrupts_enabled(regs)) + if (interrupts_enabled(regs)) { trace_hardirqs_on(); +#ifdef CONFIG_ITRACE_IRQSOFF + itrace_hardirqs_ignore(); +#endif + }
return rv; }