Commit f8ef15d6b9d8e38729cd740a43919adf88468119

Authored by Linus Torvalds

Merge branch 'perf-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip

Pull perf fixes from Ingo Molnar.

* 'perf-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip:
  perf/x86: Add Intel IvyBridge event scheduling constraints
  ftrace: Call ftrace cleanup module notifier after all other notifiers
  tracing/syscalls: Allow archs to ignore tracing compat syscalls

Showing 5 changed files Side-by-side Diff

arch/x86/include/asm/ftrace.h
... ... @@ -72,5 +72,29 @@
72 72 #endif /* __ASSEMBLY__ */
73 73 #endif /* CONFIG_FUNCTION_TRACER */
74 74  
  75 +
  76 +#if !defined(__ASSEMBLY__) && !defined(COMPILE_OFFSETS)
  77 +
  78 +#if defined(CONFIG_FTRACE_SYSCALLS) && defined(CONFIG_IA32_EMULATION)
  79 +#include <asm/compat.h>
  80 +
  81 +/*
  82 + * Because ia32 syscalls do not map to x86_64 syscall numbers
  83 + * this screws up the trace output when tracing a ia32 task.
  84 + * Instead of reporting bogus syscalls, just do not trace them.
  85 + *
  86 + * If the user realy wants these, then they should use the
  87 + * raw syscall tracepoints with filtering.
  88 + */
  89 +#define ARCH_TRACE_IGNORE_COMPAT_SYSCALLS 1
  90 +static inline bool arch_trace_is_compat_syscall(struct pt_regs *regs)
  91 +{
  92 + if (is_compat_task())
  93 + return true;
  94 + return false;
  95 +}
  96 +#endif /* CONFIG_FTRACE_SYSCALLS && CONFIG_IA32_EMULATION */
  97 +#endif /* !__ASSEMBLY__ && !COMPILE_OFFSETS */
  98 +
75 99 #endif /* _ASM_X86_FTRACE_H */
arch/x86/include/asm/thread_info.h
... ... @@ -20,7 +20,6 @@
20 20 struct task_struct;
21 21 struct exec_domain;
22 22 #include <asm/processor.h>
23   -#include <asm/ftrace.h>
24 23 #include <linux/atomic.h>
25 24  
26 25 struct thread_info {
arch/x86/kernel/cpu/perf_event_intel.c
... ... @@ -107,6 +107,27 @@
107 107 EVENT_CONSTRAINT_END
108 108 };
109 109  
  110 +static struct event_constraint intel_ivb_event_constraints[] __read_mostly =
  111 +{
  112 + FIXED_EVENT_CONSTRAINT(0x00c0, 0), /* INST_RETIRED.ANY */
  113 + FIXED_EVENT_CONSTRAINT(0x003c, 1), /* CPU_CLK_UNHALTED.CORE */
  114 + FIXED_EVENT_CONSTRAINT(0x0300, 2), /* CPU_CLK_UNHALTED.REF */
  115 + INTEL_UEVENT_CONSTRAINT(0x0148, 0x4), /* L1D_PEND_MISS.PENDING */
  116 + INTEL_UEVENT_CONSTRAINT(0x0279, 0xf), /* IDQ.EMTPY */
  117 + INTEL_UEVENT_CONSTRAINT(0x019c, 0xf), /* IDQ_UOPS_NOT_DELIVERED.CORE */
  118 + INTEL_UEVENT_CONSTRAINT(0x04a3, 0xf), /* CYCLE_ACTIVITY.CYCLES_NO_EXECUTE */
  119 + INTEL_UEVENT_CONSTRAINT(0x05a3, 0xf), /* CYCLE_ACTIVITY.STALLS_L2_PENDING */
  120 + INTEL_UEVENT_CONSTRAINT(0x06a3, 0xf), /* CYCLE_ACTIVITY.STALLS_LDM_PENDING */
  121 + INTEL_UEVENT_CONSTRAINT(0x08a3, 0x4), /* CYCLE_ACTIVITY.CYCLES_L1D_PENDING */
  122 + INTEL_UEVENT_CONSTRAINT(0x0ca3, 0x4), /* CYCLE_ACTIVITY.STALLS_L1D_PENDING */
  123 + INTEL_UEVENT_CONSTRAINT(0x01c0, 0x2), /* INST_RETIRED.PREC_DIST */
  124 + INTEL_EVENT_CONSTRAINT(0xd0, 0xf), /* MEM_UOPS_RETIRED.* */
  125 + INTEL_EVENT_CONSTRAINT(0xd1, 0xf), /* MEM_LOAD_UOPS_RETIRED.* */
  126 + INTEL_EVENT_CONSTRAINT(0xd2, 0xf), /* MEM_LOAD_UOPS_LLC_HIT_RETIRED.* */
  127 + INTEL_EVENT_CONSTRAINT(0xd3, 0xf), /* MEM_LOAD_UOPS_LLC_MISS_RETIRED.* */
  128 + EVENT_CONSTRAINT_END
  129 +};
  130 +
