History

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

Pull more perf updates from Thomas Gleixner: "A rather large set of perf updates: Kernel: - Fix various initialization issues - Prevent creating [ku]probes for not CAP_SYS_ADMIN users Tooling: - Show only failing syscalls with 'perf trace --failure' (Arnaldo Carvalho de Melo) e.g: See what 'openat' syscalls are failing: # perf trace --failure -e openat 762.323 ( 0.007 ms): VideoCapture/4566 openat(dfd: CWD, filename: /dev/video2) = -1 ENOENT No such file or directory <SNIP N /dev/videoN open attempts... sigh, where is that improvised camera lid?!? > 790.228 ( 0.008 ms): VideoCapture/4566 openat(dfd: CWD, filename: /dev/video63) = -1 ENOENT No such file or directory ^C# - Show information about the event (freq, nr_samples, total period/nr_events) in the annotate --tui and --stdio2 'perf annotate' output, similar to the first line in the 'perf report --tui', but just for the samples for a the annotated symbol (Arnaldo Carvalho de Melo) - Introduce 'perf version --build-options' to show what features were linked, aliased as well as a shorter 'perf -vv' (Jin Yao) - Add a "dso_size" sort order (Kim Phillips) - Remove redundant ')' in the tracepoint output in 'perf trace' (Changbin Du) - Synchronize x86's cpufeatures.h, no effect on toolss (Arnaldo Carvalho de Melo) - Show group details on the title line in the annotate browser and 'perf annotate --stdio2' output, so that the per-event columns can have headers (Arnaldo Carvalho de Melo) - Fixup vertical line separating metrics from instructions and cleaning unused lines at the bottom, both in the annotate TUI browser (Arnaldo Carvalho de Melo) - Remove duplicated 'samples' in lost samples warning in 'perf report' (Arnaldo Carvalho de Melo) - Synchronize i915_drm.h, silencing the perf build process, automagically adding support for the new DRM_I915_QUERY ioctl (Arnaldo Carvalho de Melo) - Make auxtrace_queues__add_buffer() allocate struct buffer, from a patchkit already applied (Adrian Hunter) - Fix the --stdio2/TUI annotate output to include group details, be it for a recorded '{a,b,f}' explicit event group or when forcing group display using 'perf report --group' for a set of events not recorded as a group (Arnaldo Carvalho de Melo) - Fix display artifacts in the ui browser (base class for the annotate and main report/top TUI browser) related to the extra title lines work (Arnaldo Carvalho de Melo) - perf auxtrace refactorings, leftovers from a previously partially processed patchset (Adrian Hunter) - Fix the builtin clang build (Sandipan Das, Arnaldo Carvalho de Melo) - Synchronize i915_drm.h, silencing a perf build warning and in the process automagically adding support for a new ioctl command (Arnaldo Carvalho de Melo) - Fix a strncpy issue in uprobe tracing" * 'perf-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: (36 commits) perf/core: Need CAP_SYS_ADMIN to create k/uprobe with perf_event_open() tracing/uprobe_event: Fix strncpy corner case perf/core: Fix perf_uprobe_init() perf/core: Fix perf_kprobe_init() perf/core: Fix use-after-free in uprobe_perf_close() perf tests clang: Fix function name for clang IR test perf clang: Add support for recent clang versions perf tools: Fix perf builds with clang support perf tools: No need to include namespaces.h in util.h perf hists browser: Remove leftover from row returned from refresh perf hists browser: Show extra_title_lines in the 'D' debug hotkey perf auxtrace: Make auxtrace_queues__add_buffer() do CPU filtering tools headers uapi: Synchronize i915_drm.h perf report: Remove duplicated 'samples' in lost samples warning perf ui browser: Fixup cleaning unused lines at the bottom perf annotate browser: Fixup vertical line separating metrics from instructions perf annotate: Show group details on the title line perf auxtrace: Make auxtrace_queues__add_buffer() allocate struct buffer perf/x86/intel: Move regs->flags EXACT bit init perf trace: Remove redundant ')' ...

Linus Torvalds committed 8 years ago

Commit 174e7192 parents 19ca90d 32e6e9633 files · +629 −187Browse files

Unified · Split

33 files
  1. arch/x86/events/intel/ds.c +24 −10
  2. kernel/events/core.c +14 −0
  3. kernel/trace/trace_event_perf.c +4 −0
  4. kernel/trace/trace_uprobe.c +2 −0
  5. tools/arch/x86/include/asm/cpufeatures.h +2 −0
  6. tools/include/tools/config.h +34 −0
  7. tools/include/uapi/drm/i915_drm.h +108 −4
  8. tools/perf/Documentation/perf-report.txt +1 −0
  9. tools/perf/Documentation/perf-trace.txt +3 −0
  10. tools/perf/Documentation/perf-version.txt +24 −0
  11. tools/perf/Makefile.config +7 −1
  12. tools/perf/Makefile.perf +2 −1
  13. tools/perf/builtin-trace.c +7 −4
  14. tools/perf/builtin-version.c +81 −1
  15. tools/perf/perf.c +6 −0
  16. tools/perf/perf.h +1 −0
  17. tools/perf/ui/browser.c +9 −3
  18. tools/perf/ui/browser.h +2 −0
  19. tools/perf/ui/browsers/annotate.c +28 −5
  20. tools/perf/ui/browsers/hists.c +32 −106
  21. tools/perf/util/annotate.c +44 −7
  22. tools/perf/util/annotate.h +12 −0
  23. tools/perf/util/auxtrace.c +33 −39
  24. tools/perf/util/c++/clang-test.cpp +1 −1
  25. tools/perf/util/c++/clang.cpp +10 −1
  26. tools/perf/util/dwarf-aux.c +1 −1
  27. tools/perf/util/hist.c +81 −0
  28. tools/perf/util/hist.h +7 −0
  29. tools/perf/util/map.h +4 −0
  30. tools/perf/util/session.c +1 −1
  31. tools/perf/util/sort.c +41 −0
  32. tools/perf/util/sort.h +1 −0
  33. tools/perf/util/util.h +2 −2
