From: Bixuan Cui <cuibixuan(a)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(a)huawei.com>
Reviewed-by: Ding Tianhong <dingtianhong(a)huawei.com>
Signed-off-by: Yang Yingliang <yangyingliang(a)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;
}
--
2.25.1