110 131 static struct extra_reg intel_westmere_extra_regs[] __read_mostly =
111 132 {
112 133 INTEL_EVENT_EXTRA_REG(0xb7, MSR_OFFCORE_RSP_0, 0xffff, RSP_0),
... ... @@ -2095,7 +2116,7 @@
2095 2116  
2096 2117 intel_pmu_lbr_init_snb();
2097 2118  
2098   - x86_pmu.event_constraints = intel_snb_event_constraints;
  2119 + x86_pmu.event_constraints = intel_ivb_event_constraints;
2099 2120 x86_pmu.pebs_constraints = intel_ivb_pebs_event_constraints;
2100 2121 x86_pmu.pebs_aliases = intel_pebs_aliases_snb;
2101 2122 x86_pmu.extra_regs = intel_snb_extra_regs;
kernel/trace/ftrace.c
... ... @@ -3996,37 +3996,51 @@
3996 3996 ftrace_process_locs(mod, start, end);
3997 3997 }
3998 3998  
3999   -static int ftrace_module_notify(struct notifier_block *self,
4000   - unsigned long val, void *data)
  3999 +static int ftrace_module_notify_enter(struct notifier_block *self,
  4000 + unsigned long val, void *data)
4001 4001 {
4002 4002 struct module *mod = data;
4003 4003  
4004   - switch (val) {
4005   - case MODULE_STATE_COMING:
  4004 + if (val == MODULE_STATE_COMING)
4006 4005 ftrace_init_module(mod, mod->ftrace_callsites,
4007 4006 mod->ftrace_callsites +
4008 4007 mod->num_ftrace_callsites);
4009   - break;
4010   - case MODULE_STATE_GOING:
  4008 + return 0;
  4009 +}
  4010 +
  4011 +static int ftrace_module_notify_exit(struct notifier_block *self,
  4012 + unsigned long val, void *data)
  4013 +{
  4014 + struct module *mod = data;
  4015 +
  4016 + if (val == MODULE_STATE_GOING)
4011 4017 ftrace_release_mod(mod);
4012   - break;
4013   - }
4014 4018  
4015 4019 return 0;
4016 4020 }
4017 4021 #else
4018   -static int ftrace_module_notify(struct notifier_block *self,
4019   - unsigned long val, void *data)
  4022 +static int ftrace_module_notify_enter(struct notifier_block *self,
  4023 + unsigned long val, void *data)
4020 4024 {
4021 4025 return 0;
4022 4026 }
  4027 +static int ftrace_module_notify_exit(struct notifier_block *self,
  4028 + unsigned long val, void *data)
  4029 +{
  4030 + return 0;
  4031 +}
4023 4032 #endif /* CONFIG_MODULES */
4024 4033  
4025   -struct notifier_block ftrace_module_nb = {
4026   - .notifier_call = ftrace_module_notify,
  4034 +struct notifier_block ftrace_module_enter_nb = {
  4035 + .notifier_call = ftrace_module_notify_enter,
4027 4036 .priority = INT_MAX, /* Run before anything that can use kprobes */
4028 4037 };
4029 4038  
  4039 +struct notifier_block ftrace_module_exit_nb = {
  4040 + .notifier_call = ftrace_module_notify_exit,
  4041 + .priority = INT_MIN, /* Run after anything that can remove kprobes */
  4042 +};
  4043 +
4030 4044 extern unsigned long __start_mcount_loc[];
4031 4045 extern unsigned long __stop_mcount_loc[];
4032 4046  
4033 4047  
... ... @@ -4058,9 +4072,13 @@
4058 4072 __start_mcount_loc,
4059 4073 __stop_mcount_loc);
4060 4074  
4061   - ret = register_module_notifier(&ftrace_module_nb);
  4075 + ret = register_module_notifier(&ftrace_module_enter_nb);
