Commit 5804b110 authored by Ingo Molnar's avatar Ingo Molnar

Merge tag 'perf-core-for-mingo-4.19-20180815' of...

Merge tag 'perf-core-for-mingo-4.19-20180815' of git://git.kernel.org/pub/scm/linux/kernel/git/acme/linux into perf/urgent

Pull perf/core improvements and fixes from Arnaldo Carvalho de Melo:

kernel:

- kallsyms, x86: Export addresses of PTI entry trampolines (Alexander Shishkin)

- kallsyms: Simplify update_iter_mod() (Adrian Hunter)

- x86: Add entry trampolines to kcore (Adrian Hunter)

Hardware tracing:

- Fix auxtrace queue resize (Adrian Hunter)

Arch specific:

- Fix uninitialized ARM SPE record error variable (Kim Phillips)

- Fix trace event post-processing in powerpc (Sandipan Das)

Build:

- Fix check-headers.sh AND list path of execution (Alexander Kapshuk)

- Remove -mcet and -fcf-protection when building the python binding
  with older clang versions (Arnaldo Carvalho de Melo)

- Make check-headers.sh check based on kernel dir (Jiri Olsa)

- Move syscall_64.tbl check into check-headers.sh (Jiri Olsa)

Infrastructure:

- Check for null when copying nsinfo.  (Benno Evers)

Libraries:

- Rename libtraceevent prefixes, prep work for making it a shared
  library generaly available (Tzvetomir Stoyanov (VMware))
