linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH] x86: Add trace points to (nearly) all vectors
@ 2019-10-22  1:23 Andi Kleen
  2019-10-24  8:38 ` kbuild test robot
  0 siblings, 1 reply; 5+ messages in thread
From: Andi Kleen @ 2019-10-22  1:23 UTC (permalink / raw)
  To: x86; +Cc: linux-kernel, Andi Kleen

From: Andi Kleen <ak@linux.intel.com>

In some scenarios it can be useful to count or trace every kernel
entry. Most entry paths are covered by trace points already,
but some of the more obscure entry points do not have
trace points.

The most common uncovered one was KVM async page fault.

This patch kit adds trace points to all the other vectors,
except UV (anyone uses?), Xen (generic code), reboot (pointless)

To avoid creating a lot of new trace points this just
lumps them all together into a "other_vector" trace point, because
they're all fairly obscure and uncommon, and can be figured
out from the number when needed, or filtered using the filter
expression. This makes the needed perf command line much shorter.

The exception is the KVM async page fault which is fairly common
inside KVM guests, so is worth breaking out.

Signed-off-by: Andi Kleen <ak@linux.intel.com>
---
 arch/x86/hyperv/hv_init.c                |  2 ++
 arch/x86/include/asm/trace/irq_vectors.h |  9 ++++++
 arch/x86/kernel/apic/vector.c            |  3 ++
 arch/x86/kernel/cpu/mce/core.c           |  3 ++
 arch/x86/kernel/irq.c                    |  6 ++++
 arch/x86/kernel/kvm.c                    |  5 +++
 arch/x86/kernel/traps.c                  | 40 +++++++++++++++++++-----
 7 files changed, 60 insertions(+), 8 deletions(-)

diff --git a/arch/x86/hyperv/hv_init.c b/arch/x86/hyperv/hv_init.c
index 2db3972c0e0f..b719cd8964e0 100644
--- a/arch/x86/hyperv/hv_init.c
+++ b/arch/x86/hyperv/hv_init.c
@@ -144,8 +144,10 @@ __visible void __irq_entry hyperv_reenlightenment_intr(struct pt_regs *regs)
 
 	inc_irq_stat(irq_hv_reenlightenment_count);
 
+	trace_other_vector_entry(HYPERV_REENLIGHTENMENT_VECTOR);
 	schedule_delayed_work(&hv_reenlightenment_work, HZ/10);
 
+	trace_other_vector_exit(HYPERV_REENLIGHTENMENT_VECTOR);
 	exiting_irq();
 }
 
diff --git a/arch/x86/include/asm/trace/irq_vectors.h b/arch/x86/include/asm/trace/irq_vectors.h
index 33b9d0f0aafe..0c92d3ced26c 100644
--- a/arch/x86/include/asm/trace/irq_vectors.h
+++ b/arch/x86/include/asm/trace/irq_vectors.h
@@ -71,6 +71,11 @@ DEFINE_IRQ_VECTOR_EVENT(error_apic);
  */
 DEFINE_IRQ_VECTOR_EVENT(x86_platform_ipi);
 
+/*
+ * Handle all other vectors.
+ */
+DEFINE_IRQ_VECTOR_EVENT(other_vector);
+
 #ifdef CONFIG_IRQ_WORK
 /*
  * irq_work - called when entering/exiting a irq work interrupt
@@ -138,6 +143,10 @@ DEFINE_IRQ_VECTOR_EVENT(deferred_error_apic);
 DEFINE_IRQ_VECTOR_EVENT(thermal_apic);
 #endif
 
+#ifdef CONFIG_KVM
+DEFINE_IRQ_VECTOR_EVENT(async_page_fault);
+#endif
+
 TRACE_EVENT(vector_config,
 
 	TP_PROTO(unsigned int irq, unsigned int vector,
diff --git a/arch/x86/kernel/apic/vector.c b/arch/x86/kernel/apic/vector.c
index 2c5676b0a6e7..2e883f38b895 100644
--- a/arch/x86/kernel/apic/vector.c
+++ b/arch/x86/kernel/apic/vector.c
@@ -860,6 +860,7 @@ asmlinkage __visible void __irq_entry smp_irq_move_cleanup_interrupt(void)
 	struct hlist_node *tmp;
 
 	entering_ack_irq();
+	trace_other_vector_entry(IRQ_MOVE_CLEANUP_VECTOR);
 	/* Prevent vectors vanishing under us */
 	raw_spin_lock(&vector_lock);
 
@@ -884,6 +885,8 @@ asmlinkage __visible void __irq_entry smp_irq_move_cleanup_interrupt(void)
 	}
 
 	raw_spin_unlock(&vector_lock);
+	trace_other_vector_exit(IRQ_MOVE_CLEANUP_VECTOR);
+	/* Prevent vectors vanishing under us */
 	exiting_irq();
 }
 
diff --git a/arch/x86/kernel/cpu/mce/core.c b/arch/x86/kernel/cpu/mce/core.c
index 743370ee4983..f593bd6b0ed7 100644
--- a/arch/x86/kernel/cpu/mce/core.c
+++ b/arch/x86/kernel/cpu/mce/core.c
@@ -61,6 +61,9 @@ static DEFINE_MUTEX(mce_sysfs_mutex);
 #define CREATE_TRACE_POINTS
 #include <trace/events/mce.h>
 
+#undef CREATE_TRACE_POINTS
+#include <asm/trace/irq_vectors.h>
+
 #define SPINUNIT		100	/* 100ns */
 
 DEFINE_PER_CPU(unsigned, mce_exception_count);
diff --git a/arch/x86/kernel/irq.c b/arch/x86/kernel/irq.c
index 21efee32e2b1..f57c148dc578 100644
--- a/arch/x86/kernel/irq.c
+++ b/arch/x86/kernel/irq.c
@@ -308,8 +308,10 @@ __visible void smp_kvm_posted_intr_ipi(struct pt_regs *regs)
 	struct pt_regs *old_regs = set_irq_regs(regs);
 
 	entering_ack_irq();
+	trace_other_vector_entry(POSTED_INTR_VECTOR);
 	inc_irq_stat(kvm_posted_intr_ipis);
 	exiting_irq();
+	trace_other_vector_exit(POSTED_INTR_VECTOR);
 	set_irq_regs(old_regs);
 }
 
@@ -321,8 +323,10 @@ __visible void smp_kvm_posted_intr_wakeup_ipi(struct pt_regs *regs)
 	struct pt_regs *old_regs = set_irq_regs(regs);
 
 	entering_ack_irq();
+	trace_other_vector_entry(POSTED_INTR_WAKEUP_VECTOR);
 	inc_irq_stat(kvm_posted_intr_wakeup_ipis);
 	kvm_posted_intr_wakeup_handler();
+	trace_other_vector_exit(POSTED_INTR_WAKEUP_VECTOR);
 	exiting_irq();
 	set_irq_regs(old_regs);
 }
@@ -335,7 +339,9 @@ __visible void smp_kvm_posted_intr_nested_ipi(struct pt_regs *regs)
 	struct pt_regs *old_regs = set_irq_regs(regs);
 
 	entering_ack_irq();
+	trace_other_vector_entry(POSTED_INTR_NESTED_VECTOR);
 	inc_irq_stat(kvm_posted_intr_nested_ipis);
+	trace_other_vector_exit(POSTED_INTR_NESTED_VECTOR);
 	exiting_irq();
 	set_irq_regs(old_regs);
 }
diff --git a/arch/x86/kernel/kvm.c b/arch/x86/kernel/kvm.c
index e820568ed4d5..8d915b559617 100644
--- a/arch/x86/kernel/kvm.c
+++ b/arch/x86/kernel/kvm.c
@@ -33,6 +33,7 @@
 #include <asm/apicdef.h>
 #include <asm/hypervisor.h>
 #include <asm/tlb.h>
+#include <asm/trace/irq_vectors.h>
 
 static int kvmapf = 1;
 
@@ -246,6 +247,8 @@ do_async_page_fault(struct pt_regs *regs, unsigned long error_code, unsigned lon
 {
 	enum ctx_state prev_state;
 
+	trace_async_page_fault_entry(0);
+
 	switch (kvm_read_and_reset_pf_reason()) {
 	default:
 		do_page_fault(regs, error_code, address);
@@ -262,6 +265,8 @@ do_async_page_fault(struct pt_regs *regs, unsigned long error_code, unsigned lon
 		rcu_irq_exit();
 		break;
 	}
+
+	trace_async_page_fault_exit(0);
 }
 NOKPROBE_SYMBOL(do_async_page_fault);
 
diff --git a/arch/x86/kernel/traps.c b/arch/x86/kernel/traps.c
index 4bb0f8447112..6ccc01d74747 100644
--- a/arch/x86/kernel/traps.c
+++ b/arch/x86/kernel/traps.c
@@ -62,6 +62,8 @@
 #include <asm/vm86.h>
 #include <asm/umip.h>
 
+#include <asm/trace/irq_vectors.h>
+
 #ifdef CONFIG_X86_64
 #include <asm/x86_init.h>
 #include <asm/pgalloc.h>
@@ -264,19 +266,22 @@ static void do_error_trap(struct pt_regs *regs, long error_code, char *str,
 	unsigned long trapnr, int signr, int sicode, void __user *addr)
 {
 	RCU_LOCKDEP_WARN(!rcu_is_watching(), "entry code didn't wake RCU");
+	trace_other_vector_entry(trapnr);
 
 	/*
 	 * WARN*()s end up here; fix them up before we call the
 	 * notifier chain.
 	 */
 	if (!user_mode(regs) && fixup_bug(regs, trapnr))
-		return;
+		goto out;
 
 	if (notify_die(DIE_TRAP, str, regs, error_code, trapnr, signr) !=
 			NOTIFY_STOP) {
 		cond_local_irq_enable(regs);
 		do_trap(trapnr, signr, str, regs, error_code, sicode, addr);
 	}
+out:
+	trace_other_vector_exit(trapnr);
 }
 
 #define IP ((void __user *)uprobe_get_trap_addr(regs))
@@ -433,9 +438,10 @@ dotraplinkage void do_bounds(struct pt_regs *regs, long error_code)
 	const struct mpx_bndcsr *bndcsr;
 
 	RCU_LOCKDEP_WARN(!rcu_is_watching(), "entry code didn't wake RCU");
+	trace_other_vector_entry(X86_TRAP_BR);
 	if (notify_die(DIE_TRAP, "bounds", regs, error_code,
 			X86_TRAP_BR, SIGSEGV) == NOTIFY_STOP)
-		return;
+		goto exit;
 	cond_local_irq_enable(regs);
 
 	if (!user_mode(regs))
@@ -501,6 +507,8 @@ dotraplinkage void do_bounds(struct pt_regs *regs, long error_code)
 		die("bounds", regs, error_code);
 	}
 
+exit:
+	trace_other_vector_exit(X86_TRAP_BR);
 	return;
 
 exit_trap:
@@ -512,6 +520,7 @@ dotraplinkage void do_bounds(struct pt_regs *regs, long error_code)
 	 * time..
 	 */
 	do_trap(X86_TRAP_BR, SIGSEGV, "bounds", regs, error_code, 0, NULL);
+	goto exit;
 }
 
 dotraplinkage void
@@ -522,22 +531,23 @@ do_general_protection(struct pt_regs *regs, long error_code)
 
 	RCU_LOCKDEP_WARN(!rcu_is_watching(), "entry code didn't wake RCU");
 	cond_local_irq_enable(regs);
+	trace_other_vector_entry(X86_TRAP_GP);
 
 	if (static_cpu_has(X86_FEATURE_UMIP)) {
 		if (user_mode(regs) && fixup_umip_exception(regs))
-			return;
+			goto out;
 	}
 
 	if (v8086_mode(regs)) {
 		local_irq_enable();
 		handle_vm86_fault((struct kernel_vm86_regs *) regs, error_code);
-		return;
+		goto out;
 	}
 
 	tsk = current;
 	if (!user_mode(regs)) {
 		if (fixup_exception(regs, X86_TRAP_GP, error_code, 0))
-			return;
+			goto out;
 
 		tsk->thread.error_code = error_code;
 		tsk->thread.trap_nr = X86_TRAP_GP;
@@ -549,12 +559,12 @@ do_general_protection(struct pt_regs *regs, long error_code)
 		 */
 		if (!preemptible() && kprobe_running() &&
 		    kprobe_fault_handler(regs, X86_TRAP_GP))
-			return;
+			goto out;
 
 		if (notify_die(DIE_GPF, desc, regs, error_code,
 			       X86_TRAP_GP, SIGSEGV) != NOTIFY_STOP)
 			die(desc, regs, error_code);
-		return;
+		goto out;
 	}
 
 	tsk->thread.error_code = error_code;
@@ -563,6 +573,9 @@ do_general_protection(struct pt_regs *regs, long error_code)
 	show_signal(tsk, SIGSEGV, "", desc, regs, error_code);
 
 	force_sig(SIGSEGV);
+
+out:
+	trace_other_vector_exit(X86_TRAP_GP);
 }
 NOKPROBE_SYMBOL(do_general_protection);
 
@@ -588,6 +601,7 @@ dotraplinkage void notrace do_int3(struct pt_regs *regs, long error_code)
 	 * This means that we can't schedule.  That's okay.
 	 */
 	ist_enter(regs);
+	trace_other_vector_entry(X86_TRAP_BP);
 	RCU_LOCKDEP_WARN(!rcu_is_watching(), "entry code didn't wake RCU");
 #ifdef CONFIG_KGDB_LOW_LEVEL_TRAP
 	if (kgdb_ll_trap(DIE_INT3, "int3", regs, error_code, X86_TRAP_BP,
@@ -609,6 +623,7 @@ dotraplinkage void notrace do_int3(struct pt_regs *regs, long error_code)
 	cond_local_irq_disable(regs);
 
 exit:
+	trace_other_vector_exit(X86_TRAP_BP);
 	ist_exit(regs);
 }
 NOKPROBE_SYMBOL(do_int3);
@@ -714,6 +729,7 @@ dotraplinkage void do_debug(struct pt_regs *regs, long error_code)
 	int si_code;
 
 	ist_enter(regs);
+	trace_other_vector_entry(X86_TRAP_DB);
 
 	get_debugreg(dr6, 6);
 	/*
@@ -806,6 +822,7 @@ dotraplinkage void do_debug(struct pt_regs *regs, long error_code)
 	debug_stack_usage_dec();
 
 exit:
+	trace_other_vector_exit(X86_TRAP_DB);
 	ist_exit(regs);
 }
 NOKPROBE_SYMBOL(do_debug);
@@ -858,14 +875,18 @@ static void math_error(struct pt_regs *regs, int error_code, int trapnr)
 dotraplinkage void do_coprocessor_error(struct pt_regs *regs, long error_code)
 {
 	RCU_LOCKDEP_WARN(!rcu_is_watching(), "entry code didn't wake RCU");
+	trace_other_vector_entry(X86_TRAP_MF);
 	math_error(regs, error_code, X86_TRAP_MF);
+	trace_other_vector_exit(X86_TRAP_MF);
 }
 
 dotraplinkage void
 do_simd_coprocessor_error(struct pt_regs *regs, long error_code)
 {
 	RCU_LOCKDEP_WARN(!rcu_is_watching(), "entry code didn't wake RCU");
+	trace_other_vector_entry(X86_TRAP_XF);
 	math_error(regs, error_code, X86_TRAP_XF);
+	trace_other_vector_exit(X86_TRAP_XF);
 }
 
 dotraplinkage void
@@ -881,6 +902,7 @@ do_device_not_available(struct pt_regs *regs, long error_code)
 
 	RCU_LOCKDEP_WARN(!rcu_is_watching(), "entry code didn't wake RCU");
 
+	trace_other_vector_entry(X86_TRAP_NM);
 #ifdef CONFIG_MATH_EMULATION
 	if (!boot_cpu_has(X86_FEATURE_FPU) && (cr0 & X86_CR0_EM)) {
 		struct math_emu_info info = { };
@@ -889,7 +911,7 @@ do_device_not_available(struct pt_regs *regs, long error_code)
 
 		info.regs = regs;
 		math_emulate(&info);
-		return;
+		goto out;
 	}
 #endif
 
@@ -905,6 +927,8 @@ do_device_not_available(struct pt_regs *regs, long error_code)
 		 */
 		die("unexpected #NM exception", regs, error_code);
 	}
+out: __maybe_unused;
+	trace_other_vector_exit(X86_TRAP_NM);
 }
 NOKPROBE_SYMBOL(do_device_not_available);
 
-- 
2.21.0


^ permalink raw reply related	[flat|nested] 5+ messages in thread

* Re: [PATCH] x86: Add trace points to (nearly) all vectors
  2019-10-22  1:23 [PATCH] x86: Add trace points to (nearly) all vectors Andi Kleen
@ 2019-10-24  8:38 ` kbuild test robot
  0 siblings, 0 replies; 5+ messages in thread