arch/x86/events/intel/ds.c+24−10
@@ -1153,7 +1153,6 @@ static void setup_pebs_sample_data(struct perf_event *event, · 1152 unmodified lines
11531153 if (pebs == NULL)
11541154 return;
11551155
1156− regs->flags &= ~PERF_EFLAGS_EXACT;
11571156 sample_type = event->attr.sample_type;
11581157 dsrc = sample_type & PERF_SAMPLE_DATA_SRC;
11591158
@@ -1197,7 +1196,13 @@ static void setup_pebs_sample_data(struct perf_event *event, · 37 unmodified lines
11971196 * and PMI.
11981197 */
11991198 *regs = *iregs;
1200− regs->flags = pebs->flags;
1199+
1200+ /*
1201+ * Initialize regs_>flags from PEBS,
1202+ * Clear exact bit (which uses x86 EFLAGS Reserved bit 3),
1203+ * i.e., do not rely on it being zero:
1204+ */
1205+ regs->flags = pebs->flags & ~PERF_EFLAGS_EXACT;
12011206
12021207 if (sample_type & PERF_SAMPLE_REGS_INTR) {
12031208 regs->ax = pebs->ax;
@@ -1217,10 +1222,6 @@ static void setup_pebs_sample_data(struct perf_event *event, · 13 unmodified lines
12171222 regs->sp = pebs->sp;
12181223 }
12191224
1220− /*
1221− * Preserve PERF_EFLAGS_VM from set_linear_ip().
1222− */
1223− regs->flags = pebs->flags | (regs->flags & PERF_EFLAGS_VM);
12241225 #ifndef CONFIG_X86_32
12251226 regs->r8 = pebs->r8;
12261227 regs->r9 = pebs->r9;
@@ -1234,20 +1235,33 @@ static void setup_pebs_sample_data(struct perf_event *event, · 7 unmodified lines
12341235 }
12351236
12361237 if (event->attr.precise_ip > 1) {
1237− /* Haswell and later have the eventing IP, so use it: */
1238+ /*
1239+ * Haswell and later processors have an 'eventing IP'
1240+ * (real IP) which fixes the off-by-1 skid in hardware.
1241+ * Use it when precise_ip >= 2 :
1242+ */
12381243 if (x86_pmu.intel_cap.pebs_format >= 2) {
12391244 set_linear_ip(regs, pebs->real_ip);
12401245 regs->flags |= PERF_EFLAGS_EXACT;
12411246 } else {
1242− /* Otherwise use PEBS off-by-1 IP: */
1247+ /* Otherwise, use PEBS off-by-1 IP: */
12431248 set_linear_ip(regs, pebs->ip);
12441249
1245− /* ... and try to fix it up using the LBR entries: */
1250+ /*
1251+ * With precise_ip >= 2, try to fix up the off-by-1 IP
1252+ * using the LBR. If successful, the fixup function
1253+ * corrects regs->ip and calls set_linear_ip() on regs:
1254+ */
12461255 if (intel_pmu_pebs_fixup_ip(regs))
12471256 regs->flags |= PERF_EFLAGS_EXACT;
12481257 }
1249− } else
1258+ } else {
1259+ /*
1260+ * When precise_ip == 1, return the PEBS off-by-1 IP,
1261+ * no fixup attempted:
1262+ */
12501263 set_linear_ip(regs, pebs->ip);
1264+ }
12511265
12521266
12531267 if ((sample_type & (PERF_SAMPLE_ADDR | PERF_SAMPLE_PHYS_ADDR)) &&
kernel/events/core.c+14−0
@@ -4447,6 +4447,9 @@ static void _free_event(struct perf_event *event) · 4446 unmodified lines
44474447 if (event->ctx)
44484448 put_ctx(event->ctx);
44494449
4450+ if (event->hw.target)
4451+ put_task_struct(event->hw.target);
4452+
44504453 exclusive_event_destroy(event);
44514454 module_put(event->pmu->module);
44524455
@@ -8397,6 +8400,10 @@ static int perf_kprobe_event_init(struct perf_event *event) · 3944 unmodified lines
83978400
83988401 if (event->attr.type != perf_kprobe.type)
83998402 return -ENOENT;
8403+
8404+ if (!capable(CAP_SYS_ADMIN))
8405+ return -EACCES;
8406+
84008407 /*
84018408 * no branch sampling for probe events
84028409 */
@@ -8434,6 +8441,10 @@ static int perf_uprobe_event_init(struct perf_event *event) · 31 unmodified lines
84348441
84358442 if (event->attr.type != perf_uprobe.type)
84368443 return -ENOENT;
8444+
8445+ if (!capable(CAP_SYS_ADMIN))
8446+ return -EACCES;
8447+
84378448 /*
84388449 * no branch sampling for probe events
84398450 */
@@ -9955,6 +9966,7 @@ perf_event_alloc(struct perf_event_attr *attr, int cpu, · 1515 unmodified lines
99559966 * and we cannot use the ctx information because we need the
99569967 * pmu before we get a ctx.
99579968 */
9969+ get_task_struct(task);
99589970 event->hw.target = task;
99599971 }
99609972
@@ -10070,6 +10082,8 @@ err_ns: · 109 unmodified lines
1007010082 perf_detach_cgroup(event);
1007110083 if (event->ns)
1007210084 put_pid_ns(event->ns);
10085+ if (event->hw.target)
10086+ put_task_struct(event->hw.target);
1007310087 kfree(event);
1007410088
1007510089 return ERR_PTR(err);
kernel/trace/trace_event_perf.c+4−0
@@ -252,6 +252,8 @@ int perf_kprobe_init(struct perf_event *p_event, bool is_retprobe) · 251 unmodified lines
252252 ret = strncpy_from_user(
253253 func, u64_to_user_ptr(p_event->attr.kprobe_func),
254254 KSYM_NAME_LEN);
255+ if (ret == KSYM_NAME_LEN)
256+ ret = -E2BIG;
255257 if (ret < 0)
256258 goto out;
257259
@@ -300,6 +302,8 @@ int perf_uprobe_init(struct perf_event *p_event, bool is_retprobe) · 42 unmodified lines
300302 return -ENOMEM;
301303 ret = strncpy_from_user(
302304 path, u64_to_user_ptr(p_event->attr.uprobe_path), PATH_MAX);
305+ if (ret == PATH_MAX)
306+ return -E2BIG;
303307 if (ret < 0)
304308 goto out;
305309 if (path[0] == '\0') {
kernel/trace/trace_uprobe.c+2−0
@@ -151,6 +151,8 @@ static void FETCH_FUNC_NAME(memory, string)(struct pt_regs *regs, · 150 unmodified lines
151151 return;
152152
153153 ret = strncpy_from_user(dst, src, maxlen);
154+ if (ret == maxlen)
155+ dst[--ret] = '\0';
154156
155157 if (ret < 0) { /* Failed to fetch string */
156158 ((u8 *)get_rloc_data(dest))[0] = '\0';
tools/arch/x86/include/asm/cpufeatures.h+2−0
@@ -316,6 +316,7 @@ · 315 unmodified lines
316316 #define X86_FEATURE_VPCLMULQDQ (16*32+10) /* Carry-Less Multiplication Double Quadword */
317317 #define X86_FEATURE_AVX512_VNNI (16*32+11) /* Vector Neural Network Instructions */
318318 #define X86_FEATURE_AVX512_BITALG (16*32+12) /* Support for VPOPCNT[B,W] and VPSHUF-BITQMB instructions */
319+#define X86_FEATURE_TME (16*32+13) /* Intel Total Memory Encryption */
319320 #define X86_FEATURE_AVX512_VPOPCNTDQ (16*32+14) /* POPCNT for vectors of DW/QW */
320321 #define X86_FEATURE_LA57 (16*32+16) /* 5-level page tables */
321322 #define X86_FEATURE_RDPID (16*32+22) /* RDPID instruction */
@@ -328,6 +329,7 @@ · 6 unmodified lines
328329 /* Intel-defined CPU features, CPUID level 0x00000007:0 (EDX), word 18 */
329330 #define X86_FEATURE_AVX512_4VNNIW (18*32+ 2) /* AVX-512 Neural Network Instructions */
330331 #define X86_FEATURE_AVX512_4FMAPS (18*32+ 3) /* AVX-512 Multiply Accumulation Single precision */
332+#define X86_FEATURE_PCONFIG (18*32+18) /* Intel PCONFIG */
331333 #define X86_FEATURE_SPEC_CTRL (18*32+26) /* "" Speculation Control (IBRS + IBPB) */
332334 #define X86_FEATURE_INTEL_STIBP (18*32+27) /* "" Single Thread Indirect Branch Predictors */
333335 #define X86_FEATURE_ARCH_CAPABILITIES (18*32+29) /* IA32_ARCH_CAPABILITIES MSR (Intel) */
tools/include/tools/config.h+34−0
@@ -0,0 +1,34 @@
1+/* SPDX-License-Identifier: GPL-2.0 */
2+#ifndef _TOOLS_CONFIG_H
3+#define _TOOLS_CONFIG_H
4+
5+/* Subset of include/linux/kconfig.h */
6+
7+#define __ARG_PLACEHOLDER_1 0,
8+#define __take_second_arg(__ignored, val, ...) val
9+
10+/*
11+ * Helper macros to use CONFIG_ options in C/CPP expressions. Note that
12+ * these only work with boolean and tristate options.
13+ */
14+
15+/*
16+ * Getting something that works in C and CPP for an arg that may or may
17+ * not be defined is tricky. Here, if we have "#define CONFIG_BOOGER 1"
18+ * we match on the placeholder define, insert the "0," for arg1 and generate
19+ * the triplet (0, 1, 0). Then the last step cherry picks the 2nd arg (a one).
20+ * When CONFIG_BOOGER is not defined, we generate a (... 1, 0) pair, and when
21+ * the last step cherry picks the 2nd arg, we get a zero.
22+ */
23+#define __is_defined(x) ___is_defined(x)
24+#define ___is_defined(val) ____is_defined(__ARG_PLACEHOLDER_##val)
25+#define ____is_defined(arg1_or_junk) __take_second_arg(arg1_or_junk 1, 0)
26+
27+/*
28+ * IS_BUILTIN(CONFIG_FOO) evaluates to 1 if CONFIG_FOO is set to 'y', 0
29+ * otherwise. For boolean options, this is equivalent to
30+ * IS_ENABLED(CONFIG_FOO).
31+ */
32+#define IS_BUILTIN(option) __is_defined(option)
33+
34+#endif /* _TOOLS_CONFIG_H */
tools/include/uapi/drm/i915_drm.h+108−4
@@ -318,6 +318,7 @@ typedef struct _drm_i915_sarea { · 317 unmodified lines
318318 #define DRM_I915_PERF_OPEN 0x36
319319 #define DRM_I915_PERF_ADD_CONFIG 0x37
320320 #define DRM_I915_PERF_REMOVE_CONFIG 0x38
321+#define DRM_I915_QUERY 0x39
321322
322323 #define DRM_IOCTL_I915_INIT DRM_IOW( DRM_COMMAND_BASE + DRM_I915_INIT, drm_i915_init_t)
323324 #define DRM_IOCTL_I915_FLUSH DRM_IO ( DRM_COMMAND_BASE + DRM_I915_FLUSH)
@@ -375,6 +376,7 @@ typedef struct _drm_i915_sarea { · 51 unmodified lines
375376 #define DRM_IOCTL_I915_PERF_OPEN DRM_IOW(DRM_COMMAND_BASE + DRM_I915_PERF_OPEN, struct drm_i915_perf_open_param)
376377 #define DRM_IOCTL_I915_PERF_ADD_CONFIG DRM_IOW(DRM_COMMAND_BASE + DRM_I915_PERF_ADD_CONFIG, struct drm_i915_perf_oa_config)
377378 #define DRM_IOCTL_I915_PERF_REMOVE_CONFIG DRM_IOW(DRM_COMMAND_BASE + DRM_I915_PERF_REMOVE_CONFIG, __u64)
379+#define DRM_IOCTL_I915_QUERY DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_QUERY, struct drm_i915_query)
378380
379381 /* Allow drivers to submit batchbuffers directly to hardware, relying
380382 * on the security mechanisms provided by hardware.
@@ -1358,7 +1360,9 @@ struct drm_intel_overlay_attrs { · 977 unmodified lines
13581360 * active on a given plane.
13591361 */
13601362
1361−#define I915_SET_COLORKEY_NONE (1<<0) /* disable color key matching */
1363+#define I915_SET_COLORKEY_NONE (1<<0) /* Deprecated. Instead set
1364+ * flags==0 to disable colorkeying.
1365+ */
13621366 #define I915_SET_COLORKEY_DESTINATION (1<<1)
13631367 #define I915_SET_COLORKEY_SOURCE (1<<2)
13641368 struct drm_intel_sprite_colorkey {
@@ -1604,15 +1608,115 @@ struct drm_i915_perf_oa_config { · 239 unmodified lines
16041608 __u32 n_flex_regs;
16051609
16061610 /*
1607− * These fields are pointers to tuples of u32 values (register
1608− * address, value). For example the expected length of the buffer
1609− * pointed by mux_regs_ptr is (2 * sizeof(u32) * n_mux_regs).
1611+ * These fields are pointers to tuples of u32 values (register address,
1612+ * value). For example the expected length of the buffer pointed by
1613+ * mux_regs_ptr is (2 * sizeof(u32) * n_mux_regs).
16101614 */
16111615 __u64 mux_regs_ptr;
16121616 __u64 boolean_regs_ptr;
16131617 __u64 flex_regs_ptr;
16141618 };
16151619
1620+struct drm_i915_query_item {
1621+ __u64 query_id;
1622+#define DRM_I915_QUERY_TOPOLOGY_INFO 1
1623+
1624+ /*
1625+ * When set to zero by userspace, this is filled with the size of the
1626+ * data to be written at the data_ptr pointer. The kernel sets this
1627+ * value to a negative value to signal an error on a particular query
1628+ * item.
1629+ */
1630+ __s32 length;
1631+
1632+ /*
1633+ * Unused for now. Must be cleared to zero.
1634+ */
1635+ __u32 flags;
1636+
1637+ /*
1638+ * Data will be written at the location pointed by data_ptr when the
1639+ * value of length matches the length of the data to be written by the
1640+ * kernel.
1641+ */
1642+ __u64 data_ptr;
1643+};
1644+
1645+struct drm_i915_query {
1646+ __u32 num_items;
1647+
1648+ /*
1649+ * Unused for now. Must be cleared to zero.
1650+ */
1651+ __u32 flags;
1652+
1653+ /*
1654+ * This points to an array of num_items drm_i915_query_item structures.
1655+ */
1656+ __u64 items_ptr;
1657+};
1658+
1659+/*
1660+ * Data written by the kernel with query DRM_I915_QUERY_TOPOLOGY_INFO :
1661+ *
1662+ * data: contains the 3 pieces of information :
1663+ *
1664+ * - the slice mask with one bit per slice telling whether a slice is
1665+ * available. The availability of slice X can be queried with the following
1666+ * formula :
1667+ *
1668+ * (data[X / 8] >> (X % 8)) & 1
1669+ *
1670+ * - the subslice mask for each slice with one bit per subslice telling
1671+ * whether a subslice is available. The availability of subslice Y in slice
1672+ * X can be queried with the following formula :
1673+ *
1674+ * (data[subslice_offset +
1675+ * X * subslice_stride +
1676+ * Y / 8] >> (Y % 8)) & 1
1677+ *
1678+ * - the EU mask for each subslice in each slice with one bit per EU telling
1679+ * whether an EU is available. The availability of EU Z in subslice Y in
1680+ * slice X can be queried with the following formula :
1681+ *
1682+ * (data[eu_offset +
1683+ * (X * max_subslices + Y) * eu_stride +
1684+ * Z / 8] >> (Z % 8)) & 1
1685+ */
1686+struct drm_i915_query_topology_info {
1687+ /*
1688+ * Unused for now. Must be cleared to zero.
1689+ */
1690+ __u16 flags;
1691+
1692+ __u16 max_slices;
1693+ __u16 max_subslices;
1694+ __u16 max_eus_per_subslice;
1695+
1696+ /*
1697+ * Offset in data[] at which the subslice masks are stored.
1698+ */
1699+ __u16 subslice_offset;
1700+
1701+ /*
1702+ * Stride at which each of the subslice masks for each slice are
1703+ * stored.
1704+ */
1705+ __u16 subslice_stride;
1706+
1707+ /*
1708+ * Offset in data[] at which the EU masks are stored.
1709+ */
1710+ __u16 eu_offset;
1711+
1712+ /*
1713+ * Stride at which each of the EU masks for each subslice are stored.
1714+ */
1715+ __u16 eu_stride;
1716+
1717+ __u8 data[];
1718+};
1719+
16161720 #if defined(__cplusplus)
16171721 }
16181722 #endif
tools/perf/Documentation/perf-report.txt+1−0
@@ -80,6 +80,7 @@ OPTIONS · 79 unmodified lines
8080 - comm: command (name) of the task which can be read via /proc/<pid>/comm
8181 - pid: command and tid of the task
8282 - dso: name of library or module executed at the time of sample
83+ - dso_size: size of library or module executed at the time of sample
8384 - symbol: name of function executed at the time of sample
8485 - symbol_size: size of function executed at the time of sample
8586 - parent: name of function matched to the parent regex filter. Unmatched
tools/perf/Documentation/perf-trace.txt+3−0
@@ -117,6 +117,9 @@ the thread executes on the designated CPUs. Default is to monitor all CPUs. · 116 unmodified lines
117117 --sched::
118118 Accrue thread runtime and provide a summary at the end of the session.
119119
120+--failure::
121+ Show only syscalls that failed, i.e. that returned < 0.
122+
120123 -i::
121124 --input::
122125 Process events from a given perf data file.
tools/perf/Documentation/perf-version.txt+24−0
@@ -0,0 +1,24 @@
1+perf-version(1)
2+===============
3+
4+NAME
5+----
6+perf-version - display the version of perf binary
7+
8+SYNOPSIS
9+--------
10+'perf version' [--build-options]
11+
12+DESCRIPTION
13+-----------
14+With no options given, the 'perf version' prints the perf version
15+on the standard output.
16+
17+If the option '--build-options' is given, then the status of
18+compiled-in libraries are printed on the standard output.
19+
20+OPTIONS
21+-------
22+--build-options::
23+ Prints the status of compiled-in libraries on the
24+ standard output.
tools/perf/Makefile.config+7−1
@@ -346,12 +346,16 @@ else · 345 unmodified lines
346346 ifneq ($(feature-dwarf_getlocations), 1)
347347 msg := $(warning Old libdw.h, finding variables at given 'perf probe' point will not work, install elfutils-devel/libdw-dev >= 0.157);
348348 else
349− CFLAGS += -DHAVE_DWARF_GETLOCATIONS
349+ CFLAGS += -DHAVE_DWARF_GETLOCATIONS_SUPPORT
350350 endif # dwarf_getlocations
351351 endif # Dwarf support
352352 endif # libelf support
353353 endif # NO_LIBELF
354354
355+ifeq ($(feature-glibc), 1)
356+ CFLAGS += -DHAVE_GLIBC_SUPPORT
357+endif
358+
355359 ifdef NO_DWARF
356360 NO_LIBDW_DWARF_UNWIND := 1
357361 endif
@@ -635,6 +639,7 @@ else · 277 unmodified lines
635639 else
636640 LDFLAGS += $(PERL_EMBED_LDFLAGS)
637641 EXTLIBS += $(PERL_EMBED_LIBADD)
642+ CFLAGS += -DHAVE_LIBPERL_SUPPORT
638643 $(call detected,CONFIG_LIBPERL)
639644 endif
640645 endif
@@ -671,6 +676,7 @@ else · 30 unmodified lines
671676 LDFLAGS += $(PYTHON_EMBED_LDFLAGS)
672677 EXTLIBS += $(PYTHON_EMBED_LIBADD)
673678 LANG_BINDINGS += $(obj-perf)python/perf.so
679+ CFLAGS += -DHAVE_LIBPYTHON_SUPPORT
674680 $(call detected,CONFIG_LIBPYTHON)
675681 endif
676682 endif
tools/perf/Makefile.perf+2−1
@@ -364,7 +364,8 @@ LIBS = -Wl,--whole-archive $(PERFLIBS) $(EXTRA_PERFLIBS) -Wl,--no-whole-archive · 363 unmodified lines
364364
365365 ifeq ($(USE_CLANG), 1)
366366 CLANGLIBS_LIST = AST Basic CodeGen Driver Frontend Lex Tooling Edit Sema Analysis Parse Serialization
367− LIBCLANG = $(foreach l,$(CLANGLIBS_LIST),$(wildcard $(shell $(LLVM_CONFIG) --libdir)/libclang$(l).a))
367+ CLANGLIBS_NOEXT_LIST = $(foreach l,$(CLANGLIBS_LIST),$(shell $(LLVM_CONFIG) --libdir)/libclang$(l))
368+ LIBCLANG = $(foreach l,$(CLANGLIBS_NOEXT_LIST),$(wildcard $(l).a $(l).so))
368369 LIBS += -Wl,--start-group $(LIBCLANG) -Wl,--end-group
369370 endif
370371
tools/perf/builtin-trace.c+7−4
@@ -112,6 +112,7 @@ struct trace { · 111 unmodified lines
112112 bool multiple_threads;
113113 bool summary;
114114 bool summary_only;
115+ bool failure_only;
115116 bool show_comm;
116117 bool print_sample;
117118 bool show_tool_stats;
@@ -1565,7 +1566,7 @@ static int trace__printf_interrupted_entry(struct trace *trace) · 1447 unmodified lines
15651566 struct thread_trace *ttrace;
15661567 size_t printed;
15671568
1568− if (trace->current == NULL)
1569+ if (trace->failure_only || trace->current == NULL)
15691570 return 0;
15701571
15711572 ttrace = thread__priv(trace->current);
@@ -1638,7 +1639,7 @@ static int trace__sys_enter(struct trace *trace, struct perf_evsel *evsel, · 66 unmodified lines
16381639 args, trace, thread);
16391640
16401641 if (sc->is_exit) {
1641− if (!(trace->duration_filter || trace->summary_only || trace->min_stack)) {
1642+ if (!(trace->duration_filter || trace->summary_only || trace->failure_only || trace->min_stack)) {
16421643 trace__fprintf_entry_head(trace, thread, 0, false, ttrace->entry_time, trace->output);
16431644 fprintf(trace->output, "%-70s)\n", ttrace->entry_str);
16441645 }
@@ -1742,7 +1743,7 @@ static int trace__sys_exit(struct trace *trace, struct perf_evsel *evsel, · 97 unmodified lines
17421743 }
17431744 }
17441745
1745− if (trace->summary_only)
1746+ if (trace->summary_only || (ret >= 0 && trace->failure_only))
17461747 goto out;
17471748
17481749 trace__fprintf_entry_head(trace, thread, duration, duration_calculated, ttrace->entry_time, trace->output);
@@ -1961,7 +1962,7 @@ static int trace__event_handler(struct trace *trace, struct perf_evsel *evsel, · 212 unmodified lines
19611962 trace->output);
19621963 }
19631964
1964− fprintf(trace->output, ")\n");
1965+ fprintf(trace->output, "\n");
19651966
19661967 if (callchain_ret > 0)
19671968 trace__fprintf_callchain(trace, sample);
@@ -3087,6 +3088,8 @@ int cmd_trace(int argc, const char **argv) · 1119 unmodified lines
30873088 OPT_INCR('v', "verbose", &verbose, "be more verbose"),
30883089 OPT_BOOLEAN('T', "time", &trace.full_time,
30893090 "Show full timestamp, not time relative to first start"),
3091+ OPT_BOOLEAN(0, "failure", &trace.failure_only,
3092+ "Show only syscalls that failed"),
30903093 OPT_BOOLEAN('s', "summary", &trace.summary_only,
30913094 "Show only syscall summary with statistics"),
30923095 OPT_BOOLEAN('S', "with-summary", &trace.summary,
tools/perf/builtin-version.c+81−1
@@ -1,11 +1,91 @@
11 // SPDX-License-Identifier: GPL-2.0
22 #include "builtin.h"
33 #include "perf.h"
4+#include "color.h"
45 #include <linux/compiler.h>
6+#include <tools/config.h>
57 #include <stdio.h>
8+#include <string.h>
9+#include <subcmd/parse-options.h>
610
7−int cmd_version(int argc __maybe_unused, const char **argv __maybe_unused)
11+int version_verbose;
12+
13+struct version {
14+ bool build_options;
15+};
16+
17+static struct version version;
18+
19+static struct option version_options[] = {
20+ OPT_BOOLEAN(0, "build-options", &version.build_options,
21+ "display the build options"),
22+};
23+
24+static const char * const version_usage[] = {
25+ "perf version [<options>]",
26+ NULL
27+};
28+
29+static void on_off_print(const char *status)
30+{
31+ printf("[ ");
32+
33+ if (!strcmp(status, "OFF"))
34+ color_fprintf(stdout, PERF_COLOR_RED, "%-3s", status);
35+ else
36+ color_fprintf(stdout, PERF_COLOR_GREEN, "%-3s", status);
37+
38+ printf(" ]");
39+}
40+
41+static void status_print(const char *name, const char *macro,
42+ const char *status)
843 {
44+ printf("%22s: ", name);
45+ on_off_print(status);
46+ printf(" # %s\n", macro);
47+}
48+
49+#define STATUS(__d, __m) \
50+do { \
51+ if (IS_BUILTIN(__d)) \
52+ status_print(#__m, #__d, "on"); \
53+ else \
54+ status_print(#__m, #__d, "OFF"); \
55+} while (0)
56+
57+static void library_status(void)
58+{
59+ STATUS(HAVE_DWARF_SUPPORT, dwarf);
60+ STATUS(HAVE_DWARF_GETLOCATIONS_SUPPORT, dwarf_getlocations);
61+ STATUS(HAVE_GLIBC_SUPPORT, glibc);
62+ STATUS(HAVE_GTK2_SUPPORT, gtk2);
63+ STATUS(HAVE_LIBAUDIT_SUPPORT, libaudit);
64+ STATUS(HAVE_LIBBFD_SUPPORT, libbfd);
65+ STATUS(HAVE_LIBELF_SUPPORT, libelf);
66+ STATUS(HAVE_LIBNUMA_SUPPORT, libnuma);
67+ STATUS(HAVE_LIBNUMA_SUPPORT, numa_num_possible_cpus);
68+ STATUS(HAVE_LIBPERL_SUPPORT, libperl);
69+ STATUS(HAVE_LIBPYTHON_SUPPORT, libpython);
70+ STATUS(HAVE_SLANG_SUPPORT, libslang);
71+ STATUS(HAVE_LIBCRYPTO_SUPPORT, libcrypto);
72+ STATUS(HAVE_LIBUNWIND_SUPPORT, libunwind);
73+ STATUS(HAVE_DWARF_SUPPORT, libdw-dwarf-unwind);
74+ STATUS(HAVE_ZLIB_SUPPORT, zlib);
75+ STATUS(HAVE_LZMA_SUPPORT, lzma);
76+ STATUS(HAVE_AUXTRACE_SUPPORT, get_cpuid);
77+ STATUS(HAVE_LIBBPF_SUPPORT, bpf);
78+}
79+
80+int cmd_version(int argc, const char **argv)
81+{
82+ argc = parse_options(argc, argv, version_options, version_usage,
83+ PARSE_OPT_STOP_AT_NON_OPTION);
84+
985 printf("perf version %s\n", perf_version_string);
86+
87+ if (version.build_options || version_verbose == 1)
88+ library_status();
89+
1090 return 0;
1191 }
tools/perf/perf.c+6−0
@@ -190,6 +190,12 @@ static int handle_options(const char ***argv, int *argc, int *envchanged) · 189 unmodified lines
190190 break;
191191 }
192192
193+ if (!strcmp(cmd, "-vv")) {
194+ (*argv)[0] = "version";
195+ version_verbose = 1;
196+ break;
197+ }
198+
193199 /*
194200 * Check remaining flags.
195201 */
tools/perf/perf.h+1−0
@@ -84,6 +84,7 @@ struct record_opts { · 83 unmodified lines
8484 struct option;
8585 extern const char * const *record_usage;
8686 extern struct option *record_options;
87+extern int version_verbose;
8788
8889 int record__parse_freq(const struct option *opt, const char *str, int unset);
8990 #endif
tools/perf/ui/browser.c+9−3
@@ -45,11 +45,16 @@ void ui_browser__set_percent_color(struct ui_browser *browser, · 44 unmodified lines
4545 ui_browser__set_color(browser, color);
4646 }
4747
48−void ui_browser__gotorc(struct ui_browser *browser, int y, int x)
48+void ui_browser__gotorc_title(struct ui_browser *browser, int y, int x)
4949 {
5050 SLsmg_gotorc(browser->y + y, browser->x + x);
5151 }
5252
53+void ui_browser__gotorc(struct ui_browser *browser, int y, int x)
54+{
55+ SLsmg_gotorc(browser->y + y + browser->extra_title_lines, browser->x + x);
56+}
57+
5358 void ui_browser__write_nstring(struct ui_browser *browser __maybe_unused, const char *msg,
5459 unsigned int width)
5560 {
@@ -191,6 +196,7 @@ void ui_browser__refresh_dimensions(struct ui_browser *browser) · 135 unmodified lines
191196 {
192197 browser->width = SLtt_Screen_Cols - 1;
193198 browser->height = browser->rows = SLtt_Screen_Rows - 2;
199+ browser->rows -= browser->extra_title_lines;
194200 browser->y = 1;
195201 browser->x = 0;
196202 }
@@ -337,8 +343,8 @@ static int __ui_browser__refresh(struct ui_browser *browser) · 140 unmodified lines
337343 else
338344 width += 1;
339345
340− SLsmg_fill_region(browser->y + row, browser->x,
341− browser->height - row, width, ' ');
346+ SLsmg_fill_region(browser->y + row + browser->extra_title_lines, browser->x,
347+ browser->rows - row, width, ' ');
342348
343349 return 0;
344350 }
tools/perf/ui/browser.h+2−0
@@ -17,6 +17,7 @@ struct ui_browser { · 16 unmodified lines
1717 u64 index, top_idx;
1818 void *top, *entries;
1919 u16 y, x, width, height, rows, columns, horiz_scroll;
20+ u8 extra_title_lines;
2021 int current_color;
2122 void *priv;
2223 const char *title;
@@ -38,6 +39,7 @@ bool ui_browser__is_current_entry(struct ui_browser *browser, unsigned row); · 15 unmodified lines
3839 void ui_browser__refresh_dimensions(struct ui_browser *browser);
3940 void ui_browser__reset_index(struct ui_browser *browser);
4041
42+void ui_browser__gotorc_title(struct ui_browser *browser, int y, int x);
4143 void ui_browser__gotorc(struct ui_browser *browser, int y, int x);
4244 void ui_browser__write_nstring(struct ui_browser *browser, const char *msg,
4345 unsigned int width);
tools/perf/ui/browsers/annotate.c+28−5
@@ -218,7 +218,7 @@ static unsigned int annotate_browser__refresh(struct ui_browser *browser) · 217 unmodified lines
218218 annotate_browser__draw_current_jump(browser);
219219
220220 ui_browser__set_color(browser, HE_COLORSET_NORMAL);
221− __ui_browser__vline(browser, pcnt_width, 0, browser->height - 1);
221+ __ui_browser__vline(browser, pcnt_width, 0, browser->rows - 1);
222222 return ret;
223223 }
224224
@@ -592,21 +592,40 @@ bool annotate_browser__continue_search_reverse(struct annotate_browser *browser, · 367 unmodified lines
592592 return __annotate_browser__search_reverse(browser);
593593 }
594594
595+static int annotate_browser__show(struct ui_browser *browser, char *title, const char *help)
596+{
597+ struct map_symbol *ms = browser->priv;
598+ struct symbol *sym = ms->sym;
599+ char symbol_dso[SYM_TITLE_MAX_SIZE];
600+
601+ if (ui_browser__show(browser, title, help) < 0)
602+ return -1;
603+
604+ sym_title(sym, ms->map, symbol_dso, sizeof(symbol_dso));
605+
606+ ui_browser__gotorc_title(browser, 0, 0);
607+ ui_browser__set_color(browser, HE_COLORSET_ROOT);
608+ ui_browser__write_nstring(browser, symbol_dso, browser->width + 1);
609+ return 0;
610+}
611+
595612 static int annotate_browser__run(struct annotate_browser *browser,
596613 struct perf_evsel *evsel,
597614 struct hist_browser_timer *hbt)
598615 {
599616 struct rb_node *nd = NULL;
617+ struct hists *hists = evsel__hists(evsel);
600618 struct map_symbol *ms = browser->b.priv;
601619 struct symbol *sym = ms->sym;
602620 struct annotation *notes = symbol__annotation(ms->sym);
603621 const char *help = "Press 'h' for help on key bindings";
604622 int delay_secs = hbt ? hbt->refresh : 0;
623+ char title[256];
605624 int key;
606− char title[SYM_TITLE_MAX_SIZE];
607625
608− sym_title(sym, ms->map, title, sizeof(title));
609− if (ui_browser__show(&browser->b, title, help) < 0)
626+ annotation__scnprintf_samples_period(notes, title, sizeof(title), evsel);
627+
628+ if (annotate_browser__show(&browser->b, title, help) < 0)
610629 return -1;
611630
612631 annotate_browser__calc_percent(browser, evsel);
@@ -637,8 +656,11 @@ static int annotate_browser__run(struct annotate_browser *browser, · 24 unmodified lines
637656 if (hbt)
638657 hbt->timer(hbt->arg);
639658
640− if (delay_secs != 0)
659+ if (delay_secs != 0) {
641660 symbol__annotate_decay_histogram(sym, evsel->idx);
661+ hists__scnprintf_title(hists, title, sizeof(title));
662+ annotate_browser__show(&browser->b, title, help);
663+ }
642664 continue;
643665 case K_TAB:
644666 if (nd != NULL) {
@@ -812,6 +834,7 @@ int symbol__tui_annotate(struct symbol *sym, struct map *map, · 167 unmodified lines
812834 .seek = ui_browser__list_head_seek,
813835 .write = annotate_browser__write,
814836 .filter = disasm_line__filter,
837+ .extra_title_lines = 1, /* for hists__scnprintf_title() */
815838 .priv = &ms,
816839 .use_navkeypressed = true,
817840 },
tools/perf/ui/browsers/hists.c+32−106
@@ -32,8 +32,7 @@ · 31 unmodified lines
3232
3333 extern void hist_browser__init_hpp(void);
3434
35−static int perf_evsel_browser_title(struct hist_browser *browser,
36− char *bf, size_t size);
35+static int hists_browser__scnprintf_title(struct hist_browser *browser, char *bf, size_t size);
3736 static void hist_browser__update_nr_entries(struct hist_browser *hb);
3837
3938 static struct rb_node *hists__filter_entries(struct rb_node *nd,
@@ -62,6 +61,15 @@ static int hist_browser__get_folding(struct hist_browser *browser) · 22 unmodified lines
6261 return unfolded_rows;
6362 }
6463
64+static void hist_browser__set_title_space(struct hist_browser *hb)
65+{
66+ struct ui_browser *browser = &hb->b;
67+ struct hists *hists = hb->hists;
68+ struct perf_hpp_list *hpp_list = hists->hpp_list;
69+
70+ browser->extra_title_lines = hb->show_headers ? hpp_list->nr_header_lines : 0;
71+}
72+
6573 static u32 hist_browser__nr_entries(struct hist_browser *hb)
6674 {
6775 u32 nr_entries;
@@ -82,10 +90,16 @@ static void hist_browser__update_rows(struct hist_browser *hb) · 14 unmodified lines
8290 struct ui_browser *browser = &hb->b;
8391 struct hists *hists = hb->hists;
8492 struct perf_hpp_list *hpp_list = hists->hpp_list;
85− u16 header_offset, index_row;
93+ u16 index_row;
8694
87− header_offset = hb->show_headers ? hpp_list->nr_header_lines : 0;
88− browser->rows = browser->height - header_offset;
95+ if (!hb->show_headers) {
96+ browser->rows += browser->extra_title_lines;
97+ browser->extra_title_lines = 0;
98+ return;
99+ }
100+
101+ browser->extra_title_lines = hpp_list->nr_header_lines;
102+ browser->rows -= browser->extra_title_lines;
89103 /*
90104 * Verify if we were at the last line and that line isn't
91105 * visibe because we now show the header line(s).
@@ -108,17 +122,6 @@ static void hist_browser__refresh_dimensions(struct ui_browser *browser) · 16 unmodified lines
108122 * changeset.
109123 */
110124 ui_browser__refresh_dimensions(browser);
111− hist_browser__update_rows(hb);
112−}
113−
114−static void hist_browser__gotorc(struct hist_browser *browser, int row, int column)
115−{
116− struct hists *hists = browser->hists;
117− struct perf_hpp_list *hpp_list = hists->hpp_list;
118− u16 header_offset;
119−
120− header_offset = browser->show_headers ? hpp_list->nr_header_lines : 0;
121− ui_browser__gotorc(&browser->b, row + header_offset, column);
122125 }
123126
124127 static void hist_browser__reset(struct hist_browser *browser)
@@ -656,9 +659,10 @@ int hist_browser__run(struct hist_browser *browser, const char *help, · 531 unmodified lines
656659 struct hist_entry *h = rb_entry(browser->b.top,
657660 struct hist_entry, rb_node);
658661 ui_helpline__pop();
659− ui_helpline__fpush("%d: nr_ent=(%d,%d), rows=%d, idx=%d, fve: idx=%d, row_off=%d, nrows=%d",
662+ ui_helpline__fpush("%d: nr_ent=(%d,%d), etl: %d, rows=%d, idx=%d, fve: idx=%d, row_off=%d, nrows=%d",
660663 seq++, browser->b.nr_entries,
661664 browser->hists->nr_entries,
665+ browser->b.extra_title_lines,
662666 browser->b.rows,
663667 browser->b.index,
664668 browser->b.top_idx,
@@ -733,7 +737,7 @@ static void hist_browser__show_callchain_entry(struct hist_browser *browser, · 68 unmodified lines
733737 }
734738
735739 ui_browser__set_color(&browser->b, color);
736− hist_browser__gotorc(browser, row, 0);
740+ ui_browser__gotorc(&browser->b, row, 0);
737741 ui_browser__write_nstring(&browser->b, " ", offset);
738742 ui_browser__printf(&browser->b, "%c", folded_sign);
739743 ui_browser__write_graph(&browser->b, show_annotated ? SLSMG_RARROW_CHAR : ' ');
@@ -1249,7 +1253,7 @@ static int hist_browser__show_entry(struct hist_browser *browser, · 509 unmodified lines
12491253 };
12501254 int column = 0;
12511255
1252− hist_browser__gotorc(browser, row, 0);
1256+ ui_browser__gotorc(&browser->b, row, 0);
12531257
12541258 hists__for_each_format(browser->hists, fmt) {
12551259 char s[2048];
@@ -1358,7 +1362,7 @@ static int hist_browser__show_hierarchy_entry(struct hist_browser *browser, · 102 unmodified lines
13581362 goto show_callchain;
13591363 }
13601364
1361− hist_browser__gotorc(browser, row, 0);
1365+ ui_browser__gotorc(&browser->b, row, 0);
13621366
13631367 if (current_entry && browser->b.navkeypressed)
13641368 ui_browser__set_color(&browser->b, HE_COLORSET_SELECTED);
@@ -1507,7 +1511,7 @@ static int hist_browser__show_no_entry(struct hist_browser *browser, · 142 unmodified lines
15071511 browser->selection = NULL;
15081512 }
15091513
1510− hist_browser__gotorc(browser, row, 0);
1514+ ui_browser__gotorc(&browser->b, row, 0);
15111515
15121516 if (current_entry && browser->b.navkeypressed)
15131517 ui_browser__set_color(&browser->b, HE_COLORSET_SELECTED);
@@ -1713,7 +1717,7 @@ static void hists_browser__headers(struct hist_browser *browser) · 199 unmodified lines
17131717 hists_browser__scnprintf_headers(browser, headers,
17141718 sizeof(headers), line);
17151719
1716− ui_browser__gotorc(&browser->b, line, 0);
1720+ ui_browser__gotorc_title(&browser->b, line, 0);
17171721 ui_browser__set_color(&browser->b, HE_COLORSET_ROOT);
17181722 ui_browser__write_nstring(&browser->b, headers, browser->b.width + 1);
17191723 }
@@ -1740,17 +1744,11 @@ static void ui_browser__hists_init_top(struct ui_browser *browser) · 20 unmodified lines
17401744 static unsigned int hist_browser__refresh(struct ui_browser *browser)
17411745 {
17421746 unsigned row = 0;
1743− u16 header_offset = 0;
17441747 struct rb_node *nd;
17451748 struct hist_browser *hb = container_of(browser, struct hist_browser, b);
1746− struct hists *hists = hb->hists;
1747−
1748− if (hb->show_headers) {
1749− struct perf_hpp_list *hpp_list = hists->hpp_list;
17501749
1750+ if (hb->show_headers)
17511751 hist_browser__show_headers(hb);
1752− header_offset = hpp_list->nr_header_lines;
1753− }
17541752
17551753 ui_browser__hists_init_top(browser);
17561754 hb->he_selection = NULL;
@@ -1788,7 +1786,7 @@ static unsigned int hist_browser__refresh(struct ui_browser *browser) · 31 unmodified lines
17881786 break;
17891787 }
17901788
1791− return row + header_offset;
1789+ return row;
17921790 }
17931791
17941792 static struct rb_node *hists__filter_entries(struct rb_node *nd,
@@ -2143,6 +2141,7 @@ void hist_browser__init(struct hist_browser *browser, · 348 unmodified lines
21432141 browser->b.seek = ui_browser__hists_seek;
21442142 browser->b.use_navkeypressed = true;
21452143 browser->show_headers = symbol_conf.show_hist_headers;
2144+ hist_browser__set_title_space(browser);
21462145
21472146 if (symbol_conf.report_hierarchy) {
21482147 struct perf_hpp_list_node *fmt_node;
@@ -2183,7 +2182,7 @@ perf_evsel_browser__new(struct perf_evsel *evsel, · 34 unmodified lines
21832182 if (browser) {
21842183 browser->hbt = hbt;
21852184 browser->env = env;
2186− browser->title = perf_evsel_browser_title;
2185+ browser->title = hists_browser__scnprintf_title;
21872186 }
21882187 return browser;
21892188 }
@@ -2209,84 +2208,11 @@ static inline bool is_report_browser(void *timer) · 19 unmodified lines
22092208 return timer == NULL;
22102209 }
22112210
2212−static int perf_evsel_browser_title(struct hist_browser *browser,
2213− char *bf, size_t size)
2211+static int hists_browser__scnprintf_title(struct hist_browser *browser, char *bf, size_t size)
22142212 {
22152213 struct hist_browser_timer *hbt = browser->hbt;
2216− struct hists *hists = browser->hists;
2217− char unit;
2218− int printed;
2219− const struct dso *dso = hists->dso_filter;
2220− const struct thread *thread = hists->thread_filter;
2221− int socket_id = hists->socket_filter;
2222− unsigned long nr_samples = hists->stats.nr_events[PERF_RECORD_SAMPLE];
2223− u64 nr_events = hists->stats.total_period;
2224− struct perf_evsel *evsel = hists_to_evsel(hists);
2225− const char *ev_name = perf_evsel__name(evsel);
2226− char buf[512], sample_freq_str[64] = "";
2227− size_t buflen = sizeof(buf);
2228− char ref[30] = " show reference callgraph, ";
2229− bool enable_ref = false;
2214+ int printed = __hists__scnprintf_title(browser->hists, bf, size, !is_report_browser(hbt));
22302215
2231− if (symbol_conf.filter_relative) {
2232− nr_samples = hists->stats.nr_non_filtered_samples;
2233− nr_events = hists->stats.total_non_filtered_period;
2234− }
2235−
2236− if (perf_evsel__is_group_event(evsel)) {
2237− struct perf_evsel *pos;
2238−
2239− perf_evsel__group_desc(evsel, buf, buflen);
2240− ev_name = buf;
2241−
2242− for_each_group_member(pos, evsel) {
2243− struct hists *pos_hists = evsel__hists(pos);
2244−
2245− if (symbol_conf.filter_relative) {
2246− nr_samples += pos_hists->stats.nr_non_filtered_samples;
2247− nr_events += pos_hists->stats.total_non_filtered_period;
2248− } else {
2249− nr_samples += pos_hists->stats.nr_events[PERF_RECORD_SAMPLE];
2250− nr_events += pos_hists->stats.total_period;
2251− }
2252− }
2253− }
2254−
2255− if (symbol_conf.show_ref_callgraph &&
2256− strstr(ev_name, "call-graph=no"))
2257− enable_ref = true;
2258−
2259− if (!is_report_browser(hbt))
2260− scnprintf(sample_freq_str, sizeof(sample_freq_str), " %d Hz,", evsel->attr.sample_freq);
2261−
2262− nr_samples = convert_unit(nr_samples, &unit);
2263− printed = scnprintf(bf, size,
2264− "Samples: %lu%c of event%s '%s',%s%sEvent count (approx.): %" PRIu64,
2265− nr_samples, unit, evsel->nr_members > 1 ? "s" : "",
2266− ev_name, sample_freq_str, enable_ref ? ref : " ", nr_events);
2267−
2268−
2269− if (hists->uid_filter_str)
2270− printed += snprintf(bf + printed, size - printed,
2271− ", UID: %s", hists->uid_filter_str);
2272− if (thread) {
2273− if (hists__has(hists, thread)) {
2274− printed += scnprintf(bf + printed, size - printed,
2275− ", Thread: %s(%d)",
2276− (thread->comm_set ? thread__comm_str(thread) : ""),
2277− thread->tid);
2278− } else {
2279− printed += scnprintf(bf + printed, size - printed,
2280− ", Thread: %s",
2281− (thread->comm_set ? thread__comm_str(thread) : ""));
2282− }
2283− }
2284− if (dso)
2285− printed += scnprintf(bf + printed, size - printed,
2286− ", DSO: %s", dso->short_name);
2287− if (socket_id > -1)
2288− printed += scnprintf(bf + printed, size - printed,
2289− ", Processor Socket: %d", socket_id);
22902216 if (!is_report_browser(hbt)) {
22912217 struct perf_top *top = hbt->arg;
22922218
tools/perf/util/annotate.c+44−7
@@ -17,6 +17,7 @@ · 16 unmodified lines
1717 #include "config.h"
1818 #include "cache.h"
1919 #include "symbol.h"
20+#include "units.h"
2021 #include "debug.h"
2122 #include "annotate.h"
2223 #include "evsel.h"
@@ -2324,7 +2325,7 @@ int symbol__tty_annotate2(struct symbol *sym, struct map *map, · 2301 unmodified lines
23242325 struct dso *dso = map->dso;
23252326 struct rb_root source_line = RB_ROOT;
23262327 struct annotation_options opts = annotation__default_options;
2327− const char *ev_name = perf_evsel__name(evsel);
2328+ struct annotation *notes = symbol__annotation(sym);
23282329 char buf[1024];
23292330
23302331 if (symbol__annotate2(sym, map, evsel, &opts, NULL) < 0)
@@ -2336,12 +2337,8 @@ int symbol__tty_annotate2(struct symbol *sym, struct map *map, · 5 unmodified lines
23362337 print_summary(&source_line, dso->long_name);
23372338 }
23382339
2339− if (perf_evsel__is_group_event(evsel)) {
2340− perf_evsel__group_desc(evsel, buf, sizeof(buf));
2341− ev_name = buf;
2342− }
2343−
2344− fprintf(stdout, "%s() %s\nEvent: %s\n\n", sym->name, dso->long_name, ev_name);
2340+ annotation__scnprintf_samples_period(notes, buf, sizeof(buf), evsel);
2341+ fprintf(stdout, "%s\n%s() %s\n", buf, sym->name, dso->long_name);
23452342 symbol__annotate_fprintf2(sym, stdout);
23462343
23472344 annotated_source__purge(symbol__annotation(sym)->src);
@@ -2597,6 +2594,46 @@ out_free_offsets: · 249 unmodified lines
25972594 return -1;
25982595 }
25992596
2597+int __annotation__scnprintf_samples_period(struct annotation *notes,
2598+ char *bf, size_t size,
2599+ struct perf_evsel *evsel,
2600+ bool show_freq)
2601+{
2602+ const char *ev_name = perf_evsel__name(evsel);
2603+ char buf[1024], ref[30] = " show reference callgraph, ";
2604+ char sample_freq_str[64] = "";
2605+ unsigned long nr_samples = 0;
2606+ int nr_members = 1;
2607+ bool enable_ref = false;
2608+ u64 nr_events = 0;
2609+ char unit;
2610+ int i;
2611+
2612+ if (perf_evsel__is_group_event(evsel)) {
2613+ perf_evsel__group_desc(evsel, buf, sizeof(buf));
2614+ ev_name = buf;
2615+ nr_members = evsel->nr_members;
2616+ }
2617+
2618+ for (i = 0; i < nr_members; i++) {
2619+ struct sym_hist *ah = annotation__histogram(notes, evsel->idx + i);
2620+
2621+ nr_samples += ah->nr_samples;
2622+ nr_events += ah->period;
2623+ }
2624+
2625+ if (symbol_conf.show_ref_callgraph && strstr(ev_name, "call-graph=no"))
2626+ enable_ref = true;
2627+
2628+ if (show_freq)
2629+ scnprintf(sample_freq_str, sizeof(sample_freq_str), " %d Hz,", evsel->attr.sample_freq);
2630+
2631+ nr_samples = convert_unit(nr_samples, &unit);
2632+ return scnprintf(bf, size, "Samples: %lu%c of event%s '%s',%s%sEvent count (approx.): %" PRIu64,
2633+ nr_samples, unit, evsel->nr_members > 1 ? "s" : "",
2634+ ev_name, sample_freq_str, enable_ref ? ref : " ", nr_events);
2635+}
2636+
26002637 #define ANNOTATION__CFG(n) \
26012638 { .name = #n, .value = &annotation__default_options.n, }
26022639
tools/perf/util/annotate.h+12−0
@@ -151,6 +151,18 @@ double annotation_line__max_percent(struct annotation_line *al, struct annotatio · 150 unmodified lines
151151 void annotation_line__write(struct annotation_line *al, struct annotation *notes,
152152 struct annotation_write_ops *ops);
153153
154+int __annotation__scnprintf_samples_period(struct annotation *notes,
155+ char *bf, size_t size,
156+ struct perf_evsel *evsel,
157+ bool show_freq);
158+
159+static inline int annotation__scnprintf_samples_period(struct annotation *notes,
160+ char *bf, size_t size,
161+ struct perf_evsel *evsel)
162+{
163+ return __annotation__scnprintf_samples_period(notes, bf, size, evsel, true);
164+}
165+
154166 int disasm_line__scnprintf(struct disasm_line *dl, char *bf, size_t size, bool raw);
155167 size_t disasm__fprintf(struct list_head *head, FILE *fp);
156168 void symbol__calc_percent(struct symbol *sym, struct perf_evsel *evsel);
tools/perf/util/auxtrace.c+33−39
@@ -302,13 +302,27 @@ static int auxtrace_queues__split_buffer(struct auxtrace_queues *queues, · 301 unmodified lines
302302 return 0;
303303 }
304304
305+static bool filter_cpu(struct perf_session *session, int cpu)
306+{
307+ unsigned long *cpu_bitmap = session->itrace_synth_opts->cpu_bitmap;
308+
309+ return cpu_bitmap && cpu != -1 && !test_bit(cpu, cpu_bitmap);
310+}
311+
305312 static int auxtrace_queues__add_buffer(struct auxtrace_queues *queues,
306313 struct perf_session *session,
307314 unsigned int idx,
308315 struct auxtrace_buffer *buffer,
309316 struct auxtrace_buffer **buffer_ptr)
310317 {
311− int err;
318+ int err = -ENOMEM;
319+
320+ if (filter_cpu(session, buffer->cpu))
321+ return 0;
322+
323+ buffer = memdup(buffer, sizeof(*buffer));
324+ if (!buffer)
325+ return -ENOMEM;
312326
313327 if (session->one_mmap) {
314328 buffer->data = buffer->data_offset - session->one_mmap_offset +
@@ -316,31 +330,28 @@ static int auxtrace_queues__add_buffer(struct auxtrace_queues *queues, · 1 unmodified line
316330 } else if (perf_data__is_pipe(session->data)) {
317331 buffer->data = auxtrace_copy_data(buffer->size, session);
318332 if (!buffer->data)
319− return -ENOMEM;
333+ goto out_free;
320334 buffer->data_needs_freeing = true;
321335 } else if (BITS_PER_LONG == 32 &&
322336 buffer->size > BUFFER_LIMIT_FOR_32_BIT) {
323337 err = auxtrace_queues__split_buffer(queues, idx, buffer);
324338 if (err)
325− return err;
339+ goto out_free;
326340 }
327341
328342 err = auxtrace_queues__queue_buffer(queues, idx, buffer);
329343 if (err)
330− return err;
344+ goto out_free;
331345
332346 /* FIXME: Doesn't work for split buffer */
333347 if (buffer_ptr)
334348 *buffer_ptr = buffer;
335349
336350 return 0;
337−}
338351
339−static bool filter_cpu(struct perf_session *session, int cpu)
340−{
341− unsigned long *cpu_bitmap = session->itrace_synth_opts->cpu_bitmap;
342−
343− return cpu_bitmap && cpu != -1 && !test_bit(cpu, cpu_bitmap);
352+out_free:
353+ auxtrace_buffer__free(buffer);
354+ return err;
344355 }
345356
346357 int auxtrace_queues__add_event(struct auxtrace_queues *queues,
@@ -348,36 +359,19 @@ int auxtrace_queues__add_event(struct auxtrace_queues *queues, · 1 unmodified line
348359 union perf_event *event, off_t data_offset,
349360 struct auxtrace_buffer **buffer_ptr)
350361 {
351− struct auxtrace_buffer *buffer;
352− unsigned int idx;
353− int err;
354−
355− if (filter_cpu(session, event->auxtrace.cpu))
356− return 0;
357−
358− buffer = zalloc(sizeof(struct auxtrace_buffer));
359− if (!buffer)
360− return -ENOMEM;
361−
362− buffer->pid = -1;
363− buffer->tid = event->auxtrace.tid;
364− buffer->cpu = event->auxtrace.cpu;
365− buffer->data_offset = data_offset;
366− buffer->offset = event->auxtrace.offset;
367− buffer->reference = event->auxtrace.reference;
368− buffer->size = event->auxtrace.size;
369− idx = event->auxtrace.idx;
370−
371− err = auxtrace_queues__add_buffer(queues, session, idx, buffer,
372− buffer_ptr);
373− if (err)
374− goto out_err;
375−
376− return 0;
362+ struct auxtrace_buffer buffer = {
363+ .pid = -1,
364+ .tid = event->auxtrace.tid,
365+ .cpu = event->auxtrace.cpu,
366+ .data_offset = data_offset,
367+ .offset = event->auxtrace.offset,
368+ .reference = event->auxtrace.reference,
369+ .size = event->auxtrace.size,
370+ };
371+ unsigned int idx = event->auxtrace.idx;
377372
378−out_err:
379− auxtrace_buffer__free(buffer);
380− return err;
373+ return auxtrace_queues__add_buffer(queues, session, idx, &buffer,
374+ buffer_ptr);
381375 }
382376
383377 static int auxtrace_queues__add_indexed_event(struct auxtrace_queues *queues,
tools/perf/util/c++/clang-test.cpp+1−1
@@ -41,7 +41,7 @@ int test__clang_to_IR(void) · 40 unmodified lines
4141 if (!M)
4242 return -1;
4343 for (llvm::Function& F : *M)
44− if (F.getName() == "bpf_func__SyS_epoll_wait")
44+ if (F.getName() == "bpf_func__SyS_epoll_pwait")
4545 return 0;
4646 return -1;
4747 }
tools/perf/util/c++/clang.cpp+10−1
@@ -9,6 +9,7 @@ · 8 unmodified lines
99 * Copyright (C) 2016 Huawei Inc.
1010 */
1111
12+#include "clang/Basic/Version.h"
1213 #include "clang/CodeGen/CodeGenAction.h"
1314 #include "clang/Frontend/CompilerInvocation.h"
1415 #include "clang/Frontend/CompilerInstance.h"
@@ -58,7 +59,8 @@ createCompilerInvocation(llvm::opt::ArgStringList CFlags, StringRef& Path, · 43 unmodified lines
5859
5960 FrontendOptions& Opts = CI->getFrontendOpts();
6061 Opts.Inputs.clear();
61− Opts.Inputs.emplace_back(Path, IK_C);
62+ Opts.Inputs.emplace_back(Path,
63+ FrontendOptions::getInputKindForExtension("c"));
6264 return CI;
6365 }
6466
@@ -71,10 +73,17 @@ getModuleFromSource(llvm::opt::ArgStringList CFlags, · 6 unmodified lines
7173
7274 Clang.setVirtualFileSystem(&*VFS);
7375
76+#if CLANG_VERSION_MAJOR < 4
7477 IntrusiveRefCntPtr<CompilerInvocation> CI =
7578 createCompilerInvocation(std::move(CFlags), Path,
7679 Clang.getDiagnostics());
7780 Clang.setInvocation(&*CI);
81+#else
82+ std::shared_ptr<CompilerInvocation> CI(
83+ createCompilerInvocation(std::move(CFlags), Path,
84+ Clang.getDiagnostics()));
85+ Clang.setInvocation(CI);
86+#endif
7887
7988 std::unique_ptr<CodeGenAction> Act(new EmitLLVMOnlyAction(&*LLVMCtx));
8089 if (!Clang.ExecuteAction(*Act))
tools/perf/util/dwarf-aux.c+1−1
@@ -979,7 +979,7 @@ int die_get_varname(Dwarf_Die *vr_die, struct strbuf *buf) · 978 unmodified lines
979979 return ret < 0 ? ret : strbuf_addf(buf, "\t%s", dwarf_diename(vr_die));
980980 }
981981
982−#ifdef HAVE_DWARF_GETLOCATIONS
982+#ifdef HAVE_DWARF_GETLOCATIONS_SUPPORT
983983 /**
984984 * die_get_var_innermost_scope - Get innermost scope range of given variable DIE
985985 * @sp_die: a subprogram DIE
tools/perf/util/hist.c+81−0
@@ -6,6 +6,7 @@ · 5 unmodified lines
66 #include "session.h"
77 #include "namespaces.h"
88 #include "sort.h"
9+#include "units.h"
910 #include "evlist.h"
1011 #include "evsel.h"
1112 #include "annotate.h"
@@ -14,6 +15,7 @@ · 2 unmodified lines
1415 #include "ui/progress.h"
1516 #include <errno.h>
1617 #include <math.h>
18+#include <inttypes.h>
1719 #include <sys/param.h>
1820
1921 static bool hists__filter_entry_by_dso(struct hists *hists,
@@ -2454,6 +2456,85 @@ u64 hists__total_period(struct hists *hists) · 2434 unmodified lines
24542456 hists->stats.total_period;
24552457 }
24562458
2459+int __hists__scnprintf_title(struct hists *hists, char *bf, size_t size, bool show_freq)
2460+{
2461+ char unit;
2462+ int printed;
2463+ const struct dso *dso = hists->dso_filter;
2464+ const struct thread *thread = hists->thread_filter;
2465+ int socket_id = hists->socket_filter;
2466+ unsigned long nr_samples = hists->stats.nr_events[PERF_RECORD_SAMPLE];
2467+ u64 nr_events = hists->stats.total_period;
2468+ struct perf_evsel *evsel = hists_to_evsel(hists);
2469+ const char *ev_name = perf_evsel__name(evsel);
2470+ char buf[512], sample_freq_str[64] = "";
2471+ size_t buflen = sizeof(buf);
2472+ char ref[30] = " show reference callgraph, ";
2473+ bool enable_ref = false;
2474+
2475+ if (symbol_conf.filter_relative) {
2476+ nr_samples = hists->stats.nr_non_filtered_samples;
2477+ nr_events = hists->stats.total_non_filtered_period;
2478+ }
2479+
2480+ if (perf_evsel__is_group_event(evsel)) {
2481+ struct perf_evsel *pos;
2482+
2483+ perf_evsel__group_desc(evsel, buf, buflen);
2484+ ev_name = buf;
2485+
2486+ for_each_group_member(pos, evsel) {
2487+ struct hists *pos_hists = evsel__hists(pos);
2488+
2489+ if (symbol_conf.filter_relative) {
2490+ nr_samples += pos_hists->stats.nr_non_filtered_samples;
2491+ nr_events += pos_hists->stats.total_non_filtered_period;
2492+ } else {
2493+ nr_samples += pos_hists->stats.nr_events[PERF_RECORD_SAMPLE];
2494+ nr_events += pos_hists->stats.total_period;
2495+ }
2496+ }
2497+ }
2498+
2499+ if (symbol_conf.show_ref_callgraph &&
2500+ strstr(ev_name, "call-graph=no"))
2501+ enable_ref = true;
2502+
2503+ if (show_freq)
2504+ scnprintf(sample_freq_str, sizeof(sample_freq_str), " %d Hz,", evsel->attr.sample_freq);
2505+
2506+ nr_samples = convert_unit(nr_samples, &unit);
2507+ printed = scnprintf(bf, size,
2508+ "Samples: %lu%c of event%s '%s',%s%sEvent count (approx.): %" PRIu64,
2509+ nr_samples, unit, evsel->nr_members > 1 ? "s" : "",
2510+ ev_name, sample_freq_str, enable_ref ? ref : " ", nr_events);
2511+
2512+
2513+ if (hists->uid_filter_str)
2514+ printed += snprintf(bf + printed, size - printed,
2515+ ", UID: %s", hists->uid_filter_str);
2516+ if (thread) {
2517+ if (hists__has(hists, thread)) {
2518+ printed += scnprintf(bf + printed, size - printed,
2519+ ", Thread: %s(%d)",
2520+ (thread->comm_set ? thread__comm_str(thread) : ""),
2521+ thread->tid);
2522+ } else {
2523+ printed += scnprintf(bf + printed, size - printed,
2524+ ", Thread: %s",
2525+ (thread->comm_set ? thread__comm_str(thread) : ""));
2526+ }
2527+ }
2528+ if (dso)
2529+ printed += scnprintf(bf + printed, size - printed,
2530+ ", DSO: %s", dso->short_name);
2531+ if (socket_id > -1)
2532+ printed += scnprintf(bf + printed, size - printed,
2533+ ", Processor Socket: %d", socket_id);
2534+
2535+ return printed;
2536+}
2537+
24572538 int parse_filter_percentage(const struct option *opt __maybe_unused,
24582539 const char *arg, int unset __maybe_unused)
24592540 {
tools/perf/util/hist.h+7−0
@@ -61,6 +61,7 @@ enum hist_column { · 60 unmodified lines
6161 HISTC_SRCLINE_TO,
6262 HISTC_TRACE,
6363 HISTC_SYM_SIZE,
64+ HISTC_DSO_SIZE,
6465 HISTC_NR_COLS, /* Last entry */
6566 };
6667
@@ -503,5 +504,11 @@ int __hpp__slsmg_color_printf(struct perf_hpp *hpp, const char *fmt, ...); · 436 unmodified lines
503504 int __hist_entry__snprintf(struct hist_entry *he, struct perf_hpp *hpp,
504505 struct perf_hpp_list *hpp_list);
505506 int hists__fprintf_headers(struct hists *hists, FILE *fp);
507+int __hists__scnprintf_title(struct hists *hists, char *bf, size_t size, bool show_freq);
508+
509+static inline int hists__scnprintf_title(struct hists *hists, char *bf, size_t size)
510+{
511+ return __hists__scnprintf_title(hists, bf, size, true);
512+}
506513
507514 #endif /* __PERF_HIST_H */
tools/perf/util/map.h+4−0
@@ -103,6 +103,10 @@ static inline u64 identity__map_ip(struct map *map __maybe_unused, u64 ip) · 102 unmodified lines
103103 return ip;
104104 }
105105
106+static inline size_t map__size(const struct map *map)
107+{
108+ return map->end - map->start;
109+}
106110
107111 /* rip/ip <-> addr suitable for passing to `objdump --start-address=` */
108112 u64 map__rip_2objdump(struct map *map, u64 rip);
tools/perf/util/session.c+1−1
@@ -1591,7 +1591,7 @@ static void perf_session__warn_about_errors(const struct perf_session *session) · 1590 unmodified lines
15911591 drop_rate = (double)stats->total_lost_samples /
15921592 (double) (stats->nr_events[PERF_RECORD_SAMPLE] + stats->total_lost_samples);
15931593 if (drop_rate > 0.05) {
1594− ui__warning("Processed %" PRIu64 " samples and lost %3.2f%% samples!\n\n",
1594+ ui__warning("Processed %" PRIu64 " samples and lost %3.2f%%!\n\n",
15951595 stats->nr_events[PERF_RECORD_SAMPLE] + stats->total_lost_samples,
15961596 drop_rate * 100.0);
15971597 }
tools/perf/util/sort.c+41−0
@@ -1545,6 +1545,46 @@ struct sort_entry sort_sym_size = { · 1544 unmodified lines
15451545 .se_width_idx = HISTC_SYM_SIZE,
15461546 };
15471547
1548+/* --sort dso_size */
1549+
1550+static int64_t _sort__dso_size_cmp(struct map *map_l, struct map *map_r)
1551+{
1552+ int64_t size_l = map_l != NULL ? map__size(map_l) : 0;
1553+ int64_t size_r = map_r != NULL ? map__size(map_r) : 0;
1554+
1555+ return size_l < size_r ? -1 :
1556+ size_l == size_r ? 0 : 1;
1557+}
1558+
1559+static int64_t
1560+sort__dso_size_cmp(struct hist_entry *left, struct hist_entry *right)
1561+{
1562+ return _sort__dso_size_cmp(right->ms.map, left->ms.map);
1563+}
1564+
1565+static int _hist_entry__dso_size_snprintf(struct map *map, char *bf,
1566+ size_t bf_size, unsigned int width)
1567+{
1568+ if (map && map->dso)
1569+ return repsep_snprintf(bf, bf_size, "%*d", width,
1570+ map__size(map));
1571+
1572+ return repsep_snprintf(bf, bf_size, "%*s", width, "unknown");
1573+}
1574+
1575+static int hist_entry__dso_size_snprintf(struct hist_entry *he, char *bf,
1576+ size_t size, unsigned int width)
1577+{
1578+ return _hist_entry__dso_size_snprintf(he->ms.map, bf, size, width);
1579+}
1580+
1581+struct sort_entry sort_dso_size = {
1582+ .se_header = "DSO size",
1583+ .se_cmp = sort__dso_size_cmp,
1584+ .se_snprintf = hist_entry__dso_size_snprintf,
1585+ .se_width_idx = HISTC_DSO_SIZE,
1586+};
1587+
15481588
15491589 struct sort_dimension {
15501590 const char *name;
@@ -1569,6 +1609,7 @@ static struct sort_dimension common_sort_dimensions[] = { · 18 unmodified lines
15691609 DIM(SORT_TRANSACTION, "transaction", sort_transaction),
15701610 DIM(SORT_TRACE, "trace", sort_trace),
15711611 DIM(SORT_SYM_SIZE, "symbol_size", sort_sym_size),
1612+ DIM(SORT_DSO_SIZE, "dso_size", sort_dso_size),
15721613 DIM(SORT_CGROUP_ID, "cgroup_id", sort_cgroup_id),
15731614 };
15741615
tools/perf/util/sort.h+1−0
@@ -220,6 +220,7 @@ enum sort_type { · 219 unmodified lines
220220 SORT_TRANSACTION,
221221 SORT_TRACE,
222222 SORT_SYM_SIZE,
223+ SORT_DSO_SIZE,
223224 SORT_CGROUP_ID,
224225
225226 /* branch stack specific sort keys */
tools/perf/util/util.h+2−2
@@ -11,8 +11,7 @@ · 10 unmodified lines
1111 #include <stdlib.h>
1212 #include <stdarg.h>
1313 #include <linux/compiler.h>
14−#include <linux/types.h>
15−#include "namespaces.h"
14+#include <sys/types.h>
1615
1716 /* General helper functions */
1817 void usage(const char *err) __noreturn;
@@ -26,6 +25,7 @@ static inline void *zalloc(size_t size) · 7 unmodified lines
2625 #define zfree(ptr) ({ free(*ptr); *ptr = NULL; })
2726
2827 struct dirent;
28+struct nsinfo;
2929 struct strlist;
3030
3131 int mkdir_p(char *path, mode_t mode);