perf/urgent fixes:
User visible: . Fix a segfault in 'perf top' when kernel map is restricted (Wang Nan) . Fix hung wakeup tasks after requeueing in 'perf bench futex' (Davidlohr Bueso) . Fix bug in perf probe global variables handling, missing curly braces on an if body (He Kuang) . 'perf bench numa' fixes (command line help/handling, etc) (Petr Holasek) Build fixes: . 'perf kmem' on RHEL6/OL6 (David Ahern) . libtraceevent on 32-bit arch (Namhyung Kim) Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com> -----BEGIN PGP SIGNATURE----- Version: GnuPG v1 iQIcBAABAgAGBQJVPmuWAAoJENZQFvNTUqpAoLQP/RXptWa0Hu72fGBMC1wUQc1N m8rlttBfN6mK21W65u5HsprMApjUGMF0iIUJO2c+TubI6RtRX5pr+KTF+qk8/W6v 7tbOBBRVPaJE1ScxrbWtR1oy82RHaETcBoZ3PeNedQ7m/U+8CtZBvJCP5Mvbj/TT umsuvTt/6vpkasPFJogMgiDZT12juETF0uhbyRtIIzqNRkz/HzpbCZm9CCeD/i56 dfCYwAu/oyAheFC4fcot0QQXtJT9cacE65etVt2cWtO64xA8vWyS/4HW0YsR0K+k ZDhpdvZBpI7deH90iRUhzP7P1mKSJPin9DuCcRJbYfUYcWd4uvvp1H71yTIeXaq8 CYVRz9+QqPQLKeuYd5HGgZURVrLH6shddVL3NwzGR3Ze+jD5Tz+CQtRCS4Lq4XJ3 R2e1pFAPy9tXIdXR5SVjS3MOT/6KlRchrzZwx558DOZm3xin2PL0HM6BJrOSL4gS 8/n10mtJ2OGkgx1+gjizDj1t2a7Nhc2JxamObt19u3yBsHP0s3+et3bEJlMJ9tEU QjNhItVb4I07UInadVpBQsIpLnV3CXyy/uUxI8EIC7KOTymBeZJBprrWh5lkmZHA iDKOetPw79e4DhjUn1ScmU0bZ3/dyz1YwyRUUoy7Y9qQRtBx9Nv4TLZEN7RRZ/rg pKcLZzhDLVvZ+wezcUXr =9vQM -----END PGP SIGNATURE----- Merge tag 'perf-urgent-for-mingo-2' of git://git.kernel.org/pub/scm/linux/kernel/git/acme/linux into perf/urgent Pull perf tooling fixes from Arnaldo Carvalho de Melo: . Fix a segfault in 'perf top' when kernel map is restricted (Wang Nan) . Fix hung wakeup tasks after requeueing in 'perf bench futex' (Davidlohr Bueso) . Fix bug in perf probe global variables handling, missing curly braces on an if body (He Kuang) . 'perf bench numa' fixes (command line help/handling, etc) (Petr Holasek) . fix the 'perf kmem' build on RHEL6/OL6 (David Ahern) . fix the libtraceevent build on 32-bit arch (Namhyung Kim) Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com> Signed-off-by: Ingo Molnar <mingo@kernel.org>
This commit is contained in:
commit
8cc67c3b93
8 changed files with 61 additions and 44 deletions
|
@ -16,7 +16,7 @@ MAKEFLAGS += --no-print-directory
|
|||
LIBFILE = $(OUTPUT)libapi.a
|
||||
|
||||
CFLAGS := $(EXTRA_WARNINGS) $(EXTRA_CFLAGS)
|
||||
CFLAGS += -ggdb3 -Wall -Wextra -std=gnu99 -Werror -O6 -D_FORTIFY_SOURCE=2 -fPIC
|
||||
CFLAGS += -ggdb3 -Wall -Wextra -std=gnu99 -Werror -O6 -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=2 -fPIC
|
||||
CFLAGS += -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64
|
||||
|
||||
RM = rm -f
|
||||
|
|
|
@ -3865,7 +3865,7 @@ static void print_str_arg(struct trace_seq *s, void *data, int size,
|
|||
} else if (el_size == 4) {
|
||||
trace_seq_printf(s, "%u", *(uint32_t *)num);
|
||||
} else if (el_size == 8) {
|
||||
trace_seq_printf(s, "%lu", *(uint64_t *)num);
|
||||
trace_seq_printf(s, "%"PRIu64, *(uint64_t *)num);
|
||||
} else {
|
||||
trace_seq_printf(s, "BAD SIZE:%d 0x%x",
|
||||
el_size, *(uint8_t *)num);
|
||||
|
|
|
@ -132,6 +132,9 @@ int bench_futex_requeue(int argc, const char **argv,
|
|||
if (!fshared)
|
||||
futex_flag = FUTEX_PRIVATE_FLAG;
|
||||
|
||||
if (nrequeue > nthreads)
|
||||
nrequeue = nthreads;
|
||||
|
||||
printf("Run summary [PID %d]: Requeuing %d threads (from [%s] %p to %p), "
|
||||
"%d at a time.\n\n", getpid(), nthreads,
|
||||
fshared ? "shared":"private", &futex1, &futex2, nrequeue);
|
||||
|
@ -161,20 +164,18 @@ int bench_futex_requeue(int argc, const char **argv,
|
|||
|
||||
/* Ok, all threads are patiently blocked, start requeueing */
|
||||
gettimeofday(&start, NULL);
|
||||
for (nrequeued = 0; nrequeued < nthreads; nrequeued += nrequeue) {
|
||||
while (nrequeued < nthreads) {
|
||||
/*
|
||||
* Do not wakeup any tasks blocked on futex1, allowing
|
||||
* us to really measure futex_wait functionality.
|
||||
*/
|
||||
futex_cmp_requeue(&futex1, 0, &futex2, 0,
|
||||
nrequeue, futex_flag);
|
||||
nrequeued += futex_cmp_requeue(&futex1, 0, &futex2, 0,
|
||||
nrequeue, futex_flag);
|
||||
}
|
||||
|
||||
gettimeofday(&end, NULL);
|
||||
timersub(&end, &start, &runtime);
|
||||
|
||||
if (nrequeued > nthreads)
|
||||
nrequeued = nthreads;
|
||||
|
||||
update_stats(&requeued_stats, nrequeued);
|
||||
update_stats(&requeuetime_stats, runtime.tv_usec);
|
||||
|
||||
|
@ -184,7 +185,7 @@ int bench_futex_requeue(int argc, const char **argv,
|
|||
}
|
||||
|
||||
/* everybody should be blocked on futex2, wake'em up */
|
||||
nrequeued = futex_wake(&futex2, nthreads, futex_flag);
|
||||
nrequeued = futex_wake(&futex2, nrequeued, futex_flag);
|
||||
if (nthreads != nrequeued)
|
||||
warnx("couldn't wakeup all tasks (%d/%d)", nrequeued, nthreads);
|
||||
|
||||
|
|
|
@ -180,7 +180,7 @@ static const struct option options[] = {
|
|||
OPT_INTEGER('H', "thp" , &p0.thp, "MADV_NOHUGEPAGE < 0 < MADV_HUGEPAGE"),
|
||||
OPT_BOOLEAN('c', "show_convergence", &p0.show_convergence, "show convergence details"),
|
||||
OPT_BOOLEAN('m', "measure_convergence", &p0.measure_convergence, "measure convergence latency"),
|
||||
OPT_BOOLEAN('q', "quiet" , &p0.show_quiet, "bzero the initial allocations"),
|
||||
OPT_BOOLEAN('q', "quiet" , &p0.show_quiet, "quiet mode"),
|
||||
OPT_BOOLEAN('S', "serialize-startup", &p0.serialize_startup,"serialize thread startup"),
|
||||
|
||||
/* Special option string parsing callbacks: */
|
||||
|
@ -828,6 +828,9 @@ static int count_process_nodes(int process_nr)
|
|||
td = g->threads + task_nr;
|
||||
|
||||
node = numa_node_of_cpu(td->curr_cpu);
|
||||
if (node < 0) /* curr_cpu was likely still -1 */
|
||||
return 0;
|
||||
|
||||
node_present[node] = 1;
|
||||
}
|
||||
|
||||
|
@ -882,6 +885,11 @@ static void calc_convergence_compression(int *strong)
|
|||
for (p = 0; p < g->p.nr_proc; p++) {
|
||||
unsigned int nodes = count_process_nodes(p);
|
||||
|
||||
if (!nodes) {
|
||||
*strong = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
nodes_min = min(nodes, nodes_min);
|
||||
nodes_max = max(nodes, nodes_max);
|
||||
}
|
||||
|
@ -1395,7 +1403,7 @@ static void print_res(const char *name, double val,
|
|||
if (!name)
|
||||
name = "main,";
|
||||
|
||||
if (g->p.show_quiet)
|
||||
if (!g->p.show_quiet)
|
||||
printf(" %-30s %15.3f, %-15s %s\n", name, val, txt_unit, txt_short);
|
||||
else
|
||||
printf(" %14.3f %s\n", val, txt_long);
|
||||
|
|
|
@ -319,7 +319,7 @@ static int page_stat_cmp(struct page_stat *a, struct page_stat *b)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static struct page_stat *search_page_alloc_stat(struct page_stat *stat, bool create)
|
||||
static struct page_stat *search_page_alloc_stat(struct page_stat *pstat, bool create)
|
||||
{
|
||||
struct rb_node **node = &page_alloc_tree.rb_node;
|
||||
struct rb_node *parent = NULL;
|
||||
|
@ -331,7 +331,7 @@ static struct page_stat *search_page_alloc_stat(struct page_stat *stat, bool cre
|
|||
parent = *node;
|
||||
data = rb_entry(*node, struct page_stat, node);
|
||||
|
||||
cmp = page_stat_cmp(data, stat);
|
||||
cmp = page_stat_cmp(data, pstat);
|
||||
if (cmp < 0)
|
||||
node = &parent->rb_left;
|
||||
else if (cmp > 0)
|
||||
|
@ -345,10 +345,10 @@ static struct page_stat *search_page_alloc_stat(struct page_stat *stat, bool cre
|
|||
|
||||
data = zalloc(sizeof(*data));
|
||||
if (data != NULL) {
|
||||
data->page = stat->page;
|
||||
data->order = stat->order;
|
||||
data->gfp_flags = stat->gfp_flags;
|
||||
data->migrate_type = stat->migrate_type;
|
||||
data->page = pstat->page;
|
||||
data->order = pstat->order;
|
||||
data->gfp_flags = pstat->gfp_flags;
|
||||
data->migrate_type = pstat->migrate_type;
|
||||
|
||||
rb_link_node(&data->node, parent, node);
|
||||
rb_insert_color(&data->node, &page_alloc_tree);
|
||||
|
@ -375,7 +375,7 @@ static int perf_evsel__process_page_alloc_event(struct perf_evsel *evsel,
|
|||
unsigned int migrate_type = perf_evsel__intval(evsel, sample,
|
||||
"migratetype");
|
||||
u64 bytes = kmem_page_size << order;
|
||||
struct page_stat *stat;
|
||||
struct page_stat *pstat;
|
||||
struct page_stat this = {
|
||||
.order = order,
|
||||
.gfp_flags = gfp_flags,
|
||||
|
@ -401,21 +401,21 @@ static int perf_evsel__process_page_alloc_event(struct perf_evsel *evsel,
|
|||
* This is to find the current page (with correct gfp flags and
|
||||
* migrate type) at free event.
|
||||
*/
|
||||
stat = search_page(page, true);
|
||||
if (stat == NULL)
|
||||
pstat = search_page(page, true);
|
||||
if (pstat == NULL)
|
||||
return -ENOMEM;
|
||||
|
||||
stat->order = order;
|
||||
stat->gfp_flags = gfp_flags;
|
||||
stat->migrate_type = migrate_type;
|
||||
pstat->order = order;
|
||||
pstat->gfp_flags = gfp_flags;
|
||||
pstat->migrate_type = migrate_type;
|
||||
|
||||
this.page = page;
|
||||
stat = search_page_alloc_stat(&this, true);
|
||||
if (stat == NULL)
|
||||
pstat = search_page_alloc_stat(&this, true);
|
||||
if (pstat == NULL)
|
||||
return -ENOMEM;
|
||||
|
||||
stat->nr_alloc++;
|
||||
stat->alloc_bytes += bytes;
|
||||
pstat->nr_alloc++;
|
||||
pstat->alloc_bytes += bytes;
|
||||
|
||||
order_stats[order][migrate_type]++;
|
||||
|
||||
|
@ -428,7 +428,7 @@ static int perf_evsel__process_page_free_event(struct perf_evsel *evsel,
|
|||
u64 page;
|
||||
unsigned int order = perf_evsel__intval(evsel, sample, "order");
|
||||
u64 bytes = kmem_page_size << order;
|
||||
struct page_stat *stat;
|
||||
struct page_stat *pstat;
|
||||
struct page_stat this = {
|
||||
.order = order,
|
||||
};
|
||||
|
@ -441,8 +441,8 @@ static int perf_evsel__process_page_free_event(struct perf_evsel *evsel,
|
|||
nr_page_frees++;
|
||||
total_page_free_bytes += bytes;
|
||||
|
||||
stat = search_page(page, false);
|
||||
if (stat == NULL) {
|
||||
pstat = search_page(page, false);
|
||||
if (pstat == NULL) {
|
||||
pr_debug2("missing free at page %"PRIx64" (order: %d)\n",
|
||||
page, order);
|
||||
|
||||
|
@ -453,18 +453,18 @@ static int perf_evsel__process_page_free_event(struct perf_evsel *evsel,
|
|||
}
|
||||
|
||||
this.page = page;
|
||||
this.gfp_flags = stat->gfp_flags;
|
||||
this.migrate_type = stat->migrate_type;
|
||||
this.gfp_flags = pstat->gfp_flags;
|
||||
this.migrate_type = pstat->migrate_type;
|
||||
|
||||
rb_erase(&stat->node, &page_tree);
|
||||
free(stat);
|
||||
rb_erase(&pstat->node, &page_tree);
|
||||
free(pstat);
|
||||
|
||||
stat = search_page_alloc_stat(&this, false);
|
||||
if (stat == NULL)
|
||||
pstat = search_page_alloc_stat(&this, false);
|
||||
if (pstat == NULL)
|
||||
return -ENOENT;
|
||||
|
||||
stat->nr_free++;
|
||||
stat->free_bytes += bytes;
|
||||
pstat->nr_free++;
|
||||
pstat->free_bytes += bytes;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -640,9 +640,9 @@ static void print_page_summary(void)
|
|||
nr_page_frees, total_page_free_bytes / 1024);
|
||||
printf("\n");
|
||||
|
||||
printf("%-30s: %'16lu [ %'16"PRIu64" KB ]\n", "Total alloc+freed requests",
|
||||
printf("%-30s: %'16"PRIu64" [ %'16"PRIu64" KB ]\n", "Total alloc+freed requests",
|
||||
nr_alloc_freed, (total_alloc_freed_bytes) / 1024);
|
||||
printf("%-30s: %'16lu [ %'16"PRIu64" KB ]\n", "Total alloc-only requests",
|
||||
printf("%-30s: %'16"PRIu64" [ %'16"PRIu64" KB ]\n", "Total alloc-only requests",
|
||||
nr_page_allocs - nr_alloc_freed,
|
||||
(total_page_alloc_bytes - total_alloc_freed_bytes) / 1024);
|
||||
printf("%-30s: %'16lu [ %'16"PRIu64" KB ]\n", "Total free-only requests",
|
||||
|
|
|
@ -733,7 +733,7 @@ static void perf_event__process_sample(struct perf_tool *tool,
|
|||
"Kernel address maps (/proc/{kallsyms,modules}) are restricted.\n\n"
|
||||
"Check /proc/sys/kernel/kptr_restrict.\n\n"
|
||||
"Kernel%s samples will not be resolved.\n",
|
||||
!RB_EMPTY_ROOT(&al.map->dso->symbols[MAP__FUNCTION]) ?
|
||||
al.map && !RB_EMPTY_ROOT(&al.map->dso->symbols[MAP__FUNCTION]) ?
|
||||
" modules" : "");
|
||||
if (use_browser <= 0)
|
||||
sleep(5);
|
||||
|
|
|
@ -2241,10 +2241,11 @@ static int trace__run(struct trace *trace, int argc, const char **argv)
|
|||
if (err < 0)
|
||||
goto out_error_mmap;
|
||||
|
||||
if (!target__none(&trace->opts.target))
|
||||
perf_evlist__enable(evlist);
|
||||
|
||||
if (forks)
|
||||
perf_evlist__start_workload(evlist);
|
||||
else
|
||||
perf_evlist__enable(evlist);
|
||||
|
||||
trace->multiple_threads = evlist->threads->map[0] == -1 ||
|
||||
evlist->threads->nr > 1 ||
|
||||
|
@ -2272,6 +2273,11 @@ static int trace__run(struct trace *trace, int argc, const char **argv)
|
|||
|
||||
if (interrupted)
|
||||
goto out_disable;
|
||||
|
||||
if (done && !draining) {
|
||||
perf_evlist__disable(evlist);
|
||||
draining = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -578,10 +578,12 @@ static int find_variable(Dwarf_Die *sc_die, struct probe_finder *pf)
|
|||
/* Search child die for local variables and parameters. */
|
||||
if (!die_find_variable_at(sc_die, pf->pvar->var, pf->addr, &vr_die)) {
|
||||
/* Search again in global variables */
|
||||
if (!die_find_variable_at(&pf->cu_die, pf->pvar->var, 0, &vr_die))
|
||||
if (!die_find_variable_at(&pf->cu_die, pf->pvar->var,
|
||||
0, &vr_die)) {
|
||||
pr_warning("Failed to find '%s' in this function.\n",
|
||||
pf->pvar->var);
|
||||
ret = -ENOENT;
|
||||
}
|
||||
}
|
||||
if (ret >= 0)
|
||||
ret = convert_variable(&vr_die, pf);
|
||||
|
|
Loading…
Reference in a new issue