4062 4076 if (ret)
4063   - pr_warning("Failed to register trace ftrace module notifier\n");
  4077 + pr_warning("Failed to register trace ftrace module enter notifier\n");
  4078 +
  4079 + ret = register_module_notifier(&ftrace_module_exit_nb);
  4080 + if (ret)
  4081 + pr_warning("Failed to register trace ftrace module exit notifier\n");
4064 4082  
4065 4083 set_ftrace_early_filters();
4066 4084  
kernel/trace/trace_syscalls.c
1 1 #include <trace/syscall.h>
2 2 #include <trace/events/syscalls.h>
  3 +#include <linux/syscalls.h>
3 4 #include <linux/slab.h>
4 5 #include <linux/kernel.h>
5 6 #include <linux/module.h> /* for MODULE_NAME_LEN via KSYM_SYMBOL_LEN */
... ... @@ -47,6 +48,38 @@
47 48 }
48 49 #endif
49 50  
  51 +#ifdef ARCH_TRACE_IGNORE_COMPAT_SYSCALLS
  52 +/*
  53 + * Some architectures that allow for 32bit applications
  54 + * to run on a 64bit kernel, do not map the syscalls for
  55 + * the 32bit tasks the same as they do for 64bit tasks.
  56 + *
  57 + * *cough*x86*cough*
  58 + *
  59 + * In such a case, instead of reporting the wrong syscalls,
  60 + * simply ignore them.
  61 + *
  62 + * For an arch to ignore the compat syscalls it needs to
  63 + * define ARCH_TRACE_IGNORE_COMPAT_SYSCALLS as well as
  64 + * define the function arch_trace_is_compat_syscall() to let
  65 + * the tracing system know that it should ignore it.
  66 + */
  67 +static int
  68 +trace_get_syscall_nr(struct task_struct *task, struct pt_regs *regs)
  69 +{
  70 + if (unlikely(arch_trace_is_compat_syscall(regs)))
  71 + return -1;
  72 +
  73 + return syscall_get_nr(task, regs);
  74 +}
  75 +#else
  76 +static inline int
  77 +trace_get_syscall_nr(struct task_struct *task, struct pt_regs *regs)
  78 +{
  79 + return syscall_get_nr(task, regs);
  80 +}
  81 +#endif /* ARCH_TRACE_IGNORE_COMPAT_SYSCALLS */
  82 +
50 83 static __init struct syscall_metadata *
51 84 find_syscall_meta(unsigned long syscall)
52 85 {
53 86  
54 87  
... ... @@ -276,10 +309,10 @@
276 309 struct syscall_metadata *sys_data;
277 310 struct ring_buffer_event *event;
278 311 struct ring_buffer *buffer;
279   - int size;
280 312 int syscall_nr;
  313 + int size;
281 314  
282   - syscall_nr = syscall_get_nr(current, regs);
  315 + syscall_nr = trace_get_syscall_nr(current, regs);
283 316 if (syscall_nr < 0)
284 317 return;
285 318 if (!test_bit(syscall_nr, enabled_enter_syscalls))
... ... @@ -313,7 +346,7 @@
313 346 struct ring_buffer *buffer;
314 347 int syscall_nr;
315 348  
316   - syscall_nr = syscall_get_nr(current, regs);
  349 + syscall_nr = trace_get_syscall_nr(current, regs);
317 350 if (syscall_nr < 0)
318 351 return;
319 352 if (!test_bit(syscall_nr, enabled_exit_syscalls))
... ... @@ -502,7 +535,7 @@
502 535 int rctx;
503 536 int size;
504 537  
505   - syscall_nr = syscall_get_nr(current, regs);
  538 + syscall_nr = trace_get_syscall_nr(current, regs);
506 539 if (syscall_nr < 0)
507 540 return;
508 541 if (!test_bit(syscall_nr, enabled_perf_enter_syscalls))
... ... @@ -578,7 +611,7 @@
578 611 int rctx;
579 612 int size;
580 613  
581   - syscall_nr = syscall_get_nr(current, regs);
  614 + syscall_nr = trace_get_syscall_nr(current, regs);
582 615 if (syscall_nr < 0)
583 616 return;
584 617 if (!test_bit(syscall_nr, enabled_perf_exit_syscalls))