perf/core improvements and fixes:
Fixes: . Fix inverted error verification bug in thread__fork, from David Ahern. New features: . Shell completion for 'perf kvm', from Ramkumar Ramachandra. Refactorings: . Get rid of panic() like calls in libtraceevent, from Namyung Kim. . Start carving out symbol parsing routines from perf, just moving routines to topic files in tools/lib/symbol/, tools that want to use it need to integrate it directly, i.e. no tools/lib/symbol/Makefile is provided. . Assorted refactoring patches, moving code around and adding utility evlist methods that will be used in the IPT patchset, from Adrian Hunter. Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com> -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.15 (GNU/Linux) iQIcBAABAgAGBQJSqyG1AAoJENZQFvNTUqpAj7kP/iPHuiuHbnribVE9ehM5stPN SqzOjRGYxEoz7hKGY5ot7CpkcGheUFe2fwRPyiMoS+GmzNJu9JYFxHzlNB907UqY EN5eLEpHHIYKkRd7wBWRsR4xnARYK1n2t0poXa8dJ1V0+wZ23ku/LBILVpIO1anf YqnzH0Uzi2GIJ0oWbQT6yggC07qz1Ma3QPJdoZ/0NkmWVKzQbre5KR6M8bnv6nXQ XHm6v9irFCbNYtXvv7NpLua99aiKpaJOT8s1x8HfAgFO0X071tGM+OjONWDQdUfD QBGYXzGWtIC5dXo+1PcK6BFz80CqgPSRG7zaIXjykapFLCoQOGPkdex2UMuAeOKF N5Be2z17FXSFSDPsopAWOcmdQ5vu2m6qzqYbOmhSMzuhrXCI/ly7Kd8mfMIL70q0 rR3e87mRmb3/Jx8WaMw6er5l1ceVXT72cFTP1GulIO7cyhwoxvUhPv35D+8F5qWI ou0cVKXRdZYb/tVbeUTXo1nqAmOi5s5Fsm4W/7pOtouaVo/K/9tEIusKpNjtVWPz PeE4ggzZNMn/Y6nU2WRfXAK0ScqS2mc8YiNqg9+SWaffBTEWBZNDph9ajhTtIDXq eLDe0DRNCvVJtRKOQfuiuO8vhXF6w/JdZVEMFGHJ9jn601XR3Sgm+ktK29AFiwgZ a0rk8IreC6Ylg/wlKX0H =qcLZ -----END PGP SIGNATURE----- Merge tag 'perf-core-for-mingo' of git://git.kernel.org/pub/scm/linux/kernel/git/acme/linux into perf/core Pull perf/core improvements and fixes from Arnaldo Carvalho de Melo: Fixes: * Fix inverted error verification bug in thread__fork, from David Ahern. New features: * Shell completion for 'perf kvm', from Ramkumar Ramachandra. Refactorings: * Get rid of panic() like calls in libtraceevent, from Namyung Kim. * Start carving out symbol parsing routines from perf, just moving routines to topic files in tools/lib/symbol/, tools that want to use it need to integrate it directly, i.e. no tools/lib/symbol/Makefile is provided. * Assorted refactoring patches, moving code around and adding utility evlist methods that will be used in the IPT patchset, from Adrian Hunter. Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com> Signed-off-by: Ingo Molnar <mingo@kernel.org>
This commit is contained in:
commit
b283d2f3b7
58
tools/lib/symbol/kallsyms.c
Normal file
58
tools/lib/symbol/kallsyms.c
Normal file
@ -0,0 +1,58 @@
|
||||
#include "symbol/kallsyms.h"
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
int kallsyms__parse(const char *filename, void *arg,
|
||||
int (*process_symbol)(void *arg, const char *name,
|
||||
char type, u64 start))
|
||||
{
|
||||
char *line = NULL;
|
||||
size_t n;
|
||||
int err = -1;
|
||||
FILE *file = fopen(filename, "r");
|
||||
|
||||
if (file == NULL)
|
||||
goto out_failure;
|
||||
|
||||
err = 0;
|
||||
|
||||
while (!feof(file)) {
|
||||
u64 start;
|
||||
int line_len, len;
|
||||
char symbol_type;
|
||||
char *symbol_name;
|
||||
|
||||
line_len = getline(&line, &n, file);
|
||||
if (line_len < 0 || !line)
|
||||
break;
|
||||
|
||||
line[--line_len] = '\0'; /* \n */
|
||||
|
||||
len = hex2u64(line, &start);
|
||||
|
||||
len++;
|
||||
if (len + 2 >= line_len)
|
||||
continue;
|
||||
|
||||
symbol_type = line[len];
|
||||
len += 2;
|
||||
symbol_name = line + len;
|
||||
len = line_len - len;
|
||||
|
||||
if (len >= KSYM_NAME_LEN) {
|
||||
err = -1;
|
||||
break;
|
||||
}
|
||||
|
||||
err = process_symbol(arg, symbol_name, symbol_type, start);
|
||||
if (err)
|
||||
break;
|
||||
}
|
||||
|
||||
free(line);
|
||||
fclose(file);
|
||||
return err;
|
||||
|
||||
out_failure:
|
||||
return -1;
|
||||
}
|
24
tools/lib/symbol/kallsyms.h
Normal file
24
tools/lib/symbol/kallsyms.h
Normal file
@ -0,0 +1,24 @@
|
||||
#ifndef __TOOLS_KALLSYMS_H_
|
||||
#define __TOOLS_KALLSYMS_H_ 1
|
||||
|
||||
#include <elf.h>
|
||||
#include <linux/ctype.h>
|
||||
#include <linux/types.h>
|
||||
|
||||
#ifndef KSYM_NAME_LEN
|
||||
#define KSYM_NAME_LEN 256
|
||||
#endif
|
||||
|
||||
static inline u8 kallsyms2elf_type(char type)
|
||||
{
|
||||
if (type == 'W')
|
||||
return STB_WEAK;
|
||||
|
||||
return isupper(type) ? STB_GLOBAL : STB_LOCAL;
|
||||
}
|
||||
|
||||
int kallsyms__parse(const char *filename, void *arg,
|
||||
int (*process_symbol)(void *arg, const char *name,
|
||||
char type, u64 start));
|
||||
|
||||
#endif /* __TOOLS_KALLSYMS_H_ */
|
@ -356,12 +356,35 @@ enum pevent_flag {
|
||||
_PE(READ_FORMAT_FAILED, "failed to read event format"), \
|
||||
_PE(READ_PRINT_FAILED, "failed to read event print fmt"), \
|
||||
_PE(OLD_FTRACE_ARG_FAILED,"failed to allocate field name for ftrace"),\
|
||||
_PE(INVALID_ARG_TYPE, "invalid argument type")
|
||||
_PE(INVALID_ARG_TYPE, "invalid argument type"), \
|
||||
_PE(INVALID_EXP_TYPE, "invalid expression type"), \
|
||||
_PE(INVALID_OP_TYPE, "invalid operator type"), \
|
||||
_PE(INVALID_EVENT_NAME, "invalid event name"), \
|
||||
_PE(EVENT_NOT_FOUND, "no event found"), \
|
||||
_PE(SYNTAX_ERROR, "syntax error"), \
|
||||
_PE(ILLEGAL_RVALUE, "illegal rvalue"), \
|
||||
_PE(ILLEGAL_LVALUE, "illegal lvalue for string comparison"), \
|
||||
_PE(INVALID_REGEX, "regex did not compute"), \
|
||||
_PE(ILLEGAL_STRING_CMP, "illegal comparison for string"), \
|
||||
_PE(ILLEGAL_INTEGER_CMP,"illegal comparison for integer"), \
|
||||
_PE(REPARENT_NOT_OP, "cannot reparent other than OP"), \
|
||||
_PE(REPARENT_FAILED, "failed to reparent filter OP"), \
|
||||
_PE(BAD_FILTER_ARG, "bad arg in filter tree"), \
|
||||
_PE(UNEXPECTED_TYPE, "unexpected type (not a value)"), \
|
||||
_PE(ILLEGAL_TOKEN, "illegal token"), \
|
||||
_PE(INVALID_PAREN, "open parenthesis cannot come here"), \
|
||||
_PE(UNBALANCED_PAREN, "unbalanced number of parenthesis"), \
|
||||
_PE(UNKNOWN_TOKEN, "unknown token"), \
|
||||
_PE(FILTER_NOT_FOUND, "no filter found"), \
|
||||
_PE(NOT_A_NUMBER, "must have number field"), \
|
||||
_PE(NO_FILTER, "no filters exists"), \
|
||||
_PE(FILTER_MISS, "record does not match to filter")
|
||||
|
||||
#undef _PE
|
||||
#define _PE(__code, __str) PEVENT_ERRNO__ ## __code
|
||||
enum pevent_errno {
|
||||
PEVENT_ERRNO__SUCCESS = 0,
|
||||
PEVENT_ERRNO__FILTER_MATCH = PEVENT_ERRNO__SUCCESS,
|
||||
|
||||
/*
|
||||
* Choose an arbitrary negative big number not to clash with standard
|
||||
@ -836,10 +859,11 @@ struct event_filter {
|
||||
|
||||
struct event_filter *pevent_filter_alloc(struct pevent *pevent);
|
||||
|
||||
#define FILTER_NONE -2
|
||||
#define FILTER_NOEXIST -1
|
||||
#define FILTER_MISS 0
|
||||
#define FILTER_MATCH 1
|
||||
/* for backward compatibility */
|
||||
#define FILTER_NONE PEVENT_ERRNO__FILTER_NOT_FOUND
|
||||
#define FILTER_NOEXIST PEVENT_ERRNO__NO_FILTER
|
||||
#define FILTER_MISS PEVENT_ERRNO__FILTER_MISS
|
||||
#define FILTER_MATCH PEVENT_ERRNO__FILTER_MATCH
|
||||
|
||||
enum filter_trivial_type {
|
||||
FILTER_TRIVIAL_FALSE,
|
||||
@ -847,13 +871,12 @@ enum filter_trivial_type {
|
||||
FILTER_TRIVIAL_BOTH,
|
||||
};
|
||||
|
||||
int pevent_filter_add_filter_str(struct event_filter *filter,
|
||||
const char *filter_str,
|
||||
char **error_str);
|
||||
enum pevent_errno pevent_filter_add_filter_str(struct event_filter *filter,
|
||||
const char *filter_str);
|
||||
|
||||
|
||||
int pevent_filter_match(struct event_filter *filter,
|
||||
struct pevent_record *record);
|
||||
enum pevent_errno pevent_filter_match(struct event_filter *filter,
|
||||
struct pevent_record *record);
|
||||
|
||||
int pevent_event_filtered(struct event_filter *filter,
|
||||
int event_id);
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -2,6 +2,8 @@ tools/perf
|
||||
tools/scripts
|
||||
tools/lib/traceevent
|
||||
tools/lib/lk
|
||||
tools/lib/symbol/kallsyms.c
|
||||
tools/lib/symbol/kallsyms.h
|
||||
include/linux/const.h
|
||||
include/linux/perf_event.h
|
||||
include/linux/rbtree.h
|
||||
|
@ -202,6 +202,7 @@ $(OUTPUT)util/pmu.o: $(OUTPUT)util/pmu-flex.c $(OUTPUT)util/pmu-bison.c
|
||||
|
||||
LIB_FILE=$(OUTPUT)libperf.a
|
||||
|
||||
LIB_H += ../lib/symbol/kallsyms.h
|
||||
LIB_H += ../../include/uapi/linux/perf_event.h
|
||||
LIB_H += ../../include/linux/rbtree.h
|
||||
LIB_H += ../../include/linux/list.h
|
||||
@ -312,6 +313,7 @@ LIB_OBJS += $(OUTPUT)util/evlist.o
|
||||
LIB_OBJS += $(OUTPUT)util/evsel.o
|
||||
LIB_OBJS += $(OUTPUT)util/exec_cmd.o
|
||||
LIB_OBJS += $(OUTPUT)util/help.o
|
||||
LIB_OBJS += $(OUTPUT)util/kallsyms.o
|
||||
LIB_OBJS += $(OUTPUT)util/levenshtein.o
|
||||
LIB_OBJS += $(OUTPUT)util/parse-options.o
|
||||
LIB_OBJS += $(OUTPUT)util/parse-events.o
|
||||
@ -672,6 +674,9 @@ $(OUTPUT)ui/browsers/map.o: ui/browsers/map.c $(OUTPUT)PERF-CFLAGS
|
||||
$(OUTPUT)ui/browsers/scripts.o: ui/browsers/scripts.c $(OUTPUT)PERF-CFLAGS
|
||||
$(QUIET_CC)$(CC) -o $@ -c $(CFLAGS) -DENABLE_SLFUTURE_CONST $<
|
||||
|
||||
$(OUTPUT)util/kallsyms.o: ../lib/symbol/kallsyms.c $(OUTPUT)PERF-CFLAGS
|
||||
$(QUIET_CC)$(CC) -o $@ -c $(CFLAGS) $<
|
||||
|
||||
$(OUTPUT)util/rbtree.o: ../../lib/rbtree.c $(OUTPUT)PERF-CFLAGS
|
||||
$(QUIET_CC)$(CC) -o $@ -c $(CFLAGS) -Wno-unused-parameter -DETC_PERFCONFIG='"$(ETC_PERFCONFIG_SQ)"' $<
|
||||
|
||||
|
@ -121,6 +121,10 @@ __perf_main ()
|
||||
elif [[ $prev == "-e" && "${words[1]}" == @(record|stat|top) ]]; then
|
||||
evts=$($cmd list --raw-dump)
|
||||
__perfcomp_colon "$evts" "$cur"
|
||||
# List subcommands for 'perf kvm'
|
||||
elif [[ $prev == "kvm" ]]; then
|
||||
subcmds="top record report diff buildid-list stat"
|
||||
__perfcomp_colon "$subcmds" "$cur"
|
||||
# List long option names
|
||||
elif [[ $cur == --* ]]; then
|
||||
subcmd=${words[1]}
|
||||
|
@ -7,6 +7,7 @@
|
||||
#include "strlist.h"
|
||||
#include "thread.h"
|
||||
#include "thread_map.h"
|
||||
#include "symbol/kallsyms.h"
|
||||
|
||||
static const char *perf_event__names[] = {
|
||||
[0] = "TOTAL",
|
||||
|
@ -1191,8 +1191,7 @@ int perf_evlist__strerror_open(struct perf_evlist *evlist __maybe_unused,
|
||||
"Error:\t%s.\n"
|
||||
"Hint:\tCheck /proc/sys/kernel/perf_event_paranoid setting.", emsg);
|
||||
|
||||
if (filename__read_int("/proc/sys/kernel/perf_event_paranoid", &value))
|
||||
break;
|
||||
value = perf_event_paranoid();
|
||||
|
||||
printed += scnprintf(buf + printed, size - printed, "\nHint:\t");
|
||||
|
||||
@ -1213,3 +1212,20 @@ int perf_evlist__strerror_open(struct perf_evlist *evlist __maybe_unused,
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void perf_evlist__to_front(struct perf_evlist *evlist,
|
||||
struct perf_evsel *move_evsel)
|
||||
{
|
||||
struct perf_evsel *evsel, *n;
|
||||
LIST_HEAD(move);
|
||||
|
||||
if (move_evsel == perf_evlist__first(evlist))
|
||||
return;
|
||||
|
||||
list_for_each_entry_safe(evsel, n, &evlist->entries, node) {
|
||||
if (evsel->leader == move_evsel->leader)
|
||||
list_move_tail(&evsel->node, &move);
|
||||
}
|
||||
|
||||
list_splice(&move, &evlist->entries);
|
||||
}
|
||||
|
@ -193,4 +193,9 @@ static inline void perf_mmap__write_tail(struct perf_mmap *md,
|
||||
pc->data_tail = tail;
|
||||
}
|
||||
|
||||
bool perf_evlist__can_select_event(struct perf_evlist *evlist, const char *str);
|
||||
void perf_evlist__to_front(struct perf_evlist *evlist,
|
||||
struct perf_evsel *move_evsel);
|
||||
|
||||
|
||||
#endif /* __PERF_EVLIST_H */
|
||||
|
@ -2327,7 +2327,8 @@ int perf_session__write_header(struct perf_session *session,
|
||||
}
|
||||
}
|
||||
|
||||
header->data_offset = lseek(fd, 0, SEEK_CUR);
|
||||
if (!header->data_offset)
|
||||
header->data_offset = lseek(fd, 0, SEEK_CUR);
|
||||
header->feat_offset = header->data_offset + header->data_size;
|
||||
|
||||
if (at_exit) {
|
||||
|
@ -9,6 +9,7 @@
|
||||
#include "strlist.h"
|
||||
#include "thread.h"
|
||||
#include <stdbool.h>
|
||||
#include <symbol/kallsyms.h>
|
||||
#include "unwind.h"
|
||||
|
||||
int machine__init(struct machine *machine, const char *root_dir, pid_t pid)
|
||||
|
@ -177,3 +177,40 @@ int perf_record_opts__config(struct perf_record_opts *opts)
|
||||
{
|
||||
return perf_record_opts__config_freq(opts);
|
||||
}
|
||||
|
||||
bool perf_evlist__can_select_event(struct perf_evlist *evlist, const char *str)
|
||||
{
|
||||
struct perf_evlist *temp_evlist;
|
||||
struct perf_evsel *evsel;
|
||||
int err, fd, cpu;
|
||||
bool ret = false;
|
||||
|
||||
temp_evlist = perf_evlist__new();
|
||||
if (!temp_evlist)
|
||||
return false;
|
||||
|
||||
err = parse_events(temp_evlist, str);
|
||||
if (err)
|
||||
goto out_delete;
|
||||
|
||||
evsel = perf_evlist__last(temp_evlist);
|
||||
|
||||
if (!evlist || cpu_map__empty(evlist->cpus)) {
|
||||
struct cpu_map *cpus = cpu_map__new(NULL);
|
||||
|
||||
cpu = cpus ? cpus->map[0] : 0;
|
||||
cpu_map__delete(cpus);
|
||||
} else {
|
||||
cpu = evlist->cpus->map[0];
|
||||
}
|
||||
|
||||
fd = sys_perf_event_open(&evsel->attr, -1, cpu, -1, 0);
|
||||
if (fd >= 0) {
|
||||
close(fd);
|
||||
ret = true;
|
||||
}
|
||||
|
||||
out_delete:
|
||||
perf_evlist__delete(temp_evlist);
|
||||
return ret;
|
||||
}
|
||||
|
@ -247,27 +247,6 @@ void perf_tool__fill_defaults(struct perf_tool *tool)
|
||||
}
|
||||
}
|
||||
|
||||
void mem_bswap_32(void *src, int byte_size)
|
||||
{
|
||||
u32 *m = src;
|
||||
while (byte_size > 0) {
|
||||
*m = bswap_32(*m);
|
||||
byte_size -= sizeof(u32);
|
||||
++m;
|
||||
}
|
||||
}
|
||||
|
||||
void mem_bswap_64(void *src, int byte_size)
|
||||
{
|
||||
u64 *m = src;
|
||||
|
||||
while (byte_size > 0) {
|
||||
*m = bswap_64(*m);
|
||||
byte_size -= sizeof(u64);
|
||||
++m;
|
||||
}
|
||||
}
|
||||
|
||||
static void swap_sample_id_all(union perf_event *event, void *data)
|
||||
{
|
||||
void *end = (void *) event + event->header.size;
|
||||
|
@ -74,8 +74,6 @@ int perf_session__resolve_callchain(struct perf_session *session,
|
||||
|
||||
bool perf_session__has_traces(struct perf_session *session, const char *msg);
|
||||
|
||||
void mem_bswap_64(void *src, int byte_size);
|
||||
void mem_bswap_32(void *src, int byte_size);
|
||||
void perf_event__attr_swap(struct perf_event_attr *attr);
|
||||
|
||||
int perf_session__create_kernel_maps(struct perf_session *session);
|
||||
|
@ -6,6 +6,7 @@
|
||||
#include <inttypes.h>
|
||||
|
||||
#include "symbol.h"
|
||||
#include <symbol/kallsyms.h>
|
||||
#include "debug.h"
|
||||
|
||||
#ifndef HAVE_ELF_GETPHDRNUM_SUPPORT
|
||||
|
@ -18,12 +18,9 @@
|
||||
|
||||
#include <elf.h>
|
||||
#include <limits.h>
|
||||
#include <symbol/kallsyms.h>
|
||||
#include <sys/utsname.h>
|
||||
|
||||
#ifndef KSYM_NAME_LEN
|
||||
#define KSYM_NAME_LEN 256
|
||||
#endif
|
||||
|
||||
static int dso__load_kernel_sym(struct dso *dso, struct map *map,
|
||||
symbol_filter_t filter);
|
||||
static int dso__load_guest_kernel_sym(struct dso *dso, struct map *map,
|
||||
@ -446,62 +443,6 @@ size_t dso__fprintf_symbols_by_name(struct dso *dso,
|
||||
return ret;
|
||||
}
|
||||
|
||||
int kallsyms__parse(const char *filename, void *arg,
|
||||
int (*process_symbol)(void *arg, const char *name,
|
||||
char type, u64 start))
|
||||
{
|
||||
char *line = NULL;
|
||||
size_t n;
|
||||
int err = -1;
|
||||
FILE *file = fopen(filename, "r");
|
||||
|
||||
if (file == NULL)
|
||||
goto out_failure;
|
||||
|
||||
err = 0;
|
||||
|
||||
while (!feof(file)) {
|
||||
u64 start;
|
||||
int line_len, len;
|
||||
char symbol_type;
|
||||
char *symbol_name;
|
||||
|
||||
line_len = getline(&line, &n, file);
|
||||
if (line_len < 0 || !line)
|
||||
break;
|
||||
|
||||
line[--line_len] = '\0'; /* \n */
|
||||
|
||||
len = hex2u64(line, &start);
|
||||
|
||||
len++;
|
||||
if (len + 2 >= line_len)
|
||||
continue;
|
||||
|
||||
symbol_type = line[len];
|
||||
len += 2;
|
||||
symbol_name = line + len;
|
||||
len = line_len - len;
|
||||
|
||||
if (len >= KSYM_NAME_LEN) {
|
||||
err = -1;
|
||||
break;
|
||||
}
|
||||
|
||||
err = process_symbol(arg, symbol_name,
|
||||
symbol_type, start);
|
||||
if (err)
|
||||
break;
|
||||
}
|
||||
|
||||
free(line);
|
||||
fclose(file);
|
||||
return err;
|
||||
|
||||
out_failure:
|
||||
return -1;
|
||||
}
|
||||
|
||||
int modules__parse(const char *filename, void *arg,
|
||||
int (*process_module)(void *arg, const char *name,
|
||||
u64 start))
|
||||
@ -565,14 +506,6 @@ struct process_kallsyms_args {
|
||||
struct dso *dso;
|
||||
};
|
||||
|
||||
static u8 kallsyms2elf_type(char type)
|
||||
{
|
||||
if (type == 'W')
|
||||
return STB_WEAK;
|
||||
|
||||
return isupper(type) ? STB_GLOBAL : STB_LOCAL;
|
||||
}
|
||||
|
||||
bool symbol__is_idle(struct symbol *sym)
|
||||
{
|
||||
const char * const idle_symbols[] = {
|
||||
|
@ -221,9 +221,6 @@ struct symbol *dso__first_symbol(struct dso *dso, enum map_type type);
|
||||
|
||||
int filename__read_build_id(const char *filename, void *bf, size_t size);
|
||||
int sysfs__read_build_id(const char *filename, void *bf, size_t size);
|
||||
int kallsyms__parse(const char *filename, void *arg,
|
||||
int (*process_symbol)(void *arg, const char *name,
|
||||
char type, u64 start));
|
||||
int modules__parse(const char *filename, void *arg,
|
||||
int (*process_module)(void *arg, const char *name,
|
||||
u64 start));
|
||||
|
@ -126,7 +126,7 @@ int thread__fork(struct thread *thread, struct thread *parent, u64 timestamp)
|
||||
if (!comm)
|
||||
return -ENOMEM;
|
||||
err = thread__set_comm(thread, comm, timestamp);
|
||||
if (!err)
|
||||
if (err)
|
||||
return err;
|
||||
thread->comm_set = true;
|
||||
}
|
||||
|
@ -1,5 +1,6 @@
|
||||
#include "../perf.h"
|
||||
#include "util.h"
|
||||
#include "fs.h"
|
||||
#include <sys/mman.h>
|
||||
#ifdef HAVE_BACKTRACE_SUPPORT
|
||||
#include <execinfo.h>
|
||||
@ -8,6 +9,8 @@
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <limits.h>
|
||||
#include <byteswap.h>
|
||||
#include <linux/kernel.h>
|
||||
|
||||
/*
|
||||
@ -496,3 +499,41 @@ const char *get_filename_for_perf_kvm(void)
|
||||
|
||||
return filename;
|
||||
}
|
||||
|
||||
int perf_event_paranoid(void)
|
||||
{
|
||||
char path[PATH_MAX];
|
||||
const char *procfs = procfs__mountpoint();
|
||||
int value;
|
||||
|
||||
if (!procfs)
|
||||
return INT_MAX;
|
||||
|
||||
scnprintf(path, PATH_MAX, "%s/sys/kernel/perf_event_paranoid", procfs);
|
||||
|
||||
if (filename__read_int(path, &value))
|
||||
return INT_MAX;
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
void mem_bswap_32(void *src, int byte_size)
|
||||
{
|
||||
u32 *m = src;
|
||||
while (byte_size > 0) {
|
||||
*m = bswap_32(*m);
|
||||
byte_size -= sizeof(u32);
|
||||
++m;
|
||||
}
|
||||
}
|
||||
|
||||
void mem_bswap_64(void *src, int byte_size)
|
||||
{
|
||||
u64 *m = src;
|
||||
|
||||
while (byte_size > 0) {
|
||||
*m = bswap_64(*m);
|
||||
byte_size -= sizeof(u64);
|
||||
++m;
|
||||
}
|
||||
}
|
||||
|
@ -321,6 +321,10 @@ void free_srcline(char *srcline);
|
||||
|
||||
int filename__read_int(const char *filename, int *value);
|
||||
int filename__read_str(const char *filename, char **buf, size_t *sizep);
|
||||
int perf_event_paranoid(void);
|
||||
|
||||
void mem_bswap_64(void *src, int byte_size);
|
||||
void mem_bswap_32(void *src, int byte_size);
|
||||
|
||||
const char *get_filename_for_perf_kvm(void);
|
||||
#endif /* GIT_COMPAT_UTIL_H */
|
||||
|
Loading…
Reference in New Issue
Block a user