Signed-off-by: default avatarArnaldo Carvalho de Melo <acme@redhat.com>
parents 13e091b6 6855dc41
......@@ -2,6 +2,8 @@
#include <linux/spinlock.h>
#include <linux/percpu.h>
#include <linux/kallsyms.h>
#include <linux/kcore.h>
#include <asm/cpu_entry_area.h>
#include <asm/pgtable.h>
......@@ -13,6 +15,7 @@ static DEFINE_PER_CPU_PAGE_ALIGNED(struct entry_stack_page, entry_stack_storage)
#ifdef CONFIG_X86_64
static DEFINE_PER_CPU_PAGE_ALIGNED(char, exception_stacks
[(N_EXCEPTION_STACKS - 1) * EXCEPTION_STKSZ + DEBUG_STKSZ]);
static DEFINE_PER_CPU(struct kcore_list, kcore_entry_trampoline);
#endif
struct cpu_entry_area *get_cpu_entry_area(int cpu)
......@@ -146,10 +149,40 @@ static void __init setup_cpu_entry_area(int cpu)
cea_set_pte(&get_cpu_entry_area(cpu)->entry_trampoline,
__pa_symbol(_entry_trampoline), PAGE_KERNEL_RX);
/*
* The cpu_entry_area alias addresses are not in the kernel binary
* so they do not show up in /proc/kcore normally. This adds entries
* for them manually.
*/
kclist_add_remap(&per_cpu(kcore_entry_trampoline, cpu),
_entry_trampoline,
&get_cpu_entry_area(cpu)->entry_trampoline, PAGE_SIZE);
#endif
percpu_setup_debug_store(cpu);
}
#ifdef CONFIG_X86_64
int arch_get_kallsym(unsigned int symnum, unsigned long *value, char *type,
char *name)
{
unsigned int cpu, ncpu = 0;
if (symnum >= num_possible_cpus())
return -EINVAL;
for_each_possible_cpu(cpu) {
if (ncpu++ >= symnum)
break;
}
*value = (unsigned long)&get_cpu_entry_area(cpu)->entry_trampoline;
*type = 't';
strlcpy(name, "__entry_SYSCALL_64_trampoline", KSYM_NAME_LEN);
return 0;
}
#endif
static __init void setup_cpu_entry_area_ptes(void)
{
#ifdef CONFIG_X86_32
......
......@@ -383,8 +383,11 @@ static void elf_kcore_store_hdr(char *bufp, int nphdr, int dataoff)
phdr->p_type = PT_LOAD;
phdr->p_flags = PF_R|PF_W|PF_X;
phdr->p_offset = kc_vaddr_to_offset(m->addr) + dataoff;
if (m->type == KCORE_REMAP)
phdr->p_vaddr = (size_t)m->vaddr;
else
phdr->p_vaddr = (size_t)m->addr;
if (m->type == KCORE_RAM || m->type == KCORE_TEXT)
if (m->type == KCORE_RAM || m->type == KCORE_TEXT || m->type == KCORE_REMAP)
phdr->p_paddr = __pa(m->addr);
else
phdr->p_paddr = (elf_addr_t)-1;
......
......@@ -12,11 +12,13 @@ enum kcore_type {
KCORE_VMEMMAP,
KCORE_USER,
KCORE_OTHER,
KCORE_REMAP,
};
struct kcore_list {
struct list_head list;
unsigned long addr;
unsigned long vaddr;
size_t size;
int type;
};
......@@ -36,11 +38,22 @@ struct vmcoredd_node {
#ifdef CONFIG_PROC_KCORE
extern void kclist_add(struct kcore_list *, void *, size_t, int type);
static inline
void kclist_add_remap(struct kcore_list *m, void *addr, void *vaddr, size_t sz)
{
m->vaddr = (unsigned long)vaddr;
kclist_add(m, addr, sz, KCORE_REMAP);
}
#else
static inline
void kclist_add(struct kcore_list *new, void *addr, size_t size, int type)
{
}
static inline
void kclist_add_remap(struct kcore_list *m, void *addr, void *vaddr, size_t sz)
{
}
#endif
#endif /* _LINUX_KCORE_H */
......@@ -432,6 +432,7 @@ int sprint_backtrace(char *buffer, unsigned long address)
/* To avoid using get_symbol_offset for every symbol, we carry prefix along. */
struct kallsym_iter {
loff_t pos;
loff_t pos_arch_end;
loff_t pos_mod_end;
loff_t pos_ftrace_mod_end;
unsigned long value;
......@@ -443,9 +444,29 @@ struct kallsym_iter {
int show_value;
};
int __weak arch_get_kallsym(unsigned int symnum, unsigned long *value,
char *type, char *name)
{
return -EINVAL;
}
static int get_ksymbol_arch(struct kallsym_iter *iter)
{
int ret = arch_get_kallsym(iter->pos - kallsyms_num_syms,
&iter->value, &iter->type,
iter->name);
if (ret < 0) {
iter->pos_arch_end = iter->pos;
return 0;
}
return 1;
}
static int get_ksymbol_mod(struct kallsym_iter *iter)
{
int ret = module_get_kallsym(iter->pos - kallsyms_num_syms,
int ret = module_get_kallsym(iter->pos - iter->pos_arch_end,
&iter->value, &iter->type,
iter->name, iter->module_name,
&iter->exported);
......@@ -501,32 +522,34 @@ static void reset_iter(struct kallsym_iter *iter, loff_t new_pos)
iter->nameoff = get_symbol_offset(new_pos);
iter->pos = new_pos;
if (new_pos == 0) {
iter->pos_arch_end = 0;
iter->pos_mod_end = 0;
iter->pos_ftrace_mod_end = 0;
}
}
/*
* The end position (last + 1) of each additional kallsyms section is recorded
* in iter->pos_..._end as each section is added, and so can be used to
* determine which get_ksymbol_...() function to call next.
*/
static int update_iter_mod(struct kallsym_iter *iter, loff_t pos)
{
iter->pos = pos;
if (iter->pos_ftrace_mod_end > 0 &&
iter->pos_ftrace_mod_end < iter->pos)
return get_ksymbol_bpf(iter);
if (iter->pos_mod_end > 0 &&
iter->pos_mod_end < iter->pos) {
if (!get_ksymbol_ftrace_mod(iter))
return get_ksymbol_bpf(iter);
if ((!iter->pos_arch_end || iter->pos_arch_end > pos) &&
get_ksymbol_arch(iter))
return 1;
}
if (!get_ksymbol_mod(iter)) {
if (!get_ksymbol_ftrace_mod(iter))
return get_ksymbol_bpf(iter);
}
if ((!iter->pos_mod_end || iter->pos_mod_end > pos) &&
get_ksymbol_mod(iter))
return 1;
if ((!iter->pos_ftrace_mod_end || iter->pos_ftrace_mod_end > pos) &&
get_ksymbol_ftrace_mod(iter))
return 1;
return get_ksymbol_bpf(iter);
}
/* Returns false if pos at or past end of file. */
......
......@@ -129,12 +129,12 @@ $(OUTPUT)liblockdep.a: $(LIB_IN)
tags: force
$(RM) tags
find . -name '*.[ch]' | xargs ctags --extra=+f --c-kinds=+px \
--regex-c++='/_PE\(([^,)]*).*/PEVENT_ERRNO__\1/'
--regex-c++='/_PE\(([^,)]*).*/TEP_ERRNO__\1/'
TAGS: force
$(RM) TAGS
find . -name '*.[ch]' | xargs etags \
--regex='/_PE(\([^,)]*\).*/PEVENT_ERRNO__\1/'
--regex='/_PE(\([^,)]*\).*/TEP_ERRNO__\1/'
define do_install
$(print_install) \
......
......@@ -233,12 +233,12 @@ endef
tags: force
$(RM) tags
find . -name '*.[ch]' | xargs ctags --extra=+f --c-kinds=+px \
--regex-c++='/_PE\(([^,)]*).*/PEVENT_ERRNO__\1/'
--regex-c++='/_PE\(([^,)]*).*/TEP_ERRNO__\1/'
TAGS: force
$(RM) TAGS
find . -name '*.[ch]' | xargs etags \
--regex='/_PE(\([^,)]*\).*/PEVENT_ERRNO__\1/'
--regex='/_PE(\([^,)]*\).*/TEP_ERRNO__\1/'
define do_install_mkdir
if [ ! -d '$(DESTDIR_SQ)$1' ]; then \
......
This diff is collapsed.
This diff is collapsed.
......@@ -34,7 +34,7 @@
static struct registered_plugin_options {
struct registered_plugin_options *next;
struct pevent_plugin_option *options;
struct tep_plugin_option *options;
} *registered_options;
static struct trace_plugin_options {
......@@ -58,7 +58,7 @@ static void lower_case(char *str)
*str = tolower(*str);
}
static int update_option_value(struct pevent_plugin_option *op, const char *val)
static int update_option_value(struct tep_plugin_option *op, const char *val)
{
char *op_val;
......@@ -97,7 +97,7 @@ static int update_option_value(struct pevent_plugin_option *op, const char *val)
}
/**
* traceevent_plugin_list_options - get list of plugin options
* tep_plugin_list_options - get list of plugin options
*
* Returns an array of char strings that list the currently registered
* plugin options in the format of <plugin>:<option>. This list can be
......@@ -106,12 +106,12 @@ static int update_option_value(struct pevent_plugin_option *op, const char *val)
* Returns NULL if there's no options registered. On error it returns
* INVALID_PLUGIN_LIST_OPTION
*
* Must be freed with traceevent_plugin_free_options_list().
* Must be freed with tep_plugin_free_options_list().
*/
char **traceevent_plugin_list_options(void)
char **tep_plugin_list_options(void)
{
struct registered_plugin_options *reg;
struct pevent_plugin_option *op;
struct tep_plugin_option *op;
char **list = NULL;
char *name;
int count = 0;
......@@ -146,7 +146,7 @@ char **traceevent_plugin_list_options(void)
return INVALID_PLUGIN_LIST_OPTION;
}
void traceevent_plugin_free_options_list(char **list)
void tep_plugin_free_options_list(char **list)
{
int i;
......@@ -163,7 +163,7 @@ void traceevent_plugin_free_options_list(char **list)
}
static int
update_option(const char *file, struct pevent_plugin_option *option)
update_option(const char *file, struct tep_plugin_option *option)
{
struct trace_plugin_options *op;
char *plugin;
......@@ -215,14 +215,14 @@ update_option(const char *file, struct pevent_plugin_option *option)
}
/**
* traceevent_plugin_add_options - Add a set of options by a plugin
* tep_plugin_add_options - Add a set of options by a plugin
* @name: The name of the plugin adding the options
* @options: The set of options being loaded
*
* Sets the options with the values that have been added by user.
*/
int traceevent_plugin_add_options(const char *name,
struct pevent_plugin_option *options)
int tep_plugin_add_options(const char *name,
struct tep_plugin_option *options)
{
struct registered_plugin_options *reg;
......@@ -241,10 +241,10 @@ int traceevent_plugin_add_options(const char *name,
}
/**
* traceevent_plugin_remove_options - remove plugin options that were registered
* @options: Options to removed that were registered with traceevent_plugin_add_options
* tep_plugin_remove_options - remove plugin options that were registered
* @options: Options to removed that were registered with tep_plugin_add_options
*/
void traceevent_plugin_remove_options(struct pevent_plugin_option *options)
void tep_plugin_remove_options(struct tep_plugin_option *options)
{
struct registered_plugin_options **last;
struct registered_plugin_options *reg;
......@@ -260,17 +260,17 @@ void traceevent_plugin_remove_options(struct pevent_plugin_option *options)
}
/**
* traceevent_print_plugins - print out the list of plugins loaded
* tep_print_plugins - print out the list of plugins loaded
* @s: the trace_seq descripter to write to
* @prefix: The prefix string to add before listing the option name
* @suffix: The suffix string ot append after the option name
* @list: The list of plugins (usually returned by traceevent_load_plugins()
* @list: The list of plugins (usually returned by tep_load_plugins()
*
* Writes to the trace_seq @s the list of plugins (files) that is
* returned by traceevent_load_plugins(). Use @prefix and @suffix for formating:
* returned by tep_load_plugins(). Use @prefix and @suffix for formating:
* @prefix = " ", @suffix = "\n".
*/
void traceevent_print_plugins(struct trace_seq *s,
void tep_print_plugins(struct trace_seq *s,
const char *prefix, const char *suffix,
const struct plugin_list *list)
{
......@@ -281,11 +281,11 @@ void traceevent_print_plugins(struct trace_seq *s,
}
static void
load_plugin(struct pevent *pevent, const char *path,
load_plugin(struct tep_handle *pevent, const char *path,
const char *file, void *data)
{
struct plugin_list **plugin_list = data;
pevent_plugin_load_func func;
tep_plugin_load_func func;
struct plugin_list *list;
const char *alias;
char *plugin;
......@@ -305,14 +305,14 @@ load_plugin(struct pevent *pevent, const char *path,
goto out_free;
}
alias = dlsym(handle, PEVENT_PLUGIN_ALIAS_NAME);
alias = dlsym(handle, TEP_PLUGIN_ALIAS_NAME);
if (!alias)
alias = file;
func = dlsym(handle, PEVENT_PLUGIN_LOADER_NAME);
func = dlsym(handle, TEP_PLUGIN_LOADER_NAME);
if (!func) {
warning("could not find func '%s' in plugin '%s'\n%s\n",
PEVENT_PLUGIN_LOADER_NAME, plugin, dlerror());
TEP_PLUGIN_LOADER_NAME, plugin, dlerror());
goto out_free;
}
......@@ -336,9 +336,9 @@ load_plugin(struct pevent *pevent, const char *path,
}
static void
load_plugins_dir(struct pevent *pevent, const char *suffix,
load_plugins_dir(struct tep_handle *pevent, const char *suffix,
const char *path,
void (*load_plugin)(struct pevent *pevent,
void (*load_plugin)(struct tep_handle *pevent,
const char *path,
const char *name,
void *data),
......@@ -378,8 +378,8 @@ load_plugins_dir(struct pevent *pevent, const char *suffix,
}
static void
load_plugins(struct pevent *pevent, const char *suffix,
void (*load_plugin)(struct pevent *pevent,
load_plugins(struct tep_handle *pevent, const char *suffix,
void (*load_plugin)(struct tep_handle *pevent,
const char *path,
const char *name,
void *data),
......@@ -390,7 +390,7 @@ load_plugins(struct pevent *pevent, const char *suffix,
char *envdir;
int ret;
if (pevent->flags & PEVENT_DISABLE_PLUGINS)
if (pevent->flags & TEP_DISABLE_PLUGINS)
return;
/*
......@@ -398,7 +398,7 @@ load_plugins(struct pevent *pevent, const char *suffix,
* check that first.
*/
#ifdef PLUGIN_DIR
if (!(pevent->flags & PEVENT_DISABLE_SYS_PLUGINS))
if (!(pevent->flags & TEP_DISABLE_SYS_PLUGINS))
load_plugins_dir(pevent, suffix, PLUGIN_DIR,
load_plugin, data);
#endif
......@@ -431,7 +431,7 @@ load_plugins(struct pevent *pevent, const char *suffix,
}
struct plugin_list*
traceevent_load_plugins(struct pevent *pevent)
tep_load_plugins(struct tep_handle *pevent)
{
struct plugin_list *list = NULL;
......@@ -440,15 +440,15 @@ traceevent_load_plugins(struct pevent *pevent)
}
void
traceevent_unload_plugins(struct plugin_list *plugin_list, struct pevent *pevent)
tep_unload_plugins(struct plugin_list *plugin_list, struct tep_handle *pevent)
{
pevent_plugin_unload_func func;
tep_plugin_unload_func func;
struct plugin_list *list;
while (plugin_list) {
list = plugin_list;
plugin_list = list->next;
func = dlsym(list->handle, PEVENT_PLUGIN_UNLOADER_NAME);
func = dlsym(list->handle, TEP_PLUGIN_UNLOADER_NAME);
if (func)
func(pevent);
dlclose(list->handle);
......
This diff is collapsed.
......@@ -25,19 +25,19 @@ process___le16_to_cpup(struct trace_seq *s, unsigned long long *args)
return val ? (long long) le16toh(*val) : 0;
}
int PEVENT_PLUGIN_LOADER(struct pevent *pevent)
int TEP_PLUGIN_LOADER(struct tep_handle *pevent)
{
pevent_register_print_function(pevent,
tep_register_print_function(pevent,
process___le16_to_cpup,
PEVENT_FUNC_ARG_INT,
TEP_FUNC_ARG_INT,
"__le16_to_cpup",
PEVENT_FUNC_ARG_PTR,
PEVENT_FUNC_ARG_VOID);
TEP_FUNC_ARG_PTR,
TEP_FUNC_ARG_VOID);
return 0;
}
void PEVENT_PLUGIN_UNLOADER(struct pevent *pevent)
void TEP_PLUGIN_UNLOADER(struct tep_handle *pevent)
{
pevent_unregister_print_function(pevent, process___le16_to_cpup,
tep_unregister_print_function(pevent, process___le16_to_cpup,
"__le16_to_cpup");
}
......@@ -33,7 +33,7 @@ static int cpus = -1;
#define STK_BLK 10
struct pevent_plugin_option plugin_options[] =
struct tep_plugin_option plugin_options[] =
{
{
.name = "parent",
......@@ -53,8 +53,8 @@ struct pevent_plugin_option plugin_options[] =
}
};
static struct pevent_plugin_option *ftrace_parent = &plugin_options[0];
static struct pevent_plugin_option *ftrace_indent = &plugin_options[1];
static struct tep_plugin_option *ftrace_parent = &plugin_options[0];
static struct tep_plugin_option *ftrace_indent = &plugin_options[1];
static void add_child(struct func_stack *stack, const char *child, int pos)
{
......@@ -122,25 +122,25 @@ static int add_and_get_index(const char *parent, const char *child, int cpu)
return 0;
}
static int function_handler(struct trace_seq *s, struct pevent_record *record,
static int function_handler(struct trace_seq *s, struct tep_record *record,
struct event_format *event, void *context)
{
struct pevent *pevent = event->pevent;
struct tep_handle *pevent = event->pevent;
unsigned long long function;
unsigned long long pfunction;
const char *func;
const char *parent;
int index = 0;
if (pevent_get_field_val(s, event, "ip", record, &function, 1))
if (tep_get_field_val(s, event, "ip", record, &function, 1))
return trace_seq_putc(s, '!');
func = pevent_find_function(pevent, function);
func = tep_find_function(pevent, function);
if (pevent_get_field_val(s, event, "parent_ip", record, &pfunction, 1))
if (tep_get_field_val(s, event, "parent_ip", record, &pfunction, 1))
return trace_seq_putc(s, '!');
parent = pevent_find_function(pevent, pfunction);
parent = tep_find_function(pevent, pfunction);
if (parent && ftrace_indent->set)
index = add_and_get_index(parent, func, record->cpu);
......@@ -163,21 +163,21 @@ static int function_handler(struct trace_seq *s, struct pevent_record *record,
return 0;
}
int PEVENT_PLUGIN_LOADER(struct pevent *pevent)
int TEP_PLUGIN_LOADER(struct tep_handle *pevent)
{
pevent_register_event_handler(pevent, -1, "ftrace", "function",
tep_register_event_handler(pevent, -1, "ftrace", "function",
function_handler, NULL);
traceevent_plugin_add_options("ftrace", plugin_options);
tep_plugin_add_options("ftrace", plugin_options);
return 0;
}
void PEVENT_PLUGIN_UNLOADER(struct pevent *pevent)
void TEP_PLUGIN_UNLOADER(struct tep_handle *pevent)
{
int i, x;
pevent_unregister_event_handler(pevent, -1, "ftrace", "function",
tep_unregister_event_handler(pevent, -1, "ftrace", "function",
function_handler, NULL);
for (i = 0; i <= cpus; i++) {
......@@ -186,7 +186,7 @@ void PEVENT_PLUGIN_UNLOADER(struct pevent *pevent)
free(fstack[i].stack);
}
traceevent_plugin_remove_options(plugin_options);
tep_plugin_remove_options(plugin_options);
free(fstack);
fstack = NULL;
......
......@@ -25,64 +25,64 @@
#include "event-parse.h"
static int timer_expire_handler(struct trace_seq *s,
struct pevent_record *record,
struct tep_record *record,
struct event_format *event, void *context)
{
trace_seq_printf(s, "hrtimer=");
if (pevent_print_num_field(s, "0x%llx", event, "timer",
if (tep_print_num_field(s, "0x%llx", event, "timer",
record, 0) == -1)
pevent_print_num_field(s, "0x%llx", event, "hrtimer",
tep_print_num_field(s, "0x%llx", event, "hrtimer",
record, 1);
trace_seq_printf(s, " now=");
pevent_print_num_field(s, "%llu", event, "now", record, 1);
tep_print_num_field(s, "%llu", event, "now", record, 1);
pevent_print_func_field(s, " function=%s", event, "function",
tep_print_func_field(s, " function=%s", event, "function",
record, 0);
return 0;
}
static int timer_start_handler(struct trace_seq *s,
struct pevent_record *record,
struct tep_record *record,
struct event_format *event, void *context)
{
trace_seq_printf(s, "hrtimer=");
if (pevent_print_num_field(s, "0x%llx", event, "timer",
if (tep_print_num_field(s, "0x%llx", event, "timer",
record, 0) == -1)
pevent_print_num_field(s, "0x%llx", event, "hrtimer",
tep_print_num_field(s, "0x%llx", event, "hrtimer",
record, 1);
pevent_print_func_field(s, " function=%s", event, "function",
tep_print_func_field(s, " function=%s", event, "function",
record, 0);
trace_seq_printf(s, " expires=");
pevent_print_num_field(s, "%llu", event, "expires", record, 1);
tep_print_num_field(s, "%llu", event, "expires", record, 1);
trace_seq_printf(s, " softexpires=");
pevent_print_num_field(s, "%llu", event, "softexpires", record, 1);
tep_print_num_field(s, "%llu", event, "softexpires", record, 1);
return 0;
}
int PEVENT_PLUGIN_LOADER(struct pevent *pevent)
int TEP_PLUGIN_LOADER(struct tep_handle *pevent)
{
pevent_register_event_handler(pevent, -1,
tep_register_event_handler(pevent, -1,
"timer", "hrtimer_expire_entry",
timer_expire_handler, NULL);
pevent_register_event_handler(pevent, -1, "timer", "hrtimer_start",
tep_register_event_handler(pevent, -1, "timer", "hrtimer_start",
timer_start_handler, NULL);
return 0;
}
void PEVENT_PLUGIN_UNLOADER(struct pevent *pevent)
void TEP_PLUGIN_UNLOADER(struct tep_handle *pevent)
{
pevent_unregister_event_handler(pevent, -1,
tep_unregister_event_handler(pevent, -1,
"timer", "hrtimer_expire_entry",
timer_expire_handler, NULL);
pevent_unregister_event_handler(pevent, -1, "timer", "hrtimer_start",
tep_unregister_event_handler(pevent, -1, "timer", "hrtimer_start",
timer_start_handler, NULL);
}
......@@ -47,29 +47,29 @@ process_jiffies_to_msecs(struct trace_seq *s, unsigned long long *args)
return jiffies;
}
int PEVENT_PLUGIN_LOADER(struct pevent *pevent)
int TEP_PLUGIN_LOADER(struct tep_handle *pevent)
{
pevent_register_print_function(pevent,
tep_register_print_function(pevent,
process_jbd2_dev_to_name,
PEVENT_FUNC_ARG_STRING,
TEP_FUNC_ARG_STRING,
"jbd2_dev_to_name",
PEVENT_FUNC_ARG_INT,
PEVENT_FUNC_ARG_VOID);
TEP_FUNC_ARG_INT,
TEP_FUNC_ARG_VOID);
pevent_register_print_function(pevent,
tep_register_print_function(pevent,
process_jiffies_to_msecs,
PEVENT_FUNC_ARG_LONG,
TEP_FUNC_ARG_LONG,
"jiffies_to_msecs",
PEVENT_FUNC_ARG_LONG,
PEVENT_FUNC_ARG_VOID);
TEP_FUNC_ARG_LONG,
TEP_FUNC_ARG_VOID);
return 0;
}
void PEVENT_PLUGIN_UNLOADER(struct pevent *pevent)
void TEP_PLUGIN_UNLOADER(struct tep_handle *pevent)
{
pevent_unregister_print_function(pevent, process_jbd2_dev_to_name,
tep_unregister_print_function(pevent, process_jbd2_dev_to_name,
"jbd2_dev_to_name");
pevent_unregister_print_function(pevent, process_jiffies_to_msecs,
tep_unregister_print_function(pevent, process_jiffies_to_msecs,
"jiffies_to_msecs");
}
......@@ -23,7 +23,7 @@
#include "event-parse.h"
static int call_site_handler(struct trace_seq *s, struct pevent_record *record,
static int call_site_handler(struct trace_seq *s, struct tep_record *record,
struct event_format *event, void *context)
{
struct format_field *field;
......@@ -31,64 +31,64 @@ static int call_site_handler(struct trace_seq *s, struct pevent_record *record,
void *data = record->data;
const char *func;
field = pevent_find_field(event, "call_site");
field = tep_find_field(event, "call_site");
if (!field)
return 1;
if (pevent_read_number_field(field, data, &val))
if (tep_read_number_field(field, data, &val))
return 1;
func = pevent_find_function(event->pevent, val);
func = tep_find_function(event->pevent, val);
if (!func)
return 1;
addr = pevent_find_function_address(event->pevent, val);
addr = tep_find_function_address(event->pevent, val);
trace_seq_printf(s, "(%s+0x%x) ", func, (int)(val - addr));
return 1;
}
int PEVENT_PLUGIN_LOADER(struct pevent *pevent)
int TEP_PLUGIN_LOADER(struct tep_handle *pevent)
{
pevent_register_event_handler(pevent, -1, "kmem", "kfree",
tep_register_event_handler(pevent, -1, "kmem", "kfree",
call_site_handler, NULL);
pevent_register_event_handler(pevent, -1, "kmem", "kmalloc",
tep_register_event_handler(pevent, -1, "kmem", "kmalloc",
call_site_handler, NULL);
pevent_register_event_handler(pevent, -1, "kmem", "kmalloc_node",
tep_register_event_handler(pevent, -1, "kmem", "kmalloc_node",
call_site_handler, NULL);
pevent_register_event_handler(pevent, -1, "kmem", "kmem_cache_alloc",
tep_register_event_handler(pevent, -1, "kmem", "kmem_cache_alloc",
call_site_handler, NULL);
pevent_register_event_handler(pevent, -1, "kmem",
tep_register_event_handler(pevent, -1, "kmem",
"kmem_cache_alloc_node",
call_site_handler, NULL);
pevent_register_event_handler(pevent, -1, "kmem", "kmem_cache_free",
tep_register_event_handler(pevent, -1, "kmem", "kmem_cache_free",
call_site_handler, NULL);
return 0;
}
void PEVENT_PLUGIN_UNLOADER(struct pevent *pevent)
void TEP_PLUGIN_UNLOADER(struct tep_handle *pevent)
{
pevent_unregister_event_handler(pevent, -1, "kmem", "kfree",
tep_unregister_event_handler(pevent, -1, "kmem", "kfree",
call_site_handler, NULL);
pevent_unregister_event_handler(pevent, -1, "kmem", "kmalloc",
tep_unregister_event_handler(pevent, -1, "kmem", "kmalloc",
call_site_handler, NULL);
pevent_unregister_event_handler(pevent, -1, "kmem", "kmalloc_node",
tep_unregister_event_handler(pevent, -1, "kmem", "kmalloc_node",
call_site_handler, NULL);
pevent_unregister_event_handler(pevent, -1, "kmem", "kmem_cache_alloc",
tep_unregister_event_handler(pevent, -1, "kmem", "kmem_cache_alloc",
call_site_handler, NULL);
pevent_unregister_event_handler(pevent, -1, "kmem",
tep_unregister_event_handler(pevent, -1, "kmem",
"kmem_cache_alloc_node",
call_site_handler, NULL);
pevent_unregister_event_handler(pevent, -1, "kmem", "kmem_cache_free",
tep_unregister_event_handler(pevent, -1, "kmem", "kmem_cache_free",
call_site_handler, NULL);
}
This diff is collapsed.
......@@ -28,7 +28,7 @@
static void print_string(struct trace_seq *s, struct event_format *event,
const char *name, const void *data)
{
struct format_field *f = pevent_find_field(event, name);
struct format_field *f = tep_find_field(event, name);
int offset;
int length;
......@@ -42,7 +42,7 @@ static void print_string(struct trace_seq *s, struct event_format *event,
if (!strncmp(f->type, "__data_loc", 10)) {
unsigned long long v;
if (pevent_read_number_field(f, data, &v)) {
if (tep_read_number_field(f, data, &v)) {
trace_seq_printf(s, "invalid_data_loc");
return;
}
......@@ -53,12 +53,12 @@ static void print_string(struct trace_seq *s, struct event_format *event,
trace_seq_printf(s, "%.*s", length, (char *)data + offset);
}
#define SF(fn) pevent_print_num_field(s, fn ":%d", event, fn, record, 0)
#define SFX(fn) pevent_print_num_field(s, fn ":%#x", event, fn, record, 0)
#define SF(fn) tep_print_num_field(s, fn ":%d", event, fn, record, 0)
#define SFX(fn) tep_print_num_field(s, fn ":%#x", event, fn, record, 0)
#define SP() trace_seq_putc(s, ' ')
static int drv_bss_info_changed(struct trace_seq *s,
struct pevent_record *record,
struct tep_record *record,
struct event_format *event, void *context)
{
void *data = record->data;
......@@ -66,7 +66,7 @@ static int drv_bss_info_changed(struct trace_seq *s,
print_string(s, event, "wiphy_name", data);
trace_seq_printf(s, " vif:");
print_string(s, event, "vif_name", data);
pevent_print_num_field(s, "(%d)", event, "vif_type", record, 1);
tep_print_num_field(s, "(%d)", event, "vif_type", record, 1);
trace_seq_printf(s, "\n%*s", INDENT, "");
SF("assoc"); SP();
......@@ -86,17 +86,17 @@ static int drv_bss_info_changed(struct trace_seq *s,
return 0;
}
int PEVENT_PLUGIN_LOADER(struct pevent *pevent)
int TEP_PLUGIN_LOADER(struct tep_handle *pevent)
{
pevent_register_event_handler(pevent, -1, "mac80211",
tep_register_event_handler(pevent, -1, "mac80211",
"drv_bss_info_changed",
drv_bss_info_changed, NULL);
return 0;
}
void PEVENT_PLUGIN_UNLOADER(struct pevent *pevent)
void TEP_PLUGIN_UNLOADER(struct tep_handle *pevent)
{
pevent_unregister_event_handler(pevent, -1, "mac80211",
tep_unregister_event_handler(pevent, -1, "mac80211",
"drv_bss_info_changed",
drv_bss_info_changed, NULL);
}
......@@ -45,7 +45,7 @@ static void write_state(struct trace_seq *s, int val)
}
static void write_and_save_comm(struct format_field *field,
struct pevent_record *record,
struct tep_record *record,
struct trace_seq *s, int pid)
{
const char *comm;
......@@ -61,100 +61,100 @@ static void write_and_save_comm(struct format_field *field,
comm = &s->buffer[len];
/* Help out the comm to ids. This will handle dups */
pevent_register_comm(field->event->pevent, comm, pid);
tep_register_comm(field->event->pevent, comm, pid);
}
static int sched_wakeup_handler(struct trace_seq *s,
struct pevent_record *record,
struct tep_record *record,
struct event_format *event, void *context)
{
struct format_field *field;
unsigned long long val;
if (pevent_get_field_val(s, event, "pid", record, &val, 1))
if (tep_get_field_val(s, event, "pid", record, &val, 1))
return trace_seq_putc(s, '!');
field = pevent_find_any_field(event, "comm");
field = tep_find_any_field(event, "comm");
if (field) {
write_and_save_comm(field, record, s, val);
trace_seq_putc(s, ':');
}
trace_seq_printf(s, "%lld", val);
if (pevent_get_field_val(s, event, "prio", record, &val, 0) == 0)
if (tep_get_field_val(s, event, "prio", record, &val, 0) == 0)
trace_seq_printf(s, " [%lld]", val);
if (pevent_get_field_val(s, event, "success", record, &val, 1) == 0)
if (tep_get_field_val(s, event, "success", record, &val, 1) == 0)
trace_seq_printf(s, " success=%lld", val);
if (pevent_get_field_val(s, event, "target_cpu", record, &val, 0) == 0)
if (tep_get_field_val(s, event, "target_cpu", record, &val, 0) == 0)
trace_seq_printf(s, " CPU:%03llu", val);
return 0;
}
static int sched_switch_handler(struct trace_seq *s,
struct pevent_record *record,
struct tep_record *record,
struct event_format *event, void *context)
{
struct format_field *field;
unsigned long long val;
if (pevent_get_field_val(s, event, "prev_pid", record, &val, 1))
if (tep_get_field_val(s, event, "prev_pid", record, &val, 1))
return trace_seq_putc(s, '!');
field = pevent_find_any_field(event, "prev_comm");
field = tep_find_any_field(event, "prev_comm");
if (field) {
write_and_save_comm(field, record, s, val);
trace_seq_putc(s, ':');
}
trace_seq_printf(s, "%lld ", val);
if (pevent_get_field_val(s, event, "prev_prio", record, &val, 0) == 0)
if (tep_get_field_val(s, event, "prev_prio", record, &val, 0) == 0)
trace_seq_printf(s, "[%d] ", (int) val);
if (pevent_get_field_val(s, event, "prev_state", record, &val, 0) == 0)
if (tep_get_field_val(s, event, "prev_state", record, &val, 0) == 0)
write_state(s, val);
trace_seq_puts(s, " ==> ");
if (pevent_get_field_val(s, event, "next_pid", record, &val, 1))
if (tep_get_field_val(s, event, "next_pid", record, &val, 1))
return trace_seq_putc(s, '!');
field = pevent_find_any_field(event, "next_comm");
field = tep_find_any_field(event, "next_comm");
if (field) {
write_and_save_comm(field, record, s, val);
trace_seq_putc(s, ':');
}
trace_seq_printf(s, "%lld", val);
if (pevent_get_field_val(s, event, "next_prio", record, &val, 0) == 0)
if (tep_get_field_val(s, event, "next_prio", record, &val, 0) == 0)
trace_seq_printf(s, " [%d]", (int) val);
return 0;
}
int PEVENT_PLUGIN_LOADER(struct pevent *pevent)
int TEP_PLUGIN_LOADER(struct tep_handle *pevent)
{
pevent_register_event_handler(pevent, -1, "sched", "sched_switch",
tep_register_event_handler(pevent, -1, "sched", "sched_switch",
sched_switch_handler, NULL);
pevent_register_event_handler(pevent, -1, "sched", "sched_wakeup",
tep_register_event_handler(pevent, -1, "sched", "sched_wakeup",
sched_wakeup_handler, NULL);
pevent_register_event_handler(pevent, -1, "sched", "sched_wakeup_new",
tep_register_event_handler(pevent, -1, "sched", "sched_wakeup_new",
sched_wakeup_handler, NULL);
return 0;
}
void PEVENT_PLUGIN_UNLOADER(struct pevent *pevent)
void TEP_PLUGIN_UNLOADER(struct tep_handle *pevent)
{
pevent_unregister_event_handler(pevent, -1, "sched", "sched_switch",
tep_unregister_event_handler(pevent, -1, "sched", "sched_switch",
sched_switch_handler, NULL);
pevent_unregister_event_handler(pevent, -1, "sched", "sched_wakeup",
tep_unregister_event_handler(pevent, -1, "sched", "sched_wakeup",
sched_wakeup_handler, NULL);
pevent_unregister_event_handler(pevent, -1, "sched", "sched_wakeup_new",
tep_unregister_event_handler(pevent, -1, "sched", "sched_wakeup_new",
sched_wakeup_handler, NULL);
}
......@@ -413,21 +413,21 @@ unsigned long long process_scsi_trace_parse_cdb(struct trace_seq *s,
return 0;
}
int PEVENT_PLUGIN_LOADER(struct pevent *pevent)
int TEP_PLUGIN_LOADER(struct tep_handle *pevent)
{
pevent_register_print_function(pevent,
tep_register_print_function(pevent,
process_scsi_trace_parse_cdb,
PEVENT_FUNC_ARG_STRING,
TEP_FUNC_ARG_STRING,
"scsi_trace_parse_cdb",
PEVENT_FUNC_ARG_PTR,
PEVENT_FUNC_ARG_PTR,
PEVENT_FUNC_ARG_INT,
PEVENT_FUNC_ARG_VOID);
TEP_FUNC_ARG_PTR,
TEP_FUNC_ARG_PTR,
TEP_FUNC_ARG_INT,
TEP_FUNC_ARG_VOID);
return 0;
}
void PEVENT_PLUGIN_UNLOADER(struct pevent *pevent)
void TEP_PLUGIN_UNLOADER(struct tep_handle *pevent)
{
pevent_unregister_print_function(pevent, process_scsi_trace_parse_cdb,
tep_unregister_print_function(pevent, process_scsi_trace_parse_cdb,
"scsi_trace_parse_cdb");
}
......@@ -119,19 +119,19 @@ unsigned long long process_xen_hypercall_name(struct trace_seq *s,
return 0;
}
int PEVENT_PLUGIN_LOADER(struct pevent *pevent)
int TEP_PLUGIN_LOADER(struct tep_handle *pevent)
{
pevent_register_print_function(pevent,
tep_register_print_function(pevent,
process_xen_hypercall_name,
PEVENT_FUNC_ARG_STRING,
TEP_FUNC_ARG_STRING,
"xen_hypercall_name",
PEVENT_FUNC_ARG_INT,
PEVENT_FUNC_ARG_VOID);
TEP_FUNC_ARG_INT,
TEP_FUNC_ARG_VOID);
return 0;
}
void PEVENT_PLUGIN_UNLOADER(struct pevent *pevent)
void TEP_PLUGIN_UNLOADER(struct tep_handle *pevent)
{
pevent_unregister_print_function(pevent, process_xen_hypercall_name,
tep_unregister_print_function(pevent, process_xen_hypercall_name,
"xen_hypercall_name");
}
......@@ -118,6 +118,15 @@ OPTIONS
--group::
Show event group information together
--percent-type::
Set annotation percent type from following choices:
global-period, local-period, global-hits, local-hits
The local/global keywords set if the percentage is computed
in the scope of the function (local) or the whole data (global).
The period/hits keywords set the base the percentage is computed
on - the samples period or the number of samples (hits).
SEE ALSO
--------
linkperf:perf-record[1], linkperf:perf-report[1]
......@@ -477,6 +477,15 @@ include::itrace.txt[]
Display monitored tasks stored in perf data. Displaying pid/tid/ppid
plus the command string aligned to distinguish parent and child tasks.
--percent-type::
Set annotation percent type from following choices:
global-period, local-period, global-hits, local-hits
The local/global keywords set if the percentage is computed
in the scope of the function (local) or the whole data (global).
The period/hits keywords set the base the percentage is computed
on - the samples period or the number of samples (hits).
include::callchain-overhead-calculation.txt[]
SEE ALSO
......
......@@ -194,6 +194,7 @@ struct auxtrace_record *arm_spe_recording_init(int *err,
sper->itr.read_finish = arm_spe_read_finish;
sper->itr.alignment = 0;
*err = 0;
return &sper->itr;
}
......
......@@ -141,8 +141,10 @@ void arch__post_process_probe_trace_events(struct perf_probe_event *pev,
for (i = 0; i < ntevs; i++) {
tev = &pev->tevs[i];
map__for_each_symbol(map, sym, tmp) {
if (map->unmap_ip(map, sym->start) == tev->point.address)
if (map->unmap_ip(map, sym->start) == tev->point.address) {
arch__fix_tev_from_maps(pev, tev, map, sym);
break;
}
}
}
}
......
......@@ -30,6 +30,7 @@ cpumsf_info_fill(struct auxtrace_record *itr __maybe_unused,
struct auxtrace_info_event *auxtrace_info __maybe_unused,
size_t priv_size __maybe_unused)
{
auxtrace_info->type = PERF_AUXTRACE_S390_CPUMSF;
return 0;
}
......
......@@ -19,9 +19,6 @@ systbl := $(sys)/syscalltbl.sh
_dummy := $(shell [ -d '$(out)' ] || mkdir -p '$(out)')
$(header): $(sys)/syscall_64.tbl $(systbl)
@(test -d ../../kernel -a -d ../../tools -a -d ../perf && ( \
(diff -B arch/x86/entry/syscalls/syscall_64.tbl ../../arch/x86/entry/syscalls/syscall_64.tbl >/dev/null) \
|| echo "Warning: Kernel ABI header at 'tools/perf/arch/x86/entry/syscalls/syscall_64.tbl' differs from latest version at 'arch/x86/entry/syscalls/syscall_64.tbl'" >&2 )) || true
$(Q)$(SHELL) '$(systbl)' $(sys)/syscall_64.tbl 'x86_64' > $@
clean::
......
......@@ -542,6 +542,10 @@ int cmd_annotate(int argc, const char **argv)
OPT_CALLBACK_DEFAULT(0, "stdio-color", NULL, "mode",
"'always' (default), 'never' or 'auto' only applicable to --stdio mode",
stdio__config_color, "always"),
OPT_CALLBACK(0, "percent-type", &annotate.opts, "local-period",
"Set percent type local/global-period/hits",
annotate_parse_percent_type),
OPT_END()
};
int ret;
......
......@@ -729,7 +729,7 @@ static char *compact_gfp_string(unsigned long gfp_flags)
static int parse_gfp_flags(struct perf_evsel *evsel, struct perf_sample *sample,
unsigned int gfp_flags)
{
struct pevent_record record = {
struct tep_record record = {
.cpu = sample->cpu,
.data = sample->raw_data,
.size = sample->raw_size,
......@@ -747,7 +747,7 @@ static int parse_gfp_flags(struct perf_evsel *evsel, struct perf_sample *sample,
}
trace_seq_init(&seq);
pevent_event_info(&seq, evsel->tp_format, &record);
tep_event_info(&seq, evsel->tp_format, &record);
str = strtok_r(seq.buffer, " ", &pos);
while (str) {
......@@ -1974,7 +1974,7 @@ int cmd_kmem(int argc, const char **argv)
goto out_delete;
}
kmem_page_size = pevent_get_page_size(evsel->tp_format->pevent);
kmem_page_size = tep_get_page_size(evsel->tp_format->pevent);
symbol_conf.use_callchain = true;
}
......
......@@ -1124,6 +1124,9 @@ int cmd_report(int argc, const char **argv)
"Time span of interest (start,stop)"),
OPT_BOOLEAN(0, "inline", &symbol_conf.inline_name,
"Show inline function"),
OPT_CALLBACK(0, "percent-type", &report.annotation_opts, "local-period",
"Set percent type local/global-period/hits",
annotate_parse_percent_type),
OPT_END()
};
struct perf_data data = {
......@@ -1366,7 +1369,7 @@ int cmd_report(int argc, const char **argv)
}
if (session->tevent.pevent &&
pevent_set_function_resolver(session->tevent.pevent,
tep_set_function_resolver(session->tevent.pevent,
machine__resolve_kernel_addr,
&session->machines.host) < 0) {
pr_err("%s: failed to set libtraceevent function resolver\n",
......
......@@ -3429,7 +3429,7 @@ int cmd_script(int argc, const char **argv)
symbol_conf.use_callchain = false;
if (session->tevent.pevent &&
pevent_set_function_resolver(session->tevent.pevent,
tep_set_function_resolver(session->tevent.pevent,
machine__resolve_kernel_addr,
&session->machines.host) < 0) {
pr_err("%s: failed to set libtraceevent function resolver\n", __func__);
......
This diff is collapsed.
......@@ -67,8 +67,12 @@ check_2 () {
cmd="diff $* $file1 $file2 > /dev/null"
test -f $file2 &&
eval $cmd || echo "Warning: Kernel ABI header at 'tools/$file' differs from latest version at '$file'" >&2
test -f $file2 && {
eval $cmd || {
echo "Warning: Kernel ABI header at '$file1' differs from latest version at '$file2'" >&2
echo diff -u $file1 $file2
}
}
}
check () {
......@@ -76,7 +80,7 @@ check () {
shift
check_2 ../$file ../../$file $*
check_2 tools/$file $file $*
}
# Check if we have the kernel headers (tools/perf/../../include), else
......@@ -84,6 +88,8 @@ check () {
# differences.
test -d ../../include || exit 0
cd ../..
# simple diff check
for i in $HEADERS; do
check $i -B
......@@ -94,3 +100,8 @@ check arch/x86/lib/memcpy_64.S '-I "^EXPORT_SYMBOL" -I "^#include <asm/ex
check arch/x86/lib/memset_64.S '-I "^EXPORT_SYMBOL" -I "^#include <asm/export.h>"'
check include/uapi/asm-generic/mman.h '-I "^#include <\(uapi/\)*asm-generic/mman-common.h>"'
check include/uapi/linux/mman.h '-I "^#include <\(uapi/\)*asm/mman.h>"'
# diff non-symmetric files
check_2 tools/perf/arch/x86/entry/syscalls/syscall_64.tbl arch/x86/entry/syscalls/syscall_64.tbl
cd tools/perf
This diff is collapsed.
#include <stdio.h>
int syscall_enter(openat)(void *args)
{
puts("Hello, world\n");
return 0;
}
license(GPL);
// SPDX-License-Identifier: GPL-2.0
/*
* Hook into 'openat' syscall entry tracepoint
*
* Test it with:
*
* perf trace -e tools/perf/examples/bpf/sys_enter_openat.c cat /etc/passwd > /dev/null
*
* It'll catch some openat syscalls related to the dynamic linked and
* the last one should be the one for '/etc/passwd'.
*
* The syscall_enter_openat_args can be used to get the syscall fields
* and use them for filtering calls, i.e. use in expressions for
* the return value.
*/
#include <bpf.h>
struct syscall_enter_openat_args {
unsigned long long unused;
long syscall_nr;
long dfd;
char *filename_ptr;
long flags;
long mode;
};
int syscall_enter(openat)(struct syscall_enter_openat_args *args)
{
return 1;
}
license(GPL);
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment