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

Pull perf fixes from Thomas Gleixner:
 - fix for do_div() abuse on x86
 - locking fix in perf core
 - a pile of (build) fixes and cleanups in perf tools

* 'perf-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: (27 commits)
  perf/x86: Fix incorrect use of do_div() in NMI warning
  perf: Fix perf_lock_task_context() vs RCU
  perf: Remove WARN_ON_ONCE() check in __perf_event_enable() for valid scenario
  perf: Clone child context from parent context pmu
  perf script: Fix broken include in Context.xs
  perf tools: Fix -ldw/-lelf link test when static linking
  perf tools: Revert regression in configuration of Python support
  perf tools: Fix perf version generation
  perf stat: Fix per-socket output bug for uncore events
  perf symbols: Fix vdso list searching
  perf evsel: Fix missing increment in sample parsing
  perf tools: Update symbol_conf.nr_events when processing attribute events
  perf tools: Fix new_term() missing free on error path
  perf tools: Fix parse_events_terms() segfault on error path
  perf evsel: Fix count parameter to read call in event_format__new
  perf tools: fix a typo of a Power7 event name
  perf tools: Fix -x/--exclude-other option for report command
  perf evlist: Enhance perf_evlist__start_workload()
  perf record: Remove -f/--force option
  perf record: Remove -A/--append option
  ...
This commit is contained in:
Linus Torvalds 2013-07-13 15:35:47 -07:00
commit 560ae37178
34 changed files with 154 additions and 163 deletions

View File

@ -29,7 +29,7 @@ Description: Generic performance monitoring events
What: /sys/devices/cpu/events/PM_1PLUS_PPC_CMPL
/sys/devices/cpu/events/PM_BRU_FIN
/sys/devices/cpu/events/PM_BRU_MPRED
/sys/devices/cpu/events/PM_BR_MPRED
/sys/devices/cpu/events/PM_CMPLU_STALL
/sys/devices/cpu/events/PM_CMPLU_STALL_BRU
/sys/devices/cpu/events/PM_CMPLU_STALL_DCACHE_MISS

View File

@ -60,7 +60,7 @@
#define PME_PM_LD_REF_L1 0xc880
#define PME_PM_LD_MISS_L1 0x400f0
#define PME_PM_BRU_FIN 0x10068
#define PME_PM_BRU_MPRED 0x400f6
#define PME_PM_BR_MPRED 0x400f6
#define PME_PM_CMPLU_STALL_FXU 0x20014
#define PME_PM_CMPLU_STALL_DIV 0x40014
@ -349,7 +349,7 @@ static int power7_generic_events[] = {
[PERF_COUNT_HW_CACHE_REFERENCES] = PME_PM_LD_REF_L1,
[PERF_COUNT_HW_CACHE_MISSES] = PME_PM_LD_MISS_L1,
[PERF_COUNT_HW_BRANCH_INSTRUCTIONS] = PME_PM_BRU_FIN,
[PERF_COUNT_HW_BRANCH_MISSES] = PME_PM_BRU_MPRED,
[PERF_COUNT_HW_BRANCH_MISSES] = PME_PM_BR_MPRED,
};
#define C(x) PERF_COUNT_HW_CACHE_##x
@ -405,7 +405,7 @@ GENERIC_EVENT_ATTR(instructions, INST_CMPL);
GENERIC_EVENT_ATTR(cache-references, LD_REF_L1);
GENERIC_EVENT_ATTR(cache-misses, LD_MISS_L1);
GENERIC_EVENT_ATTR(branch-instructions, BRU_FIN);
GENERIC_EVENT_ATTR(branch-misses, BRU_MPRED);
GENERIC_EVENT_ATTR(branch-misses, BR_MPRED);
POWER_EVENT_ATTR(CYC, CYC);
POWER_EVENT_ATTR(GCT_NOSLOT_CYC, GCT_NOSLOT_CYC);
@ -414,7 +414,7 @@ POWER_EVENT_ATTR(INST_CMPL, INST_CMPL);
POWER_EVENT_ATTR(LD_REF_L1, LD_REF_L1);
POWER_EVENT_ATTR(LD_MISS_L1, LD_MISS_L1);
POWER_EVENT_ATTR(BRU_FIN, BRU_FIN)
POWER_EVENT_ATTR(BRU_MPRED, BRU_MPRED);
POWER_EVENT_ATTR(BR_MPRED, BR_MPRED);
POWER_EVENT_ATTR(CMPLU_STALL_FXU, CMPLU_STALL_FXU);
POWER_EVENT_ATTR(CMPLU_STALL_DIV, CMPLU_STALL_DIV);
@ -449,7 +449,7 @@ static struct attribute *power7_events_attr[] = {
GENERIC_EVENT_PTR(LD_REF_L1),
GENERIC_EVENT_PTR(LD_MISS_L1),
GENERIC_EVENT_PTR(BRU_FIN),
GENERIC_EVENT_PTR(BRU_MPRED),
GENERIC_EVENT_PTR(BR_MPRED),
POWER_EVENT_PTR(CYC),
POWER_EVENT_PTR(GCT_NOSLOT_CYC),
@ -458,7 +458,7 @@ static struct attribute *power7_events_attr[] = {
POWER_EVENT_PTR(LD_REF_L1),
POWER_EVENT_PTR(LD_MISS_L1),
POWER_EVENT_PTR(BRU_FIN),
POWER_EVENT_PTR(BRU_MPRED),
POWER_EVENT_PTR(BR_MPRED),
POWER_EVENT_PTR(CMPLU_STALL_FXU),
POWER_EVENT_PTR(CMPLU_STALL_DIV),

View File

@ -111,7 +111,7 @@ static int __kprobes nmi_handle(unsigned int type, struct pt_regs *regs, bool b2
*/
list_for_each_entry_rcu(a, &desc->head, list) {
u64 before, delta, whole_msecs;
int decimal_msecs, thishandled;
int remainder_ns, decimal_msecs, thishandled;
before = local_clock();
thishandled = a->handler(type, regs);
@ -123,8 +123,9 @@ static int __kprobes nmi_handle(unsigned int type, struct pt_regs *regs, bool b2
continue;
nmi_longest_ns = delta;
whole_msecs = do_div(delta, (1000 * 1000));
decimal_msecs = do_div(delta, 1000) % 1000;
whole_msecs = delta;
remainder_ns = do_div(whole_msecs, (1000 * 1000));
decimal_msecs = remainder_ns / 1000;
printk_ratelimited(KERN_INFO
"INFO: NMI handler (%ps) took too long to run: "
"%lld.%03d msecs\n", a->handler, whole_msecs,

View File

@ -947,8 +947,18 @@ perf_lock_task_context(struct task_struct *task, int ctxn, unsigned long *flags)
{
struct perf_event_context *ctx;
rcu_read_lock();
retry:
/*
* One of the few rules of preemptible RCU is that one cannot do
* rcu_read_unlock() while holding a scheduler (or nested) lock when
* part of the read side critical section was preemptible -- see
* rcu_read_unlock_special().
*
* Since ctx->lock nests under rq->lock we must ensure the entire read
* side critical section is non-preemptible.
*/
preempt_disable();
rcu_read_lock();
ctx = rcu_dereference(task->perf_event_ctxp[ctxn]);
if (ctx) {
/*
@ -964,6 +974,8 @@ retry:
raw_spin_lock_irqsave(&ctx->lock, *flags);
if (ctx != rcu_dereference(task->perf_event_ctxp[ctxn])) {
raw_spin_unlock_irqrestore(&ctx->lock, *flags);
rcu_read_unlock();
preempt_enable();
goto retry;
}
@ -973,6 +985,7 @@ retry:
}
}
rcu_read_unlock();
preempt_enable();
return ctx;
}
@ -1950,7 +1963,16 @@ static int __perf_event_enable(void *info)
struct perf_cpu_context *cpuctx = __get_cpu_context(ctx);
int err;
if (WARN_ON_ONCE(!ctx->is_active))
/*
* There's a time window between 'ctx->is_active' check
* in perf_event_enable function and this place having:
* - IRQs on
* - ctx->lock unlocked
*
* where the task could be killed and 'ctx' deactivated
* by perf_event_exit_task.
*/
if (!ctx->is_active)
return -EINVAL;
raw_spin_lock(&ctx->lock);
@ -7465,7 +7487,7 @@ inherit_task_group(struct perf_event *event, struct task_struct *parent,
* child.
*/
child_ctx = alloc_perf_context(event->pmu, child);
child_ctx = alloc_perf_context(parent_ctx->pmu, child);
if (!child_ctx)
return -ENOMEM;

View File

@ -3,6 +3,21 @@ include ../../scripts/Makefile.include
CC = $(CROSS_COMPILE)gcc
AR = $(CROSS_COMPILE)ar
# Makefiles suck: This macro sets a default value of $(2) for the
# variable named by $(1), unless the variable has been set by
# environment or command line. This is necessary for CC and AR
# because make sets default values, so the simpler ?= approach
# won't work as expected.
define allow-override
$(if $(or $(findstring environment,$(origin $(1))),\
$(findstring command line,$(origin $(1)))),,\
$(eval $(1) = $(2)))
endef
# Allow setting CC and AR, or setting CROSS_COMPILE as a prefix.
$(call allow-override,CC,$(CROSS_COMPILE)gcc)
$(call allow-override,AR,$(CROSS_COMPILE)ar)
# guard against environment variables
LIB_H=
LIB_OBJS=
@ -14,7 +29,7 @@ LIB_OBJS += $(OUTPUT)debugfs.o
LIBFILE = liblk.a
CFLAGS = -ggdb3 -Wall -Wextra -std=gnu99 -Werror -O6 -D_FORTIFY_SOURCE=2 $(EXTRA_WARNINGS) $(EXTRA_CFLAGS) -fPIC
EXTLIBS = -lpthread -lrt -lelf -lm
EXTLIBS = -lelf -lpthread -lrt -lm
ALL_CFLAGS = $(CFLAGS) $(BASIC_CFLAGS) -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64
ALL_LDFLAGS = $(LDFLAGS)

View File

@ -1,12 +1,6 @@
include ../../scripts/Makefile.include
include ../config/utilities.mak
OUTPUT := ./
ifeq ("$(origin O)", "command line")
ifneq ($(O),)
OUTPUT := $(O)/
endif
endif
MAN1_TXT= \
$(filter-out $(addsuffix .txt, $(ARTICLES) $(SP_ARTICLES)), \
$(wildcard perf-*.txt)) \
@ -150,7 +144,7 @@ NO_SUBDIR = :
endif
ifneq ($(findstring $(MAKEFLAGS),s),s)
ifndef V
ifneq ($(V),1)
QUIET_ASCIIDOC = @echo ' ' ASCIIDOC $@;
QUIET_XMLTO = @echo ' ' XMLTO $@;
QUIET_DB2TEXI = @echo ' ' DB2TEXI $@;
@ -277,7 +271,7 @@ $(MAN_HTML): $(OUTPUT)%.html : %.txt
$(OUTPUT)%.1 $(OUTPUT)%.5 $(OUTPUT)%.7 : $(OUTPUT)%.xml
$(QUIET_XMLTO)$(RM) $@ && \
$(XMLTO) -o $(OUTPUT) -m $(MANPAGE_XSL) $(XMLTO_EXTRA) man $<
$(XMLTO) -o $(OUTPUT). -m $(MANPAGE_XSL) $(XMLTO_EXTRA) man $<
$(OUTPUT)%.xml : %.txt
$(QUIET_ASCIIDOC)$(RM) $@+ $@ && \

View File

@ -66,7 +66,7 @@ Furthermore, these tracepoints can be used to sample the workload as
well. For example the page allocations done by a 'git gc' can be
captured the following way:
titan:~/git> perf record -f -e kmem:mm_page_alloc -c 1 ./git gc
titan:~/git> perf record -e kmem:mm_page_alloc -c 1 ./git gc
Counting objects: 1148, done.
Delta compression using up to 2 threads.
Compressing objects: 100% (450/450), done.
@ -120,7 +120,7 @@ Furthermore, call-graph sampling can be done too, of page
allocations - to see precisely what kind of page allocations there
are:
titan:~/git> perf record -f -g -e kmem:mm_page_alloc -c 1 ./git gc
titan:~/git> perf record -g -e kmem:mm_page_alloc -c 1 ./git gc
Counting objects: 1148, done.
Delta compression using up to 2 threads.
Compressing objects: 100% (450/450), done.

View File

@ -65,16 +65,10 @@ OPTIONS
-r::
--realtime=::
Collect data with this RT SCHED_FIFO priority.
-D::
--no-delay::
Collect data without buffering.
-A::
--append::
Append to the output file to do incremental profiling.
-f::
--force::
Overwrite existing data file. (deprecated)
-c::
--count=::

View File

@ -121,17 +121,16 @@ SCRIPT_SH += perf-archive.sh
grep-libs = $(filter -l%,$(1))
strip-libs = $(filter-out -l%,$(1))
LK_PATH=$(LK_DIR)
ifneq ($(OUTPUT),)
TE_PATH=$(OUTPUT)
ifneq ($(subdir),)
LK_PATH=$(OUTPUT)$(LK_DIR)
LK_PATH=$(objtree)/lib/lk/
else
LK_PATH=$(OUTPUT)
endif
else
TE_PATH=$(TRACE_EVENT_DIR)
LK_PATH=$(LK_DIR)
endif
LIBTRACEEVENT = $(TE_PATH)libtraceevent.a

View File

@ -111,11 +111,11 @@ static double timeval2double(struct timeval *ts)
static void alloc_mem(void **dst, void **src, size_t length)
{
*dst = zalloc(length);
if (!dst)
if (!*dst)
die("memory allocation failed - maybe length is too large?\n");
*src = zalloc(length);
if (!src)
if (!*src)
die("memory allocation failed - maybe length is too large?\n");
}

View File

@ -111,7 +111,7 @@ static double timeval2double(struct timeval *ts)
static void alloc_mem(void **dst, size_t length)
{
*dst = zalloc(length);
if (!dst)
if (!*dst)
die("memory allocation failed - maybe length is too large?\n");
}

View File

@ -607,7 +607,6 @@ int cmd_diff(int argc, const char **argv, const char *prefix __maybe_unused)
input_new = "perf.data.guest";
}
symbol_conf.exclude_other = false;
if (symbol__init() < 0)
return -1;

View File

@ -708,7 +708,7 @@ static int parse_line_opt(const struct option *opt __maybe_unused,
static int __cmd_record(int argc, const char **argv)
{
const char * const record_args[] = {
"record", "-a", "-R", "-f", "-c", "1",
"record", "-a", "-R", "-c", "1",
"-e", "kmem:kmalloc",
"-e", "kmem:kmalloc_node",
"-e", "kmem:kfree",

View File

@ -878,7 +878,7 @@ static int __cmd_report(void)
static int __cmd_record(int argc, const char **argv)
{
const char *record_args[] = {
"record", "-R", "-f", "-m", "1024", "-c", "1",
"record", "-R", "-m", "1024", "-c", "1",
};
unsigned int rec_argc, i, j;
const char **rec_argv;

View File

@ -61,11 +61,6 @@ static void __handle_on_exit_funcs(void)
}
#endif
enum write_mode_t {
WRITE_FORCE,
WRITE_APPEND
};
struct perf_record {
struct perf_tool tool;
struct perf_record_opts opts;
@ -77,12 +72,8 @@ struct perf_record {
int output;
unsigned int page_size;
int realtime_prio;
enum write_mode_t write_mode;
bool no_buildid;
bool no_buildid_cache;
bool force;
bool file_new;
bool append_file;
long samples;
off_t post_processing_offset;
};
@ -200,25 +191,6 @@ static void perf_record__sig_exit(int exit_status __maybe_unused, void *arg)
signal(signr, SIG_DFL);
}
static bool perf_evlist__equal(struct perf_evlist *evlist,
struct perf_evlist *other)
{
struct perf_evsel *pos, *pair;
if (evlist->nr_entries != other->nr_entries)
return false;
pair = perf_evlist__first(other);
list_for_each_entry(pos, &evlist->entries, node) {
if (memcmp(&pos->attr, &pair->attr, sizeof(pos->attr) != 0))
return false;
pair = perf_evsel__next(pair);
}
return true;
}
static int perf_record__open(struct perf_record *rec)
{
char msg[512];
@ -273,16 +245,7 @@ try_again:
goto out;
}
if (rec->file_new)
session->evlist = evlist;
else {
if (!perf_evlist__equal(session->evlist, evlist)) {
fprintf(stderr, "incompatible append\n");
rc = -1;
goto out;
}
}
session->evlist = evlist;
perf_session__set_id_hdr_size(session);
out:
return rc;
@ -415,23 +378,15 @@ static int __cmd_record(struct perf_record *rec, int argc, const char **argv)
if (!strcmp(output_name, "-"))
opts->pipe_output = true;
else if (!stat(output_name, &st) && st.st_size) {
if (rec->write_mode == WRITE_FORCE) {
char oldname[PATH_MAX];
snprintf(oldname, sizeof(oldname), "%s.old",
output_name);
unlink(oldname);
rename(output_name, oldname);
}
} else if (rec->write_mode == WRITE_APPEND) {
rec->write_mode = WRITE_FORCE;
char oldname[PATH_MAX];
snprintf(oldname, sizeof(oldname), "%s.old",
output_name);
unlink(oldname);
rename(output_name, oldname);
}
}
flags = O_CREAT|O_RDWR;
if (rec->write_mode == WRITE_APPEND)
rec->file_new = 0;
else
flags |= O_TRUNC;
flags = O_CREAT|O_RDWR|O_TRUNC;
if (opts->pipe_output)
output = STDOUT_FILENO;
@ -445,7 +400,7 @@ static int __cmd_record(struct perf_record *rec, int argc, const char **argv)
rec->output = output;
session = perf_session__new(output_name, O_WRONLY,
rec->write_mode == WRITE_FORCE, false, NULL);
true, false, NULL);
if (session == NULL) {
pr_err("Not enough memory for reading perf file header\n");
return -1;
@ -465,12 +420,6 @@ static int __cmd_record(struct perf_record *rec, int argc, const char **argv)
if (!rec->opts.branch_stack)
perf_header__clear_feat(&session->header, HEADER_BRANCH_STACK);
if (!rec->file_new) {
err = perf_session__read_header(session, output);
if (err < 0)
goto out_delete_session;
}
if (forks) {
err = perf_evlist__prepare_workload(evsel_list, &opts->target,
argv, opts->pipe_output,
@ -498,7 +447,7 @@ static int __cmd_record(struct perf_record *rec, int argc, const char **argv)
err = perf_header__write_pipe(output);
if (err < 0)
goto out_delete_session;
} else if (rec->file_new) {
} else {
err = perf_session__write_header(session, evsel_list,
output, false);
if (err < 0)
@ -869,8 +818,6 @@ static struct perf_record record = {
.uses_mmap = true,
},
},
.write_mode = WRITE_FORCE,
.file_new = true,
};
#define CALLCHAIN_HELP "do call-graph (stack chain/backtrace) recording: "
@ -906,12 +853,8 @@ const struct option record_options[] = {
"collect raw sample records from all opened counters"),
OPT_BOOLEAN('a', "all-cpus", &record.opts.target.system_wide,
"system-wide collection from all CPUs"),
OPT_BOOLEAN('A', "append", &record.append_file,
"append to the output file to do incremental profiling"),
OPT_STRING('C', "cpu", &record.opts.target.cpu_list, "cpu",
"list of cpus to monitor"),
OPT_BOOLEAN('f', "force", &record.force,
"overwrite existing data file (deprecated)"),
OPT_U64('c', "count", &record.opts.user_interval, "event period to sample"),
OPT_STRING('o', "output", &record.output_name, "file",
"output file name"),
@ -977,16 +920,6 @@ int cmd_record(int argc, const char **argv, const char *prefix __maybe_unused)
if (!argc && perf_target__none(&rec->opts.target))
usage_with_options(record_usage, record_options);
if (rec->force && rec->append_file) {
ui__error("Can't overwrite and append at the same time."
" You need to choose between -f and -A");
usage_with_options(record_usage, record_options);
} else if (rec->append_file) {
rec->write_mode = WRITE_APPEND;
} else {
rec->write_mode = WRITE_FORCE;
}
if (nr_cgroups && !rec->opts.target.system_wide) {
ui__error("cgroup monitoring only available in"
" system-wide mode\n");

View File

@ -939,8 +939,7 @@ repeat:
*/
if (!strstr(sort_order, "parent"))
sort_parent.elide = 1;
} else
symbol_conf.exclude_other = false;
}
if (argc) {
/*

View File

@ -1632,7 +1632,6 @@ static int __cmd_record(int argc, const char **argv)
"record",
"-a",
"-R",
"-f",
"-m", "1024",
"-c", "1",
"-e", "sched:sched_switch",

View File

@ -87,7 +87,7 @@ static int run_count = 1;
static bool no_inherit = false;
static bool scale = true;
static enum aggr_mode aggr_mode = AGGR_GLOBAL;
static pid_t child_pid = -1;
static volatile pid_t child_pid = -1;
static bool null_run = false;
static int detailed_run = 0;
static bool big_num = true;
@ -924,7 +924,7 @@ static void abs_printout(int cpu, int nr, struct perf_evsel *evsel, double avg)
static void print_aggr(char *prefix)
{
struct perf_evsel *counter;
int cpu, s, s2, id, nr;
int cpu, cpu2, s, s2, id, nr;
u64 ena, run, val;
if (!(aggr_map || aggr_get_id))
@ -936,7 +936,8 @@ static void print_aggr(char *prefix)
val = ena = run = 0;
nr = 0;
for (cpu = 0; cpu < perf_evsel__nr_cpus(counter); cpu++) {
s2 = aggr_get_id(evsel_list->cpus, cpu);
cpu2 = perf_evsel__cpus(counter)->map[cpu];
s2 = aggr_get_id(evsel_list->cpus, cpu2);
if (s2 != id)
continue;
val += counter->counts->cpu[cpu].val;
@ -948,7 +949,7 @@ static void print_aggr(char *prefix)
fprintf(output, "%s", prefix);
if (run == 0 || ena == 0) {
aggr_printout(counter, cpu, nr);
aggr_printout(counter, id, nr);
fprintf(output, "%*s%s%*s",
csv_output ? 0 : 18,
@ -1148,13 +1149,34 @@ static void skip_signal(int signo)
done = 1;
signr = signo;
/*
* render child_pid harmless
* won't send SIGTERM to a random
* process in case of race condition
* and fast PID recycling
*/
child_pid = -1;
}
static void sig_atexit(void)
{
sigset_t set, oset;
/*
* avoid race condition with SIGCHLD handler
* in skip_signal() which is modifying child_pid
* goal is to avoid send SIGTERM to a random
* process
*/
sigemptyset(&set);
sigaddset(&set, SIGCHLD);
sigprocmask(SIG_BLOCK, &set, &oset);
if (child_pid != -1)
kill(child_pid, SIGTERM);
sigprocmask(SIG_SETMASK, &oset, NULL);
if (signr == -1)
return;

View File

@ -1005,7 +1005,7 @@ static int __cmd_record(int argc, const char **argv)
{
#ifdef SUPPORT_OLD_POWER_EVENTS
const char * const record_old_args[] = {
"record", "-a", "-R", "-f", "-c", "1",
"record", "-a", "-R", "-c", "1",
"-e", "power:power_start",
"-e", "power:power_end",
"-e", "power:power_frequency",
@ -1014,7 +1014,7 @@ static int __cmd_record(int argc, const char **argv)
};
#endif
const char * const record_new_args[] = {
"record", "-a", "-R", "-f", "-c", "1",
"record", "-a", "-R", "-c", "1",
"-e", "power:cpu_frequency",
"-e", "power:cpu_idle",
"-e", "sched:sched_wakeup",

View File

@ -1130,8 +1130,6 @@ int cmd_top(int argc, const char **argv, const char *prefix __maybe_unused)
if (top.evlist == NULL)
return -ENOMEM;
symbol_conf.exclude_other = false;
argc = parse_options(argc, argv, options, top_usage, 0);
if (argc)
usage_with_options(top_usage, options);

View File

@ -39,7 +39,7 @@ src-perf := $(srctree)/tools/perf
endif
ifeq ($(obj-perf),)
obj-perf := $(objtree)
obj-perf := $(OUTPUT)
endif
ifneq ($(obj-perf),)
@ -85,7 +85,7 @@ CFLAGS += -Wall
CFLAGS += -Wextra
CFLAGS += -std=gnu99
EXTLIBS = -lpthread -lrt -lelf -lm
EXTLIBS = -lelf -lpthread -lrt -lm
ifeq ($(call try-cc,$(SOURCE_HELLO),$(CFLAGS) -Werror -fstack-protector-all,-fstack-protector-all),y)
CFLAGS += -fstack-protector-all
@ -165,7 +165,7 @@ else
LIBDW_LDFLAGS := -L$(LIBDW_DIR)/lib
endif
FLAGS_DWARF=$(CFLAGS) $(LIBDW_CFLAGS) -ldw -lelf $(LIBDW_LDFLAGS) $(LDFLAGS) $(EXTLIBS)
FLAGS_DWARF=$(CFLAGS) $(LIBDW_CFLAGS) -ldw -lz -lelf $(LIBDW_LDFLAGS) $(LDFLAGS) $(EXTLIBS)
ifneq ($(call try-cc,$(SOURCE_DWARF),$(FLAGS_DWARF),libdw),y)
msg := $(warning No libdw.h found or old libdw.h found or elfutils is older than 0.138, disables dwarf support. Please install new elfutils-devel/libdw-dev);
NO_DWARF := 1

View File

@ -173,7 +173,7 @@ _ge-abspath = $(if $(is-executable),$(1))
# Usage: absolute-executable-path-or-empty = $(call get-executable-or-default,variable,default)
#
define get-executable-or-default
$(if $($(1)),$(call _ge_attempt,$($(1)),$(1)),$(call _ge_attempt,$(2),$(1)))
$(if $($(1)),$(call _ge_attempt,$($(1)),$(1)),$(call _ge_attempt,$(2)))
endef
_ge_attempt = $(if $(get-executable),$(get-executable),$(_gea_warn)$(call _gea_err,$(2)))
_gea_warn = $(warning The path '$(1)' is not executable.)
@ -181,7 +181,7 @@ _gea_err = $(if $(1),$(error Please set '$(1)' appropriately))
# try-cc
# Usage: option = $(call try-cc, source-to-build, cc-options, msg)
ifndef V
ifneq ($(V),1)
TRY_CC_OUTPUT= > /dev/null 2>&1
endif
TRY_CC_MSG=echo " CHK $(3)" 1>&2;

View File

@ -23,7 +23,7 @@
#include "perl.h"
#include "XSUB.h"
#include "../../../perf.h"
#include "../../../util/script-event.h"
#include "../../../util/trace-event.h"
MODULE = Perf::Trace::Context PACKAGE = Perf::Trace::Context
PROTOTYPES: ENABLE

View File

@ -13,13 +13,22 @@ LF='
# First check if there is a .git to get the version from git describe
# otherwise try to get the version from the kernel Makefile
#
if test -d ../../.git -o -f ../../.git &&
VN=$(git tag 2>/dev/null | tail -1 | grep -E "v[0-9].[0-9]*")
CID=
TAG=
if test -d ../../.git -o -f ../../.git
then
VN=$(echo $VN"-g"$(git log -1 --abbrev=4 --pretty=format:"%h" HEAD))
VN=$(echo "$VN" | sed -e 's/-/./g');
else
VN=$(MAKEFLAGS= make -sC ../.. kernelversion)
TAG=$(git describe --abbrev=0 --match "v[0-9].[0-9]*" 2>/dev/null )
CID=$(git log -1 --abbrev=4 --pretty=format:"%h" 2>/dev/null) && CID="-g$CID"
fi
if test -z "$TAG"
then
TAG=$(MAKEFLAGS= make -sC ../.. kernelversion)
fi
VN="$TAG$CID"
if test -n "$CID"
then
# format version string, strip trailing zero of sublevel:
VN=$(echo "$VN" | sed -e 's/-/./g;s/\([0-9]*[.][0-9]*\)[.]0/\1/')
fi
VN=$(expr "$VN" : v*'\(.*\)')

View File

@ -513,10 +513,16 @@ void dsos__add(struct list_head *head, struct dso *dso)
list_add_tail(&dso->node, head);
}
struct dso *dsos__find(struct list_head *head, const char *name)
struct dso *dsos__find(struct list_head *head, const char *name, bool cmp_short)
{
struct dso *pos;
if (cmp_short) {
list_for_each_entry(pos, head, node)
if (strcmp(pos->short_name, name) == 0)
return pos;
return NULL;
}
list_for_each_entry(pos, head, node)
if (strcmp(pos->long_name, name) == 0)
return pos;
@ -525,7 +531,7 @@ struct dso *dsos__find(struct list_head *head, const char *name)
struct dso *__dsos__findnew(struct list_head *head, const char *name)
{
struct dso *dso = dsos__find(head, name);
struct dso *dso = dsos__find(head, name, false);
if (!dso) {
dso = dso__new(name);

View File

@ -133,7 +133,8 @@ struct dso *dso__kernel_findnew(struct machine *machine, const char *name,
const char *short_name, int dso_type);
void dsos__add(struct list_head *head, struct dso *dso);
struct dso *dsos__find(struct list_head *head, const char *name);
struct dso *dsos__find(struct list_head *head, const char *name,
bool cmp_short);
struct dso *__dsos__findnew(struct list_head *head, const char *name);
bool __dsos__read_build_ids(struct list_head *head, bool with_hits);

View File

@ -821,6 +821,7 @@ int perf_evlist__prepare_workload(struct perf_evlist *evlist,
goto out_close_pipes;
}
fcntl(go_pipe[1], F_SETFD, FD_CLOEXEC);
evlist->workload.cork_fd = go_pipe[1];
close(child_ready_pipe[0]);
return 0;
@ -837,10 +838,17 @@ out_close_ready_pipe:
int perf_evlist__start_workload(struct perf_evlist *evlist)
{
if (evlist->workload.cork_fd > 0) {
char bf;
int ret;
/*
* Remove the cork, let it rip!
*/
return close(evlist->workload.cork_fd);
ret = write(evlist->workload.cork_fd, &bf, 1);
if (ret < 0)
perror("enable to write to pipe");
close(evlist->workload.cork_fd);
return ret;
}
return 0;

View File

@ -124,7 +124,7 @@ struct event_format *event_format__new(const char *sys, const char *name)
bf = nbf;
}
n = read(fd, bf + size, BUFSIZ);
n = read(fd, bf + size, alloc_size - size);
if (n < 0)
goto out_free_bf;
size += n;
@ -1170,7 +1170,7 @@ int perf_evsel__parse_sample(struct perf_evsel *evsel, union perf_event *event,
} else {
data->user_stack.data = (char *)array;
array += size / sizeof(*array);
data->user_stack.size = *array;
data->user_stack.size = *array++;
}
}

View File

@ -2303,29 +2303,18 @@ int perf_session__write_header(struct perf_session *session,
struct perf_file_header f_header;
struct perf_file_attr f_attr;
struct perf_header *header = &session->header;
struct perf_evsel *evsel, *pair = NULL;
struct perf_evsel *evsel;
int err;
lseek(fd, sizeof(f_header), SEEK_SET);
if (session->evlist != evlist)
pair = perf_evlist__first(session->evlist);
list_for_each_entry(evsel, &evlist->entries, node) {
evsel->id_offset = lseek(fd, 0, SEEK_CUR);
err = do_write(fd, evsel->id, evsel->ids * sizeof(u64));
if (err < 0) {
out_err_write:
pr_debug("failed to write perf header\n");
return err;
}
if (session->evlist != evlist) {
err = do_write(fd, pair->id, pair->ids * sizeof(u64));
if (err < 0)
goto out_err_write;
evsel->ids += pair->ids;
pair = perf_evsel__next(pair);
}
}
header->attr_offset = lseek(fd, 0, SEEK_CUR);
@ -2967,6 +2956,8 @@ int perf_event__process_attr(union perf_event *event,
perf_evlist__id_add(evlist, evsel, 0, i, event->attr.id[i]);
}
symbol_conf.nr_events = evlist->nr_entries;
return 0;
}

View File

@ -860,7 +860,8 @@ int parse_events_terms(struct list_head *terms, const char *str)
return 0;
}
parse_events__free_terms(data.terms);
if (data.terms)
parse_events__free_terms(data.terms);
return ret;
}
@ -1183,6 +1184,7 @@ static int new_term(struct parse_events_term **_term, int type_val,
term->val.str = str;
break;
default:
free(term);
return -EINVAL;
}

View File

@ -32,7 +32,6 @@ int vmlinux_path__nr_entries;
char **vmlinux_path;
struct symbol_conf symbol_conf = {
.exclude_other = true,
.use_modules = true,
.try_vmlinux_path = true,
.annotate_src = true,

View File

@ -72,6 +72,7 @@
#include "types.h"
#include <sys/ttydefaults.h>
#include <lk/debugfs.h>
#include <termios.h>
extern const char *graph_line;
extern const char *graph_dotted_line;
@ -274,6 +275,5 @@ void dump_stack(void);
extern unsigned int page_size;
struct winsize;
void get_term_dimensions(struct winsize *ws);
#endif /* GIT_COMPAT_UTIL_H */

View File

@ -91,7 +91,7 @@ void vdso__exit(void)
struct dso *vdso__dso_findnew(struct list_head *head)
{
struct dso *dso = dsos__find(head, VDSO__MAP_NAME);
struct dso *dso = dsos__find(head, VDSO__MAP_NAME, true);
if (!dso) {
char *file;

View File

@ -59,7 +59,7 @@ QUIET_SUBDIR0 = +$(MAKE) $(COMMAND_O) -C # space to separate -C and subdir
QUIET_SUBDIR1 =
ifneq ($(findstring $(MAKEFLAGS),s),s)
ifndef V
ifneq ($(V),1)
QUIET_CC = @echo ' ' CC $@;
QUIET_AR = @echo ' ' AR $@;
QUIET_LINK = @echo ' ' LINK $@;