aboutsummaryrefslogtreecommitdiffstats
path: root/tools
diff options
context:
space:
mode:
authorIngo Molnar <mingo@kernel.org>2016-05-20 02:19:20 -0400
committerIngo Molnar <mingo@kernel.org>2016-05-20 02:20:14 -0400
commit21f77d231fabd33c5de61fbff31818d93203353e (patch)
tree74bd85f1184b26409605884bf65ae1c1ba5d724c /tools
parentb0a434fb7412937d55f15b8897c5646c81497bbe (diff)
parenta29d5c9b8167dbc21a7ca8c0302e3799f9063b4e (diff)
Merge tag 'perf-core-for-mingo-20160516' 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: User visible changes: - Honour the kernel.perf_event_max_stack knob more precisely by not counting PERF_CONTEXT_{KERNEL,USER} when deciding when to stop adding entries to the perf_sample->ip_callchain[] array (Arnaldo Carvalho de Melo) - Fix identation of 'stalled-backend-cycles' in 'perf stat' (Namhyung Kim) - Update runtime using 'cpu-clock' event in 'perf stat' (Namhyung Kim) - Use 'cpu-clock' for cpu targets in 'perf stat' (Namhyung Kim) - Avoid fractional digits for integer scales in 'perf stat' (Andi Kleen) - Store vdso buildid unconditionally, as it appears in callchains and we're not checking those when creating the build-id table, so we end up not being able to resolve VDSO symbols when doing analysis on a different machine than the one where recording was done, possibly of a different arch even (arm -> x86_64) (He Kuang) Infrastructure changes: - Generalize max_stack sysctl handler, will be used for configuring multiple kernel knobs related to callchains (Arnaldo Carvalho de Melo) Cleanups: - Introduce DSO__NAME_KALLSYMS and DSO__NAME_KCORE, to stop using open coded strings (Masami Hiramatsu) Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com> Signed-off-by: Ingo Molnar <mingo@kernel.org>
Diffstat (limited to 'tools')
-rw-r--r--tools/perf/builtin-buildid-cache.c8
-rw-r--r--tools/perf/builtin-stat.c22
-rw-r--r--tools/perf/perf.c3
-rw-r--r--tools/perf/util/annotate.c2
-rw-r--r--tools/perf/util/build-id.c2
-rw-r--r--tools/perf/util/dso.c3
-rw-r--r--tools/perf/util/machine.c28
-rw-r--r--tools/perf/util/stat-shadow.c8
-rw-r--r--tools/perf/util/symbol.c10
-rw-r--r--tools/perf/util/symbol.h3
-rw-r--r--tools/perf/util/util.c3
-rw-r--r--tools/perf/util/util.h3
12 files changed, 59 insertions, 36 deletions
diff --git a/tools/perf/builtin-buildid-cache.c b/tools/perf/builtin-buildid-cache.c
index 632efc6b79a0..d75bded21fe0 100644
--- a/tools/perf/builtin-buildid-cache.c
+++ b/tools/perf/builtin-buildid-cache.c
@@ -119,8 +119,8 @@ static int build_id_cache__add_kcore(const char *filename, bool force)
119 if (build_id_cache__kcore_buildid(from_dir, sbuildid) < 0) 119 if (build_id_cache__kcore_buildid(from_dir, sbuildid) < 0)
120 return -1; 120 return -1;
121 121
122 scnprintf(to_dir, sizeof(to_dir), "%s/[kernel.kcore]/%s", 122 scnprintf(to_dir, sizeof(to_dir), "%s/%s/%s",
123 buildid_dir, sbuildid); 123 buildid_dir, DSO__NAME_KCORE, sbuildid);
124 124
125 if (!force && 125 if (!force &&
126 !build_id_cache__kcore_existing(from_dir, to_dir, sizeof(to_dir))) { 126 !build_id_cache__kcore_existing(from_dir, to_dir, sizeof(to_dir))) {
@@ -131,8 +131,8 @@ static int build_id_cache__add_kcore(const char *filename, bool force)
131 if (build_id_cache__kcore_dir(dir, sizeof(dir))) 131 if (build_id_cache__kcore_dir(dir, sizeof(dir)))
132 return -1; 132 return -1;
133 133
134 scnprintf(to_dir, sizeof(to_dir), "%s/[kernel.kcore]/%s/%s", 134 scnprintf(to_dir, sizeof(to_dir), "%s/%s/%s/%s",
135 buildid_dir, sbuildid, dir); 135 buildid_dir, DSO__NAME_KCORE, sbuildid, dir);
136 136
137 if (mkdir_p(to_dir, 0755)) 137 if (mkdir_p(to_dir, 0755))
138 return -1; 138 return -1;
diff --git a/tools/perf/builtin-stat.c b/tools/perf/builtin-stat.c
index e459b685a4e9..ee7ada78d86f 100644
--- a/tools/perf/builtin-stat.c
+++ b/tools/perf/builtin-stat.c
@@ -66,6 +66,7 @@
66#include <stdlib.h> 66#include <stdlib.h>
67#include <sys/prctl.h> 67#include <sys/prctl.h>
68#include <locale.h> 68#include <locale.h>
69#include <math.h>
69 70
70#define DEFAULT_SEPARATOR " " 71#define DEFAULT_SEPARATOR " "
71#define CNTR_NOT_SUPPORTED "<not supported>" 72#define CNTR_NOT_SUPPORTED "<not supported>"
@@ -991,12 +992,12 @@ static void abs_printout(int id, int nr, struct perf_evsel *evsel, double avg)
991 const char *fmt; 992 const char *fmt;
992 993
993 if (csv_output) { 994 if (csv_output) {
994 fmt = sc != 1.0 ? "%.2f%s" : "%.0f%s"; 995 fmt = floor(sc) != sc ? "%.2f%s" : "%.0f%s";
995 } else { 996 } else {
996 if (big_num) 997 if (big_num)
997 fmt = sc != 1.0 ? "%'18.2f%s" : "%'18.0f%s"; 998 fmt = floor(sc) != sc ? "%'18.2f%s" : "%'18.0f%s";
998 else 999 else
999 fmt = sc != 1.0 ? "%18.2f%s" : "%18.0f%s"; 1000 fmt = floor(sc) != sc ? "%18.2f%s" : "%18.0f%s";
1000 } 1001 }
1001 1002
1002 aggr_printout(evsel, id, nr); 1003 aggr_printout(evsel, id, nr);
@@ -1909,6 +1910,9 @@ static int add_default_attributes(void)
1909 } 1910 }
1910 1911
1911 if (!evsel_list->nr_entries) { 1912 if (!evsel_list->nr_entries) {
1913 if (target__has_cpu(&target))
1914 default_attrs0[0].config = PERF_COUNT_SW_CPU_CLOCK;
1915
1912 if (perf_evlist__add_default_attrs(evsel_list, default_attrs0) < 0) 1916 if (perf_evlist__add_default_attrs(evsel_list, default_attrs0) < 0)
1913 return -1; 1917 return -1;
1914 if (pmu_have_event("cpu", "stalled-cycles-frontend")) { 1918 if (pmu_have_event("cpu", "stalled-cycles-frontend")) {
@@ -2000,7 +2004,7 @@ static int process_stat_round_event(struct perf_tool *tool __maybe_unused,
2000 union perf_event *event, 2004 union perf_event *event,
2001 struct perf_session *session) 2005 struct perf_session *session)
2002{ 2006{
2003 struct stat_round_event *round = &event->stat_round; 2007 struct stat_round_event *stat_round = &event->stat_round;
2004 struct perf_evsel *counter; 2008 struct perf_evsel *counter;
2005 struct timespec tsh, *ts = NULL; 2009 struct timespec tsh, *ts = NULL;
2006 const char **argv = session->header.env.cmdline_argv; 2010 const char **argv = session->header.env.cmdline_argv;
@@ -2009,12 +2013,12 @@ static int process_stat_round_event(struct perf_tool *tool __maybe_unused,
2009 evlist__for_each(evsel_list, counter) 2013 evlist__for_each(evsel_list, counter)
2010 perf_stat_process_counter(&stat_config, counter); 2014 perf_stat_process_counter(&stat_config, counter);
2011 2015
2012 if (round->type == PERF_STAT_ROUND_TYPE__FINAL) 2016 if (stat_round->type == PERF_STAT_ROUND_TYPE__FINAL)
2013 update_stats(&walltime_nsecs_stats, round->time); 2017 update_stats(&walltime_nsecs_stats, stat_round->time);
2014 2018
2015 if (stat_config.interval && round->time) { 2019 if (stat_config.interval && stat_round->time) {
2016 tsh.tv_sec = round->time / NSECS_PER_SEC; 2020 tsh.tv_sec = stat_round->time / NSECS_PER_SEC;
2017 tsh.tv_nsec = round->time % NSECS_PER_SEC; 2021 tsh.tv_nsec = stat_round->time % NSECS_PER_SEC;
2018 ts = &tsh; 2022 ts = &tsh;
2019 } 2023 }
2020 2024
diff --git a/tools/perf/perf.c b/tools/perf/perf.c
index 797000842d40..15982cee5ef3 100644
--- a/tools/perf/perf.c
+++ b/tools/perf/perf.c
@@ -549,6 +549,9 @@ int main(int argc, const char **argv)
549 if (sysctl__read_int("kernel/perf_event_max_stack", &value) == 0) 549 if (sysctl__read_int("kernel/perf_event_max_stack", &value) == 0)
550 sysctl_perf_event_max_stack = value; 550 sysctl_perf_event_max_stack = value;
551 551
552 if (sysctl__read_int("kernel/perf_event_max_contexts_per_stack", &value) == 0)
553 sysctl_perf_event_max_contexts_per_stack = value;
554
552 cmd = extract_argv0_path(argv[0]); 555 cmd = extract_argv0_path(argv[0]);
553 if (!cmd) 556 if (!cmd)
554 cmd = "perf-help"; 557 cmd = "perf-help";
diff --git a/tools/perf/util/annotate.c b/tools/perf/util/annotate.c
index 4db73d5a0dbc..b811924e5e1b 100644
--- a/tools/perf/util/annotate.c
+++ b/tools/perf/util/annotate.c
@@ -1122,7 +1122,7 @@ int symbol__annotate(struct symbol *sym, struct map *map, size_t privsize)
1122 } else if (dso__is_kcore(dso)) { 1122 } else if (dso__is_kcore(dso)) {
1123 goto fallback; 1123 goto fallback;
1124 } else if (readlink(symfs_filename, command, sizeof(command)) < 0 || 1124 } else if (readlink(symfs_filename, command, sizeof(command)) < 0 ||
1125 strstr(command, "[kernel.kallsyms]") || 1125 strstr(command, DSO__NAME_KALLSYMS) ||
1126 access(symfs_filename, R_OK)) { 1126 access(symfs_filename, R_OK)) {
1127 free(filename); 1127 free(filename);
1128fallback: 1128fallback:
diff --git a/tools/perf/util/build-id.c b/tools/perf/util/build-id.c
index bff425e1232c..67e5966503b2 100644
--- a/tools/perf/util/build-id.c
+++ b/tools/perf/util/build-id.c
@@ -256,7 +256,7 @@ static int machine__write_buildid_table(struct machine *machine, int fd)
256 size_t name_len; 256 size_t name_len;
257 bool in_kernel = false; 257 bool in_kernel = false;
258 258
259 if (!pos->hit) 259 if (!pos->hit && !dso__is_vdso(pos))
260 continue; 260 continue;
261 261
262 if (dso__is_vdso(pos)) { 262 if (dso__is_vdso(pos)) {
diff --git a/tools/perf/util/dso.c b/tools/perf/util/dso.c
index 3357479082ca..75b75615e2f8 100644
--- a/tools/perf/util/dso.c
+++ b/tools/perf/util/dso.c
@@ -7,6 +7,7 @@
7#include "auxtrace.h" 7#include "auxtrace.h"
8#include "util.h" 8#include "util.h"
9#include "debug.h" 9#include "debug.h"
10#include "vdso.h"
10 11
11char dso__symtab_origin(const struct dso *dso) 12char dso__symtab_origin(const struct dso *dso)
12{ 13{
@@ -1169,7 +1170,7 @@ bool __dsos__read_build_ids(struct list_head *head, bool with_hits)
1169 struct dso *pos; 1170 struct dso *pos;
1170 1171
1171 list_for_each_entry(pos, head, node) { 1172 list_for_each_entry(pos, head, node) {
1172 if (with_hits && !pos->hit) 1173 if (with_hits && !pos->hit && !dso__is_vdso(pos))
1173 continue; 1174 continue;
1174 if (pos->has_build_id) { 1175 if (pos->has_build_id) {
1175 have_build_id = true; 1176 have_build_id = true;
diff --git a/tools/perf/util/machine.c b/tools/perf/util/machine.c
index 639a2903065e..7ba9fadb68af 100644
--- a/tools/perf/util/machine.c
+++ b/tools/perf/util/machine.c
@@ -709,7 +709,7 @@ static struct dso *machine__get_kernel(struct machine *machine)
709 if (machine__is_host(machine)) { 709 if (machine__is_host(machine)) {
710 vmlinux_name = symbol_conf.vmlinux_name; 710 vmlinux_name = symbol_conf.vmlinux_name;
711 if (!vmlinux_name) 711 if (!vmlinux_name)
712 vmlinux_name = "[kernel.kallsyms]"; 712 vmlinux_name = DSO__NAME_KALLSYMS;
713 713
714 kernel = machine__findnew_kernel(machine, vmlinux_name, 714 kernel = machine__findnew_kernel(machine, vmlinux_name,
715 "[kernel]", DSO_TYPE_KERNEL); 715 "[kernel]", DSO_TYPE_KERNEL);
@@ -1811,9 +1811,9 @@ static int thread__resolve_callchain_sample(struct thread *thread,
1811{ 1811{
1812 struct branch_stack *branch = sample->branch_stack; 1812 struct branch_stack *branch = sample->branch_stack;
1813 struct ip_callchain *chain = sample->callchain; 1813 struct ip_callchain *chain = sample->callchain;
1814 int chain_nr = min(max_stack, (int)chain->nr); 1814 int chain_nr = chain->nr;
1815 u8 cpumode = PERF_RECORD_MISC_USER; 1815 u8 cpumode = PERF_RECORD_MISC_USER;
1816 int i, j, err; 1816 int i, j, err, nr_entries, nr_contexts;
1817 int skip_idx = -1; 1817 int skip_idx = -1;
1818 int first_call = 0; 1818 int first_call = 0;
1819 1819
@@ -1828,7 +1828,7 @@ static int thread__resolve_callchain_sample(struct thread *thread,
1828 * Based on DWARF debug information, some architectures skip 1828 * Based on DWARF debug information, some architectures skip
1829 * a callchain entry saved by the kernel. 1829 * a callchain entry saved by the kernel.
1830 */ 1830 */
1831 if (chain->nr < sysctl_perf_event_max_stack) 1831 if (chain_nr < sysctl_perf_event_max_stack)
1832 skip_idx = arch_skip_callchain_idx(thread, chain); 1832 skip_idx = arch_skip_callchain_idx(thread, chain);
1833 1833
1834 /* 1834 /*
@@ -1889,12 +1889,8 @@ static int thread__resolve_callchain_sample(struct thread *thread,
1889 } 1889 }
1890 1890
1891check_calls: 1891check_calls:
1892 if (chain->nr > sysctl_perf_event_max_stack && (int)chain->nr > max_stack) { 1892 for (i = first_call, nr_entries = 0, nr_contexts = 0;
1893 pr_warning("corrupted callchain. skipping...\n"); 1893 i < chain_nr && nr_entries < max_stack; i++) {
1894 return 0;
1895 }
1896
1897 for (i = first_call; i < chain_nr; i++) {
1898 u64 ip; 1894 u64 ip;
1899 1895
1900 if (callchain_param.order == ORDER_CALLEE) 1896 if (callchain_param.order == ORDER_CALLEE)
@@ -1908,6 +1904,14 @@ check_calls:
1908#endif 1904#endif
1909 ip = chain->ips[j]; 1905 ip = chain->ips[j];
1910 1906
1907 if (ip >= PERF_CONTEXT_MAX) {
1908 if (++nr_contexts > sysctl_perf_event_max_contexts_per_stack)
1909 goto out_corrupted_callchain;
1910 } else {
1911 if (++nr_entries > sysctl_perf_event_max_stack)
1912 goto out_corrupted_callchain;
1913 }
1914
1911 err = add_callchain_ip(thread, cursor, parent, root_al, &cpumode, ip); 1915 err = add_callchain_ip(thread, cursor, parent, root_al, &cpumode, ip);
1912 1916
1913 if (err) 1917 if (err)
@@ -1915,6 +1919,10 @@ check_calls:
1915 } 1919 }
1916 1920
1917 return 0; 1921 return 0;
1922
1923out_corrupted_callchain:
1924 pr_warning("corrupted callchain. skipping...\n");
1925 return 0;
1918} 1926}
1919 1927
1920static int unwind_entry(struct unwind_entry *entry, void *arg) 1928static int unwind_entry(struct unwind_entry *entry, void *arg)
diff --git a/tools/perf/util/stat-shadow.c b/tools/perf/util/stat-shadow.c
index fdb71961143e..aa9efe08762b 100644
--- a/tools/perf/util/stat-shadow.c
+++ b/tools/perf/util/stat-shadow.c
@@ -94,7 +94,8 @@ void perf_stat__update_shadow_stats(struct perf_evsel *counter, u64 *count,
94{ 94{
95 int ctx = evsel_context(counter); 95 int ctx = evsel_context(counter);
96 96
97 if (perf_evsel__match(counter, SOFTWARE, SW_TASK_CLOCK)) 97 if (perf_evsel__match(counter, SOFTWARE, SW_TASK_CLOCK) ||
98 perf_evsel__match(counter, SOFTWARE, SW_CPU_CLOCK))
98 update_stats(&runtime_nsecs_stats[cpu], count[0]); 99 update_stats(&runtime_nsecs_stats[cpu], count[0]);
99 else if (perf_evsel__match(counter, HARDWARE, HW_CPU_CYCLES)) 100 else if (perf_evsel__match(counter, HARDWARE, HW_CPU_CYCLES))
100 update_stats(&runtime_cycles_stats[ctx][cpu], count[0]); 101 update_stats(&runtime_cycles_stats[ctx][cpu], count[0]);
@@ -188,7 +189,7 @@ static void print_stalled_cycles_backend(int cpu,
188 189
189 color = get_ratio_color(GRC_STALLED_CYCLES_BE, ratio); 190 color = get_ratio_color(GRC_STALLED_CYCLES_BE, ratio);
190 191
191 out->print_metric(out->ctx, color, "%6.2f%%", "backend cycles idle", ratio); 192 out->print_metric(out->ctx, color, "%7.2f%%", "backend cycles idle", ratio);
192} 193}
193 194
194static void print_branch_misses(int cpu, 195static void print_branch_misses(int cpu,
@@ -444,7 +445,8 @@ void perf_stat__print_shadow_stats(struct perf_evsel *evsel,
444 ratio = total / avg; 445 ratio = total / avg;
445 446
446 print_metric(ctxp, NULL, "%8.0f", "cycles / elision", ratio); 447 print_metric(ctxp, NULL, "%8.0f", "cycles / elision", ratio);
447 } else if (perf_evsel__match(evsel, SOFTWARE, SW_TASK_CLOCK)) { 448 } else if (perf_evsel__match(evsel, SOFTWARE, SW_TASK_CLOCK) ||
449 perf_evsel__match(evsel, SOFTWARE, SW_CPU_CLOCK)) {
448 if ((ratio = avg_stats(&walltime_nsecs_stats)) != 0) 450 if ((ratio = avg_stats(&walltime_nsecs_stats)) != 0)
449 print_metric(ctxp, NULL, "%8.3f", "CPUs utilized", 451 print_metric(ctxp, NULL, "%8.3f", "CPUs utilized",
450 avg / ratio); 452 avg / ratio);
diff --git a/tools/perf/util/symbol.c b/tools/perf/util/symbol.c
index 7fb33304fb4e..2252b545ff43 100644
--- a/tools/perf/util/symbol.c
+++ b/tools/perf/util/symbol.c
@@ -1662,8 +1662,8 @@ static char *dso__find_kallsyms(struct dso *dso, struct map *map)
1662 1662
1663 build_id__sprintf(dso->build_id, sizeof(dso->build_id), sbuild_id); 1663 build_id__sprintf(dso->build_id, sizeof(dso->build_id), sbuild_id);
1664 1664
1665 scnprintf(path, sizeof(path), "%s/[kernel.kcore]/%s", buildid_dir, 1665 scnprintf(path, sizeof(path), "%s/%s/%s", buildid_dir,
1666 sbuild_id); 1666 DSO__NAME_KCORE, sbuild_id);
1667 1667
1668 /* Use /proc/kallsyms if possible */ 1668 /* Use /proc/kallsyms if possible */
1669 if (is_host) { 1669 if (is_host) {
@@ -1699,8 +1699,8 @@ static char *dso__find_kallsyms(struct dso *dso, struct map *map)
1699 if (!find_matching_kcore(map, path, sizeof(path))) 1699 if (!find_matching_kcore(map, path, sizeof(path)))
1700 return strdup(path); 1700 return strdup(path);
1701 1701
1702 scnprintf(path, sizeof(path), "%s/[kernel.kallsyms]/%s", 1702 scnprintf(path, sizeof(path), "%s/%s/%s",
1703 buildid_dir, sbuild_id); 1703 buildid_dir, DSO__NAME_KALLSYMS, sbuild_id);
1704 1704
1705 if (access(path, F_OK)) { 1705 if (access(path, F_OK)) {
1706 pr_err("No kallsyms or vmlinux with build-id %s was found\n", 1706 pr_err("No kallsyms or vmlinux with build-id %s was found\n",
@@ -1769,7 +1769,7 @@ do_kallsyms:
1769 1769
1770 if (err > 0 && !dso__is_kcore(dso)) { 1770 if (err > 0 && !dso__is_kcore(dso)) {
1771 dso->binary_type = DSO_BINARY_TYPE__KALLSYMS; 1771 dso->binary_type = DSO_BINARY_TYPE__KALLSYMS;
1772 dso__set_long_name(dso, "[kernel.kallsyms]", false); 1772 dso__set_long_name(dso, DSO__NAME_KALLSYMS, false);
1773 map__fixup_start(map); 1773 map__fixup_start(map);
1774 map__fixup_end(map); 1774 map__fixup_end(map);
1775 } 1775 }
diff --git a/tools/perf/util/symbol.h b/tools/perf/util/symbol.h
index 2b5e4ed76fcb..25f2fd672c2e 100644
--- a/tools/perf/util/symbol.h
+++ b/tools/perf/util/symbol.h
@@ -44,6 +44,9 @@ Elf_Scn *elf_section_by_name(Elf *elf, GElf_Ehdr *ep,
44#define DMGL_ANSI (1 << 1) /* Include const, volatile, etc */ 44#define DMGL_ANSI (1 << 1) /* Include const, volatile, etc */
45#endif 45#endif
46 46
47#define DSO__NAME_KALLSYMS "[kernel.kallsyms]"
48#define DSO__NAME_KCORE "[kernel.kcore]"
49
47/** struct symbol - symtab entry 50/** struct symbol - symtab entry
48 * 51 *
49 * @ignore - resolvable but tools ignore it (e.g. idle routines) 52 * @ignore - resolvable but tools ignore it (e.g. idle routines)
diff --git a/tools/perf/util/util.c b/tools/perf/util/util.c
index eab077ad6ca9..23504ad5d6dd 100644
--- a/tools/perf/util/util.c
+++ b/tools/perf/util/util.c
@@ -33,7 +33,8 @@ struct callchain_param callchain_param = {
33unsigned int page_size; 33unsigned int page_size;
34int cacheline_size; 34int cacheline_size;
35 35
36unsigned int sysctl_perf_event_max_stack = PERF_MAX_STACK_DEPTH; 36int sysctl_perf_event_max_stack = PERF_MAX_STACK_DEPTH;
37int sysctl_perf_event_max_contexts_per_stack = PERF_MAX_CONTEXTS_PER_STACK;
37 38
38bool test_attr__enabled; 39bool test_attr__enabled;
39 40
diff --git a/tools/perf/util/util.h b/tools/perf/util/util.h
index 7651633a8dc7..1e8c3167b9fb 100644
--- a/tools/perf/util/util.h
+++ b/tools/perf/util/util.h
@@ -261,7 +261,8 @@ void sighandler_dump_stack(int sig);
261 261
262extern unsigned int page_size; 262extern unsigned int page_size;
263extern int cacheline_size; 263extern int cacheline_size;
264extern unsigned int sysctl_perf_event_max_stack; 264extern int sysctl_perf_event_max_stack;
265extern int sysctl_perf_event_max_contexts_per_stack;
265 266
266struct parse_tag { 267struct parse_tag {
267 char tag; 268 char tag;