From: kbuild test robot @ 2019-10-24  8:38 UTC (permalink / raw)
  To: Andi Kleen; +Cc: kbuild-all, x86, linux-kernel, Andi Kleen

[-- Attachment #1: Type: text/plain, Size: 2671 bytes --]

Hi Andi,

Thank you for the patch! Yet something to improve:

[auto build test ERROR on tip/auto-latest]
[cannot apply to v5.4-rc4 next-20191023]
[if your patch is applied to the wrong git tree, please drop us a note to help
improve the system. BTW, we also suggest to use '--base' option to specify the
base tree in git format-patch, please see https://stackoverflow.com/a/37406982]

url:    https://github.com/0day-ci/linux/commits/Andi-Kleen/x86-Add-trace-points-to-nearly-all-vectors/20191024-145326
base:   https://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git a5b576bfb3ba85d3e356f9900dce1428d4760582
config: i386-allmodconfig (attached as .config)
compiler: gcc-7 (Debian 7.4.0-14) 7.4.0
reproduce:
        # save the attached .config to linux build tree
        make ARCH=i386 

If you fix the issue, kindly add following tag
Reported-by: kbuild test robot <lkp@intel.com>

All errors (new ones prefixed by >>):

   arch/x86/kernel/kvm.c: In function 'do_async_page_fault':
>> arch/x86/kernel/kvm.c:250:2: error: implicit declaration of function 'trace_async_page_fault_entry'; did you mean 'do_async_page_fault'? [-Werror=implicit-function-declaration]
     trace_async_page_fault_entry(0);
     ^~~~~~~~~~~~~~~~~~~~~~~~~~~~
     do_async_page_fault
>> arch/x86/kernel/kvm.c:269:2: error: implicit declaration of function 'trace_async_page_fault_exit'; did you mean 'do_async_page_fault'? [-Werror=implicit-function-declaration]
     trace_async_page_fault_exit(0);
     ^~~~~~~~~~~~~~~~~~~~~~~~~~~
     do_async_page_fault
   cc1: some warnings being treated as errors

vim +250 arch/x86/kernel/kvm.c

   244	
   245	dotraplinkage void
   246	do_async_page_fault(struct pt_regs *regs, unsigned long error_code, unsigned long address)
   247	{
   248		enum ctx_state prev_state;
   249	
 > 250		trace_async_page_fault_entry(0);
   251	
   252		switch (kvm_read_and_reset_pf_reason()) {
   253		default:
   254			do_page_fault(regs, error_code, address);
   255			break;
   256		case KVM_PV_REASON_PAGE_NOT_PRESENT:
   257			/* page is swapped out by the host. */
   258			prev_state = exception_enter();
   259			kvm_async_pf_task_wait((u32)address, !user_mode(regs));
   260			exception_exit(prev_state);
   261			break;
   262		case KVM_PV_REASON_PAGE_READY:
   263			rcu_irq_enter();
   264			kvm_async_pf_task_wake((u32)address);
   265			rcu_irq_exit();
   266			break;
   267		}
   268	
 > 269		trace_async_page_fault_exit(0);
   270	}
   271	NOKPROBE_SYMBOL(do_async_page_fault);
   272	

---
0-DAY kernel test infrastructure                Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all                   Intel Corporation

[-- Attachment #2: .config.gz --]
[-- Type: application/gzip, Size: 70206 bytes --]

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [PATCH] x86: Add trace points to (nearly) all vectors
  2020-03-12 23:39 ` Andy Lutomirski
@ 2020-03-13 11:51   ` Andi Kleen
  0 siblings, 0 replies; 5+ messages in thread
From: Andi Kleen @ 2020-03-13 11:51 UTC (permalink / raw)
  To: Andy Lutomirski; +Cc: Andi Kleen, x86, linux-kernel, Andi Kleen

On Thu, Mar 12, 2020 at 04:39:04PM -0700, Andy Lutomirski wrote:
> 
> > On Mar 12, 2020, at 4:19 PM, Andi Kleen <andi@firstfloor.org> wrote:
> > 
> > From: Andi Kleen <ak@linux.intel.com>
> > 
> > In some scenarios it can be useful to count or trace every kernel
> > entry.
> 
> Can you elaborate?  What problem does this solve?

So that we know how often or where kernel entries happen,
how long every kernel execution is, and also can do an accurate break
down.

> 
> > Most entry paths are covered by trace points already,
> > but some of the more obscure entry points do not have
> > trace points.
> > 
> > The most common uncovered one was KVM async page fault.
> 
> NAK.  This path is going away. 

Okay. Can you provide details? When will it go away?

Anyways KVM async is just one case, my patch covers lots of other cases
too. Even if KVM async goes away it still makes sense
for the other entry points and can be easily rebased (just drop
that hunk)

-Andi


^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [PATCH] x86: Add trace points to (nearly) all vectors
  2020-03-12 23:19 Andi Kleen
@ 2020-03-12 23:39 ` Andy Lutomirski
  2020-03-13 11:51   ` Andi Kleen
  0 siblings, 1 reply; 5+ messages in thread
From: Andy Lutomirski @ 2020-03-12 23:39 UTC (permalink / raw)
  To: Andi Kleen; +Cc: x86, linux-kernel, Andi Kleen


> On Mar 12, 2020, at 4:19 PM, Andi Kleen <andi@firstfloor.org> wrote:
> 
> From: Andi Kleen <ak@linux.intel.com>
> 
> In some scenarios it can be useful to count or trace every kernel
> entry.

Can you elaborate?  What problem does this solve?

> Most entry paths are covered by trace points already,
> but some of the more obscure entry points do not have
> trace points.
> 
> The most common uncovered one was KVM async page fault.

NAK.  This path is going away. 

> 
> This patch kit adds trace points to all the other vectors,
> except UV (anyone uses?), Xen (generic code), reboot (pointless)
> 
> To avoid creating a lot of new trace points this just
> lumps them all together into a "other_vector" trace point, because
> they're all fairly obscure and uncommon, and can be figured
> out from the number when needed, or filtered using the filter
> expression. This makes the needed perf command line much shorter.
> 
> The exception is the KVM async page fault which is fairly common
> inside KVM guests, so is worth breaking out.
> 
> The Xen vectors could be done done as a followon if desired.
> 
> Signed-off-by: Andi Kleen <ak@linux.intel.com>
> 
> --
> 
> v2: Fix build errors found by 0day for some configurations.
> v3: Finally use correct CONFIG symbol to check for KVM guest.
> Thanks 0day.
> v4: Fix build for 32bit with !CONFIG_X86_LOCAL_APIC. Thanks 0day.
> v5: Rebase. No changes.
> ---
> arch/x86/hyperv/hv_init.c                |  3 ++
> arch/x86/include/asm/trace/irq_vectors.h | 17 ++++++++--
> arch/x86/kernel/apic/vector.c            |  3 ++
> arch/x86/kernel/cpu/mce/core.c           |  3 ++
> arch/x86/kernel/irq.c                    |  6 ++++
> arch/x86/kernel/kvm.c                    |  5 +++
> arch/x86/kernel/traps.c                  | 40 +++++++++++++++++++-----
> 7 files changed, 67 insertions(+), 10 deletions(-)
> 
> diff --git a/arch/x86/hyperv/hv_init.c b/arch/x86/hyperv/hv_init.c
> index 2db3972c0e0f..d97e570e37b6 100644
> --- a/arch/x86/hyperv/hv_init.c
> +++ b/arch/x86/hyperv/hv_init.c
> @@ -21,6 +21,7 @@
> #include <linux/slab.h>
> #include <linux/cpuhotplug.h>
> #include <clocksource/hyperv_timer.h>
> +#include <asm/trace/irq_vectors.h>
> 
> void *hv_hypercall_pg;
> EXPORT_SYMBOL_GPL(hv_hypercall_pg);
> @@ -144,8 +145,10 @@ __visible void __irq_entry hyperv_reenlightenment_intr(struct pt_regs *regs)
> 
>    inc_irq_stat(irq_hv_reenlightenment_count);
> 
> +    trace_other_vector_entry(HYPERV_REENLIGHTENMENT_VECTOR);
>    schedule_delayed_work(&hv_reenlightenment_work, HZ/10);
> 
> +    trace_other_vector_exit(HYPERV_REENLIGHTENMENT_VECTOR);
>    exiting_irq();
> }
> 
> diff --git a/arch/x86/include/asm/trace/irq_vectors.h b/arch/x86/include/asm/trace/irq_vectors.h
> index 33b9d0f0aafe..b50b3dc02e71 100644
> --- a/arch/x86/include/asm/trace/irq_vectors.h
> +++ b/arch/x86/include/asm/trace/irq_vectors.h
> @@ -8,8 +8,6 @@
> #include <linux/tracepoint.h>
> #include <asm/trace/common.h>
> 
> -#ifdef CONFIG_X86_LOCAL_APIC
> -
> extern int trace_resched_ipi_reg(void);
> extern void trace_resched_ipi_unreg(void);
> 
> @@ -49,6 +47,8 @@ DEFINE_EVENT_FN(x86_irq_vector, name##_exit,    \
>    trace_resched_ipi_reg,            \
>    trace_resched_ipi_unreg);
> 
> +#ifdef CONFIG_X86_LOCAL_APIC
> +
> /*
>  * local_timer - called when entering/exiting a local timer interrupt
>  * vector handler
> @@ -138,6 +138,19 @@ DEFINE_IRQ_VECTOR_EVENT(deferred_error_apic);
> DEFINE_IRQ_VECTOR_EVENT(thermal_apic);
> #endif
> 
> +#endif /* CONFIG_X86_LOCAL_APIC */
> +
> +#ifdef CONFIG_KVM_GUEST
> +DEFINE_IRQ_VECTOR_EVENT(async_page_fault);
> +#endif
> +
> +/*
> + * Handle all other vectors.
> + */
> +DEFINE_IRQ_VECTOR_EVENT(other_vector);
> +
> +#ifdef CONFIG_X86_LOCAL_APIC
> +
> TRACE_EVENT(vector_config,
> 
>    TP_PROTO(unsigned int irq, unsigned int vector,
> diff --git a/arch/x86/kernel/apic/vector.c b/arch/x86/kernel/apic/vector.c
> index 2c5676b0a6e7..2e883f38b895 100644
> --- a/arch/x86/kernel/apic/vector.c
> +++ b/arch/x86/kernel/apic/vector.c
> @@ -860,6 +860,7 @@ asmlinkage __visible void __irq_entry smp_irq_move_cleanup_interrupt(void)
>    struct hlist_node *tmp;
> 
>    entering_ack_irq();
> +    trace_other_vector_entry(IRQ_MOVE_CLEANUP_VECTOR);
>    /* Prevent vectors vanishing under us */
>    raw_spin_lock(&vector_lock);
> 
> @@ -884,6 +885,8 @@ asmlinkage __visible void __irq_entry smp_irq_move_cleanup_interrupt(void)
>    }
> 
>    raw_spin_unlock(&vector_lock);
> +    trace_other_vector_exit(IRQ_MOVE_CLEANUP_VECTOR);
> +    /* Prevent vectors vanishing under us */
>    exiting_irq();
> }
> 
> diff --git a/arch/x86/kernel/cpu/mce/core.c b/arch/x86/kernel/cpu/mce/core.c
> index 743370ee4983..f593bd6b0ed7 100644
> --- a/arch/x86/kernel/cpu/mce/core.c
> +++ b/arch/x86/kernel/cpu/mce/core.c
> @@ -61,6 +61,9 @@ static DEFINE_MUTEX(mce_sysfs_mutex);
> #define CREATE_TRACE_POINTS
> #include <trace/events/mce.h>
> 
> +#undef CREATE_TRACE_POINTS
> +#include <asm/trace/irq_vectors.h>
> +
> #define SPINUNIT        100    /* 100ns */
> 
> DEFINE_PER_CPU(unsigned, mce_exception_count);
> diff --git a/arch/x86/kernel/irq.c b/arch/x86/kernel/irq.c
> index 21efee32e2b1..f57c148dc578 100644
> --- a/arch/x86/kernel/irq.c
> +++ b/arch/x86/kernel/irq.c
> @@ -308,8 +308,10 @@ __visible void smp_kvm_posted_intr_ipi(struct pt_regs *regs)
>    struct pt_regs *old_regs = set_irq_regs(regs);
> 
>    entering_ack_irq();
> +    trace_other_vector_entry(POSTED_INTR_VECTOR);
>    inc_irq_stat(kvm_posted_intr_ipis);
>    exiting_irq();
> +    trace_other_vector_exit(POSTED_INTR_VECTOR);
>    set_irq_regs(old_regs);
> }
> 
> @@ -321,8 +323,10 @@ __visible void smp_kvm_posted_intr_wakeup_ipi(struct pt_regs *regs)
>    struct pt_regs *old_regs = set_irq_regs(regs);
> 
>    entering_ack_irq();
> +    trace_other_vector_entry(POSTED_INTR_WAKEUP_VECTOR);
>    inc_irq_stat(kvm_posted_intr_wakeup_ipis);
>    kvm_posted_intr_wakeup_handler();
> +    trace_other_vector_exit(POSTED_INTR_WAKEUP_VECTOR);
>    exiting_irq();
>    set_irq_regs(old_regs);
> }
> @@ -335,7 +339,9 @@ __visible void smp_kvm_posted_intr_nested_ipi(struct pt_regs *regs)
>    struct pt_regs *old_regs = set_irq_regs(regs);
> 
>    entering_ack_irq();
> +    trace_other_vector_entry(POSTED_INTR_NESTED_VECTOR);
>    inc_irq_stat(kvm_posted_intr_nested_ipis);
> +    trace_other_vector_exit(POSTED_INTR_NESTED_VECTOR);
>    exiting_irq();
>    set_irq_regs(old_regs);
> }
> diff --git a/arch/x86/kernel/kvm.c b/arch/x86/kernel/kvm.c
> index e820568ed4d5..8d915b559617 100644
> --- a/arch/x86/kernel/kvm.c
> +++ b/arch/x86/kernel/kvm.c
> @@ -33,6 +33,7 @@
> #include <asm/apicdef.h>
> #include <asm/hypervisor.h>
> #include <asm/tlb.h>
> +#include <asm/trace/irq_vectors.h>
> 
> static int kvmapf = 1;
> 
> @@ -246,6 +247,8 @@ do_async_page_fault(struct pt_regs *regs, unsigned long error_code, unsigned lon
> {
>    enum ctx_state prev_state;
> 
> +    trace_async_page_fault_entry(0);
> +
>    switch (kvm_read_and_reset_pf_reason()) {
>    default:
>        do_page_fault(regs, error_code, address);
> @@ -262,6 +265,8 @@ do_async_page_fault(struct pt_regs *regs, unsigned long error_code, unsigned lon
>        rcu_irq_exit();
>        break;
>    }
> +
> +    trace_async_page_fault_exit(0);
> }
> NOKPROBE_SYMBOL(do_async_page_fault);
> 
> diff --git a/arch/x86/kernel/traps.c b/arch/x86/kernel/traps.c
> index 4bb0f8447112..6ccc01d74747 100644
> --- a/arch/x86/kernel/traps.c
> +++ b/arch/x86/kernel/traps.c
> @@ -62,6 +62,8 @@
> #include <asm/vm86.h>
> #include <asm/umip.h>
> 
> +#include <asm/trace/irq_vectors.h>
> +
> #ifdef CONFIG_X86_64
> #include <asm/x86_init.h>
> #include <asm/pgalloc.h>
> @@ -264,19 +266,22 @@ static void do_error_trap(struct pt_regs *regs, long error_code, char *str,
>    unsigned long trapnr, int signr, int sicode, void __user *addr)
> {
>    RCU_LOCKDEP_WARN(!rcu_is_watching(), "entry code didn't wake RCU");
> +    trace_other_vector_entry(trapnr);
> 
>    /*
>     * WARN*()s end up here; fix them up before we call the
>     * notifier chain.
>     */
>    if (!user_mode(regs) && fixup_bug(regs, trapnr))
> -        return;
> +        goto out;
> 
>    if (notify_die(DIE_TRAP, str, regs, error_code, trapnr, signr) !=
>            NOTIFY_STOP) {
>        cond_local_irq_enable(regs);
>        do_trap(trapnr, signr, str, regs, error_code, sicode, addr);
>    }
> +out:
> +    trace_other_vector_exit(trapnr);
> }
> 
> #define IP ((void __user *)uprobe_get_trap_addr(regs))
> @@ -433,9 +438,10 @@ dotraplinkage void do_bounds(struct pt_regs *regs, long error_code)
>    const struct mpx_bndcsr *bndcsr;
> 
>    RCU_LOCKDEP_WARN(!rcu_is_watching(), "entry code didn't wake RCU");
> +    trace_other_vector_entry(X86_TRAP_BR);
>    if (notify_die(DIE_TRAP, "bounds", regs, error_code,
>            X86_TRAP_BR, SIGSEGV) == NOTIFY_STOP)
> -        return;
> +        goto exit;
>    cond_local_irq_enable(regs);
> 
>    if (!user_mode(regs))
> @@ -501,6 +507,8 @@ dotraplinkage void do_bounds(struct pt_regs *regs, long error_code)
>        die("bounds", regs, error_code);
>    }
> 
> +exit:
> +    trace_other_vector_exit(X86_TRAP_BR);
>    return;
> 
> exit_trap:
> @@ -512,6 +520,7 @@ dotraplinkage void do_bounds(struct pt_regs *regs, long error_code)
>     * time..
>     */
>    do_trap(X86_TRAP_BR, SIGSEGV, "bounds", regs, error_code, 0, NULL);
> +    goto exit;
> }
> 
> dotraplinkage void
> @@ -522,22 +531,23 @@ do_general_protection(struct pt_regs *regs, long error_code)
> 
>    RCU_LOCKDEP_WARN(!rcu_is_watching(), "entry code didn't wake RCU");
>    cond_local_irq_enable(regs);
> +    trace_other_vector_entry(X86_TRAP_GP);
> 
>    if (static_cpu_has(X86_FEATURE_UMIP)) {
>        if (user_mode(regs) && fixup_umip_exception(regs))
> -            return;
> +            goto out;
>    }
> 
>    if (v8086_mode(regs)) {
>        local_irq_enable();
>        handle_vm86_fault((struct kernel_vm86_regs *) regs, error_code);
> -        return;
> +        goto out;
>    }
> 
>    tsk = current;
>    if (!user_mode(regs)) {
>        if (fixup_exception(regs, X86_TRAP_GP, error_code, 0))
> -            return;
> +            goto out;
> 
>        tsk->thread.error_code = error_code;
>        tsk->thread.trap_nr = X86_TRAP_GP;
> @@ -549,12 +559,12 @@ do_general_protection(struct pt_regs *regs, long error_code)
>         */
>        if (!preemptible() && kprobe_running() &&
>            kprobe_fault_handler(regs, X86_TRAP_GP))
> -            return;
> +            goto out;
> 
>        if (notify_die(DIE_GPF, desc, regs, error_code,
>                   X86_TRAP_GP, SIGSEGV) != NOTIFY_STOP)
>            die(desc, regs, error_code);
> -        return;
> +        goto out;
>    }
> 
>    tsk->thread.error_code = error_code;
> @@ -563,6 +573,9 @@ do_general_protection(struct pt_regs *regs, long error_code)
>    show_signal(tsk, SIGSEGV, "", desc, regs, error_code);
> 
>    force_sig(SIGSEGV);
> +
> +out:
> +    trace_other_vector_exit(X86_TRAP_GP);
> }
> NOKPROBE_SYMBOL(do_general_protection);
> 
> @@ -588,6 +601,7 @@ dotraplinkage void notrace do_int3(struct pt_regs *regs, long error_code)
>     * This means that we can't schedule.  That's okay.
>     */
>    ist_enter(regs);
> +    trace_other_vector_entry(X86_TRAP_BP);
>    RCU_LOCKDEP_WARN(!rcu_is_watching(), "entry code didn't wake RCU");
> #ifdef CONFIG_KGDB_LOW_LEVEL_TRAP
>    if (kgdb_ll_trap(DIE_INT3, "int3", regs, error_code, X86_TRAP_BP,
> @@ -609,6 +623,7 @@ dotraplinkage void notrace do_int3(struct pt_regs *regs, long error_code)
>    cond_local_irq_disable(regs);
> 
> exit:
> +    trace_other_vector_exit(X86_TRAP_BP);
>    ist_exit(regs);
> }
> NOKPROBE_SYMBOL(do_int3);
> @@ -714,6 +729,7 @@ dotraplinkage void do_debug(struct pt_regs *regs, long error_code)
>    int si_code;
> 
>    ist_enter(regs);
> +    trace_other_vector_entry(X86_TRAP_DB);
> 
>    get_debugreg(dr6, 6);
>    /*
> @@ -806,6 +822,7 @@ dotraplinkage void do_debug(struct pt_regs *regs, long error_code)
>    debug_stack_usage_dec();
> 
> exit:
> +    trace_other_vector_exit(X86_TRAP_DB);
>    ist_exit(regs);
> }
> NOKPROBE_SYMBOL(do_debug);
> @@ -858,14 +875,18 @@ static void math_error(struct pt_regs *regs, int error_code, int trapnr)
> dotraplinkage void do_coprocessor_error(struct pt_regs *regs, long error_code)
> {
>    RCU_LOCKDEP_WARN(!rcu_is_watching(), "entry code didn't wake RCU");
> +    trace_other_vector_entry(X86_TRAP_MF);
>    math_error(regs, error_code, X86_TRAP_MF);
> +    trace_other_vector_exit(X86_TRAP_MF);
> }
> 
> dotraplinkage void
> do_simd_coprocessor_error(struct pt_regs *regs, long error_code)
> {
>    RCU_LOCKDEP_WARN(!rcu_is_watching(), "entry code didn't wake RCU");
> +    trace_other_vector_entry(X86_TRAP_XF);
>    math_error(regs, error_code, X86_TRAP_XF);
> +    trace_other_vector_exit(X86_TRAP_XF);
> }
> 
> dotraplinkage void
> @@ -881,6 +902,7 @@ do_device_not_available(struct pt_regs *regs, long error_code)
> 
>    RCU_LOCKDEP_WARN(!rcu_is_watching(), "entry code didn't wake RCU");
> 
> +    trace_other_vector_entry(X86_TRAP_NM);
> #ifdef CONFIG_MATH_EMULATION
>    if (!boot_cpu_has(X86_FEATURE_FPU) && (cr0 & X86_CR0_EM)) {
>        struct math_emu_info info = { };
> @@ -889,7 +911,7 @@ do_device_not_available(struct pt_regs *regs, long error_code)
> 
>        info.regs = regs;
>        math_emulate(&info);
> -        return;
> +        goto out;
>    }
> #endif
> 
> @@ -905,6 +927,8 @@ do_device_not_available(struct pt_regs *regs, long error_code)
>         */
>        die("unexpected #NM exception", regs, error_code);
>    }
> +out: __maybe_unused;
> +    trace_other_vector_exit(X86_TRAP_NM);
> }
> NOKPROBE_SYMBOL(do_device_not_available);
> 
> -- 
> 2.24.1
> 

^ permalink raw reply	[flat|nested] 5+ messages in thread

* [PATCH] x86: Add trace points to (nearly) all vectors
@ 2020-03-12 23:19 Andi Kleen
  2020-03-12 23:39 ` Andy Lutomirski
  0 siblings, 1 reply; 5+ messages in thread
From: Andi Kleen @ 2020-03-12 23:19 UTC (permalink / raw)
  To: x86; +Cc: linux-kernel, Andi Kleen

From: Andi Kleen <ak@linux.intel.com>

In some scenarios it can be useful to count or trace every kernel
entry. Most entry paths are covered by trace points already,
but some of the more obscure entry points do not have
trace points.

The most common uncovered one was KVM async page fault.

This patch kit adds trace points to all the other vectors,
except UV (anyone uses?), Xen (generic code), reboot (pointless)

To avoid creating a lot of new trace points this just
lumps them all together into a "other_vector" trace point, because
they're all fairly obscure and uncommon, and can be figured
out from the number when needed, or filtered using the filter
expression. This makes the needed perf command line much shorter.

The exception is the KVM async page fault which is fairly common
inside KVM guests, so is worth breaking out.

The Xen vectors could be done done as a followon if desired.

Signed-off-by: Andi Kleen <ak@linux.intel.com>

--

v2: Fix build errors found by 0day for some configurations.
v3: Finally use correct CONFIG symbol to check for KVM guest.
Thanks 0day.
v4: Fix build for 32bit with !CONFIG_X86_LOCAL_APIC. Thanks 0day.
v5: Rebase. No changes.
---
 arch/x86/hyperv/hv_init.c                |  3 ++
 arch/x86/include/asm/trace/irq_vectors.h | 17 ++++++++--
 arch/x86/kernel/apic/vector.c            |  3 ++
 arch/x86/kernel/cpu/mce/core.c           |  3 ++
 arch/x86/kernel/irq.c                    |  6 ++++
 arch/x86/kernel/kvm.c                    |  5 +++
 arch/x86/kernel/traps.c                  | 40 +++++++++++++++++++-----
 7 files changed, 67 insertions(+), 10 deletions(-)

diff --git a/arch/x86/hyperv/hv_init.c b/arch/x86/hyperv/hv_init.c
index 2db3972c0e0f..d97e570e37b6 100644
--- a/arch/x86/hyperv/hv_init.c
+++ b/arch/x86/hyperv/hv_init.c
@@ -21,6 +21,7 @@
 #include <linux/slab.h>
 #include <linux/cpuhotplug.h>
 #include <clocksource/hyperv_timer.h>
+#include <asm/trace/irq_vectors.h>
 
 void *hv_hypercall_pg;
 EXPORT_SYMBOL_GPL(hv_hypercall_pg);
@@ -144,8 +145,10 @@ __visible void __irq_entry hyperv_reenlightenment_intr(struct pt_regs *regs)
 
 	inc_irq_stat(irq_hv_reenlightenment_count);
 
+	trace_other_vector_entry(HYPERV_REENLIGHTENMENT_VECTOR);
 	schedule_delayed_work(&hv_reenlightenment_work, HZ/10);
 
+	trace_other_vector_exit(HYPERV_REENLIGHTENMENT_VECTOR);
 	exiting_irq();
 }
 
diff --git a/arch/x86/include/asm/trace/irq_vectors.h b/arch/x86/include/asm/trace/irq_vectors.h
index 33b9d0f0aafe..b50b3dc02e71 100644
--- a/arch/x86/include/asm/trace/irq_vectors.h
+++ b/arch/x86/include/asm/trace/irq_vectors.h
@@ -8,8 +8,6 @@
 #include <linux/tracepoint.h>
 #include <asm/trace/common.h>
 
-#ifdef CONFIG_X86_LOCAL_APIC
-
 extern int trace_resched_ipi_reg(void);
 extern void trace_resched_ipi_unreg(void);
 
@@ -49,6 +47,8 @@ DEFINE_EVENT_FN(x86_irq_vector, name##_exit,	\
 	trace_resched_ipi_reg,			\
 	trace_resched_ipi_unreg);
 
+#ifdef CONFIG_X86_LOCAL_APIC
+
 /*
  * local_timer - called when entering/exiting a local timer interrupt
  * vector handler
@@ -138,6 +138,19 @@ DEFINE_IRQ_VECTOR_EVENT(deferred_error_apic);
 DEFINE_IRQ_VECTOR_EVENT(thermal_apic);
 #endif
 
+#endif /* CONFIG_X86_LOCAL_APIC */
+
+#ifdef CONFIG_KVM_GUEST
+DEFINE_IRQ_VECTOR_EVENT(async_page_fault);
+#endif
+
+/*
+ * Handle all other vectors.
+ */
+DEFINE_IRQ_VECTOR_EVENT(other_vector);
+
+#ifdef CONFIG_X86_LOCAL_APIC
+
 TRACE_EVENT(vector_config,
 
 	TP_PROTO(unsigned int irq, unsigned int vector,
diff --git a/arch/x86/kernel/apic/vector.c b/arch/x86/kernel/apic/vector.c
index 2c5676b0a6e7..2e883f38b895 100644
--- a/arch/x86/kernel/apic/vector.c
+++ b/arch/x86/kernel/apic/vector.c
@@ -860,6 +860,7 @@ asmlinkage __visible void __irq_entry smp_irq_move_cleanup_interrupt(void)
 	struct hlist_node *tmp;
 
 	entering_ack_irq();
+	trace_other_vector_entry(IRQ_MOVE_CLEANUP_VECTOR);
 	/* Prevent vectors vanishing under us */
 	raw_spin_lock(&vector_lock);
 
@@ -884,6 +885,8 @@ asmlinkage __visible void __irq_entry smp_irq_move_cleanup_interrupt(void)
 	}
 
 	raw_spin_unlock(&vector_lock);
+	trace_other_vector_exit(IRQ_MOVE_CLEANUP_VECTOR);
+	/* Prevent vectors vanishing under us */
 	exiting_irq();
 }
 
diff --git a/arch/x86/kernel/cpu/mce/core.c b/arch/x86/kernel/cpu/mce/core.c
index 743370ee4983..f593bd6b0ed7 100644
--- a/arch/x86/kernel/cpu/mce/core.c
+++ b/arch/x86/kernel/cpu/mce/core.c
@@ -61,6 +61,9 @@ static DEFINE_MUTEX(mce_sysfs_mutex);
 #define CREATE_TRACE_POINTS
 #include <trace/events/mce.h>
 
+#undef CREATE_TRACE_POINTS
+#include <asm/trace/irq_vectors.h>
+
 #define SPINUNIT		100	/* 100ns */
 
 DEFINE_PER_CPU(unsigned, mce_exception_count);
diff --git a/arch/x86/kernel/irq.c b/arch/x86/kernel/irq.c
index 21efee32e2b1..f57c148dc578 100644
--- a/arch/x86/kernel/irq.c
+++ b/arch/x86/kernel/irq.c
@@ -308,8 +308,10 @@ __visible void smp_kvm_posted_intr_ipi(struct pt_regs *regs)
 	struct pt_regs *old_regs = set_irq_regs(regs);
 
 	entering_ack_irq();
+	trace_other_vector_entry(POSTED_INTR_VECTOR);
 	inc_irq_stat(kvm_posted_intr_ipis);
 	exiting_irq();
+	trace_other_vector_exit(POSTED_INTR_VECTOR);
 	set_irq_regs(old_regs);
 }
 
@@ -321,8 +323,10 @@ __visible void smp_kvm_posted_intr_wakeup_ipi(struct pt_regs *regs)
 	struct pt_regs *old_regs = set_irq_regs(regs);
 
 	entering_ack_irq();
+	trace_other_vector_entry(POSTED_INTR_WAKEUP_VECTOR);
 	inc_irq_stat(kvm_posted_intr_wakeup_ipis);
 	kvm_posted_intr_wakeup_handler();
+	trace_other_vector_exit(POSTED_INTR_WAKEUP_VECTOR);
 	exiting_irq();
 	set_irq_regs(old_regs);
 }
@@ -335,7 +339,9 @@ __visible void smp_kvm_posted_intr_nested_ipi(struct pt_regs *regs)
 	struct pt_regs *old_regs = set_irq_regs(regs);
 
 	entering_ack_irq();
+	trace_other_vector_entry(POSTED_INTR_NESTED_VECTOR);
 	inc_irq_stat(kvm_posted_intr_nested_ipis);
+	trace_other_vector_exit(POSTED_INTR_NESTED_VECTOR);
 	exiting_irq();
 	set_irq_regs(old_regs);
 }
diff --git a/arch/x86/kernel/kvm.c b/arch/x86/kernel/kvm.c
index e820568ed4d5..8d915b559617 100644
--- a/arch/x86/kernel/kvm.c
+++ b/arch/x86/kernel/kvm.c
@@ -33,6 +33,7 @@
 #include <asm/apicdef.h>
 #include <asm/hypervisor.h>
 #include <asm/tlb.h>
+#include <asm/trace/irq_vectors.h>
 
 static int kvmapf = 1;
 
@@ -246,6 +247,8 @@ do_async_page_fault(struct pt_regs *regs, unsigned long error_code, unsigned lon
 {
 	enum ctx_state prev_state;
 
+	trace_async_page_fault_entry(0);
+
 	switch (kvm_read_and_reset_pf_reason()) {
 	default:
 		do_page_fault(regs, error_code, address);
@@ -262,6 +265,8 @@ do_async_page_fault(struct pt_regs *regs, unsigned long error_code, unsigned lon
 		rcu_irq_exit();
 		break;
 	}
+
+	trace_async_page_fault_exit(0);
 }
 NOKPROBE_SYMBOL(do_async_page_fault);
 
diff --git a/arch/x86/kernel/traps.c b/arch/x86/kernel/traps.c
index 4bb0f8447112..6ccc01d74747 100644
--- a/arch/x86/kernel/traps.c
+++ b/arch/x86/kernel/traps.c
@@ -62,6 +62,8 @@
 #include <asm/vm86.h>
 #include <asm/umip.h>
 
+#include <asm/trace/irq_vectors.h>
+
 #ifdef CONFIG_X86_64
 #include <asm/x86_init.h>
 #include <asm/pgalloc.h>
@@ -264,19 +266,22 @@ static void do_error_trap(struct pt_regs *regs, long error_code, char *str,
 	unsigned long trapnr, int signr, int sicode, void __user *addr)
 {
 	RCU_LOCKDEP_WARN(!rcu_is_watching(), "entry code didn't wake RCU");
+	trace_other_vector_entry(trapnr);
 
 	/*
 	 * WARN*()s end up here; fix them up before we call the
 	 * notifier chain.
 	 */
 	if (!user_mode(regs) && fixup_bug(regs, trapnr))
-		return;
+		goto out;
 
 	if (notify_die(DIE_TRAP, str, regs, error_code, trapnr, signr) !=
 			NOTIFY_STOP) {
 		cond_local_irq_enable(regs);
 		do_trap(trapnr, signr, str, regs, error_code, sicode, addr);
 	}
+out:
+	trace_other_vector_exit(trapnr);
 }
 
 #define IP ((void __user *)uprobe_get_trap_addr(regs))
@@ -433,9 +438,10 @@ dotraplinkage void do_bounds(struct pt_regs *regs, long error_code)
 	const struct mpx_bndcsr *bndcsr;
 
 	RCU_LOCKDEP_WARN(!rcu_is_watching(), "entry code didn't wake RCU");
+	trace_other_vector_entry(X86_TRAP_BR);
 	if (notify_die(DIE_TRAP, "bounds", regs, error_code,
 			X86_TRAP_BR, SIGSEGV) == NOTIFY_STOP)
-		return;
+		goto exit;
 	cond_local_irq_enable(regs);
 
 	if (!user_mode(regs))
@@ -501,6 +507,8 @@ dotraplinkage void do_bounds(struct pt_regs *regs, long error_code)
 		die("bounds", regs, error_code);
 	}
 
+exit:
+	trace_other_vector_exit(X86_TRAP_BR);
 	return;
 
 exit_trap:
@@ -512,6 +520,7 @@ dotraplinkage void do_bounds(struct pt_regs *regs, long error_code)
 	 * time..
 	 */
 	do_trap(X86_TRAP_BR, SIGSEGV, "bounds", regs, error_code, 0, NULL);
+	goto exit;
 }
 
 dotraplinkage void
@@ -522,22 +531,23 @@ do_general_protection(struct pt_regs *regs, long error_code)
 
 	RCU_LOCKDEP_WARN(!rcu_is_watching(), "entry code didn't wake RCU");
 	cond_local_irq_enable(regs);
+	trace_other_vector_entry(X86_TRAP_GP);
 
 	if (static_cpu_has(X86_FEATURE_UMIP)) {
 		if (user_mode(regs) && fixup_umip_exception(regs))
-			return;
+			goto out;
 	}
 
 	if (v8086_mode(regs)) {
 		local_irq_enable();
 		handle_vm86_fault((struct kernel_vm86_regs *) regs, error_code);
-		return;
+		goto out;
 	}
 
 	tsk = current;
 	if (!user_mode(regs)) {
 		if (fixup_exception(regs, X86_TRAP_GP, error_code, 0))
-			return;
+			goto out;
 
 		tsk->thread.error_code = error_code;
 		tsk->thread.trap_nr = X86_TRAP_GP;
@@ -549,12 +559,12 @@ do_general_protection(struct pt_regs *regs, long error_code)
 		 */
 		if (!preemptible() && kprobe_running() &&
 		    kprobe_fault_handler(regs, X86_TRAP_GP))
-			return;
+			goto out;
 
 		if (notify_die(DIE_GPF, desc, regs, error_code,
 			       X86_TRAP_GP, SIGSEGV) != NOTIFY_STOP)
 			die(desc, regs, error_code);
-		return;
+		goto out;
 	}
 
 	tsk->thread.error_code = error_code;
@@ -563,6 +573,9 @@ do_general_protection(struct pt_regs *regs, long error_code)
 	show_signal(tsk, SIGSEGV, "", desc, regs, error_code);
 
 	force_sig(SIGSEGV);
+
+out:
+	trace_other_vector_exit(X86_TRAP_GP);
 }
 NOKPROBE_SYMBOL(do_general_protection);
 
@@ -588,6 +601,7 @@ dotraplinkage void notrace do_int3(struct pt_regs *regs, long error_code)
 	 * This means that we can't schedule.  That's okay.
 	 */
 	ist_enter(regs);
+	trace_other_vector_entry(X86_TRAP_BP);
 	RCU_LOCKDEP_WARN(!rcu_is_watching(), "entry code didn't wake RCU");
 #ifdef CONFIG_KGDB_LOW_LEVEL_TRAP
 	if (kgdb_ll_trap(DIE_INT3, "int3", regs, error_code, X86_TRAP_BP,
@@ -609,6 +623,7 @@ dotraplinkage void notrace do_int3(struct pt_regs *regs, long error_code)
 	cond_local_irq_disable(regs);
 
 exit:
+	trace_other_vector_exit(X86_TRAP_BP);
 	ist_exit(regs);
 }
 NOKPROBE_SYMBOL(do_int3);
@@ -714,6 +729,7 @@ dotraplinkage void do_debug(struct pt_regs *regs, long error_code)
 	int si_code;
 
 	ist_enter(regs);
+	trace_other_vector_entry(X86_TRAP_DB);
 
 	get_debugreg(dr6, 6);
 	/*
@@ -806,6 +822,7 @@ dotraplinkage void do_debug(struct pt_regs *regs, long error_code)
 	debug_stack_usage_dec();
 
 exit:
+	trace_other_vector_exit(X86_TRAP_DB);
 	ist_exit(regs);
 }
 NOKPROBE_SYMBOL(do_debug);
@@ -858,14 +875,18 @@ static void math_error(struct pt_regs *regs, int error_code, int trapnr)
 dotraplinkage void do_coprocessor_error(struct pt_regs *regs, long error_code)
 {
 	RCU_LOCKDEP_WARN(!rcu_is_watching(), "entry code didn't wake RCU");
+	trace_other_vector_entry(X86_TRAP_MF);
 	math_error(regs, error_code, X86_TRAP_MF);
+	trace_other_vector_exit(X86_TRAP_MF);
 }
 
 dotraplinkage void
 do_simd_coprocessor_error(struct pt_regs *regs, long error_code)
 {
 	RCU_LOCKDEP_WARN(!rcu_is_watching(), "entry code didn't wake RCU");
+	trace_other_vector_entry(X86_TRAP_XF);
 	math_error(regs, error_code, X86_TRAP_XF);
+	trace_other_vector_exit(X86_TRAP_XF);
 }
 
 dotraplinkage void
@@ -881,6 +902,7 @@ do_device_not_available(struct pt_regs *regs, long error_code)
 
 	RCU_LOCKDEP_WARN(!rcu_is_watching(), "entry code didn't wake RCU");
 
+	trace_other_vector_entry(X86_TRAP_NM);
 #ifdef CONFIG_MATH_EMULATION
 	if (!boot_cpu_has(X86_FEATURE_FPU) && (cr0 & X86_CR0_EM)) {
 		struct math_emu_info info = { };
@@ -889,7 +911,7 @@ do_device_not_available(struct pt_regs *regs, long error_code)
 
 		info.regs = regs;
 		math_emulate(&info);
-		return;
+		goto out;
 	}
 #endif
 
@@ -905,6 +927,8 @@ do_device_not_available(struct pt_regs *regs, long error_code)
 		 */
 		die("unexpected #NM exception", regs, error_code);
 	}
+out: __maybe_unused;
+	trace_other_vector_exit(X86_TRAP_NM);
 }
 NOKPROBE_SYMBOL(do_device_not_available);
 
-- 
2.24.1


^ permalink raw reply related	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2020-03-13 12:01 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-10-22  1:23 [PATCH] x86: Add trace points to (nearly) all vectors Andi Kleen
2019-10-24  8:38 ` kbuild test robot
2020-03-12 23:19 Andi Kleen
2020-03-12 23:39 ` Andy Lutomirski
2020-03-13 11:51   ` Andi Kleen

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).