summaryrefslogtreecommitdiffstats
path: root/tools
diff options
context:
space:
mode:
Diffstat (limited to 'tools')
-rw-r--r--tools/include/linux/compiler-gcc.h9
-rw-r--r--tools/include/uapi/linux/perf_event.h4
-rw-r--r--tools/lib/api/Makefile8
-rw-r--r--tools/pci/pcitest.c1
-rw-r--r--tools/perf/Documentation/intel-pt.txt2
-rw-r--r--tools/perf/Documentation/perf-mem.txt4
-rw-r--r--tools/perf/Documentation/perf-record.txt5
-rw-r--r--tools/perf/Documentation/perf-report.txt1
-rw-r--r--tools/perf/Documentation/perf-script.txt2
-rw-r--r--tools/perf/Documentation/perf-trace.txt2
-rw-r--r--tools/perf/builtin-config.c2
-rw-r--r--tools/perf/builtin-kmem.c1
-rw-r--r--tools/perf/builtin-mem.c97
-rw-r--r--tools/perf/builtin-record.c2
-rw-r--r--tools/perf/builtin-script.c15
-rw-r--r--tools/perf/builtin-stat.c4
-rw-r--r--tools/perf/builtin-trace.c39
-rw-r--r--tools/perf/perf.c14
-rw-r--r--tools/perf/perf.h1
-rw-r--r--tools/perf/pmu-events/arch/powerpc/power9/frontend.json7
-rw-r--r--tools/perf/pmu-events/arch/powerpc/power9/other.json120
-rw-r--r--tools/perf/pmu-events/arch/powerpc/power9/pipeline.json7
-rw-r--r--tools/perf/pmu-events/arch/powerpc/power9/pmc.json7
-rw-r--r--tools/perf/tests/code-reading.c5
-rw-r--r--tools/perf/tests/dwarf-unwind.c2
-rw-r--r--tools/perf/tests/sample-parsing.c6
-rw-r--r--tools/perf/ui/browsers/annotate.c3
-rw-r--r--tools/perf/ui/browsers/hists.c8
-rw-r--r--tools/perf/ui/progress.c9
-rw-r--r--tools/perf/ui/stdio/hist.c10
-rw-r--r--tools/perf/util/callchain.c49
-rw-r--r--tools/perf/util/callchain.h9
-rw-r--r--tools/perf/util/data.c13
-rw-r--r--tools/perf/util/event.h1
-rw-r--r--tools/perf/util/evsel.c19
-rw-r--r--tools/perf/util/evsel.h1
-rw-r--r--tools/perf/util/hist.c4
-rw-r--r--tools/perf/util/hist.h1
-rw-r--r--tools/perf/util/machine.c96
-rw-r--r--tools/perf/util/parse-events.c24
-rw-r--r--tools/perf/util/session.c3
-rw-r--r--tools/perf/util/sort.c42
-rw-r--r--tools/perf/util/sort.h1
-rw-r--r--tools/perf/util/symbol.h1
-rw-r--r--tools/perf/util/syscalltbl.c33
-rw-r--r--tools/perf/util/syscalltbl.h3
-rw-r--r--tools/power/cpupower/Makefile2
-rw-r--r--tools/scripts/Makefile.include6
-rw-r--r--tools/testing/nvdimm/test/nfit.c4
-rw-r--r--tools/testing/selftests/bpf/test_maps.c51
-rw-r--r--tools/testing/selftests/breakpoints/breakpoint_test.c4
-rw-r--r--tools/testing/selftests/capabilities/test_execve.c193
-rw-r--r--tools/testing/selftests/capabilities/validate_cap.c24
-rwxr-xr-xtools/testing/selftests/cpu-hotplug/cpu-on-off-test.sh14
-rwxr-xr-xtools/testing/selftests/ftrace/ftracetest51
-rw-r--r--tools/testing/selftests/futex/functional/futex_requeue_pi.c8
-rw-r--r--tools/testing/selftests/futex/functional/futex_requeue_pi_mismatched_ops.c3
-rw-r--r--tools/testing/selftests/futex/functional/futex_requeue_pi_signal_restart.c5
-rw-r--r--tools/testing/selftests/futex/functional/futex_wait_private_mapped_file.c6
-rw-r--r--tools/testing/selftests/futex/functional/futex_wait_timeout.c5
-rw-r--r--tools/testing/selftests/futex/functional/futex_wait_uninitialized_heap.c3
-rw-r--r--tools/testing/selftests/futex/functional/futex_wait_wouldblock.c3
-rw-r--r--tools/testing/selftests/futex/include/logging.h20
-rw-r--r--tools/testing/selftests/kcmp/kcmp_test.c60
-rw-r--r--tools/testing/selftests/kselftest.h30
-rw-r--r--tools/testing/selftests/kselftest_harness.h39
-rw-r--r--tools/testing/selftests/lib.mk17
-rw-r--r--tools/testing/selftests/memfd/fuse_test.c2
-rw-r--r--tools/testing/selftests/nsfs/config3
-rw-r--r--tools/testing/selftests/pstore/.gitignore2
-rw-r--r--tools/testing/selftests/ptp/Makefile1
-rw-r--r--tools/testing/selftests/seccomp/seccomp_bpf.c2
-rw-r--r--tools/testing/selftests/sigaltstack/sas.c53
-rw-r--r--tools/testing/selftests/splice/.gitignore1
-rw-r--r--tools/testing/selftests/splice/Makefile5
-rw-r--r--tools/testing/selftests/sync/sync_test.c71
-rw-r--r--tools/testing/selftests/sync/synctest.h3
-rw-r--r--tools/testing/selftests/timers/Makefile23
-rw-r--r--tools/testing/selftests/timers/adjtick.c11
-rw-r--r--tools/testing/selftests/timers/alarmtimer-suspend.c11
-rw-r--r--tools/testing/selftests/timers/change_skew.c11
-rw-r--r--tools/testing/selftests/timers/clocksource-switch.c13
-rw-r--r--tools/testing/selftests/timers/inconsistency-check.c11
-rw-r--r--tools/testing/selftests/timers/leap-a-day.c28
-rw-r--r--tools/testing/selftests/timers/leapcrash.c13
-rw-r--r--tools/testing/selftests/timers/mqueue-lat.c11
-rw-r--r--tools/testing/selftests/timers/nanosleep.c11
-rw-r--r--tools/testing/selftests/timers/nsleep-lat.c11
-rw-r--r--tools/testing/selftests/timers/raw_skew.c12
-rw-r--r--tools/testing/selftests/timers/rtctest.c7
-rw-r--r--tools/testing/selftests/timers/set-2038.c11
-rw-r--r--tools/testing/selftests/timers/set-tai.c11
-rw-r--r--tools/testing/selftests/timers/set-timer-lat.c11
-rw-r--r--tools/testing/selftests/timers/set-tz.c11
-rw-r--r--tools/testing/selftests/timers/skew_consistency.c11
-rw-r--r--tools/testing/selftests/timers/threadtest.c12
-rw-r--r--tools/testing/selftests/timers/valid-adjtimex.c11
-rw-r--r--tools/testing/selftests/watchdog/watchdog-test.c190
-rw-r--r--tools/testing/selftests/x86/mpx-mini-test.c3
-rw-r--r--tools/testing/selftests/x86/protection_keys.c13
100 files changed, 1053 insertions, 792 deletions
diff --git a/tools/include/linux/compiler-gcc.h b/tools/include/linux/compiler-gcc.h
index bd39b2090ad1..3723b9f8f964 100644
--- a/tools/include/linux/compiler-gcc.h
+++ b/tools/include/linux/compiler-gcc.h
@@ -21,11 +21,14 @@
#define __must_be_array(a) BUILD_BUG_ON_ZERO(__same_type((a), &(a)[0]))
#define noinline __attribute__((noinline))
-
+#ifndef __packed
#define __packed __attribute__((packed))
-
+#endif
+#ifndef __noreturn
#define __noreturn __attribute__((noreturn))
-
+#endif
+#ifndef __aligned
#define __aligned(x) __attribute__((aligned(x)))
+#endif
#define __printf(a, b) __attribute__((format(printf, a, b)))
#define __scanf(a, b) __attribute__((format(scanf, a, b)))
diff --git a/tools/include/uapi/linux/perf_event.h b/tools/include/uapi/linux/perf_event.h
index 2a37ae925d85..140ae638cfd6 100644
--- a/tools/include/uapi/linux/perf_event.h
+++ b/tools/include/uapi/linux/perf_event.h
@@ -139,8 +139,9 @@ enum perf_event_sample_format {
PERF_SAMPLE_IDENTIFIER = 1U << 16,
PERF_SAMPLE_TRANSACTION = 1U << 17,
PERF_SAMPLE_REGS_INTR = 1U << 18,
+ PERF_SAMPLE_PHYS_ADDR = 1U << 19,
- PERF_SAMPLE_MAX = 1U << 19, /* non-ABI */
+ PERF_SAMPLE_MAX = 1U << 20, /* non-ABI */
};
/*
@@ -814,6 +815,7 @@ enum perf_event_type {
* { u64 transaction; } && PERF_SAMPLE_TRANSACTION
* { u64 abi; # enum perf_sample_regs_abi
* u64 regs[weight(mask)]; } && PERF_SAMPLE_REGS_INTR
+ * { u64 phys_addr;} && PERF_SAMPLE_PHYS_ADDR
* };
*/
PERF_RECORD_SAMPLE = 9,
diff --git a/tools/lib/api/Makefile b/tools/lib/api/Makefile
index 4563ba7ede6f..1e83e3c07448 100644
--- a/tools/lib/api/Makefile
+++ b/tools/lib/api/Makefile
@@ -17,13 +17,19 @@ MAKEFLAGS += --no-print-directory
LIBFILE = $(OUTPUT)libapi.a
CFLAGS := $(EXTRA_WARNINGS) $(EXTRA_CFLAGS)
-CFLAGS += -ggdb3 -Wall -Wextra -std=gnu99 -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=2 -fPIC
+CFLAGS += -ggdb3 -Wall -Wextra -std=gnu99 -U_FORTIFY_SOURCE -fPIC
+ifeq ($(DEBUG),0)
ifeq ($(CC_NO_CLANG), 0)
CFLAGS += -O3
else
CFLAGS += -O6
endif
+endif
+
+ifeq ($(DEBUG),0)
+ CFLAGS += -D_FORTIFY_SOURCE
+endif
# Treat warnings as errors unless directed not to
ifneq ($(WERROR),0)
diff --git a/tools/pci/pcitest.c b/tools/pci/pcitest.c
index ad54a58d7dda..9074b477bff0 100644
--- a/tools/pci/pcitest.c
+++ b/tools/pci/pcitest.c
@@ -173,6 +173,7 @@ usage:
"\t-D <dev> PCI endpoint test device {default: /dev/pci-endpoint-test.0}\n"
"\t-b <bar num> BAR test (bar number between 0..5)\n"
"\t-m <msi num> MSI test (msi number between 1..32)\n"
+ "\t-l Legacy IRQ test\n"
"\t-r Read buffer test\n"
"\t-w Write buffer test\n"
"\t-c Copy buffer test\n"
diff --git a/tools/perf/Documentation/intel-pt.txt b/tools/perf/Documentation/intel-pt.txt
index ab1b0825130a..76971d2e4164 100644
--- a/tools/perf/Documentation/intel-pt.txt
+++ b/tools/perf/Documentation/intel-pt.txt
@@ -873,7 +873,7 @@ amended to take the number of elements as a parameter.
$ cat ~/.perfconfig
[intel-pt]
- mispred-all
+ mispred-all = on
$ perf record -e intel_pt//u ./sort 3000
Bubble sorting array of 3000 elements
diff --git a/tools/perf/Documentation/perf-mem.txt b/tools/perf/Documentation/perf-mem.txt
index 73496320fca3..4be08a1e3f8d 100644
--- a/tools/perf/Documentation/perf-mem.txt
+++ b/tools/perf/Documentation/perf-mem.txt
@@ -59,6 +59,10 @@ OPTIONS
--ldload::
Specify desired latency for loads event.
+-p::
+--phys-data::
+ Record/Report sample physical addresses
+
SEE ALSO
--------
linkperf:perf-record[1], linkperf:perf-report[1]
diff --git a/tools/perf/Documentation/perf-record.txt b/tools/perf/Documentation/perf-record.txt
index 9bdea047c5db..e397453e5a46 100644
--- a/tools/perf/Documentation/perf-record.txt
+++ b/tools/perf/Documentation/perf-record.txt
@@ -249,7 +249,10 @@ OPTIONS
-d::
--data::
- Record the sample addresses.
+ Record the sample virtual addresses.
+
+--phys-data::
+ Record the sample physical addresses.
-T::
--timestamp::
diff --git a/tools/perf/Documentation/perf-report.txt b/tools/perf/Documentation/perf-report.txt
index 9fa84617181e..383a98d992ed 100644
--- a/tools/perf/Documentation/perf-report.txt
+++ b/tools/perf/Documentation/perf-report.txt
@@ -137,6 +137,7 @@ OPTIONS
- mem: type of memory access for the data at the time of the sample
- snoop: type of snoop (if any) for the data at the time of the sample
- dcacheline: the cacheline the data address is on at the time of the sample
+ - phys_daddr: physical address of data being executed on at the time of sample
And the default sort keys are changed to local_weight, mem, sym, dso,
symbol_daddr, dso_daddr, snoop, tlb, locked, see '--mem-mode'.
diff --git a/tools/perf/Documentation/perf-script.txt b/tools/perf/Documentation/perf-script.txt
index 5ee8796be96e..18dfcfa38454 100644
--- a/tools/perf/Documentation/perf-script.txt
+++ b/tools/perf/Documentation/perf-script.txt
@@ -117,7 +117,7 @@ OPTIONS
Comma separated list of fields to print. Options are:
comm, tid, pid, time, cpu, event, trace, ip, sym, dso, addr, symoff,
srcline, period, iregs, brstack, brstacksym, flags, bpf-output, brstackinsn, brstackoff,
- callindent, insn, insnlen, synth.
+ callindent, insn, insnlen, synth, phys_addr.
Field list can be prepended with the type, trace, sw or hw,
to indicate to which event type the field list applies.
e.g., -F sw:comm,tid,time,ip,sym and -F trace:time,cpu,trace
diff --git a/tools/perf/Documentation/perf-trace.txt b/tools/perf/Documentation/perf-trace.txt
index c1e3288a2dfb..d53bea6bd571 100644
--- a/tools/perf/Documentation/perf-trace.txt
+++ b/tools/perf/Documentation/perf-trace.txt
@@ -37,7 +37,7 @@ OPTIONS
--expr::
--event::
List of syscalls and other perf events (tracepoints, HW cache events,
- etc) to show.
+ etc) to show. Globbing is supported, e.g.: "epoll_*", "*msg*", etc.
See 'perf list' for a complete list of events.
Prefixing with ! shows all syscalls but the ones specified. You may
need to escape it.
diff --git a/tools/perf/builtin-config.c b/tools/perf/builtin-config.c
index 3ddcc6e2abeb..a1d82e33282c 100644
--- a/tools/perf/builtin-config.c
+++ b/tools/perf/builtin-config.c
@@ -59,7 +59,7 @@ static int set_config(struct perf_config_set *set, const char *file_name,
fprintf(fp, "[%s]\n", section->name);
perf_config_items__for_each_entry(&section->items, item) {
- if (!use_system_config && section->from_system_config)
+ if (!use_system_config && item->from_system_config)
continue;
if (item->value)
fprintf(fp, "\t%s = %s\n",
diff --git a/tools/perf/builtin-kmem.c b/tools/perf/builtin-kmem.c
index a1497c516d85..24ee68ecdd42 100644
--- a/tools/perf/builtin-kmem.c
+++ b/tools/perf/builtin-kmem.c
@@ -627,7 +627,6 @@ static const struct {
{ "GFP_HIGHUSER_MOVABLE", "HUM" },
{ "GFP_HIGHUSER", "HU" },
{ "GFP_USER", "U" },
- { "GFP_TEMPORARY", "TMP" },
{ "GFP_KERNEL_ACCOUNT", "KAC" },
{ "GFP_KERNEL", "K" },
{ "GFP_NOFS", "NF" },
diff --git a/tools/perf/builtin-mem.c b/tools/perf/builtin-mem.c
index e001c0290793..0f15634ef82c 100644
--- a/tools/perf/builtin-mem.c
+++ b/tools/perf/builtin-mem.c
@@ -23,6 +23,7 @@ struct perf_mem {
bool hide_unresolved;
bool dump_raw;
bool force;
+ bool phys_addr;
int operation;
const char *cpu_list;
DECLARE_BITMAP(cpu_bitmap, MAX_NR_CPUS);
@@ -101,6 +102,9 @@ static int __cmd_record(int argc, const char **argv, struct perf_mem *mem)
rec_argv[i++] = "-d";
+ if (mem->phys_addr)
+ rec_argv[i++] = "--phys-data";
+
for (j = 0; j < PERF_MEM_EVENTS__MAX; j++) {
if (!perf_mem_events[j].record)
continue;
@@ -161,30 +165,60 @@ dump_raw_samples(struct perf_tool *tool,
if (al.map != NULL)
al.map->dso->hit = 1;
- if (symbol_conf.field_sep) {
- fmt = "%d%s%d%s0x%"PRIx64"%s0x%"PRIx64"%s%"PRIu64
- "%s0x%"PRIx64"%s%s:%s\n";
+ if (mem->phys_addr) {
+ if (symbol_conf.field_sep) {
+ fmt = "%d%s%d%s0x%"PRIx64"%s0x%"PRIx64"%s0x%016"PRIx64
+ "%s%"PRIu64"%s0x%"PRIx64"%s%s:%s\n";
+ } else {
+ fmt = "%5d%s%5d%s0x%016"PRIx64"%s0x016%"PRIx64
+ "%s0x%016"PRIx64"%s%5"PRIu64"%s0x%06"PRIx64
+ "%s%s:%s\n";
+ symbol_conf.field_sep = " ";
+ }
+
+ printf(fmt,
+ sample->pid,
+ symbol_conf.field_sep,
+ sample->tid,
+ symbol_conf.field_sep,
+ sample->ip,
+ symbol_conf.field_sep,
+ sample->addr,
+ symbol_conf.field_sep,
+ sample->phys_addr,
+ symbol_conf.field_sep,
+ sample->weight,
+ symbol_conf.field_sep,
+ sample->data_src,
+ symbol_conf.field_sep,
+ al.map ? (al.map->dso ? al.map->dso->long_name : "???") : "???",
+ al.sym ? al.sym->name : "???");
} else {
- fmt = "%5d%s%5d%s0x%016"PRIx64"%s0x016%"PRIx64
- "%s%5"PRIu64"%s0x%06"PRIx64"%s%s:%s\n";
- symbol_conf.field_sep = " ";
- }
+ if (symbol_conf.field_sep) {
+ fmt = "%d%s%d%s0x%"PRIx64"%s0x%"PRIx64"%s%"PRIu64
+ "%s0x%"PRIx64"%s%s:%s\n";
+ } else {
+ fmt = "%5d%s%5d%s0x%016"PRIx64"%s0x016%"PRIx64
+ "%s%5"PRIu64"%s0x%06"PRIx64"%s%s:%s\n";
+ symbol_conf.field_sep = " ";
+ }
- printf(fmt,
- sample->pid,
- symbol_conf.field_sep,
- sample->tid,
- symbol_conf.field_sep,
- sample->ip,
- symbol_conf.field_sep,
- sample->addr,
- symbol_conf.field_sep,
- sample->weight,
- symbol_conf.field_sep,
- sample->data_src,
- symbol_conf.field_sep,
- al.map ? (al.map->dso ? al.map->dso->long_name : "???") : "???",
- al.sym ? al.sym->name : "???");
+ printf(fmt,
+ sample->pid,
+ symbol_conf.field_sep,
+ sample->tid,
+ symbol_conf.field_sep,
+ sample->ip,
+ symbol_conf.field_sep,
+ sample->addr,
+ symbol_conf.field_sep,
+ sample->weight,
+ symbol_conf.field_sep,
+ sample->data_src,
+ symbol_conf.field_sep,
+ al.map ? (al.map->dso ? al.map->dso->long_name : "???") : "???",
+ al.sym ? al.sym->name : "???");
+ }
out_put:
addr_location__put(&al);
return 0;
@@ -224,7 +258,10 @@ static int report_raw_events(struct perf_mem *mem)
if (ret < 0)
goto out_delete;
- printf("# PID, TID, IP, ADDR, LOCAL WEIGHT, DSRC, SYMBOL\n");
+ if (mem->phys_addr)
+ printf("# PID, TID, IP, ADDR, PHYS ADDR, LOCAL WEIGHT, DSRC, SYMBOL\n");
+ else
+ printf("# PID, TID, IP, ADDR, LOCAL WEIGHT, DSRC, SYMBOL\n");
ret = perf_session__process_events(session);
@@ -254,9 +291,16 @@ static int report_events(int argc, const char **argv, struct perf_mem *mem)
* there is no weight (cost) associated with stores, so don't print
* the column
*/
- if (!(mem->operation & MEM_OPERATION_LOAD))
- rep_argv[i++] = "--sort=mem,sym,dso,symbol_daddr,"
- "dso_daddr,tlb,locked";
+ if (!(mem->operation & MEM_OPERATION_LOAD)) {
+ if (mem->phys_addr)
+ rep_argv[i++] = "--sort=mem,sym,dso,symbol_daddr,"
+ "dso_daddr,tlb,locked,phys_daddr";
+ else
+ rep_argv[i++] = "--sort=mem,sym,dso,symbol_daddr,"
+ "dso_daddr,tlb,locked";
+ } else if (mem->phys_addr)
+ rep_argv[i++] = "--sort=local_weight,mem,sym,dso,symbol_daddr,"
+ "dso_daddr,snoop,tlb,locked,phys_daddr";
for (j = 1; j < argc; j++, i++)
rep_argv[i] = argv[j];
@@ -373,6 +417,7 @@ int cmd_mem(int argc, const char **argv)
"separator for columns, no spaces will be added"
" between columns '.' is reserved."),
OPT_BOOLEAN('f', "force", &mem.force, "don't complain, do it"),
+ OPT_BOOLEAN('p', "phys-data", &mem.phys_addr, "Record/Report sample physical addresses"),
OPT_END()
};
const char *const mem_subcommands[] = { "record", "report", NULL };
diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c
index 36d7117a7562..56f8142ff97f 100644
--- a/tools/perf/builtin-record.c
+++ b/tools/perf/builtin-record.c
@@ -1604,6 +1604,8 @@ static struct option __record_options[] = {
OPT_BOOLEAN('s', "stat", &record.opts.inherit_stat,
"per thread counts"),
OPT_BOOLEAN('d', "data", &record.opts.sample_address, "Record the sample addresses"),
+ OPT_BOOLEAN(0, "phys-data", &record.opts.sample_phys_addr,
+ "Record the sample physical addresses"),
OPT_BOOLEAN(0, "sample-cpu", &record.opts.sample_cpu, "Record the sample cpu"),
OPT_BOOLEAN_SET('T', "timestamp", &record.opts.sample_time,
&record.opts.sample_time_set,
diff --git a/tools/perf/builtin-script.c b/tools/perf/builtin-script.c
index 378f76cdf923..3d4c3b5e1868 100644
--- a/tools/perf/builtin-script.c
+++ b/tools/perf/builtin-script.c
@@ -87,6 +87,7 @@ enum perf_output_field {
PERF_OUTPUT_BRSTACKINSN = 1U << 23,
PERF_OUTPUT_BRSTACKOFF = 1U << 24,
PERF_OUTPUT_SYNTH = 1U << 25,
+ PERF_OUTPUT_PHYS_ADDR = 1U << 26,
};
struct output_option {
@@ -119,6 +120,7 @@ struct output_option {
{.str = "brstackinsn", .field = PERF_OUTPUT_BRSTACKINSN},
{.str = "brstackoff", .field = PERF_OUTPUT_BRSTACKOFF},
{.str = "synth", .field = PERF_OUTPUT_SYNTH},
+ {.str = "phys_addr", .field = PERF_OUTPUT_PHYS_ADDR},
};
enum {
@@ -175,7 +177,8 @@ static struct {
PERF_OUTPUT_EVNAME | PERF_OUTPUT_IP |
PERF_OUTPUT_SYM | PERF_OUTPUT_DSO |
PERF_OUTPUT_PERIOD | PERF_OUTPUT_ADDR |
- PERF_OUTPUT_DATA_SRC | PERF_OUTPUT_WEIGHT,
+ PERF_OUTPUT_DATA_SRC | PERF_OUTPUT_WEIGHT |
+ PERF_OUTPUT_PHYS_ADDR,
.invalid_fields = PERF_OUTPUT_TRACE | PERF_OUTPUT_BPF_OUTPUT,
},
@@ -382,6 +385,11 @@ static int perf_evsel__check_attr(struct perf_evsel *evsel,
PERF_OUTPUT_IREGS))
return -EINVAL;
+ if (PRINT_FIELD(PHYS_ADDR) &&
+ perf_evsel__check_stype(evsel, PERF_SAMPLE_PHYS_ADDR, "PHYS_ADDR",
+ PERF_OUTPUT_PHYS_ADDR))
+ return -EINVAL;
+
return 0;
}
@@ -1446,6 +1454,9 @@ static void process_event(struct perf_script *script,
if (perf_evsel__is_bpf_output(evsel) && PRINT_FIELD(BPF_OUTPUT))
print_sample_bpf_output(sample);
print_insn(sample, attr, thread, machine);
+
+ if (PRINT_FIELD(PHYS_ADDR))
+ printf("%16" PRIx64, sample->phys_addr);
printf("\n");
}
@@ -2729,7 +2740,7 @@ int cmd_script(int argc, const char **argv)
"Valid types: hw,sw,trace,raw,synth. "
"Fields: comm,tid,pid,time,cpu,event,trace,ip,sym,dso,"
"addr,symoff,period,iregs,brstack,brstacksym,flags,"
- "bpf-output,callindent,insn,insnlen,brstackinsn,synth",
+ "bpf-output,callindent,insn,insnlen,brstackinsn,synth,phys_addr",
parse_output_fields),
OPT_BOOLEAN('a', "all-cpus", &system_wide,
"system-wide collection from all CPUs"),
diff --git a/tools/perf/builtin-stat.c b/tools/perf/builtin-stat.c
index 866da7aa54bf..69523ed55894 100644
--- a/tools/perf/builtin-stat.c
+++ b/tools/perf/builtin-stat.c
@@ -707,7 +707,7 @@ try_again:
process_interval();
}
}
- wait(&status);
+ waitpid(child_pid, &status, 0);
if (workload_exec_errno) {
const char *emsg = str_error_r(workload_exec_errno, msg, sizeof(msg));
@@ -1257,7 +1257,7 @@ static bool collect_data(struct perf_evsel *counter,
if (counter->merged_stat)
return false;
cb(counter, data, true);
- if (!no_merge)
+ if (!no_merge && counter->auto_merge_stats)
collect_all_aliases(counter, cb, data);
return true;
}
diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c
index d59cdadf3a79..771ddab94bb0 100644
--- a/tools/perf/builtin-trace.c
+++ b/tools/perf/builtin-trace.c
@@ -1261,6 +1261,7 @@ static int trace__read_syscall_info(struct trace *trace, int id)
static int trace__validate_ev_qualifier(struct trace *trace)
{
int err = 0, i;
+ size_t nr_allocated;
struct str_node *pos;
trace->ev_qualifier_ids.nr = strlist__nr_entries(trace->ev_qualifier);
@@ -1274,13 +1275,18 @@ static int trace__validate_ev_qualifier(struct trace *trace)
goto out;
}
+ nr_allocated = trace->ev_qualifier_ids.nr;
i = 0;
strlist__for_each_entry(pos, trace->ev_qualifier) {
const char *sc = pos->s;
- int id = syscalltbl__id(trace->sctbl, sc);
+ int id = syscalltbl__id(trace->sctbl, sc), match_next = -1;
if (id < 0) {
+ id = syscalltbl__strglobmatch_first(trace->sctbl, sc, &match_next);
+ if (id >= 0)
+ goto matches;
+
if (err == 0) {
fputs("Error:\tInvalid syscall ", trace->output);
err = -EINVAL;
@@ -1290,13 +1296,37 @@ static int trace__validate_ev_qualifier(struct trace *trace)
fputs(sc, trace->output);
}
-
+matches:
trace->ev_qualifier_ids.entries[i++] = id;
+ if (match_next == -1)
+ continue;
+
+ while (1) {
+ id = syscalltbl__strglobmatch_next(trace->sctbl, sc, &match_next);
+ if (id < 0)
+ break;
+ if (nr_allocated == trace->ev_qualifier_ids.nr) {
+ void *entries;
+
+ nr_allocated += 8;
+ entries = realloc(trace->ev_qualifier_ids.entries,
+ nr_allocated * sizeof(trace->ev_qualifier_ids.entries[0]));
+ if (entries == NULL) {
+ err = -ENOMEM;
+ fputs("\nError:\t Not enough memory for parsing\n", trace->output);
+ goto out_free;
+ }
+ trace->ev_qualifier_ids.entries = entries;
+ }
+ trace->ev_qualifier_ids.nr++;
+ trace->ev_qualifier_ids.entries[i++] = id;
+ }
}
if (err < 0) {
fputs("\nHint:\ttry 'perf list syscalls:sys_enter_*'"
"\nHint:\tand: 'man syscalls'\n", trace->output);
+out_free:
zfree(&trace->ev_qualifier_ids.entries);
trace->ev_qualifier_ids.nr = 0;
}
@@ -2814,7 +2844,7 @@ static int trace__parse_events_option(const struct option *opt, const char *str,
struct trace *trace = (struct trace *)opt->value;
const char *s = str;
char *sep = NULL, *lists[2] = { NULL, NULL, };
- int len = strlen(str) + 1, err = -1, list;
+ int len = strlen(str) + 1, err = -1, list, idx;
char *strace_groups_dir = system_path(STRACE_GROUPS_DIR);
char group_name[PATH_MAX];
@@ -2831,7 +2861,8 @@ static int trace__parse_events_option(const struct option *opt, const char *str,
*sep = '\0';
list = 0;
- if (syscalltbl__id(trace->sctbl, s) >= 0) {
+ if (syscalltbl__id(trace->sctbl, s) >= 0 ||
+ syscalltbl__strglobmatch_first(trace->sctbl, s, &idx) >= 0) {
list = 1;
} else {
path__join(group_name, sizeof(group_name), strace_groups_dir, s);
diff --git a/tools/perf/perf.c b/tools/perf/perf.c
index e0279babe0c0..2f19e03c5c40 100644
--- a/tools/perf/perf.c
+++ b/tools/perf/perf.c
@@ -467,15 +467,21 @@ int main(int argc, const char **argv)
* - cannot execute it externally (since it would just do
* the same thing over again)
*
- * So we just directly call the internal command handler, and
- * die if that one cannot handle it.
+ * So we just directly call the internal command handler. If that one
+ * fails to handle this, then maybe we just run a renamed perf binary
+ * that contains a dash in its name. To handle this scenario, we just
+ * fall through and ignore the "xxxx" part of the command string.
*/
if (strstarts(cmd, "perf-")) {
cmd += 5;
argv[0] = cmd;
handle_internal_command(argc, argv);
- fprintf(stderr, "cannot handle %s internally", cmd);
- goto out;
+ /*
+ * If the command is handled, the above function does not
+ * return undo changes and fall through in such a case.
+ */
+ cmd -= 5;
+ argv[0] = cmd;
}
if (strstarts(cmd, "trace")) {
#ifdef HAVE_LIBAUDIT_SUPPORT
diff --git a/tools/perf/perf.h b/tools/perf/perf.h
index 2c010dd6a79d..dc442ba21bf6 100644
--- a/tools/perf/perf.h
+++ b/tools/perf/perf.h
@@ -43,6 +43,7 @@ struct record_opts {
bool no_samples;
bool raw_samples;
bool sample_address;
+ bool sample_phys_addr;
bool sample_weight;
bool sample_time;
bool sample_time_set;
diff --git a/tools/perf/pmu-events/arch/powerpc/power9/frontend.json b/tools/perf/pmu-events/arch/powerpc/power9/frontend.json
index 7e62c46d7a20..c63a919eda98 100644
--- a/tools/perf/pmu-events/arch/powerpc/power9/frontend.json
+++ b/tools/perf/pmu-events/arch/powerpc/power9/frontend.json
@@ -80,11 +80,6 @@
"BriefDescription": "Load Missed L1, counted at execution time (can be greater than loads finished). LMQ merges are not included in this count. i.e. if a load instruction misses on an address that is already allocated on the LMQ, this event will not increment for that load). Note that this count is per slice, so if a load spans multiple slices this event will increment multiple times for a single load."
},
{,
- "EventCode": "0x400F0",
- "EventName": "PM_LD_MISS_L1",
- "BriefDescription": "Load Missed L1, counted at execution time (can be greater than loads finished). LMQ merges are not included in this count. i.e. if a load instruction misses on an address that is already allocated on the LMQ, this event will not increment for that load). Note that this count is per slice, so if a load spans multiple slices this event will increment multiple times for a single load."
- },
- {,
"EventCode": "0x2E01A",
"EventName": "PM_CMPLU_STALL_LSU_FLUSH_NEXT",
"BriefDescription": "Completion stall of one cycle because the LSU requested to flush the next iop in the sequence. It takes 1 cycle for the ISU to process this request before the LSU instruction is allowed to complete"
@@ -374,4 +369,4 @@
"EventName": "PM_IPTEG_FROM_L31_ECO_MOD",
"BriefDescription": "A Page Table Entry was loaded into the TLB with Modified (M) data from another core's ECO L3 on the same chip due to a instruction side request"
}
-] \ No newline at end of file
+]
diff --git a/tools/perf/pmu-events/arch/powerpc/power9/other.json b/tools/perf/pmu-events/arch/powerpc/power9/other.json
index 00f3d2a21f31..54cc3be00fc2 100644
--- a/tools/perf/pmu-events/arch/powerpc/power9/other.json
+++ b/tools/perf/pmu-events/arch/powerpc/power9/other.json
@@ -605,11 +605,6 @@
"BriefDescription": "RC retries on PB for any load from core (excludes DCBFs)"
},
{,
- "EventCode": "0x3689E",
- "EventName": "PM_L2_RTY_LD",
- "BriefDescription": "RC retries on PB for any load from core (excludes DCBFs)"
- },
- {,
"EventCode": "0xE08C",
"EventName": "PM_LSU0_ERAT_HIT",
"BriefDescription": "Primary ERAT hit. There is no secondary ERAT"
@@ -715,11 +710,6 @@
"BriefDescription": "Lifetime, sample of RD machine 0 valid"
},
{,
- "EventCode": "0x468B4",
- "EventName": "PM_L3_RD0_BUSY",
- "BriefDescription": "Lifetime, sample of RD machine 0 valid"
- },
- {,
"EventCode": "0x46080",
"EventName": "PM_L2_DISP_ALL_L2MISS",
"BriefDescription": "All successful Ld/St dispatches for this thread that were an L2 miss (excludes i_l2mru_tch_reqs)"
@@ -850,21 +840,11 @@
"BriefDescription": "RC mach 0 Busy. Used by PMU to sample ave RC lifetime (mach0 used as sample point)"
},
{,
- "EventCode": "0x2608C",
- "EventName": "PM_RC0_BUSY",
- "BriefDescription": "RC mach 0 Busy. Used by PMU to sample ave RC lifetime (mach0 used as sample point)"
- },
- {,
"EventCode": "0x36082",
"EventName": "PM_L2_LD_DISP",
"BriefDescription": "All successful I-or-D side load dispatches for this thread (excludes i_l2mru_tch_reqs)."
},
{,
- "EventCode": "0x1609E",
- "EventName": "PM_L2_LD_DISP",
- "BriefDescription": "All successful D side load dispatches for this thread (L2 miss + L2 hits)"
- },
- {,
"EventCode": "0xF8B0",
"EventName": "PM_L3_SW_PREF",
"BriefDescription": "L3 load prefetch, sourced from a software prefetch stream, was sent to the nest"
@@ -1040,11 +1020,6 @@
"BriefDescription": "L3 castouts in Mepf state for this thread"
},
{,
- "EventCode": "0x168A0",
- "EventName": "PM_L3_CO_MEPF",
- "BriefDescription": "L3 CO of line in Mep state (includes casthrough to memory). The Mepf state indicates that a line was brought in to satisfy an L3 prefetch request"
- },
- {,
"EventCode": "0x460A2",
"EventName": "PM_L3_LAT_CI_HIT",
"BriefDescription": "L3 Lateral Castins Hit"
@@ -1150,11 +1125,6 @@
"BriefDescription": "RC retries on PB for any store from core (excludes DCBFs)"
},
{,
- "EventCode": "0x4689E",
- "EventName": "PM_L2_RTY_ST",
- "BriefDescription": "RC retries on PB for any store from core (excludes DCBFs)"
- },
- {,
"EventCode": "0x24040",
"EventName": "PM_INST_FROM_L2_MEPF",
"BriefDescription": "The processor's Instruction cache was reloaded from local core's L2 hit without dispatch conflicts on Mepf state. due to an instruction fetch (not prefetch)"
@@ -1255,11 +1225,6 @@
"BriefDescription": "CO mach 0 Busy. Used by PMU to sample ave CO lifetime (mach0 used as sample point)"
},
{,
- "EventCode": "0x4608C",
- "EventName": "PM_CO0_BUSY",
- "BriefDescription": "CO mach 0 Busy. Used by PMU to sample ave CO lifetime (mach0 used as sample point)"
- },
- {,
"EventCode": "0x2C122",
"EventName": "PM_MRK_DATA_FROM_L3_DISP_CONFLICT_CYC",
"BriefDescription": "Duration in cycles to reload from local core's L3 with dispatch conflict due to a marked load"
@@ -1395,11 +1360,6 @@
"BriefDescription": "A Page Table Entry was loaded into the TLB from the local chip's Memory due to a instruction side request"
},
{,
- "EventCode": "0x40006",
- "EventName": "PM_ISLB_MISS",
- "BriefDescription": "Number of ISLB misses for this thread"
- },
- {,
"EventCode": "0xD8A8",
"EventName": "PM_ISLB_MISS",
"BriefDescription": "Instruction SLB miss - Total of all segment sizes"
@@ -1515,11 +1475,6 @@
"BriefDescription": "All successful I-side dispatches for this thread (excludes i_l2mru_tch reqs)."
},
{,
- "EventCode": "0x3609E",
- "EventName": "PM_L2_INST",
- "BriefDescription": "All successful I-side dispatches that were an L2 miss for this thread (excludes i_l2mru_tch reqs)"
- },
- {,
"EventCode": "0x3504C",
"EventName": "PM_IPTEG_FROM_DL4",
"BriefDescription": "A Page Table Entry was loaded into the TLB from another chip's L4 on a different Node or Group (Distant) due to a instruction side request"
@@ -1690,11 +1645,6 @@
"BriefDescription": "All successful I-or-D side load dispatches for this thread that were L2 hits (excludes i_l2mru_tch_reqs)"
},
{,
- "EventCode": "0x2609E",
- "EventName": "PM_L2_LD_HIT",
- "BriefDescription": "All successful D side load dispatches for this thread that were L2 hits for this thread"
- },
- {,
"EventCode": "0x168AC",
"EventName": "PM_L3_CI_USAGE",
"BriefDescription": "Rotating sample of 16 CI or CO actives"
@@ -1795,21 +1745,11 @@
"BriefDescription": "Rotating sample of 8 WI valid"
},
{,
- "EventCode": "0x260B6",
- "EventName": "PM_L3_WI0_BUSY",
- "BriefDescription": "Rotating sample of 8 WI valid (duplicate)"
- },
- {,
"EventCode": "0x368AC",
"EventName": "PM_L3_CO0_BUSY",
"BriefDescription": "Lifetime, sample of CO machine 0 valid"
},
{,
- "EventCode": "0x468AC",
- "EventName": "PM_L3_CO0_BUSY",
- "BriefDescription": "Lifetime, sample of CO machine 0 valid"
- },
- {,
"EventCode": "0x2E040",
"EventName": "PM_DPTEG_FROM_L2_MEPF",
"BriefDescription": "A Page Table Entry was loaded into the TLB from local core's L2 hit without dispatch conflicts on Mepf state. due to a data side request. When using Radix Page Translation, this count excludes PDE reloads. Only PTE reloads are included"
@@ -1840,11 +1780,6 @@
"BriefDescription": "L3 PF received retry port 0, every retry counted"
},
{,
- "EventCode": "0x260AE",
- "EventName": "PM_L3_P0_PF_RTY",
- "BriefDescription": "L3 PF received retry port 0, every retry counted"
- },
- {,
"EventCode": "0x268B2",
"EventName": "PM_L3_LOC_GUESS_WRONG",
"BriefDescription": "Initial scope=node (LNS) but data from out side local node (near or far or rem). Prediction too Low"
@@ -1895,11 +1830,6 @@
"BriefDescription": "Lifetime, sample of snooper machine 0 valid"
},
{,
- "EventCode": "0x460AC",
- "EventName": "PM_L3_SN0_BUSY",
- "BriefDescription": "Lifetime, sample of snooper machine 0 valid"
- },
- {,
"EventCode": "0x3005C",
"EventName": "PM_BFU_BUSY",
"BriefDescription": "Cycles in which all 4 Binary Floating Point units are busy. The BFU is running at capacity"
@@ -1935,11 +1865,6 @@
"BriefDescription": "Lifetime, sample of PF machine 0 valid"
},
{,
- "EventCode": "0x460B4",
- "EventName": "PM_L3_PF0_BUSY",
- "BriefDescription": "Lifetime, sample of PF machine 0 valid"
- },
- {,
"EventCode": "0xC0B0",
"EventName": "PM_LSU_FLUSH_UE",
"BriefDescription": "Correctable ECC error on reload data, reported at critical data forward time"
@@ -2085,11 +2010,6 @@
"BriefDescription": "L3 CO received retry port 1 (memory only), every retry counted"
},
{,
- "EventCode": "0x468AE",
- "EventName": "PM_L3_P1_CO_RTY",
- "BriefDescription": "L3 CO received retry port 3 (memory only), every retry counted"
- },
- {,
"EventCode": "0xC0AC",
"EventName": "PM_LSU_FLUSH_EMSH",
"BriefDescription": "An ERAT miss was detected after a set-p hit. Erat tracker indicates fail due to tlbmiss and the instruction gets flushed because the instruction was working on the wrong address"
@@ -2195,11 +2115,6 @@
"BriefDescription": "SNP dispatched for a write and was M (true M); for DMA cacheinj this will pulse if rty/push is required (won't pulse if cacheinj is accepted)"
},
{,
- "EventCode": "0x46886",
- "EventName": "PM_L2_SN_M_WR_DONE",
- "BriefDescription": "SNP dispatched for a write and was M (true M); for DMA cacheinj this will pulse if rty/push is required (won't pulse if cacheinj is accepted)"
- },
- {,
"EventCode": "0x489C",
"EventName": "PM_BR_CORECT_PRED_TAKEN_CMPL",
"BriefDescription": "Conditional Branch Completed in which the HW correctly predicted the direction as taken. Counted at completion time"
@@ -2290,21 +2205,11 @@
"BriefDescription": "SN mach 0 Busy. Used by PMU to sample ave SN lifetime (mach0 used as sample point)"
},
{,
- "EventCode": "0x26090",
- "EventName": "PM_SN0_BUSY",
- "BriefDescription": "SN mach 0 Busy. Used by PMU to sample ave SN lifetime (mach0 used as sample point)"
- },
- {,
"EventCode": "0x360AE",
"EventName": "PM_L3_P0_CO_RTY",
"BriefDescription": "L3 CO received retry port 0 (memory only), every retry counted"
},
{,
- "EventCode": "0x460AE",
- "EventName": "PM_L3_P0_CO_RTY",
- "BriefDescription": "L3 CO received retry port 0 (memory only), every retry counted"
- },
- {,
"EventCode": "0x168A8",
"EventName": "PM_L3_WI_USAGE",
"BriefDescription": "Lifetime, sample of Write Inject machine 0 valid"
@@ -2340,26 +2245,11 @@
"BriefDescription": "L3 PF received retry port 1, every retry counted"
},
{,
- "EventCode": "0x268AE",
- "EventName": "PM_L3_P1_PF_RTY",
- "BriefDescription": "L3 PF received retry port 3, every retry counted"
- },
- {,
"EventCode": "0x46082",
"EventName": "PM_L2_ST_DISP",
"BriefDescription": "All successful D-side store dispatches for this thread "
},
{,
- "EventCode": "0x1689E",
- "EventName": "PM_L2_ST_DISP",
- "BriefDescription": "All successful D-side store dispatches for this thread (L2 miss + L2 hits)"
- },
- {,
- "EventCode": "0x36880",
- "EventName": "PM_L2_INST_MISS",
- "BriefDescription": "All successful I-side dispatches that were an L2 miss for this thread (excludes i_l2mru_tch reqs)"
- },
- {,
"EventCode": "0x4609E",
"EventName": "PM_L2_INST_MISS",
"BriefDescription": "All successful I-side dispatches that were an L2 miss for this thread (excludes i_l2mru_tch reqs)"
@@ -2430,11 +2320,6 @@
"BriefDescription": "# PPC Dispatched"
},
{,
- "EventCode": "0x300F2",
- "EventName": "PM_INST_DISP",
- "BriefDescription": "# PPC Dispatched"
- },
- {,
"EventCode": "0x4E05E",
"EventName": "PM_TM_OUTER_TBEGIN_DISP",
"BriefDescription": "Number of outer tbegin instructions dispatched. The dispatch unit determines whether the tbegin instruction is outer or nested. This is a speculative count, which includes flushed instructions"
@@ -2460,11 +2345,6 @@
"BriefDescription": "All successful D-side store dispatches for this thread that were L2 hits"
},
{,
- "EventCode": "0x2689E",
- "EventName": "PM_L2_ST_HIT",
- "BriefDescription": "All successful D-side store dispatches that were L2 hits for this thread"
- },
- {,
"EventCode": "0x360A8",
"EventName": "PM_L3_CO",
"BriefDescription": "L3 castout occurring (does not include casthrough or log writes (cinj/dmaw))"
diff --git a/tools/perf/pmu-events/arch/powerpc/power9/pipeline.json b/tools/perf/pmu-events/arch/powerpc/power9/pipeline.json
index 47a82568a8df..bc2db636dabf 100644
--- a/tools/perf/pmu-events/arch/powerpc/power9/pipeline.json
+++ b/tools/perf/pmu-events/arch/powerpc/power9/pipeline.json
@@ -420,11 +420,6 @@
"BriefDescription": "Final Pump Scope (Group) ended up larger than Initial Pump Scope (Chip) for an instruction fetch"
},
{,
- "EventCode": "0x10016",
- "EventName": "PM_DSLB_MISS",
- "BriefDescription": "Data SLB Miss - Total of all segment sizes"
- },
- {,
"EventCode": "0xD0A8",
"EventName": "PM_DSLB_MISS",
"BriefDescription": "Data SLB Miss - Total of all segment sizes"
@@ -554,4 +549,4 @@
"EventName": "PM_MRK_DATA_FROM_L21_SHR_CYC",
"BriefDescription": "Duration in cycles to reload with Shared (S) data from another core's L2 on the same chip due to a marked load"
}
-] \ No newline at end of file
+]
diff --git a/tools/perf/pmu-events/arch/powerpc/power9/pmc.json b/tools/perf/pmu-events/arch/powerpc/power9/pmc.json
index a2c95a99e168..3ef8a10aac86 100644
--- a/tools/perf/pmu-events/arch/powerpc/power9/pmc.json
+++ b/tools/perf/pmu-events/arch/powerpc/power9/pmc.json
@@ -5,11 +5,6 @@
"BriefDescription": "Branches that are not strongly biased"
},
{,
- "EventCode": "0x40036",
- "EventName": "PM_BR_2PATH",
- "BriefDescription": "Branches that are not strongly biased"
- },
- {,
"EventCode": "0x40056",
"EventName": "PM_MEM_LOC_THRESH_LSU_HIGH",
"BriefDescription": "Local memory above threshold for LSU medium"
@@ -124,4 +119,4 @@
"EventName": "PM_1FLOP_CMPL",
"BriefDescription": "one flop (fadd, fmul, fsub, fcmp, fsel, fabs, fnabs, fres, fsqrte, fneg) operation completed"
}
-] \ No newline at end of file
+]
diff --git a/tools/perf/tests/code-reading.c b/tools/perf/tests/code-reading.c
index 761c5a448c56..466a462b26d1 100644
--- a/tools/perf/tests/code-reading.c
+++ b/tools/perf/tests/code-reading.c
@@ -237,6 +237,11 @@ static int read_object_code(u64 addr, size_t len, u8 cpumode,
thread__find_addr_map(thread, cpumode, MAP__FUNCTION, addr, &al);
if (!al.map || !al.map->dso) {
+ if (cpumode == PERF_RECORD_MISC_HYPERVISOR) {
+ pr_debug("Hypervisor address can not be resolved - skipping\n");
+ return 0;
+ }
+
pr_debug("thread__find_addr_map failed\n");
return -1;
}
diff --git a/tools/perf/tests/dwarf-unwind.c b/tools/perf/tests/dwarf-unwind.c
index 2a7b9b47bbcb..9ba1d216a89f 100644
--- a/tools/perf/tests/dwarf-unwind.c
+++ b/tools/perf/tests/dwarf-unwind.c
@@ -6,7 +6,7 @@
#include "debug.h"
#include "machine.h"
#include "event.h"
-#include "unwind.h"
+#include "../util/unwind.h"
#include "perf_regs.h"
#include "map.h"
#include "thread.h"
diff --git a/tools/perf/tests/sample-parsing.c b/tools/perf/tests/sample-parsing.c
index 6d028f42b3cf..c3858487159d 100644
--- a/tools/perf/tests/sample-parsing.c
+++ b/tools/perf/tests/sample-parsing.c
@@ -141,6 +141,9 @@ static bool samples_same(const struct perf_sample *s1,
}
}
+ if (type & PERF_SAMPLE_PHYS_ADDR)
+ COMP(phys_addr);
+
return true;
}
@@ -206,6 +209,7 @@ static int do_test(u64 sample_type, u64 sample_regs, u64 read_format)
.mask = sample_regs,
.regs = regs,
},
+ .phys_addr = 113,
};
struct sample_read_value values[] = {{1, 5}, {9, 3}, {2, 7}, {6, 4},};
struct perf_sample sample_out;
@@ -305,7 +309,7 @@ int test__sample_parsing(struct test *test __maybe_unused, int subtest __maybe_u
* were added. Please actually update the test rather than just change
* the condition below.
*/
- if (PERF_SAMPLE_MAX > PERF_SAMPLE_REGS_INTR << 1) {
+ if (PERF_SAMPLE_MAX > PERF_SAMPLE_PHYS_ADDR << 1) {
pr_debug("sample format has changed, some new PERF_SAMPLE_ bit was introduced - test needs updating\n");
return -1;
}
diff --git a/tools/perf/ui/browsers/annotate.c b/tools/perf/ui/browsers/annotate.c
index ba0aee576a2b..786fecaf578e 100644
--- a/tools/perf/ui/browsers/annotate.c
+++ b/tools/perf/ui/browsers/annotate.c
@@ -829,7 +829,8 @@ static int annotate_browser__run(struct annotate_browser *browser,
"q/ESC/CTRL+C Exit\n\n"
"ENTER Go to target\n"
"ESC Exit\n"
- "H Cycle thru hottest instructions\n"
+ "H Go to hottest instruction\n"
+ "TAB/shift+TAB Cycle thru hottest instructions\n"
"j Toggle showing jump to target arrows\n"
"J Toggle showing number of jump sources on targets\n"
"n Search next string\n"
diff --git a/tools/perf/ui/browsers/hists.c b/tools/perf/ui/browsers/hists.c
index f4bc2462bc2c..13dfb0a0bdeb 100644
--- a/tools/perf/ui/browsers/hists.c
+++ b/tools/perf/ui/browsers/hists.c
@@ -931,12 +931,8 @@ static int hist_browser__show_callchain_list(struct hist_browser *browser,
browser->show_dso);
if (symbol_conf.show_branchflag_count) {
- if (need_percent)
- callchain_list_counts__printf_value(node, chain, NULL,
- buf, sizeof(buf));
- else
- callchain_list_counts__printf_value(NULL, chain, NULL,
- buf, sizeof(buf));
+ callchain_list_counts__printf_value(chain, NULL,
+ buf, sizeof(buf));
if (asprintf(&alloc_str2, "%s%s", str, buf) < 0)
str = "Not enough memory!";
diff --git a/tools/perf/ui/progress.c b/tools/perf/ui/progress.c
index a0f24c7115c5..ae91c8148edf 100644
--- a/tools/perf/ui/progress.c
+++ b/tools/perf/ui/progress.c
@@ -1,3 +1,4 @@
+#include <linux/kernel.h>
#include "../cache.h"
#include "progress.h"
@@ -14,10 +15,14 @@ struct ui_progress_ops *ui_progress__ops = &null_progress__ops;
void ui_progress__update(struct ui_progress *p, u64 adv)
{
+ u64 last = p->curr;
+
p->curr += adv;
if (p->curr >= p->next) {
- p->next += p->step;
+ u64 nr = DIV_ROUND_UP(p->curr - last, p->step);
+
+ p->next += nr * p->step;
ui_progress__ops->update(p);
}
}
@@ -25,7 +30,7 @@ void ui_progress__update(struct ui_progress *p, u64 adv)
void ui_progress__init(struct ui_progress *p, u64 total, const char *title)
{
p->curr = 0;
- p->next = p->step = total / 16;
+ p->next = p->step = total / 16 ?: 1;
p->total = total;
p->title = title;
diff --git a/tools/perf/ui/stdio/hist.c b/tools/perf/ui/stdio/hist.c
index 5c95b8301c67..8bdb7a500181 100644
--- a/tools/perf/ui/stdio/hist.c
+++ b/tools/perf/ui/stdio/hist.c
@@ -124,12 +124,8 @@ static size_t ipchain__fprintf_graph(FILE *fp, struct callchain_node *node,
str = callchain_list__sym_name(chain, bf, sizeof(bf), false);
if (symbol_conf.show_branchflag_count) {
- if (!period)
- callchain_list_counts__printf_value(node, chain, NULL,
- buf, sizeof(buf));
- else
- callchain_list_counts__printf_value(NULL, chain, NULL,
- buf, sizeof(buf));
+ callchain_list_counts__printf_value(chain, NULL,
+ buf, sizeof(buf));
if (asprintf(&alloc_str, "%s%s", str, buf) < 0)
str = "Not enough memory!";
@@ -313,7 +309,7 @@ static size_t callchain__fprintf_graph(FILE *fp, struct rb_root *root,
if (symbol_conf.show_branchflag_count)
ret += callchain_list_counts__printf_value(
- NULL, chain, fp, NULL, 0);
+ chain, fp, NULL, 0);
ret += fprintf(fp, "\n");
if (++entries_printed == callchain_param.print_limit)
diff --git a/tools/perf/util/callchain.c b/tools/perf/util/callchain.c
index f320b0777e0d..510b513e0f01 100644
--- a/tools/perf/util/callchain.c
+++ b/tools/perf/util/callchain.c
@@ -588,7 +588,7 @@ fill_node(struct callchain_node *node, struct callchain_cursor *cursor)
call->cycles_count =
cursor_node->branch_flags.cycles;
call->iter_count = cursor_node->nr_loop_iter;
- call->samples_count = cursor_node->samples;
+ call->iter_cycles = cursor_node->iter_cycles;
}
}
@@ -722,7 +722,7 @@ static enum match_result match_chain(struct callchain_cursor_node *node,
cnode->cycles_count +=
node->branch_flags.cycles;
cnode->iter_count += node->nr_loop_iter;
- cnode->samples_count += node->samples;
+ cnode->iter_cycles += node->iter_cycles;
}
}
@@ -998,7 +998,7 @@ int callchain_merge(struct callchain_cursor *cursor,
int callchain_cursor_append(struct callchain_cursor *cursor,
u64 ip, struct map *map, struct symbol *sym,
bool branch, struct branch_flags *flags,
- int nr_loop_iter, int samples, u64 branch_from)
+ int nr_loop_iter, u64 iter_cycles, u64 branch_from)
{
struct callchain_cursor_node *node = *cursor->last;
@@ -1016,7 +1016,7 @@ int callchain_cursor_append(struct callchain_cursor *cursor,
node->sym = sym;
node->branch = branch;
node->nr_loop_iter = nr_loop_iter;
- node->samples = samples;
+ node->iter_cycles = iter_cycles;
if (flags)
memcpy(&node->branch_flags, flags,
@@ -1306,7 +1306,7 @@ static int branch_to_str(char *bf, int bfsize,
static int branch_from_str(char *bf, int bfsize,
u64 branch_count,
u64 cycles_count, u64 iter_count,
- u64 samples_count)
+ u64 iter_cycles)
{
int printed = 0, i = 0;
u64 cycles;
@@ -1318,9 +1318,13 @@ static int branch_from_str(char *bf, int bfsize,
bf + printed, bfsize - printed);
}
- if (iter_count && samples_count) {
- printed += count_pri64_printf(i++, "iterations",
- iter_count / samples_count,
+ if (iter_count) {
+ printed += count_pri64_printf(i++, "iter",
+ iter_count,
+ bf + printed, bfsize - printed);
+
+ printed += count_pri64_printf(i++, "avg_cycles",
+ iter_cycles / iter_count,
bf + printed, bfsize - printed);
}
@@ -1333,7 +1337,7 @@ static int branch_from_str(char *bf, int bfsize,
static int counts_str_build(char *bf, int bfsize,
u64 branch_count, u64 predicted_count,
u64 abort_count, u64 cycles_count,
- u64 iter_count, u64 samples_count,
+ u64 iter_count, u64 iter_cycles,
struct branch_type_stat *brtype_stat)
{
int printed;
@@ -1346,7 +1350,7 @@ static int counts_str_build(char *bf, int bfsize,
predicted_count, abort_count, brtype_stat);
} else {
printed = branch_from_str(bf, bfsize, branch_count,
- cycles_count, iter_count, samples_count);
+ cycles_count, iter_count, iter_cycles);
}
if (!printed)
@@ -1358,14 +1362,14 @@ static int counts_str_build(char *bf, int bfsize,
static int callchain_counts_printf(FILE *fp, char *bf, int bfsize,
u64 branch_count, u64 predicted_count,
u64 abort_count, u64 cycles_count,
- u64 iter_count, u64 samples_count,
+ u64 iter_count, u64 iter_cycles,
struct branch_type_stat *brtype_stat)
{
char str[256];
counts_str_build(str, sizeof(str), branch_count,
predicted_count, abort_count, cycles_count,
- iter_count, samples_count, brtype_stat);
+ iter_count, iter_cycles, brtype_stat);
if (fp)
return fprintf(fp, "%s", str);
@@ -1373,31 +1377,23 @@ static int callchain_counts_printf(FILE *fp, char *bf, int bfsize,
return scnprintf(bf, bfsize, "%s", str);
}
-int callchain_list_counts__printf_value(struct callchain_node *node,
- struct callchain_list *clist,
+int callchain_list_counts__printf_value(struct callchain_list *clist,
FILE *fp, char *bf, int bfsize)
{
u64 branch_count, predicted_count;
u64 abort_count, cycles_count;
- u64 iter_count = 0, samples_count = 0;
+ u64 iter_count, iter_cycles;
branch_count = clist->branch_count;
predicted_count = clist->predicted_count;
abort_count = clist->abort_count;
cycles_count = clist->cycles_count;
-
- if (node) {
- struct callchain_list *call;
-
- list_for_each_entry(call, &node->val, list) {
- iter_count += call->iter_count;
- samples_count += call->samples_count;
- }
- }
+ iter_count = clist->iter_count;
+ iter_cycles = clist->iter_cycles;
return callchain_counts_printf(fp, bf, bfsize, branch_count,
predicted_count, abort_count,
- cycles_count, iter_count, samples_count,
+ cycles_count, iter_count, iter_cycles,
&clist->brtype_stat);
}
@@ -1523,7 +1519,8 @@ int callchain_cursor__copy(struct callchain_cursor *dst,
rc = callchain_cursor_append(dst, node->ip, node->map, node->sym,
node->branch, &node->branch_flags,
- node->nr_loop_iter, node->samples,
+ node->nr_loop_iter,
+ node->iter_cycles,
node->branch_from);
if (rc)
break;
diff --git a/tools/perf/util/callchain.h b/tools/perf/util/callchain.h
index 97738201464a..1ed6fc61d0a5 100644
--- a/tools/perf/util/callchain.h
+++ b/tools/perf/util/callchain.h
@@ -119,7 +119,7 @@ struct callchain_list {
u64 abort_count;
u64 cycles_count;
u64 iter_count;
- u64 samples_count;
+ u64 iter_cycles;
struct branch_type_stat brtype_stat;
char *srcline;
struct list_head list;
@@ -139,7 +139,7 @@ struct callchain_cursor_node {
struct branch_flags branch_flags;
u64 branch_from;
int nr_loop_iter;
- int samples;
+ u64 iter_cycles;
struct callchain_cursor_node *next;
};
@@ -201,7 +201,7 @@ static inline void callchain_cursor_reset(struct callchain_cursor *cursor)
int callchain_cursor_append(struct callchain_cursor *cursor, u64 ip,
struct map *map, struct symbol *sym,
bool branch, struct branch_flags *flags,
- int nr_loop_iter, int samples, u64 branch_from);
+ int nr_loop_iter, u64 iter_cycles, u64 branch_from);
/* Close a cursor writing session. Initialize for the reader */
static inline void callchain_cursor_commit(struct callchain_cursor *cursor)
@@ -282,8 +282,7 @@ char *callchain_node__scnprintf_value(struct callchain_node *node,
int callchain_node__fprintf_value(struct callchain_node *node,
FILE *fp, u64 total);
-int callchain_list_counts__printf_value(struct callchain_node *node,
- struct callchain_list *clist,
+int callchain_list_counts__printf_value(struct callchain_list *clist,
FILE *fp, char *bf, int bfsize);
void free_callchain(struct callchain_root *root);
diff --git a/tools/perf/util/data.c b/tools/perf/util/data.c
index e84bbc8ec058..263f5a906ba5 100644
--- a/tools/perf/util/data.c
+++ b/tools/perf/util/data.c
@@ -10,6 +10,16 @@
#include "util.h"
#include "debug.h"
+#ifndef O_CLOEXEC
+#ifdef __sparc__
+#define O_CLOEXEC 0x400000
+#elif defined(__alpha__) || defined(__hppa__)
+#define O_CLOEXEC 010000000
+#else
+#define O_CLOEXEC 02000000
+#endif
+#endif
+
static bool check_pipe(struct perf_data_file *file)
{
struct stat st;
@@ -96,7 +106,8 @@ static int open_file_write(struct perf_data_file *file)
if (check_backup(file))
return -1;
- fd = open(file->path, O_CREAT|O_RDWR|O_TRUNC, S_IRUSR|S_IWUSR);
+ fd = open(file->path, O_CREAT|O_RDWR|O_TRUNC|O_CLOEXEC,
+ S_IRUSR|S_IWUSR);
if (fd < 0)
pr_err("failed to open %s : %s\n", file->path,
diff --git a/tools/perf/util/event.h b/tools/perf/util/event.h
index 423ac82605f3..ee7bcc898d35 100644
--- a/tools/perf/util/event.h
+++ b/tools/perf/util/event.h
@@ -200,6 +200,7 @@ struct perf_sample {
u32 cpu;
u32 raw_size;
u64 data_src;
+ u64 phys_addr;
u32 flags;
u16 insn_len;
u8 cpumode;
diff --git a/tools/perf/util/evsel.c b/tools/perf/util/evsel.c
index d9bd632ed7db..4bb89373eb52 100644
--- a/tools/perf/util/evsel.c
+++ b/tools/perf/util/evsel.c
@@ -955,6 +955,9 @@ void perf_evsel__config(struct perf_evsel *evsel, struct record_opts *opts,
if (opts->sample_address)
perf_evsel__set_sample_bit(evsel, DATA_SRC);
+ if (opts->sample_phys_addr)
+ perf_evsel__set_sample_bit(evsel, PHYS_ADDR);
+
if (opts->no_buffering) {
attr->watermark = 0;
attr->wakeup_events = 1;
@@ -1464,7 +1467,7 @@ static void __p_sample_type(char *buf, size_t size, u64 value)
bit_name(PERIOD), bit_name(STREAM_ID), bit_name(RAW),
bit_name(BRANCH_STACK), bit_name(REGS_USER), bit_name(STACK_USER),
bit_name(IDENTIFIER), bit_name(REGS_INTR), bit_name(DATA_SRC),
- bit_name(WEIGHT),
+ bit_name(WEIGHT), bit_name(PHYS_ADDR),
{ .name = NULL, }
};
#undef bit_name
@@ -2206,6 +2209,12 @@ int perf_evsel__parse_sample(struct perf_evsel *evsel, union perf_event *event,
}
}
+ data->phys_addr = 0;
+ if (type & PERF_SAMPLE_PHYS_ADDR) {
+ data->phys_addr = *array;
+ array++;
+ }
+
return 0;
}
@@ -2311,6 +2320,9 @@ size_t perf_event__sample_event_size(const struct perf_sample *sample, u64 type,
}
}
+ if (type & PERF_SAMPLE_PHYS_ADDR)
+ result += sizeof(u64);
+
return result;
}
@@ -2500,6 +2512,11 @@ int perf_event__synthesize_sample(union perf_event *event, u64 type,
}
}
+ if (type & PERF_SAMPLE_PHYS_ADDR) {
+ *array = sample->phys_addr;
+ array++;
+ }
+
return 0;
}
diff --git a/tools/perf/util/evsel.h b/tools/perf/util/evsel.h
index 351d3b2d8887..dd2c4b5112a5 100644
--- a/tools/perf/util/evsel.h
+++ b/tools/perf/util/evsel.h
@@ -131,6 +131,7 @@ struct perf_evsel {
bool cmdline_group_boundary;
struct list_head config_terms;
int bpf_fd;
+ bool auto_merge_stats;
bool merged_stat;
const char * metric_expr;
const char * metric_name;
diff --git a/tools/perf/util/hist.c b/tools/perf/util/hist.c
index 9453b2e27015..e60d8d8ea4c2 100644
--- a/tools/perf/util/hist.c
+++ b/tools/perf/util/hist.c
@@ -167,6 +167,10 @@ void hists__calc_col_len(struct hists *hists, struct hist_entry *h)
symlen = unresolved_col_width + 4 + 2;
hists__set_unres_dso_col_len(hists, HISTC_MEM_DADDR_DSO);
}
+
+ hists__new_col_len(hists, HISTC_MEM_PHYS_DADDR,
+ unresolved_col_width + 4 + 2);
+
} else {
symlen = unresolved_col_width + 4 + 2;
hists__new_col_len(hists, HISTC_MEM_DADDR_SYMBOL, symlen);
diff --git a/tools/perf/util/hist.h b/tools/perf/util/hist.h
index ee3670a388df..e60dda26a920 100644
--- a/tools/perf/util/hist.h
+++ b/tools/perf/util/hist.h
@@ -47,6 +47,7 @@ enum hist_column {
HISTC_GLOBAL_WEIGHT,
HISTC_MEM_DADDR_SYMBOL,
HISTC_MEM_DADDR_DSO,
+ HISTC_MEM_PHYS_DADDR,
HISTC_MEM_LOCKED,
HISTC_MEM_TLB,
HISTC_MEM_LVL,
diff --git a/tools/perf/util/machine.c b/tools/perf/util/machine.c
index 5c8eacaca4f4..df709363ef69 100644
--- a/tools/perf/util/machine.c
+++ b/tools/perf/util/machine.c
@@ -1635,10 +1635,12 @@ static void ip__resolve_ams(struct thread *thread,
ams->al_addr = al.addr;
ams->sym = al.sym;
ams->map = al.map;
+ ams->phys_addr = 0;
}
static void ip__resolve_data(struct thread *thread,
- u8 m, struct addr_map_symbol *ams, u64 addr)
+ u8 m, struct addr_map_symbol *ams,
+ u64 addr, u64 phys_addr)
{
struct addr_location al;
@@ -1658,6 +1660,7 @@ static void ip__resolve_data(struct thread *thread,
ams->al_addr = al.addr;
ams->sym = al.sym;
ams->map = al.map;
+ ams->phys_addr = phys_addr;
}
struct mem_info *sample__resolve_mem(struct perf_sample *sample,
@@ -1669,12 +1672,18 @@ struct mem_info *sample__resolve_mem(struct perf_sample *sample,
return NULL;
ip__resolve_ams(al->thread, &mi->iaddr, sample->ip);
- ip__resolve_data(al->thread, al->cpumode, &mi->daddr, sample->addr);
+ ip__resolve_data(al->thread, al->cpumode, &mi->daddr,
+ sample->addr, sample->phys_addr);
mi->data_src.val = sample->data_src;
return mi;
}
+struct iterations {
+ int nr_loop_iter;
+ u64 cycles;
+};
+
static int add_callchain_ip(struct thread *thread,
struct callchain_cursor *cursor,
struct symbol **parent,
@@ -1683,11 +1692,12 @@ static int add_callchain_ip(struct thread *thread,
u64 ip,
bool branch,
struct branch_flags *flags,
- int nr_loop_iter,
- int samples,
+ struct iterations *iter,
u64 branch_from)
{
struct addr_location al;
+ int nr_loop_iter = 0;
+ u64 iter_cycles = 0;
al.filtered = 0;
al.sym = NULL;
@@ -1737,9 +1747,15 @@ static int add_callchain_ip(struct thread *thread,
if (symbol_conf.hide_unresolved && al.sym == NULL)
return 0;
+
+ if (iter) {
+ nr_loop_iter = iter->nr_loop_iter;
+ iter_cycles = iter->cycles;
+ }
+
return callchain_cursor_append(cursor, al.addr, al.map, al.sym,
- branch, flags, nr_loop_iter, samples,
- branch_from);
+ branch, flags, nr_loop_iter,
+ iter_cycles, branch_from);
}
struct branch_info *sample__resolve_bstack(struct perf_sample *sample,
@@ -1760,6 +1776,18 @@ struct branch_info *sample__resolve_bstack(struct perf_sample *sample,
return bi;
}
+static void save_iterations(struct iterations *iter,
+ struct branch_entry *be, int nr)
+{
+ int i;
+
+ iter->nr_loop_iter = nr;
+ iter->cycles = 0;
+
+ for (i = 0; i < nr; i++)
+ iter->cycles += be[i].flags.cycles;
+}
+
#define CHASHSZ 127
#define CHASHBITS 7
#define NO_ENTRY 0xff
@@ -1767,7 +1795,8 @@ struct branch_info *sample__resolve_bstack(struct perf_sample *sample,
#define PERF_MAX_BRANCH_DEPTH 127
/* Remove loops. */
-static int remove_loops(struct branch_entry *l, int nr)
+static int remove_loops(struct branch_entry *l, int nr,
+ struct iterations *iter)
{
int i, j, off;
unsigned char chash[CHASHSZ];
@@ -1792,8 +1821,18 @@ static int remove_loops(struct branch_entry *l, int nr)
break;
}
if (is_loop) {
- memmove(l + i, l + i + off,
- (nr - (i + off)) * sizeof(*l));
+ j = nr - (i + off);
+ if (j > 0) {
+ save_iterations(iter + i + off,
+ l + i, off);
+
+ memmove(iter + i, iter + i + off,
+ j * sizeof(*iter));
+
+ memmove(l + i, l + i + off,
+ j * sizeof(*l));
+ }
+
nr -= off;
}
}
@@ -1883,7 +1922,7 @@ static int resolve_lbr_callchain_sample(struct thread *thread,
err = add_callchain_ip(thread, cursor, parent,
root_al, &cpumode, ip,
- branch, flags, 0, 0,
+ branch, flags, NULL,
branch_from);
if (err)
return (err < 0) ? err : 0;
@@ -1909,7 +1948,6 @@ static int thread__resolve_callchain_sample(struct thread *thread,
int i, j, err, nr_entries;
int skip_idx = -1;
int first_call = 0;
- int nr_loop_iter;
if (chain)
chain_nr = chain->nr;
@@ -1942,6 +1980,7 @@ static int thread__resolve_callchain_sample(struct thread *thread,
if (branch && callchain_param.branch_callstack) {
int nr = min(max_stack, (int)branch->nr);
struct branch_entry be[nr];
+ struct iterations iter[nr];
if (branch->nr > PERF_MAX_BRANCH_DEPTH) {
pr_warning("corrupted branch chain. skipping...\n");
@@ -1972,38 +2011,21 @@ static int thread__resolve_callchain_sample(struct thread *thread,
be[i] = branch->entries[branch->nr - i - 1];
}
- nr_loop_iter = nr;
- nr = remove_loops(be, nr);
-
- /*
- * Get the number of iterations.
- * It's only approximation, but good enough in practice.
- */
- if (nr_loop_iter > nr)
- nr_loop_iter = nr_loop_iter - nr + 1;
- else
- nr_loop_iter = 0;
+ memset(iter, 0, sizeof(struct iterations) * nr);
+ nr = remove_loops(be, nr, iter);
for (i = 0; i < nr; i++) {
- if (i == nr - 1)
- err = add_callchain_ip(thread, cursor, parent,
- root_al,
- NULL, be[i].to,
- true, &be[i].flags,
- nr_loop_iter, 1,
- be[i].from);
- else
- err = add_callchain_ip(thread, cursor, parent,
- root_al,
- NULL, be[i].to,
- true, &be[i].flags,
- 0, 0, be[i].from);
+ err = add_callchain_ip(thread, cursor, parent,
+ root_al,
+ NULL, be[i].to,
+ true, &be[i].flags,
+ NULL, be[i].from);
if (!err)
err = add_callchain_ip(thread, cursor, parent, root_al,
NULL, be[i].from,
true, &be[i].flags,
- 0, 0, 0);
+ &iter[i], 0);
if (err == -EINVAL)
break;
if (err)
@@ -2037,7 +2059,7 @@ check_calls:
err = add_callchain_ip(thread, cursor, parent,
root_al, &cpumode, ip,
- false, NULL, 0, 0, 0);
+ false, NULL, NULL, 0);
if (err)
return (err < 0) ? err : 0;
diff --git a/tools/perf/util/parse-events.c b/tools/perf/util/parse-events.c
index f44aeba51d1f..f6257fb4f08c 100644
--- a/tools/perf/util/parse-events.c
+++ b/tools/perf/util/parse-events.c
@@ -310,7 +310,7 @@ static struct perf_evsel *
__add_event(struct list_head *list, int *idx,
struct perf_event_attr *attr,
char *name, struct cpu_map *cpus,
- struct list_head *config_terms)
+ struct list_head *config_terms, bool auto_merge_stats)
{
struct perf_evsel *evsel;
@@ -324,6 +324,7 @@ __add_event(struct list_head *list, int *idx,
evsel->cpus = cpu_map__get(cpus);
evsel->own_cpus = cpu_map__get(cpus);
evsel->system_wide = !!cpus;
+ evsel->auto_merge_stats = auto_merge_stats;
if (name)
evsel->name = strdup(name);
@@ -339,7 +340,7 @@ static int add_event(struct list_head *list, int *idx,
struct perf_event_attr *attr, char *name,
struct list_head *config_terms)
{
- return __add_event(list, idx, attr, name, NULL, config_terms) ? 0 : -ENOMEM;
+ return __add_event(list, idx, attr, name, NULL, config_terms, false) ? 0 : -ENOMEM;
}
static int parse_aliases(char *str, const char *names[][PERF_EVSEL__MAX_ALIASES], int size)
@@ -1209,9 +1210,9 @@ int parse_events_add_numeric(struct parse_events_state *parse_state,
get_config_name(head_config), &config_terms);
}
-int parse_events_add_pmu(struct parse_events_state *parse_state,
+static int __parse_events_add_pmu(struct parse_events_state *parse_state,
struct list_head *list, char *name,
- struct list_head *head_config)
+ struct list_head *head_config, bool auto_merge_stats)
{
struct perf_event_attr attr;
struct perf_pmu_info info;
@@ -1232,7 +1233,7 @@ int parse_events_add_pmu(struct parse_events_state *parse_state,
if (!head_config) {
attr.type = pmu->type;
- evsel = __add_event(list, &parse_state->idx, &attr, NULL, pmu->cpus, NULL);
+ evsel = __add_event(list, &parse_state->idx, &attr, NULL, pmu->cpus, NULL, auto_merge_stats);
return evsel ? 0 : -ENOMEM;
}
@@ -1254,7 +1255,7 @@ int parse_events_add_pmu(struct parse_events_state *parse_state,
evsel = __add_event(list, &parse_state->idx, &attr,
get_config_name(head_config), pmu->cpus,
- &config_terms);
+ &config_terms, auto_merge_stats);
if (evsel) {
evsel->unit = info.unit;
evsel->scale = info.scale;
@@ -1267,6 +1268,13 @@ int parse_events_add_pmu(struct parse_events_state *parse_state,
return evsel ? 0 : -ENOMEM;
}
+int parse_events_add_pmu(struct parse_events_state *parse_state,
+ struct list_head *list, char *name,
+ struct list_head *head_config)
+{
+ return __parse_events_add_pmu(parse_state, list, name, head_config, false);
+}
+
int parse_events_multi_pmu_add(struct parse_events_state *parse_state,
char *str, struct list_head **listp)
{
@@ -1296,8 +1304,8 @@ int parse_events_multi_pmu_add(struct parse_events_state *parse_state,
return -1;
list_add_tail(&term->list, head);
- if (!parse_events_add_pmu(parse_state, list,
- pmu->name, head)) {
+ if (!__parse_events_add_pmu(parse_state, list,
+ pmu->name, head, true)) {
pr_debug("%s -> %s/%s/\n", str,
pmu->name, alias->str);
ok++;
diff --git a/tools/perf/util/session.c b/tools/perf/util/session.c
index ac863691605f..a7ebd9fe8e40 100644
--- a/tools/perf/util/session.c
+++ b/tools/perf/util/session.c
@@ -1120,6 +1120,9 @@ static void dump_sample(struct perf_evsel *evsel, union perf_event *event,
if (sample_type & PERF_SAMPLE_DATA_SRC)
printf(" . data_src: 0x%"PRIx64"\n", sample->data_src);
+ if (sample_type & PERF_SAMPLE_PHYS_ADDR)
+ printf(" .. phys_addr: 0x%"PRIx64"\n", sample->phys_addr);
+
if (sample_type & PERF_SAMPLE_TRANSACTION)
printf("... transaction: %" PRIx64 "\n", sample->transaction);
diff --git a/tools/perf/util/sort.c b/tools/perf/util/sort.c
index 12359bd986db..eb3ab902a1c0 100644
--- a/tools/perf/util/sort.c
+++ b/tools/perf/util/sort.c
@@ -1316,6 +1316,47 @@ struct sort_entry sort_mem_dcacheline = {
};
static int64_t
+sort__phys_daddr_cmp(struct hist_entry *left, struct hist_entry *right)
+{
+ uint64_t l = 0, r = 0;
+
+ if (left->mem_info)
+ l = left->mem_info->daddr.phys_addr;
+ if (right->mem_info)
+ r = right->mem_info->daddr.phys_addr;
+
+ return (int64_t)(r - l);
+}
+
+static int hist_entry__phys_daddr_snprintf(struct hist_entry *he, char *bf,
+ size_t size, unsigned int width)
+{
+ uint64_t addr = 0;
+ size_t ret = 0;
+ size_t len = BITS_PER_LONG / 4;
+
+ addr = he->mem_info->daddr.phys_addr;
+
+ ret += repsep_snprintf(bf + ret, size - ret, "[%c] ", he->level);
+
+ ret += repsep_snprintf(bf + ret, size - ret, "%-#.*llx", len, addr);
+
+ ret += repsep_snprintf(bf + ret, size - ret, "%-*s", width - ret, "");
+
+ if (ret > width)
+ bf[width] = '\0';
+
+ return width;
+}
+
+struct sort_entry sort_mem_phys_daddr = {
+ .se_header = "Data Physical Address",
+ .se_cmp = sort__phys_daddr_cmp,
+ .se_snprintf = hist_entry__phys_daddr_snprintf,
+ .se_width_idx = HISTC_MEM_PHYS_DADDR,
+};
+
+static int64_t
sort__abort_cmp(struct hist_entry *left, struct hist_entry *right)
{
if (!left->branch_info || !right->branch_info)
@@ -1547,6 +1588,7 @@ static struct sort_dimension memory_sort_dimensions[] = {
DIM(SORT_MEM_LVL, "mem", sort_mem_lvl),
DIM(SORT_MEM_SNOOP, "snoop", sort_mem_snoop),
DIM(SORT_MEM_DCACHELINE, "dcacheline", sort_mem_dcacheline),
+ DIM(SORT_MEM_PHYS_DADDR, "phys_daddr", sort_mem_phys_daddr),
};
#undef DIM
diff --git a/tools/perf/util/sort.h b/tools/perf/util/sort.h
index b7c75597e18f..f36dc4980a6c 100644
--- a/tools/perf/util/sort.h
+++ b/tools/perf/util/sort.h
@@ -245,6 +245,7 @@ enum sort_type {
SORT_MEM_SNOOP,
SORT_MEM_DCACHELINE,
SORT_MEM_IADDR_SYMBOL,
+ SORT_MEM_PHYS_DADDR,
};
/*
diff --git a/tools/perf/util/symbol.h b/tools/perf/util/symbol.h
index d00a012cfdfb..2bd6a1f01a1c 100644
--- a/tools/perf/util/symbol.h
+++ b/tools/perf/util/symbol.h
@@ -186,6 +186,7 @@ struct addr_map_symbol {
struct symbol *sym;
u64 addr;
u64 al_addr;
+ u64 phys_addr;
};
struct branch_info {
diff --git a/tools/perf/util/syscalltbl.c b/tools/perf/util/syscalltbl.c
index bbb4c1957578..19e5db90394c 100644
--- a/tools/perf/util/syscalltbl.c
+++ b/tools/perf/util/syscalltbl.c
@@ -19,6 +19,7 @@
#ifdef HAVE_SYSCALL_TABLE
#include <linux/compiler.h>
#include <string.h>
+#include "string2.h"
#include "util.h"
#if defined(__x86_64__)
@@ -105,6 +106,27 @@ int syscalltbl__id(struct syscalltbl *tbl, const char *name)
return sc ? sc->id : -1;
}
+int syscalltbl__strglobmatch_next(struct syscalltbl *tbl, const char *syscall_glob, int *idx)
+{
+ int i;
+ struct syscall *syscalls = tbl->syscalls.entries;
+
+ for (i = *idx + 1; i < tbl->syscalls.nr_entries; ++i) {
+ if (strglobmatch(syscalls[i].name, syscall_glob)) {
+ *idx = i;
+ return syscalls[i].id;
+ }
+ }
+
+ return -1;
+}
+
+int syscalltbl__strglobmatch_first(struct syscalltbl *tbl, const char *syscall_glob, int *idx)
+{
+ *idx = -1;
+ return syscalltbl__strglobmatch_next(tbl, syscall_glob, idx);
+}
+
#else /* HAVE_SYSCALL_TABLE */
#include <libaudit.h>
@@ -131,4 +153,15 @@ int syscalltbl__id(struct syscalltbl *tbl, const char *name)
{
return audit_name_to_syscall(name, tbl->audit_machine);
}
+
+int syscalltbl__strglobmatch_next(struct syscalltbl *tbl __maybe_unused,
+ const char *syscall_glob __maybe_unused, int *idx __maybe_unused)
+{
+ return -1;
+}
+
+int syscalltbl__strglobmatch_first(struct syscalltbl *tbl, const char *syscall_glob, int *idx)
+{
+ return syscalltbl__strglobmatch_next(tbl, syscall_glob, idx);
+}
#endif /* HAVE_SYSCALL_TABLE */
diff --git a/tools/perf/util/syscalltbl.h b/tools/perf/util/syscalltbl.h
index e2951510484f..e9fb8786da7c 100644
--- a/tools/perf/util/syscalltbl.h
+++ b/tools/perf/util/syscalltbl.h
@@ -17,4 +17,7 @@ void syscalltbl__delete(struct syscalltbl *tbl);
const char *syscalltbl__name(const struct syscalltbl *tbl, int id);
int syscalltbl__id(struct syscalltbl *tbl, const char *name);
+int syscalltbl__strglobmatch_first(struct syscalltbl *tbl, const char *syscall_glob, int *idx);
+int syscalltbl__strglobmatch_next(struct syscalltbl *tbl, const char *syscall_glob, int *idx);
+
#endif /* __PERF_SYSCALLTBL_H */
diff --git a/tools/power/cpupower/Makefile b/tools/power/cpupower/Makefile
index d6e1c02ddcfe..4c5a481a850c 100644
--- a/tools/power/cpupower/Makefile
+++ b/tools/power/cpupower/Makefile
@@ -26,7 +26,7 @@ endif
ifneq ($(OUTPUT),)
# check that the output directory actually exists
-OUTDIR := $(shell cd $(OUTPUT) && /bin/pwd)
+OUTDIR := $(realpath $(OUTPUT))
$(if $(OUTDIR),, $(error output directory "$(OUTPUT)" does not exist))
endif
diff --git a/tools/scripts/Makefile.include b/tools/scripts/Makefile.include
index 1e8b6116ba3c..9dc8f078a83c 100644
--- a/tools/scripts/Makefile.include
+++ b/tools/scripts/Makefile.include
@@ -1,7 +1,7 @@
ifneq ($(O),)
ifeq ($(origin O), command line)
- dummy := $(if $(shell test -d $(O) || echo $(O)),$(error O=$(O) does not exist),)
- ABSOLUTE_O := $(shell cd $(O) ; pwd)
+ ABSOLUTE_O := $(realpath $(O))
+ dummy := $(if $(ABSOLUTE_O),,$(error O=$(O) does not exist))
OUTPUT := $(ABSOLUTE_O)/$(if $(subdir),$(subdir)/)
COMMAND_O := O=$(ABSOLUTE_O)
ifeq ($(objtree),)
@@ -12,7 +12,7 @@ endif
# check that the output directory actually exists
ifneq ($(OUTPUT),)
-OUTDIR := $(shell cd $(OUTPUT) && /bin/pwd)
+OUTDIR := $(realpath $(OUTPUT))
$(if $(OUTDIR),, $(error output directory "$(OUTPUT)" does not exist))
endif
diff --git a/tools/testing/nvdimm/test/nfit.c b/tools/testing/nvdimm/test/nfit.c
index 4c2fa98ef39d..d20791c3f499 100644
--- a/tools/testing/nvdimm/test/nfit.c
+++ b/tools/testing/nvdimm/test/nfit.c
@@ -1546,8 +1546,8 @@ static int nfit_test_blk_do_io(struct nd_blk_region *ndbr, resource_size_t dpa,
else {
memcpy(iobuf, mmio->addr.base + dpa, len);
- /* give us some some coverage of the mmio_flush_range() API */
- mmio_flush_range(mmio->addr.base + dpa, len);
+ /* give us some some coverage of the arch_invalidate_pmem() API */
+ arch_invalidate_pmem(mmio->addr.base + dpa, len);
}
nd_region_release_lane(nd_region, lane);
diff --git a/tools/testing/selftests/bpf/test_maps.c b/tools/testing/selftests/bpf/test_maps.c
index 4acc772a28c0..fe3a443a1102 100644
--- a/tools/testing/selftests/bpf/test_maps.c
+++ b/tools/testing/selftests/bpf/test_maps.c
@@ -558,7 +558,7 @@ static void test_sockmap(int tasks, void *data)
}
}
- /* Test attaching bad fds */
+ /* Test attaching/detaching bad fds */
err = bpf_prog_attach(-1, fd, BPF_SK_SKB_STREAM_PARSER, 0);
if (!err) {
printf("Failed invalid parser prog attach\n");
@@ -571,6 +571,30 @@ static void test_sockmap(int tasks, void *data)
goto out_sockmap;
}
+ err = bpf_prog_attach(-1, fd, __MAX_BPF_ATTACH_TYPE, 0);
+ if (!err) {
+ printf("Failed unknown prog attach\n");
+ goto out_sockmap;
+ }
+
+ err = bpf_prog_detach(fd, BPF_SK_SKB_STREAM_PARSER);
+ if (err) {
+ printf("Failed empty parser prog detach\n");
+ goto out_sockmap;
+ }
+
+ err = bpf_prog_detach(fd, BPF_SK_SKB_STREAM_VERDICT);
+ if (err) {
+ printf("Failed empty verdict prog detach\n");
+ goto out_sockmap;
+ }
+
+ err = bpf_prog_detach(fd, __MAX_BPF_ATTACH_TYPE);
+ if (!err) {
+ printf("Detach invalid prog successful\n");
+ goto out_sockmap;
+ }
+
/* Load SK_SKB program and Attach */
err = bpf_prog_load(SOCKMAP_PARSE_PROG,
BPF_PROG_TYPE_SK_SKB, &obj, &parse_prog);
@@ -643,6 +667,13 @@ static void test_sockmap(int tasks, void *data)
goto out_sockmap;
}
+ err = bpf_prog_attach(verdict_prog, map_fd_rx,
+ __MAX_BPF_ATTACH_TYPE, 0);
+ if (!err) {
+ printf("Attached unknown bpf prog\n");
+ goto out_sockmap;
+ }
+
/* Test map update elem afterwards fd lives in fd and map_fd */
for (i = 0; i < 6; i++) {
err = bpf_map_update_elem(map_fd_rx, &i, &sfd[i], BPF_ANY);
@@ -809,6 +840,24 @@ static void test_sockmap(int tasks, void *data)
assert(status == 0);
}
+ err = bpf_prog_detach(map_fd_rx, __MAX_BPF_ATTACH_TYPE);
+ if (!err) {
+ printf("Detached an invalid prog type.\n");
+ goto out_sockmap;
+ }
+
+ err = bpf_prog_detach(map_fd_rx, BPF_SK_SKB_STREAM_PARSER);
+ if (err) {
+ printf("Failed parser prog detach\n");
+ goto out_sockmap;
+ }
+
+ err = bpf_prog_detach(map_fd_rx, BPF_SK_SKB_STREAM_VERDICT);
+ if (err) {
+ printf("Failed parser prog detach\n");
+ goto out_sockmap;
+ }
+
/* Test map close sockets */
for (i = 0; i < 6; i++)
close(sfd[i]);
diff --git a/tools/testing/selftests/breakpoints/breakpoint_test.c b/tools/testing/selftests/breakpoints/breakpoint_test.c
index f63356151ad4..901b85ea6a59 100644
--- a/tools/testing/selftests/breakpoints/breakpoint_test.c
+++ b/tools/testing/selftests/breakpoints/breakpoint_test.c
@@ -367,11 +367,11 @@ static void launch_tests(void)
/* Icebp traps */
ptrace(PTRACE_CONT, child_pid, NULL, 0);
- check_success("Test icebp");
+ check_success("Test icebp\n");
/* Int 3 traps */
ptrace(PTRACE_CONT, child_pid, NULL, 0);
- check_success("Test int 3 trap");
+ check_success("Test int 3 trap\n");
ptrace(PTRACE_CONT, child_pid, NULL, 0);
}
diff --git a/tools/testing/selftests/capabilities/test_execve.c b/tools/testing/selftests/capabilities/test_execve.c
index 763f37fecfb8..cf6778441381 100644
--- a/tools/testing/selftests/capabilities/test_execve.c
+++ b/tools/testing/selftests/capabilities/test_execve.c
@@ -1,7 +1,6 @@
#define _GNU_SOURCE
#include <cap-ng.h>
-#include <err.h>
#include <linux/capability.h>
#include <stdbool.h>
#include <string.h>
@@ -18,6 +17,8 @@
#include <sys/prctl.h>
#include <sys/stat.h>
+#include "../kselftest.h"
+
#ifndef PR_CAP_AMBIENT
#define PR_CAP_AMBIENT 47
# define PR_CAP_AMBIENT_IS_SET 1
@@ -27,6 +28,7 @@
#endif
static int nerrs;
+static pid_t mpid; /* main() pid is used to avoid duplicate test counts */
static void vmaybe_write_file(bool enoent_ok, char *filename, char *fmt, va_list ap)
{
@@ -36,29 +38,32 @@ static void vmaybe_write_file(bool enoent_ok, char *filename, char *fmt, va_list
int buf_len;
buf_len = vsnprintf(buf, sizeof(buf), fmt, ap);
- if (buf_len < 0) {
- err(1, "vsnprintf failed");
- }
- if (buf_len >= sizeof(buf)) {
- errx(1, "vsnprintf output truncated");
- }
+ if (buf_len < 0)
+ ksft_exit_fail_msg("vsnprintf failed - %s\n", strerror(errno));
+
+ if (buf_len >= sizeof(buf))
+ ksft_exit_fail_msg("vsnprintf output truncated\n");
+
fd = open(filename, O_WRONLY);
if (fd < 0) {
if ((errno == ENOENT) && enoent_ok)
return;
- err(1, "open of %s failed", filename);
+ ksft_exit_fail_msg("open of %s failed - %s\n",
+ filename, strerror(errno));
}
written = write(fd, buf, buf_len);
if (written != buf_len) {
if (written >= 0) {
- errx(1, "short write to %s", filename);
+ ksft_exit_fail_msg("short write to %s\n", filename);
} else {
- err(1, "write to %s failed", filename);
+ ksft_exit_fail_msg("write to %s failed - %s\n",
+ filename, strerror(errno));
}
}
if (close(fd) != 0) {
- err(1, "close of %s failed", filename);
+ ksft_exit_fail_msg("close of %s failed - %s\n",
+ filename, strerror(errno));
}
}
@@ -95,11 +100,12 @@ static bool create_and_enter_ns(uid_t inner_uid)
*/
if (unshare(CLONE_NEWNS) == 0) {
- printf("[NOTE]\tUsing global UIDs for tests\n");
+ ksft_print_msg("[NOTE]\tUsing global UIDs for tests\n");
if (prctl(PR_SET_KEEPCAPS, 1, 0, 0, 0) != 0)
- err(1, "PR_SET_KEEPCAPS");
+ ksft_exit_fail_msg("PR_SET_KEEPCAPS - %s\n",
+ strerror(errno));
if (setresuid(inner_uid, inner_uid, -1) != 0)
- err(1, "setresuid");
+ ksft_exit_fail_msg("setresuid - %s\n", strerror(errno));
// Re-enable effective caps
capng_get_caps_process();
@@ -107,22 +113,24 @@ static bool create_and_enter_ns(uid_t inner_uid)
if (capng_have_capability(CAPNG_PERMITTED, i))
capng_update(CAPNG_ADD, CAPNG_EFFECTIVE, i);
if (capng_apply(CAPNG_SELECT_CAPS) != 0)
- err(1, "capng_apply");
+ ksft_exit_fail_msg(
+ "capng_apply - %s\n", strerror(errno));
have_outer_privilege = true;
} else if (unshare(CLONE_NEWUSER | CLONE_NEWNS) == 0) {
- printf("[NOTE]\tUsing a user namespace for tests\n");
+ ksft_print_msg("[NOTE]\tUsing a user namespace for tests\n");
maybe_write_file("/proc/self/setgroups", "deny");
write_file("/proc/self/uid_map", "%d %d 1", inner_uid, outer_uid);
write_file("/proc/self/gid_map", "0 %d 1", outer_gid);
have_outer_privilege = false;
} else {
- errx(1, "must be root or be able to create a userns");
+ ksft_exit_skip("must be root or be able to create a userns\n");
}
if (mount("none", "/", NULL, MS_REC | MS_PRIVATE, NULL) != 0)
- err(1, "remount everything private");
+ ksft_exit_fail_msg("remount everything private - %s\n",
+ strerror(errno));
return have_outer_privilege;
}
@@ -131,20 +139,22 @@ static void chdir_to_tmpfs(void)
{
char cwd[PATH_MAX];
if (getcwd(cwd, sizeof(cwd)) != cwd)
- err(1, "getcwd");
+ ksft_exit_fail_msg("getcwd - %s\n", strerror(errno));
if (mount("private_tmp", ".", "tmpfs", 0, "mode=0777") != 0)
- err(1, "mount private tmpfs");
+ ksft_exit_fail_msg("mount private tmpfs - %s\n",
+ strerror(errno));
if (chdir(cwd) != 0)
- err(1, "chdir to private tmpfs");
+ ksft_exit_fail_msg("chdir to private tmpfs - %s\n",
+ strerror(errno));
}
static void copy_fromat_to(int fromfd, const char *fromname, const char *toname)
{
int from = openat(fromfd, fromname, O_RDONLY);
if (from == -1)
- err(1, "open copy source");
+ ksft_exit_fail_msg("open copy source - %s\n", strerror(errno));
int to = open(toname, O_CREAT | O_WRONLY | O_EXCL, 0700);
@@ -154,10 +164,11 @@ static void copy_fromat_to(int fromfd, const char *fromname, const char *toname)
if (sz == 0)
break;
if (sz < 0)
- err(1, "read");
+ ksft_exit_fail_msg("read - %s\n", strerror(errno));
if (write(to, buf, sz) != sz)
- err(1, "write"); /* no short writes on tmpfs */
+ /* no short writes on tmpfs */
+ ksft_exit_fail_msg("write - %s\n", strerror(errno));
}
close(from);
@@ -174,18 +185,20 @@ static bool fork_wait(void)
int status;
if (waitpid(child, &status, 0) != child ||
!WIFEXITED(status)) {
- printf("[FAIL]\tChild died\n");
+ ksft_print_msg("Child died\n");
nerrs++;
} else if (WEXITSTATUS(status) != 0) {
- printf("[FAIL]\tChild failed\n");
+ ksft_print_msg("Child failed\n");
nerrs++;
} else {
- printf("[OK]\tChild succeeded\n");
+ /* don't print this message for mpid */
+ if (getpid() != mpid)
+ ksft_test_result_pass("Passed\n");
}
-
return false;
} else {
- err(1, "fork");
+ ksft_exit_fail_msg("fork - %s\n", strerror(errno));
+ return false;
}
}
@@ -195,7 +208,7 @@ static void exec_other_validate_cap(const char *name,
execl(name, name, (eff ? "1" : "0"),
(perm ? "1" : "0"), (inh ? "1" : "0"), (ambient ? "1" : "0"),
NULL);
- err(1, "execl");
+ ksft_exit_fail_msg("execl - %s\n", strerror(errno));
}
static void exec_validate_cap(bool eff, bool perm, bool inh, bool ambient)
@@ -209,7 +222,8 @@ static int do_tests(int uid, const char *our_path)
int ourpath_fd = open(our_path, O_RDONLY | O_DIRECTORY);
if (ourpath_fd == -1)
- err(1, "open '%s'", our_path);
+ ksft_exit_fail_msg("open '%s' - %s\n",
+ our_path, strerror(errno));
chdir_to_tmpfs();
@@ -221,30 +235,30 @@ static int do_tests(int uid, const char *our_path)
copy_fromat_to(ourpath_fd, "validate_cap",
"validate_cap_suidroot");
if (chown("validate_cap_suidroot", 0, -1) != 0)
- err(1, "chown");
+ ksft_exit_fail_msg("chown - %s\n", strerror(errno));
if (chmod("validate_cap_suidroot", S_ISUID | 0700) != 0)
- err(1, "chmod");
+ ksft_exit_fail_msg("chmod - %s\n", strerror(errno));
copy_fromat_to(ourpath_fd, "validate_cap",
"validate_cap_suidnonroot");
if (chown("validate_cap_suidnonroot", uid + 1, -1) != 0)
- err(1, "chown");
+ ksft_exit_fail_msg("chown - %s\n", strerror(errno));
if (chmod("validate_cap_suidnonroot", S_ISUID | 0700) != 0)
- err(1, "chmod");
+ ksft_exit_fail_msg("chmod - %s\n", strerror(errno));
copy_fromat_to(ourpath_fd, "validate_cap",
"validate_cap_sgidroot");
if (chown("validate_cap_sgidroot", -1, 0) != 0)
- err(1, "chown");
+ ksft_exit_fail_msg("chown - %s\n", strerror(errno));
if (chmod("validate_cap_sgidroot", S_ISGID | 0710) != 0)
- err(1, "chmod");
+ ksft_exit_fail_msg("chmod - %s\n", strerror(errno));
copy_fromat_to(ourpath_fd, "validate_cap",
"validate_cap_sgidnonroot");
if (chown("validate_cap_sgidnonroot", -1, gid + 1) != 0)
- err(1, "chown");
+ ksft_exit_fail_msg("chown - %s\n", strerror(errno));
if (chmod("validate_cap_sgidnonroot", S_ISGID | 0710) != 0)
- err(1, "chmod");
+ ksft_exit_fail_msg("chmod - %s\n", strerror(errno));
}
capng_get_caps_process();
@@ -252,147 +266,162 @@ static int do_tests(int uid, const char *our_path)
/* Make sure that i starts out clear */
capng_update(CAPNG_DROP, CAPNG_INHERITABLE, CAP_NET_BIND_SERVICE);
if (capng_apply(CAPNG_SELECT_CAPS) != 0)
- err(1, "capng_apply");
+ ksft_exit_fail_msg("capng_apply - %s\n", strerror(errno));
if (uid == 0) {
- printf("[RUN]\tRoot => ep\n");
+ ksft_print_msg("[RUN]\tRoot => ep\n");
if (fork_wait())
exec_validate_cap(true, true, false, false);
} else {
- printf("[RUN]\tNon-root => no caps\n");
+ ksft_print_msg("[RUN]\tNon-root => no caps\n");
if (fork_wait())
exec_validate_cap(false, false, false, false);
}
- printf("[OK]\tCheck cap_ambient manipulation rules\n");
+ ksft_print_msg("Check cap_ambient manipulation rules\n");
/* We should not be able to add ambient caps yet. */
if (prctl(PR_CAP_AMBIENT, PR_CAP_AMBIENT_RAISE, CAP_NET_BIND_SERVICE, 0, 0, 0) != -1 || errno != EPERM) {
if (errno == EINVAL)
- printf("[FAIL]\tPR_CAP_AMBIENT_RAISE isn't supported\n");
+ ksft_test_result_fail(
+ "PR_CAP_AMBIENT_RAISE isn't supported\n");
else
- printf("[FAIL]\tPR_CAP_AMBIENT_RAISE should have failed eith EPERM on a non-inheritable cap\n");
+ ksft_test_result_fail(
+ "PR_CAP_AMBIENT_RAISE should have failed eith EPERM on a non-inheritable cap\n");
return 1;
}
- printf("[OK]\tPR_CAP_AMBIENT_RAISE failed on non-inheritable cap\n");
+ ksft_test_result_pass(
+ "PR_CAP_AMBIENT_RAISE failed on non-inheritable cap\n");
capng_update(CAPNG_ADD, CAPNG_INHERITABLE, CAP_NET_RAW);
capng_update(CAPNG_DROP, CAPNG_PERMITTED, CAP_NET_RAW);
capng_update(CAPNG_DROP, CAPNG_EFFECTIVE, CAP_NET_RAW);
if (capng_apply(CAPNG_SELECT_CAPS) != 0)
- err(1, "capng_apply");
+ ksft_exit_fail_msg("capng_apply - %s\n", strerror(errno));
if (prctl(PR_CAP_AMBIENT, PR_CAP_AMBIENT_RAISE, CAP_NET_RAW, 0, 0, 0) != -1 || errno != EPERM) {
- printf("[FAIL]\tPR_CAP_AMBIENT_RAISE should have failed on a non-permitted cap\n");
+ ksft_test_result_fail(
+ "PR_CAP_AMBIENT_RAISE should have failed on a non-permitted cap\n");
return 1;
}
- printf("[OK]\tPR_CAP_AMBIENT_RAISE failed on non-permitted cap\n");
+ ksft_test_result_pass(
+ "PR_CAP_AMBIENT_RAISE failed on non-permitted cap\n");
capng_update(CAPNG_ADD, CAPNG_INHERITABLE, CAP_NET_BIND_SERVICE);
if (capng_apply(CAPNG_SELECT_CAPS) != 0)
- err(1, "capng_apply");
+ ksft_exit_fail_msg("capng_apply - %s\n", strerror(errno));
if (prctl(PR_CAP_AMBIENT, PR_CAP_AMBIENT_RAISE, CAP_NET_BIND_SERVICE, 0, 0, 0) != 0) {
- printf("[FAIL]\tPR_CAP_AMBIENT_RAISE should have succeeded\n");
+ ksft_test_result_fail(
+ "PR_CAP_AMBIENT_RAISE should have succeeded\n");
return 1;
}
- printf("[OK]\tPR_CAP_AMBIENT_RAISE worked\n");
+ ksft_test_result_pass("PR_CAP_AMBIENT_RAISE worked\n");
if (prctl(PR_CAP_AMBIENT, PR_CAP_AMBIENT_IS_SET, CAP_NET_BIND_SERVICE, 0, 0, 0) != 1) {
- printf("[FAIL]\tPR_CAP_AMBIENT_IS_SET is broken\n");
+ ksft_test_result_fail("PR_CAP_AMBIENT_IS_SET is broken\n");
return 1;
}
if (prctl(PR_CAP_AMBIENT, PR_CAP_AMBIENT_CLEAR_ALL, 0, 0, 0, 0) != 0)
- err(1, "PR_CAP_AMBIENT_CLEAR_ALL");
+ ksft_exit_fail_msg("PR_CAP_AMBIENT_CLEAR_ALL - %s\n",
+ strerror(errno));
if (prctl(PR_CAP_AMBIENT, PR_CAP_AMBIENT_IS_SET, CAP_NET_BIND_SERVICE, 0, 0, 0) != 0) {
- printf("[FAIL]\tPR_CAP_AMBIENT_CLEAR_ALL didn't work\n");
+ ksft_test_result_fail(
+ "PR_CAP_AMBIENT_CLEAR_ALL didn't work\n");
return 1;
}
if (prctl(PR_CAP_AMBIENT, PR_CAP_AMBIENT_RAISE, CAP_NET_BIND_SERVICE, 0, 0, 0) != 0)
- err(1, "PR_CAP_AMBIENT_RAISE");
+ ksft_exit_fail_msg("PR_CAP_AMBIENT_RAISE - %s\n",
+ strerror(errno));
capng_update(CAPNG_DROP, CAPNG_INHERITABLE, CAP_NET_BIND_SERVICE);
if (capng_apply(CAPNG_SELECT_CAPS) != 0)
- err(1, "capng_apply");
+ ksft_exit_fail_msg("capng_apply - %s\n", strerror(errno));
if (prctl(PR_CAP_AMBIENT, PR_CAP_AMBIENT_IS_SET, CAP_NET_BIND_SERVICE, 0, 0, 0) != 0) {
- printf("[FAIL]\tDropping I should have dropped A\n");
+ ksft_test_result_fail("Dropping I should have dropped A\n");
return 1;
}
- printf("[OK]\tBasic manipulation appears to work\n");
+ ksft_test_result_pass("Basic manipulation appears to work\n");
capng_update(CAPNG_ADD, CAPNG_INHERITABLE, CAP_NET_BIND_SERVICE);
if (capng_apply(CAPNG_SELECT_CAPS) != 0)
- err(1, "capng_apply");
+ ksft_exit_fail_msg("capng_apply - %s\n", strerror(errno));
if (uid == 0) {
- printf("[RUN]\tRoot +i => eip\n");
+ ksft_print_msg("[RUN]\tRoot +i => eip\n");
if (fork_wait())
exec_validate_cap(true, true, true, false);
} else {
- printf("[RUN]\tNon-root +i => i\n");
+ ksft_print_msg("[RUN]\tNon-root +i => i\n");
if (fork_wait())
exec_validate_cap(false, false, true, false);
}
if (prctl(PR_CAP_AMBIENT, PR_CAP_AMBIENT_RAISE, CAP_NET_BIND_SERVICE, 0, 0, 0) != 0)
- err(1, "PR_CAP_AMBIENT_RAISE");
+ ksft_exit_fail_msg("PR_CAP_AMBIENT_RAISE - %s\n",
+ strerror(errno));
- printf("[RUN]\tUID %d +ia => eipa\n", uid);
+ ksft_print_msg("[RUN]\tUID %d +ia => eipa\n", uid);
if (fork_wait())
exec_validate_cap(true, true, true, true);
/* The remaining tests need real privilege */
if (!have_outer_privilege) {
- printf("[SKIP]\tSUID/SGID tests (needs privilege)\n");
+ ksft_test_result_skip("SUID/SGID tests (needs privilege)\n");
goto done;
}
if (uid == 0) {
- printf("[RUN]\tRoot +ia, suidroot => eipa\n");
+ ksft_print_msg("[RUN]\tRoot +ia, suidroot => eipa\n");
if (fork_wait())
exec_other_validate_cap("./validate_cap_suidroot",
true, true, true, true);
- printf("[RUN]\tRoot +ia, suidnonroot => ip\n");
+ ksft_print_msg("[RUN]\tRoot +ia, suidnonroot => ip\n");
if (fork_wait())
exec_other_validate_cap("./validate_cap_suidnonroot",
false, true, true, false);
- printf("[RUN]\tRoot +ia, sgidroot => eipa\n");
+ ksft_print_msg("[RUN]\tRoot +ia, sgidroot => eipa\n");
if (fork_wait())
exec_other_validate_cap("./validate_cap_sgidroot",
true, true, true, true);
if (fork_wait()) {
- printf("[RUN]\tRoot, gid != 0, +ia, sgidroot => eip\n");
+ ksft_print_msg(
+ "[RUN]\tRoot, gid != 0, +ia, sgidroot => eip\n");
if (setresgid(1, 1, 1) != 0)
- err(1, "setresgid");
+ ksft_exit_fail_msg("setresgid - %s\n",
+ strerror(errno));
exec_other_validate_cap("./validate_cap_sgidroot",
true, true, true, false);
}
- printf("[RUN]\tRoot +ia, sgidnonroot => eip\n");
+ ksft_print_msg("[RUN]\tRoot +ia, sgidnonroot => eip\n");
if (fork_wait())
exec_other_validate_cap("./validate_cap_sgidnonroot",
true, true, true, false);
} else {
- printf("[RUN]\tNon-root +ia, sgidnonroot => i\n");
- exec_other_validate_cap("./validate_cap_sgidnonroot",
+ ksft_print_msg("[RUN]\tNon-root +ia, sgidnonroot => i\n");
+ if (fork_wait())
+ exec_other_validate_cap("./validate_cap_sgidnonroot",
false, false, true, false);
if (fork_wait()) {
- printf("[RUN]\tNon-root +ia, sgidroot => i\n");
+ ksft_print_msg("[RUN]\tNon-root +ia, sgidroot => i\n");
if (setresgid(1, 1, 1) != 0)
- err(1, "setresgid");
+ ksft_exit_fail_msg("setresgid - %s\n",
+ strerror(errno));
exec_other_validate_cap("./validate_cap_sgidroot",
false, false, true, false);
}
}
done:
+ ksft_print_cnts();
return nerrs ? 1 : 0;
}
@@ -400,23 +429,29 @@ int main(int argc, char **argv)
{
char *tmp1, *tmp2, *our_path;
+ ksft_print_header();
+
/* Find our path */
tmp1 = strdup(argv[0]);
if (!tmp1)
- err(1, "strdup");
+ ksft_exit_fail_msg("strdup - %s\n", strerror(errno));
tmp2 = dirname(tmp1);
our_path = strdup(tmp2);
if (!our_path)
- err(1, "strdup");
+ ksft_exit_fail_msg("strdup - %s\n", strerror(errno));
free(tmp1);
+ mpid = getpid();
+
if (fork_wait()) {
- printf("[RUN]\t+++ Tests with uid == 0 +++\n");
+ ksft_print_msg("[RUN]\t+++ Tests with uid == 0 +++\n");
return do_tests(0, our_path);
}
+ ksft_print_msg("==================================================\n");
+
if (fork_wait()) {
- printf("[RUN]\t+++ Tests with uid != 0 +++\n");
+ ksft_print_msg("[RUN]\t+++ Tests with uid != 0 +++\n");
return do_tests(1, our_path);
}
diff --git a/tools/testing/selftests/capabilities/validate_cap.c b/tools/testing/selftests/capabilities/validate_cap.c
index dd3c45f7b23c..694cd73d4493 100644
--- a/tools/testing/selftests/capabilities/validate_cap.c
+++ b/tools/testing/selftests/capabilities/validate_cap.c
@@ -1,5 +1,4 @@
#include <cap-ng.h>
-#include <err.h>
#include <linux/capability.h>
#include <stdbool.h>
#include <string.h>
@@ -7,6 +6,8 @@
#include <sys/prctl.h>
#include <sys/auxv.h>
+#include "../kselftest.h"
+
#ifndef PR_CAP_AMBIENT
#define PR_CAP_AMBIENT 47
# define PR_CAP_AMBIENT_IS_SET 1
@@ -25,8 +26,10 @@ static bool bool_arg(char **argv, int i)
return false;
else if (!strcmp(argv[i], "1"))
return true;
- else
- errx(1, "wrong argv[%d]", i);
+ else {
+ ksft_exit_fail_msg("wrong argv[%d]\n", i);
+ return false;
+ }
}
int main(int argc, char **argv)
@@ -39,7 +42,7 @@ int main(int argc, char **argv)
*/
if (argc != 5)
- errx(1, "wrong argc");
+ ksft_exit_fail_msg("wrong argc\n");
#ifdef HAVE_GETAUXVAL
if (getauxval(AT_SECURE))
@@ -51,23 +54,26 @@ int main(int argc, char **argv)
capng_get_caps_process();
if (capng_have_capability(CAPNG_EFFECTIVE, CAP_NET_BIND_SERVICE) != bool_arg(argv, 1)) {
- printf("[FAIL]\tWrong effective state%s\n", atsec);
+ ksft_print_msg("Wrong effective state%s\n", atsec);
return 1;
}
+
if (capng_have_capability(CAPNG_PERMITTED, CAP_NET_BIND_SERVICE) != bool_arg(argv, 2)) {
- printf("[FAIL]\tWrong permitted state%s\n", atsec);
+ ksft_print_msg("Wrong permitted state%s\n", atsec);
return 1;
}
+
if (capng_have_capability(CAPNG_INHERITABLE, CAP_NET_BIND_SERVICE) != bool_arg(argv, 3)) {
- printf("[FAIL]\tWrong inheritable state%s\n", atsec);
+ ksft_print_msg("Wrong inheritable state%s\n", atsec);
return 1;
}
if (prctl(PR_CAP_AMBIENT, PR_CAP_AMBIENT_IS_SET, CAP_NET_BIND_SERVICE, 0, 0, 0) != bool_arg(argv, 4)) {
- printf("[FAIL]\tWrong ambient state%s\n", atsec);
+ ksft_print_msg("Wrong ambient state%s\n", atsec);
return 1;
}
- printf("[OK]\tCapabilities after execve were correct\n");
+ ksft_print_msg("%s: Capabilities after execve were correct\n",
+ "validate_cap:");
return 0;
}
diff --git a/tools/testing/selftests/cpu-hotplug/cpu-on-off-test.sh b/tools/testing/selftests/cpu-hotplug/cpu-on-off-test.sh
index 98b1d6565f2c..b18b253d7bfb 100755
--- a/tools/testing/selftests/cpu-hotplug/cpu-on-off-test.sh
+++ b/tools/testing/selftests/cpu-hotplug/cpu-on-off-test.sh
@@ -28,6 +28,12 @@ prerequisite()
echo "CPU online/offline summary:"
online_cpus=`cat $SYSFS/devices/system/cpu/online`
online_max=${online_cpus##*-}
+
+ if [[ "$online_cpus" = "$online_max" ]]; then
+ echo "$msg: since there is only one cpu: $online_cpus"
+ exit 0
+ fi
+
echo -e "\t Cpus in online state: $online_cpus"
offline_cpus=`cat $SYSFS/devices/system/cpu/offline`
@@ -89,8 +95,10 @@ online_cpu_expect_success()
if ! online_cpu $cpu; then
echo $FUNCNAME $cpu: unexpected fail >&2
+ exit 1
elif ! cpu_is_online $cpu; then
echo $FUNCNAME $cpu: unexpected offline >&2
+ exit 1
fi
}
@@ -100,8 +108,10 @@ online_cpu_expect_fail()
if online_cpu $cpu 2> /dev/null; then
echo $FUNCNAME $cpu: unexpected success >&2
+ exit 1
elif ! cpu_is_offline $cpu; then
echo $FUNCNAME $cpu: unexpected online >&2
+ exit 1
fi
}
@@ -111,8 +121,10 @@ offline_cpu_expect_success()
if ! offline_cpu $cpu; then
echo $FUNCNAME $cpu: unexpected fail >&2
+ exit 1
elif ! cpu_is_offline $cpu; then
echo $FUNCNAME $cpu: unexpected offline >&2
+ exit 1
fi
}
@@ -122,8 +134,10 @@ offline_cpu_expect_fail()
if offline_cpu $cpu 2> /dev/null; then
echo $FUNCNAME $cpu: unexpected success >&2
+ exit 1
elif ! cpu_is_online $cpu; then
echo $FUNCNAME $cpu: unexpected offline >&2
+ exit 1
fi
}
diff --git a/tools/testing/selftests/ftrace/ftracetest b/tools/testing/selftests/ftrace/ftracetest
index 14a03ea1e21d..abc706cf7702 100755
--- a/tools/testing/selftests/ftrace/ftracetest
+++ b/tools/testing/selftests/ftrace/ftracetest
@@ -8,15 +8,18 @@
# Released under the terms of the GPL v2.
usage() { # errno [message]
-[ "$2" ] && echo $2
+[ ! -z "$2" ] && echo $2
echo "Usage: ftracetest [options] [testcase(s)] [testcase-directory(s)]"
echo " Options:"
echo " -h|--help Show help message"
echo " -k|--keep Keep passed test logs"
echo " -v|--verbose Increase verbosity of test messages"
echo " -vv Alias of -v -v (Show all results in stdout)"
+echo " -vvv Alias of -v -v -v (Show all commands immediately)"
+echo " --fail-unsupported Treat UNSUPPORTED as a failure"
echo " -d|--debug Debug mode (trace all shell commands)"
echo " -l|--logdir <dir> Save logs on the <dir>"
+echo " If <dir> is -, all logs output in console only"
exit $1
}
@@ -47,7 +50,7 @@ parse_opts() { # opts
local OPT_TEST_CASES=
local OPT_TEST_DIR=
- while [ "$1" ]; do
+ while [ ! -z "$1" ]; do
case "$1" in
--help|-h)
usage 0
@@ -56,15 +59,20 @@ parse_opts() { # opts
KEEP_LOG=1
shift 1
;;
- --verbose|-v|-vv)
+ --verbose|-v|-vv|-vvv)
VERBOSE=$((VERBOSE + 1))
[ $1 = '-vv' ] && VERBOSE=$((VERBOSE + 1))
+ [ $1 = '-vvv' ] && VERBOSE=$((VERBOSE + 2))
shift 1
;;
--debug|-d)
DEBUG=1
shift 1
;;
+ --fail-unsupported)
+ UNSUPPORTED_RESULT=1
+ shift 1
+ ;;
--logdir|-l)
LOG_DIR=$2
shift 2
@@ -88,7 +96,7 @@ parse_opts() { # opts
;;
esac
done
- if [ "$OPT_TEST_CASES" ]; then
+ if [ ! -z "$OPT_TEST_CASES" ]; then
TEST_CASES=$OPT_TEST_CASES
fi
}
@@ -108,6 +116,7 @@ LOG_DIR=$TOP_DIR/logs/`date +%Y%m%d-%H%M%S`/
KEEP_LOG=0
DEBUG=0
VERBOSE=0
+UNSUPPORTED_RESULT=0
# Parse command-line options
parse_opts $*
@@ -119,14 +128,20 @@ if [ -z "$TRACING_DIR" -o ! -d "$TRACING_DIR" ]; then
fi
# Preparing logs
-LOG_FILE=$LOG_DIR/ftracetest.log
-mkdir -p $LOG_DIR || errexit "Failed to make a log directory: $LOG_DIR"
-date > $LOG_FILE
+if [ "x$LOG_DIR" = "x-" ]; then
+ LOG_FILE=
+ date
+else
+ LOG_FILE=$LOG_DIR/ftracetest.log
+ mkdir -p $LOG_DIR || errexit "Failed to make a log directory: $LOG_DIR"
+ date > $LOG_FILE
+fi
+
prlog() { # messages
- echo "$@" | tee -a $LOG_FILE
+ [ -z "$LOG_FILE" ] && echo "$@" || echo "$@" | tee -a $LOG_FILE
}
catlog() { #file
- cat $1 | tee -a $LOG_FILE
+ [ -z "$LOG_FILE" ] && cat $1 || cat $1 | tee -a $LOG_FILE
}
prlog "=== Ftrace unit tests ==="
@@ -187,7 +202,7 @@ eval_result() { # sigval
$UNSUPPORTED)
prlog " [UNSUPPORTED]"
UNSUPPORTED_CASES="$UNSUPPORTED_CASES $CASENO"
- return 1 # this is not a bug, but the result should be reported.
+ return $UNSUPPORTED_RESULT # depends on use case
;;
$XFAIL)
prlog " [XFAIL]"
@@ -247,12 +262,20 @@ __run_test() { # testfile
# Run one test case
run_test() { # testfile
local testname=`basename $1`
- local testlog=`mktemp $LOG_DIR/${testname}-log.XXXXXX`
+ if [ ! -z "$LOG_FILE" ] ; then
+ local testlog=`mktemp $LOG_DIR/${testname}-log.XXXXXX`
+ else
+ local testlog=/proc/self/fd/1
+ fi
export TMPDIR=`mktemp -d /tmp/ftracetest-dir.XXXXXX`
testcase $1
echo "execute$INSTANCE: "$1 > $testlog
SIG_RESULT=0
- if [ $VERBOSE -ge 2 ]; then
+ if [ -z "$LOG_FILE" ]; then
+ __run_test $1 2>&1
+ elif [ $VERBOSE -ge 3 ]; then
+ __run_test $1 | tee -a $testlog 2>&1
+ elif [ $VERBOSE -eq 2 ]; then
__run_test $1 2>> $testlog | tee -a $testlog
else
__run_test $1 >> $testlog 2>&1
@@ -260,9 +283,9 @@ run_test() { # testfile
eval_result $SIG_RESULT
if [ $? -eq 0 ]; then
# Remove test log if the test was done as it was expected.
- [ $KEEP_LOG -eq 0 ] && rm $testlog
+ [ $KEEP_LOG -eq 0 -a ! -z "$LOG_FILE" ] && rm $testlog
else
- [ $VERBOSE -ge 1 ] && catlog $testlog
+ [ $VERBOSE -eq 1 -o $VERBOSE -eq 2 ] && catlog $testlog
TOTAL_RESULT=1
fi
rm -rf $TMPDIR
diff --git a/tools/testing/selftests/futex/functional/futex_requeue_pi.c b/tools/testing/selftests/futex/functional/futex_requeue_pi.c
index d24ab7421e73..54cd5c414e82 100644
--- a/tools/testing/selftests/futex/functional/futex_requeue_pi.c
+++ b/tools/testing/selftests/futex/functional/futex_requeue_pi.c
@@ -394,9 +394,11 @@ int main(int argc, char *argv[])
}
}
- printf("%s: Test requeue functionality\n", basename(argv[0]));
- printf("\tArguments: broadcast=%d locked=%d owner=%d timeout=%ldns\n",
- broadcast, locked, owner, timeout_ns);
+ ksft_print_header();
+ ksft_print_msg("%s: Test requeue functionality\n", basename(argv[0]));
+ ksft_print_msg(
+ "\tArguments: broadcast=%d locked=%d owner=%d timeout=%ldns\n",
+ broadcast, locked, owner, timeout_ns);
/*
* FIXME: unit_test is obsolete now that we parse options and the
diff --git a/tools/testing/selftests/futex/functional/futex_requeue_pi_mismatched_ops.c b/tools/testing/selftests/futex/functional/futex_requeue_pi_mismatched_ops.c
index e0a798ad0d21..08187a16507f 100644
--- a/tools/testing/selftests/futex/functional/futex_requeue_pi_mismatched_ops.c
+++ b/tools/testing/selftests/futex/functional/futex_requeue_pi_mismatched_ops.c
@@ -78,7 +78,8 @@ int main(int argc, char *argv[])
}
}
- printf("%s: Detect mismatched requeue_pi operations\n",
+ ksft_print_header();
+ ksft_print_msg("%s: Detect mismatched requeue_pi operations\n",
basename(argv[0]));
if (pthread_create(&child, NULL, blocking_child, NULL)) {
diff --git a/tools/testing/selftests/futex/functional/futex_requeue_pi_signal_restart.c b/tools/testing/selftests/futex/functional/futex_requeue_pi_signal_restart.c
index 982f83577501..f0542a344d95 100644
--- a/tools/testing/selftests/futex/functional/futex_requeue_pi_signal_restart.c
+++ b/tools/testing/selftests/futex/functional/futex_requeue_pi_signal_restart.c
@@ -143,9 +143,10 @@ int main(int argc, char *argv[])
}
}
- printf("%s: Test signal handling during requeue_pi\n",
+ ksft_print_header();
+ ksft_print_msg("%s: Test signal handling during requeue_pi\n",
basename(argv[0]));
- printf("\tArguments: <none>\n");
+ ksft_print_msg("\tArguments: <none>\n");
sa.sa_handler = handle_signal;
sigemptyset(&sa.sa_mask);
diff --git a/tools/testing/selftests/futex/functional/futex_wait_private_mapped_file.c b/tools/testing/selftests/futex/functional/futex_wait_private_mapped_file.c
index bdc48dc047e5..6216de828093 100644
--- a/tools/testing/selftests/futex/functional/futex_wait_private_mapped_file.c
+++ b/tools/testing/selftests/futex/functional/futex_wait_private_mapped_file.c
@@ -97,8 +97,10 @@ int main(int argc, char **argv)
}
}
- printf("%s: Test the futex value of private file mappings in FUTEX_WAIT\n",
- basename(argv[0]));
+ ksft_print_header();
+ ksft_print_msg(
+ "%s: Test the futex value of private file mappings in FUTEX_WAIT\n",
+ basename(argv[0]));
ret = pthread_create(&thr, NULL, thr_futex_wait, NULL);
if (ret < 0) {
diff --git a/tools/testing/selftests/futex/functional/futex_wait_timeout.c b/tools/testing/selftests/futex/functional/futex_wait_timeout.c
index 6aadd560366e..bab3dfe1787f 100644
--- a/tools/testing/selftests/futex/functional/futex_wait_timeout.c
+++ b/tools/testing/selftests/futex/functional/futex_wait_timeout.c
@@ -68,9 +68,10 @@ int main(int argc, char *argv[])
}
}
- printf("%s: Block on a futex and wait for timeout\n",
+ ksft_print_header();
+ ksft_print_msg("%s: Block on a futex and wait for timeout\n",
basename(argv[0]));
- printf("\tArguments: timeout=%ldns\n", timeout_ns);
+ ksft_print_msg("\tArguments: timeout=%ldns\n", timeout_ns);
/* initialize timeout */
to.tv_sec = 0;
diff --git a/tools/testing/selftests/futex/functional/futex_wait_uninitialized_heap.c b/tools/testing/selftests/futex/functional/futex_wait_uninitialized_heap.c
index d237a8b702f0..26975322545b 100644
--- a/tools/testing/selftests/futex/functional/futex_wait_uninitialized_heap.c
+++ b/tools/testing/selftests/futex/functional/futex_wait_uninitialized_heap.c
@@ -99,7 +99,8 @@ int main(int argc, char **argv)
exit(1);
}
- printf("%s: Test the uninitialized futex value in FUTEX_WAIT\n",
+ ksft_print_header();
+ ksft_print_msg("%s: Test the uninitialized futex value in FUTEX_WAIT\n",
basename(argv[0]));
diff --git a/tools/testing/selftests/futex/functional/futex_wait_wouldblock.c b/tools/testing/selftests/futex/functional/futex_wait_wouldblock.c
index 9a2c56fa7305..da15a63269b4 100644
--- a/tools/testing/selftests/futex/functional/futex_wait_wouldblock.c
+++ b/tools/testing/selftests/futex/functional/futex_wait_wouldblock.c
@@ -64,7 +64,8 @@ int main(int argc, char *argv[])
}
}
- printf("%s: Test the unexpected futex value in FUTEX_WAIT\n",
+ ksft_print_header();
+ ksft_print_msg("%s: Test the unexpected futex value in FUTEX_WAIT\n",
basename(argv[0]));
info("Calling futex_wait on f1: %u @ %p with val=%u\n", f1, &f1, f1+1);
diff --git a/tools/testing/selftests/futex/include/logging.h b/tools/testing/selftests/futex/include/logging.h
index 4e7944984fbb..01989644e50a 100644
--- a/tools/testing/selftests/futex/include/logging.h
+++ b/tools/testing/selftests/futex/include/logging.h
@@ -109,22 +109,20 @@ void log_verbosity(int level)
*/
void print_result(const char *test_name, int ret)
{
- const char *result = "Unknown return code";
-
switch (ret) {
case RET_PASS:
- ksft_inc_pass_cnt();
- result = PASS;
- break;
+ ksft_test_result_pass("%s\n", test_name);
+ ksft_print_cnts();
+ return;
case RET_ERROR:
- result = ERROR;
- break;
+ ksft_test_result_error("%s\n", test_name);
+ ksft_print_cnts();
+ return;
case RET_FAIL:
- ksft_inc_fail_cnt();
- result = FAIL;
- break;
+ ksft_test_result_fail("%s\n", test_name);
+ ksft_print_cnts();
+ return;
}
- printf("selftests: %s [%s]\n", test_name, result);
}
/* log level macros */
diff --git a/tools/testing/selftests/kcmp/kcmp_test.c b/tools/testing/selftests/kcmp/kcmp_test.c
index a5a4da856dfe..73684c4a1ed6 100644
--- a/tools/testing/selftests/kcmp/kcmp_test.c
+++ b/tools/testing/selftests/kcmp/kcmp_test.c
@@ -8,7 +8,6 @@
#include <errno.h>
#include <string.h>
#include <fcntl.h>
-
#include <linux/unistd.h>
#include <linux/kcmp.h>
@@ -16,20 +15,28 @@
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/wait.h>
+#include <sys/epoll.h>
#include "../kselftest.h"
-static long sys_kcmp(int pid1, int pid2, int type, int fd1, int fd2)
+static long sys_kcmp(int pid1, int pid2, int type, unsigned long fd1, unsigned long fd2)
{
return syscall(__NR_kcmp, pid1, pid2, type, fd1, fd2);
}
+static const unsigned int duped_num = 64;
+
int main(int argc, char **argv)
{
const char kpath[] = "kcmp-test-file";
+ struct kcmp_epoll_slot epoll_slot;
+ struct epoll_event ev;
int pid1, pid2;
+ int pipefd[2];
int fd1, fd2;
+ int epollfd;
int status;
+ int fddup;
fd1 = open(kpath, O_RDWR | O_CREAT | O_TRUNC, 0644);
pid1 = getpid();
@@ -39,6 +46,37 @@ int main(int argc, char **argv)
ksft_exit_fail();
}
+ if (pipe(pipefd)) {
+ perror("Can't create pipe");
+ ksft_exit_fail();
+ }
+
+ epollfd = epoll_create1(0);
+ if (epollfd < 0) {
+ perror("epoll_create1 failed");
+ ksft_exit_fail();
+ }
+
+ memset(&ev, 0xff, sizeof(ev));
+ ev.events = EPOLLIN | EPOLLOUT;
+
+ if (epoll_ctl(epollfd, EPOLL_CTL_ADD, pipefd[0], &ev)) {
+ perror("epoll_ctl failed");
+ ksft_exit_fail();
+ }
+
+ fddup = dup2(pipefd[1], duped_num);
+ if (fddup < 0) {
+ perror("dup2 failed");
+ ksft_exit_fail();
+ }
+
+ if (epoll_ctl(epollfd, EPOLL_CTL_ADD, fddup, &ev)) {
+ perror("epoll_ctl failed");
+ ksft_exit_fail();
+ }
+ close(fddup);
+
pid2 = fork();
if (pid2 < 0) {
perror("fork failed");
@@ -95,6 +133,24 @@ int main(int argc, char **argv)
ksft_inc_pass_cnt();
}
+ /* Compare epoll target */
+ epoll_slot = (struct kcmp_epoll_slot) {
+ .efd = epollfd,
+ .tfd = duped_num,
+ .toff = 0,
+ };
+ ret = sys_kcmp(pid1, pid1, KCMP_EPOLL_TFD, pipefd[1],
+ (unsigned long)(void *)&epoll_slot);
+ if (ret) {
+ printf("FAIL: 0 expected but %d returned (%s)\n",
+ ret, strerror(errno));
+ ksft_inc_fail_cnt();
+ ret = -1;
+ } else {
+ printf("PASS: 0 returned as expected\n");
+ ksft_inc_pass_cnt();
+ }
+
ksft_print_cnts();
if (ret)
diff --git a/tools/testing/selftests/kselftest.h b/tools/testing/selftests/kselftest.h
index 08e90c2cc5cb..1ae565ed9bf0 100644
--- a/tools/testing/selftests/kselftest.h
+++ b/tools/testing/selftests/kselftest.h
@@ -19,7 +19,8 @@
#define KSFT_FAIL 1
#define KSFT_XFAIL 2
#define KSFT_XPASS 3
-#define KSFT_SKIP 4
+/* Treat skip as pass */
+#define KSFT_SKIP KSFT_PASS
/* counters */
struct ksft_count {
@@ -28,6 +29,7 @@ struct ksft_count {
unsigned int ksft_xfail;
unsigned int ksft_xpass;
unsigned int ksft_xskip;
+ unsigned int ksft_error;
};
static struct ksft_count ksft_cnt;
@@ -36,7 +38,7 @@ static inline int ksft_test_num(void)
{
return ksft_cnt.ksft_pass + ksft_cnt.ksft_fail +
ksft_cnt.ksft_xfail + ksft_cnt.ksft_xpass +
- ksft_cnt.ksft_xskip;
+ ksft_cnt.ksft_xskip + ksft_cnt.ksft_error;
}
static inline void ksft_inc_pass_cnt(void) { ksft_cnt.ksft_pass++; }
@@ -44,6 +46,14 @@ static inline void ksft_inc_fail_cnt(void) { ksft_cnt.ksft_fail++; }
static inline void ksft_inc_xfail_cnt(void) { ksft_cnt.ksft_xfail++; }
static inline void ksft_inc_xpass_cnt(void) { ksft_cnt.ksft_xpass++; }
static inline void ksft_inc_xskip_cnt(void) { ksft_cnt.ksft_xskip++; }
+static inline void ksft_inc_error_cnt(void) { ksft_cnt.ksft_error++; }
+
+static inline int ksft_get_pass_cnt(void) { return ksft_cnt.ksft_pass; }
+static inline int ksft_get_fail_cnt(void) { return ksft_cnt.ksft_fail; }
+static inline int ksft_get_xfail_cnt(void) { return ksft_cnt.ksft_xfail; }
+static inline int ksft_get_xpass_cnt(void) { return ksft_cnt.ksft_xpass; }
+static inline int ksft_get_xskip_cnt(void) { return ksft_cnt.ksft_xskip; }
+static inline int ksft_get_error_cnt(void) { return ksft_cnt.ksft_error; }
static inline void ksft_print_header(void)
{
@@ -52,6 +62,10 @@ static inline void ksft_print_header(void)
static inline void ksft_print_cnts(void)
{
+ printf("Pass %d Fail %d Xfail %d Xpass %d Skip %d Error %d\n",
+ ksft_cnt.ksft_pass, ksft_cnt.ksft_fail,
+ ksft_cnt.ksft_xfail, ksft_cnt.ksft_xpass,
+ ksft_cnt.ksft_xskip, ksft_cnt.ksft_error);
printf("1..%d\n", ksft_test_num());
}
@@ -101,6 +115,18 @@ static inline void ksft_test_result_skip(const char *msg, ...)
va_end(args);
}
+static inline void ksft_test_result_error(const char *msg, ...)
+{
+ va_list args;
+
+ ksft_cnt.ksft_error++;
+
+ va_start(args, msg);
+ printf("not ok %d # error ", ksft_test_num());
+ vprintf(msg, args);
+ va_end(args);
+}
+
static inline int ksft_exit_pass(void)
{
ksft_print_cnts();
diff --git a/tools/testing/selftests/kselftest_harness.h b/tools/testing/selftests/kselftest_harness.h
index c56f72e07cd7..e81bd28bdd89 100644
--- a/tools/testing/selftests/kselftest_harness.h
+++ b/tools/testing/selftests/kselftest_harness.h
@@ -51,6 +51,9 @@
#define __KSELFTEST_HARNESS_H
#define _GNU_SOURCE
+#include <asm/types.h>
+#include <errno.h>
+#include <stdbool.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
@@ -84,6 +87,14 @@
* E.g., #define TH_LOG_ENABLED 1
*
* If no definition is provided, logging is enabled by default.
+ *
+ * If there is no way to print an error message for the process running the
+ * test (e.g. not allowed to write to stderr), it is still possible to get the
+ * ASSERT_* number for which the test failed. This behavior can be enabled by
+ * writing `_metadata->no_print = true;` before the check sequence that is
+ * unable to print. When an error occur, instead of printing an error message
+ * and calling `abort(3)`, the test process call `_exit(2)` with the assert
+ * number as argument, which is then printed by the parent process.
*/
#define TH_LOG(fmt, ...) do { \
if (TH_LOG_ENABLED) \
@@ -555,12 +566,18 @@
* return while still providing an optional block to the API consumer.
*/
#define OPTIONAL_HANDLER(_assert) \
- for (; _metadata->trigger; _metadata->trigger = __bail(_assert))
+ for (; _metadata->trigger; _metadata->trigger = \
+ __bail(_assert, _metadata->no_print, _metadata->step))
+
+#define __INC_STEP(_metadata) \
+ if (_metadata->passed && _metadata->step < 255) \
+ _metadata->step++;
#define __EXPECT(_expected, _seen, _t, _assert) do { \
/* Avoid multiple evaluation of the cases */ \
__typeof__(_expected) __exp = (_expected); \
__typeof__(_seen) __seen = (_seen); \
+ if (_assert) __INC_STEP(_metadata); \
if (!(__exp _t __seen)) { \
unsigned long long __exp_print = (uintptr_t)__exp; \
unsigned long long __seen_print = (uintptr_t)__seen; \
@@ -576,6 +593,7 @@
#define __EXPECT_STR(_expected, _seen, _t, _assert) do { \
const char *__exp = (_expected); \
const char *__seen = (_seen); \
+ if (_assert) __INC_STEP(_metadata); \
if (!(strcmp(__exp, __seen) _t 0)) { \
__TH_LOG("Expected '%s' %s '%s'.", __exp, #_t, __seen); \
_metadata->passed = 0; \
@@ -590,6 +608,8 @@ struct __test_metadata {
int termsig;
int passed;
int trigger; /* extra handler after the evaluation */
+ __u8 step;
+ bool no_print; /* manual trigger when TH_LOG_STREAM is not available */
struct __test_metadata *prev, *next;
};
@@ -634,10 +654,13 @@ static inline void __register_test(struct __test_metadata *t)
}
}
-static inline int __bail(int for_realz)
+static inline int __bail(int for_realz, bool no_print, __u8 step)
{
- if (for_realz)
+ if (for_realz) {
+ if (no_print)
+ _exit(step);
abort();
+ }
return 0;
}
@@ -655,18 +678,24 @@ void __run_test(struct __test_metadata *t)
t->passed = 0;
} else if (child_pid == 0) {
t->fn(t);
- _exit(t->passed);
+ /* return the step that failed or 0 */
+ _exit(t->passed ? 0 : t->step);
} else {
/* TODO(wad) add timeout support. */
waitpid(child_pid, &status, 0);
if (WIFEXITED(status)) {
- t->passed = t->termsig == -1 ? WEXITSTATUS(status) : 0;
+ t->passed = t->termsig == -1 ? !WEXITSTATUS(status) : 0;
if (t->termsig != -1) {
fprintf(TH_LOG_STREAM,
"%s: Test exited normally "
"instead of by signal (code: %d)\n",
t->name,
WEXITSTATUS(status));
+ } else if (!t->passed) {
+ fprintf(TH_LOG_STREAM,
+ "%s: Test failed at step #%d\n",
+ t->name,
+ WEXITSTATUS(status));
}
} else if (WIFSIGNALED(status)) {
t->passed = 0;
diff --git a/tools/testing/selftests/lib.mk b/tools/testing/selftests/lib.mk
index 959273c3a52e..693616651da5 100644
--- a/tools/testing/selftests/lib.mk
+++ b/tools/testing/selftests/lib.mk
@@ -11,15 +11,26 @@ TEST_GEN_FILES := $(patsubst %,$(OUTPUT)/%,$(TEST_GEN_FILES))
all: $(TEST_GEN_PROGS) $(TEST_GEN_PROGS_EXTENDED) $(TEST_GEN_FILES)
+.ONESHELL:
define RUN_TESTS
- @for TEST in $(TEST_GEN_PROGS) $(TEST_PROGS); do \
+ @test_num=`echo 0`;
+ @echo "TAP version 13";
+ @for TEST in $(1); do \
BASENAME_TEST=`basename $$TEST`; \
- cd `dirname $$TEST`; (./$$BASENAME_TEST && echo "selftests: $$BASENAME_TEST [PASS]") || echo "selftests: $$BASENAME_TEST [FAIL]"; cd -;\
+ test_num=`echo $$test_num+1 | bc`; \
+ echo "selftests: $$BASENAME_TEST"; \
+ echo "========================================"; \
+ if [ ! -x $$BASENAME_TEST ]; then \
+ echo "selftests: Warning: file $$BASENAME_TEST is not executable, correct this.";\
+ echo "not ok 1..$$test_num selftests: $$BASENAME_TEST [FAIL]"; \
+ else \
+ cd `dirname $$TEST` > /dev/null; (./$$BASENAME_TEST && echo "ok 1..$$test_num selftests: $$BASENAME_TEST [PASS]") || echo "not ok 1..$$test_num selftests: $$BASENAME_TEST [FAIL]"; cd - > /dev/null;\
+ fi; \
done;
endef
run_tests: all
- $(RUN_TESTS)
+ $(call RUN_TESTS, $(TEST_GEN_PROGS) $(TEST_PROGS))
define INSTALL_RULE
@if [ "X$(TEST_PROGS)$(TEST_PROGS_EXTENDED)$(TEST_FILES)" != "X" ]; then \
diff --git a/tools/testing/selftests/memfd/fuse_test.c b/tools/testing/selftests/memfd/fuse_test.c
index 67908b18f035..7f3617274bf5 100644
--- a/tools/testing/selftests/memfd/fuse_test.c
+++ b/tools/testing/selftests/memfd/fuse_test.c
@@ -33,7 +33,7 @@
#include <unistd.h>
#define MFD_DEF_SIZE 8192
-#define STACK_SIZE 65535
+#define STACK_SIZE 65536
static int sys_memfd_create(const char *name,
unsigned int flags)
diff --git a/tools/testing/selftests/nsfs/config b/tools/testing/selftests/nsfs/config
new file mode 100644
index 000000000000..598d0a225fc9
--- /dev/null
+++ b/tools/testing/selftests/nsfs/config
@@ -0,0 +1,3 @@
+CONFIG_USER_NS=y
+CONFIG_UTS_NS=y
+CONFIG_PID_NS=y
diff --git a/tools/testing/selftests/pstore/.gitignore b/tools/testing/selftests/pstore/.gitignore
new file mode 100644
index 000000000000..5a4a26e5464b
--- /dev/null
+++ b/tools/testing/selftests/pstore/.gitignore
@@ -0,0 +1,2 @@
+logs
+*uuid
diff --git a/tools/testing/selftests/ptp/Makefile b/tools/testing/selftests/ptp/Makefile
index 83dd42b2129e..d4064c742c26 100644
--- a/tools/testing/selftests/ptp/Makefile
+++ b/tools/testing/selftests/ptp/Makefile
@@ -1,3 +1,4 @@
+CFLAGS += -I../../../../usr/include/
TEST_PROGS := testptp
LDLIBS += -lrt
all: $(TEST_PROGS)
diff --git a/tools/testing/selftests/seccomp/seccomp_bpf.c b/tools/testing/selftests/seccomp/seccomp_bpf.c
index 73f5ea6778ce..4d6f92a9df6b 100644
--- a/tools/testing/selftests/seccomp/seccomp_bpf.c
+++ b/tools/testing/selftests/seccomp/seccomp_bpf.c
@@ -107,7 +107,7 @@ TEST(mode_strict_support)
ASSERT_EQ(0, ret) {
TH_LOG("Kernel does not support CONFIG_SECCOMP");
}
- syscall(__NR_exit, 1);
+ syscall(__NR_exit, 0);
}
TEST_SIGNAL(mode_strict_cannot_call_prctl, SIGKILL)
diff --git a/tools/testing/selftests/sigaltstack/sas.c b/tools/testing/selftests/sigaltstack/sas.c
index ccd07343d418..7d406c3973ba 100644
--- a/tools/testing/selftests/sigaltstack/sas.c
+++ b/tools/testing/selftests/sigaltstack/sas.c
@@ -17,6 +17,8 @@
#include <assert.h>
#include <errno.h>
+#include "../kselftest.h"
+
#ifndef SS_AUTODISARM
#define SS_AUTODISARM (1U << 31)
#endif
@@ -41,8 +43,7 @@ void my_usr1(int sig, siginfo_t *si, void *u)
if (sp < (unsigned long)sstack ||
sp >= (unsigned long)sstack + SIGSTKSZ) {
- printf("[FAIL]\tSP is not on sigaltstack\n");
- exit(EXIT_FAILURE);
+ ksft_exit_fail_msg("SP is not on sigaltstack\n");
}
/* put some data on stack. other sighandler will try to overwrite it */
aa = alloca(1024);
@@ -50,21 +51,22 @@ void my_usr1(int sig, siginfo_t *si, void *u)
p = (struct stk_data *)(aa + 512);
strcpy(p->msg, msg);
p->flag = 1;
- printf("[RUN]\tsignal USR1\n");
+ ksft_print_msg("[RUN]\tsignal USR1\n");
err = sigaltstack(NULL, &stk);
if (err) {
- perror("[FAIL]\tsigaltstack()");
+ ksft_exit_fail_msg("sigaltstack() - %s\n", strerror(errno));
exit(EXIT_FAILURE);
}
if (stk.ss_flags != SS_DISABLE)
- printf("[FAIL]\tss_flags=%x, should be SS_DISABLE\n",
+ ksft_test_result_fail("tss_flags=%x, should be SS_DISABLE\n",
stk.ss_flags);
else
- printf("[OK]\tsigaltstack is disabled in sighandler\n");
+ ksft_test_result_pass(
+ "sigaltstack is disabled in sighandler\n");
swapcontext(&sc, &uc);
- printf("%s\n", p->msg);
+ ksft_print_msg("%s\n", p->msg);
if (!p->flag) {
- printf("[RUN]\tAborting\n");
+ ksft_exit_skip("[RUN]\tAborting\n");
exit(EXIT_FAILURE);
}
}
@@ -74,13 +76,13 @@ void my_usr2(int sig, siginfo_t *si, void *u)
char *aa;
struct stk_data *p;
- printf("[RUN]\tsignal USR2\n");
+ ksft_print_msg("[RUN]\tsignal USR2\n");
aa = alloca(1024);
/* dont run valgrind on this */
/* try to find the data stored by previous sighandler */
p = memmem(aa, 1024, msg, strlen(msg));
if (p) {
- printf("[FAIL]\tsigaltstack re-used\n");
+ ksft_test_result_fail("sigaltstack re-used\n");
/* corrupt the data */
strcpy(p->msg, msg2);
/* tell other sighandler that his data is corrupted */
@@ -90,7 +92,7 @@ void my_usr2(int sig, siginfo_t *si, void *u)
static void switch_fn(void)
{
- printf("[RUN]\tswitched to user ctx\n");
+ ksft_print_msg("[RUN]\tswitched to user ctx\n");
raise(SIGUSR2);
setcontext(&sc);
}
@@ -101,6 +103,8 @@ int main(void)
stack_t stk;
int err;
+ ksft_print_header();
+
sigemptyset(&act.sa_mask);
act.sa_flags = SA_ONSTACK | SA_SIGINFO;
act.sa_sigaction = my_usr1;
@@ -110,19 +114,20 @@ int main(void)
sstack = mmap(NULL, SIGSTKSZ, PROT_READ | PROT_WRITE,
MAP_PRIVATE | MAP_ANONYMOUS | MAP_STACK, -1, 0);
if (sstack == MAP_FAILED) {
- perror("mmap()");
+ ksft_exit_fail_msg("mmap() - %s\n", strerror(errno));
return EXIT_FAILURE;
}
err = sigaltstack(NULL, &stk);
if (err) {
- perror("[FAIL]\tsigaltstack()");
+ ksft_exit_fail_msg("sigaltstack() - %s\n", strerror(errno));
exit(EXIT_FAILURE);
}
if (stk.ss_flags == SS_DISABLE) {
- printf("[OK]\tInitial sigaltstack state was SS_DISABLE\n");
+ ksft_test_result_pass(
+ "Initial sigaltstack state was SS_DISABLE\n");
} else {
- printf("[FAIL]\tInitial sigaltstack state was %x; "
+ ksft_exit_fail_msg("Initial sigaltstack state was %x; "
"should have been SS_DISABLE\n", stk.ss_flags);
return EXIT_FAILURE;
}
@@ -133,7 +138,8 @@ int main(void)
err = sigaltstack(&stk, NULL);
if (err) {
if (errno == EINVAL) {
- printf("[NOTE]\tThe running kernel doesn't support SS_AUTODISARM\n");
+ ksft_exit_skip(
+ "[NOTE]\tThe running kernel doesn't support SS_AUTODISARM\n");
/*
* If test cases for the !SS_AUTODISARM variant were
* added, we could still run them. We don't have any
@@ -142,7 +148,9 @@ int main(void)
*/
return 0;
} else {
- perror("[FAIL]\tsigaltstack(SS_ONSTACK | SS_AUTODISARM)");
+ ksft_exit_fail_msg(
+ "sigaltstack(SS_ONSTACK | SS_AUTODISARM) %s\n",
+ strerror(errno));
return EXIT_FAILURE;
}
}
@@ -150,7 +158,7 @@ int main(void)
ustack = mmap(NULL, SIGSTKSZ, PROT_READ | PROT_WRITE,
MAP_PRIVATE | MAP_ANONYMOUS | MAP_STACK, -1, 0);
if (ustack == MAP_FAILED) {
- perror("mmap()");
+ ksft_exit_fail_msg("mmap() - %s\n", strerror(errno));
return EXIT_FAILURE;
}
getcontext(&uc);
@@ -162,16 +170,17 @@ int main(void)
err = sigaltstack(NULL, &stk);
if (err) {
- perror("[FAIL]\tsigaltstack()");
+ ksft_exit_fail_msg("sigaltstack() - %s\n", strerror(errno));
exit(EXIT_FAILURE);
}
if (stk.ss_flags != SS_AUTODISARM) {
- printf("[FAIL]\tss_flags=%x, should be SS_AUTODISARM\n",
+ ksft_exit_fail_msg("ss_flags=%x, should be SS_AUTODISARM\n",
stk.ss_flags);
exit(EXIT_FAILURE);
}
- printf("[OK]\tsigaltstack is still SS_AUTODISARM after signal\n");
+ ksft_test_result_pass(
+ "sigaltstack is still SS_AUTODISARM after signal\n");
- printf("[OK]\tTest passed\n");
+ ksft_exit_pass();
return 0;
}
diff --git a/tools/testing/selftests/splice/.gitignore b/tools/testing/selftests/splice/.gitignore
new file mode 100644
index 000000000000..1e23fefd68e8
--- /dev/null
+++ b/tools/testing/selftests/splice/.gitignore
@@ -0,0 +1 @@
+default_file_splice_read
diff --git a/tools/testing/selftests/splice/Makefile b/tools/testing/selftests/splice/Makefile
index 9fc78e5e5451..7e1187e007fa 100644
--- a/tools/testing/selftests/splice/Makefile
+++ b/tools/testing/selftests/splice/Makefile
@@ -1,7 +1,4 @@
TEST_PROGS := default_file_splice_read.sh
-EXTRA := default_file_splice_read
-all: $(TEST_PROGS) $(EXTRA)
+TEST_GEN_PROGS_EXTENDED := default_file_splice_read
include ../lib.mk
-
-EXTRA_CLEAN := $(EXTRA)
diff --git a/tools/testing/selftests/sync/sync_test.c b/tools/testing/selftests/sync/sync_test.c
index 62fa666e501a..7f7938263c5c 100644
--- a/tools/testing/selftests/sync/sync_test.c
+++ b/tools/testing/selftests/sync/sync_test.c
@@ -31,62 +31,83 @@
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/wait.h>
+#include <errno.h>
+#include <string.h>
+#include "../kselftest.h"
#include "synctest.h"
static int run_test(int (*test)(void), char *name)
{
int result;
pid_t childpid;
+ int ret;
fflush(stdout);
childpid = fork();
if (childpid) {
waitpid(childpid, &result, 0);
- if (WIFEXITED(result))
- return WEXITSTATUS(result);
+ if (WIFEXITED(result)) {
+ ret = WEXITSTATUS(result);
+ if (!ret)
+ ksft_test_result_pass("[RUN]\t%s\n", name);
+ else
+ ksft_test_result_fail("[RUN]\t%s\n", name);
+ return ret;
+ }
return 1;
}
- printf("[RUN]\tExecuting %s\n", name);
exit(test());
}
-static int sync_api_supported(void)
+static void sync_api_supported(void)
{
struct stat sbuf;
+ int ret;
- return 0 == stat("/sys/kernel/debug/sync/sw_sync", &sbuf);
+ ret = stat("/sys/kernel/debug/sync/sw_sync", &sbuf);
+ if (!ret)
+ return;
+
+ if (errno == ENOENT)
+ ksft_exit_skip("Sync framework not supported by kernel\n");
+
+ if (errno == EACCES)
+ ksft_exit_skip("Run Sync test as root.\n");
+
+ ksft_exit_fail_msg("stat failed on /sys/kernel/debug/sync/sw_sync: %s",
+ strerror(errno));
}
int main(void)
{
- int err = 0;
+ int err;
- if (!sync_api_supported()) {
- printf("SKIP: Sync framework not supported by kernel\n");
- return 0;
- }
+ ksft_print_header();
+
+ sync_api_supported();
- printf("[RUN]\tTesting sync framework\n");
+ ksft_print_msg("[RUN]\tTesting sync framework\n");
- err += RUN_TEST(test_alloc_timeline);
- err += RUN_TEST(test_alloc_fence);
- err += RUN_TEST(test_alloc_fence_negative);
+ RUN_TEST(test_alloc_timeline);
+ RUN_TEST(test_alloc_fence);
+ RUN_TEST(test_alloc_fence_negative);
- err += RUN_TEST(test_fence_one_timeline_wait);
- err += RUN_TEST(test_fence_one_timeline_merge);
- err += RUN_TEST(test_fence_merge_same_fence);
- err += RUN_TEST(test_fence_multi_timeline_wait);
- err += RUN_TEST(test_stress_two_threads_shared_timeline);
- err += RUN_TEST(test_consumer_stress_multi_producer_single_consumer);
- err += RUN_TEST(test_merge_stress_random_merge);
+ RUN_TEST(test_fence_one_timeline_wait);
+ RUN_TEST(test_fence_one_timeline_merge);
+ RUN_TEST(test_fence_merge_same_fence);
+ RUN_TEST(test_fence_multi_timeline_wait);
+ RUN_TEST(test_stress_two_threads_shared_timeline);
+ RUN_TEST(test_consumer_stress_multi_producer_single_consumer);
+ RUN_TEST(test_merge_stress_random_merge);
+ err = ksft_get_fail_cnt();
if (err)
- printf("[FAIL]\tsync errors: %d\n", err);
- else
- printf("[OK]\tsync\n");
+ ksft_exit_fail_msg("%d out of %d sync tests failed\n",
+ err, ksft_test_num());
- return !!err;
+ /* need this return to keep gcc happy */
+ return ksft_exit_pass();
}
diff --git a/tools/testing/selftests/sync/synctest.h b/tools/testing/selftests/sync/synctest.h
index e7d1d57dba7a..90a8e5369914 100644
--- a/tools/testing/selftests/sync/synctest.h
+++ b/tools/testing/selftests/sync/synctest.h
@@ -29,10 +29,11 @@
#define SELFTESTS_SYNCTEST_H
#include <stdio.h>
+#include "../kselftest.h"
#define ASSERT(cond, msg) do { \
if (!(cond)) { \
- printf("[ERROR]\t%s", (msg)); \
+ ksft_print_msg("[ERROR]\t%s", (msg)); \
return 1; \
} \
} while (0)
diff --git a/tools/testing/selftests/timers/Makefile b/tools/testing/selftests/timers/Makefile
index a9b86133b9b3..ae4593115408 100644
--- a/tools/testing/selftests/timers/Makefile
+++ b/tools/testing/selftests/timers/Makefile
@@ -1,5 +1,4 @@
-BUILD_FLAGS = -DKTEST
-CFLAGS += -O3 -Wl,-no-as-needed -Wall $(BUILD_FLAGS)
+CFLAGS += -O3 -Wl,-no-as-needed -Wall
LDFLAGS += -lrt -lpthread -lm
# these are all "safe" tests that don't modify
@@ -7,9 +6,11 @@ LDFLAGS += -lrt -lpthread -lm
TEST_GEN_PROGS = posix_timers nanosleep nsleep-lat set-timer-lat mqueue-lat \
inconsistency-check raw_skew threadtest rtctest
-TEST_GEN_PROGS_EXTENDED = alarmtimer-suspend valid-adjtimex adjtick change_skew \
+DESTRUCTIVE_TESTS = alarmtimer-suspend valid-adjtimex adjtick change_skew \
skew_consistency clocksource-switch freq-step leap-a-day \
- leapcrash set-tai set-2038 set-tz rtctest_setdate
+ leapcrash set-tai set-2038 set-tz
+
+TEST_GEN_PROGS_EXTENDED = $(DESTRUCTIVE_TESTS) rtctest_setdate
include ../lib.mk
@@ -18,16 +19,4 @@ include ../lib.mk
# and may modify the system time or trigger
# other behavior like suspend
run_destructive_tests: run_tests
- ./alarmtimer-suspend
- ./valid-adjtimex
- ./adjtick
- ./change_skew
- ./skew_consistency
- ./clocksource-switch
- ./freq-step
- ./leap-a-day -s -i 10
- ./leapcrash
- ./set-tz
- ./set-tai
- ./set-2038
-
+ $(call RUN_TESTS, $(DESTRUCTIVE_TESTS))
diff --git a/tools/testing/selftests/timers/adjtick.c b/tools/testing/selftests/timers/adjtick.c
index 9887fd538fec..0caca3a06bd2 100644
--- a/tools/testing/selftests/timers/adjtick.c
+++ b/tools/testing/selftests/timers/adjtick.c
@@ -23,18 +23,7 @@
#include <sys/timex.h>
#include <time.h>
-#ifdef KTEST
#include "../kselftest.h"
-#else
-static inline int ksft_exit_pass(void)
-{
- exit(0);
-}
-static inline int ksft_exit_fail(void)
-{
- exit(1);
-}
-#endif
#define CLOCK_MONOTONIC_RAW 4
diff --git a/tools/testing/selftests/timers/alarmtimer-suspend.c b/tools/testing/selftests/timers/alarmtimer-suspend.c
index 2b361b830395..4da09dbf83ba 100644
--- a/tools/testing/selftests/timers/alarmtimer-suspend.c
+++ b/tools/testing/selftests/timers/alarmtimer-suspend.c
@@ -28,18 +28,7 @@
#include <signal.h>
#include <stdlib.h>
#include <pthread.h>
-#ifdef KTEST
#include "../kselftest.h"
-#else
-static inline int ksft_exit_pass(void)
-{
- exit(0);
-}
-static inline int ksft_exit_fail(void)
-{
- exit(1);
-}
-#endif
#define CLOCK_REALTIME 0
#define CLOCK_MONOTONIC 1
diff --git a/tools/testing/selftests/timers/change_skew.c b/tools/testing/selftests/timers/change_skew.c
index cb1968977c04..c4eab7124990 100644
--- a/tools/testing/selftests/timers/change_skew.c
+++ b/tools/testing/selftests/timers/change_skew.c
@@ -28,18 +28,7 @@
#include <sys/time.h>
#include <sys/timex.h>
#include <time.h>
-#ifdef KTEST
#include "../kselftest.h"
-#else
-static inline int ksft_exit_pass(void)
-{
- exit(0);
-}
-static inline int ksft_exit_fail(void)
-{
- exit(1);
-}
-#endif
#define NSEC_PER_SEC 1000000000LL
diff --git a/tools/testing/selftests/timers/clocksource-switch.c b/tools/testing/selftests/timers/clocksource-switch.c
index 5ff165373f8b..bfc974b4572d 100644
--- a/tools/testing/selftests/timers/clocksource-switch.c
+++ b/tools/testing/selftests/timers/clocksource-switch.c
@@ -34,18 +34,7 @@
#include <fcntl.h>
#include <string.h>
#include <sys/wait.h>
-#ifdef KTEST
#include "../kselftest.h"
-#else
-static inline int ksft_exit_pass(void)
-{
- exit(0);
-}
-static inline int ksft_exit_fail(void)
-{
- exit(1);
-}
-#endif
int get_clocksources(char list[][30])
@@ -61,7 +50,7 @@ int get_clocksources(char list[][30])
close(fd);
- for (i = 0; i < 30; i++)
+ for (i = 0; i < 10; i++)
list[i][0] = '\0';
head = buf;
diff --git a/tools/testing/selftests/timers/inconsistency-check.c b/tools/testing/selftests/timers/inconsistency-check.c
index 74c60e8759a0..022d3ffe3fbf 100644
--- a/tools/testing/selftests/timers/inconsistency-check.c
+++ b/tools/testing/selftests/timers/inconsistency-check.c
@@ -28,18 +28,7 @@
#include <sys/timex.h>
#include <string.h>
#include <signal.h>
-#ifdef KTEST
#include "../kselftest.h"
-#else
-static inline int ksft_exit_pass(void)
-{
- exit(0);
-}
-static inline int ksft_exit_fail(void)
-{
- exit(1);
-}
-#endif
#define CALLS_PER_LOOP 64
#define NSEC_PER_SEC 1000000000ULL
diff --git a/tools/testing/selftests/timers/leap-a-day.c b/tools/testing/selftests/timers/leap-a-day.c
index fb46ad6ac92c..19e46ed5dfb5 100644
--- a/tools/testing/selftests/timers/leap-a-day.c
+++ b/tools/testing/selftests/timers/leap-a-day.c
@@ -48,18 +48,7 @@
#include <string.h>
#include <signal.h>
#include <unistd.h>
-#ifdef KTEST
#include "../kselftest.h"
-#else
-static inline int ksft_exit_pass(void)
-{
- exit(0);
-}
-static inline int ksft_exit_fail(void)
-{
- exit(1);
-}
-#endif
#define NSEC_PER_SEC 1000000000ULL
#define CLOCK_TAI 11
@@ -190,18 +179,18 @@ int main(int argc, char **argv)
struct sigevent se;
struct sigaction act;
int signum = SIGRTMAX;
- int settime = 0;
+ int settime = 1;
int tai_time = 0;
int insert = 1;
- int iterations = -1;
+ int iterations = 10;
int opt;
/* Process arguments */
while ((opt = getopt(argc, argv, "sti:")) != -1) {
switch (opt) {
- case 's':
- printf("Setting time to speed up testing\n");
- settime = 1;
+ case 'w':
+ printf("Only setting leap-flag, not changing time. It could take up to a day for leap to trigger.\n");
+ settime = 0;
break;
case 'i':
iterations = atoi(optarg);
@@ -210,9 +199,10 @@ int main(int argc, char **argv)
tai_time = 1;
break;
default:
- printf("Usage: %s [-s] [-i <iterations>]\n", argv[0]);
- printf(" -s: Set time to right before leap second each iteration\n");
- printf(" -i: Number of iterations\n");
+ printf("Usage: %s [-w] [-i <iterations>]\n", argv[0]);
+ printf(" -w: Set flag and wait for leap second each iteration");
+ printf(" (default sets time to right before leapsecond)\n");
+ printf(" -i: Number of iterations (-1 = infinite, default is 10)\n");
printf(" -t: Print TAI time\n");
exit(-1);
}
diff --git a/tools/testing/selftests/timers/leapcrash.c b/tools/testing/selftests/timers/leapcrash.c
index a1071bdbdeb7..830c462f605d 100644
--- a/tools/testing/selftests/timers/leapcrash.c
+++ b/tools/testing/selftests/timers/leapcrash.c
@@ -22,20 +22,7 @@
#include <sys/timex.h>
#include <string.h>
#include <signal.h>
-#ifdef KTEST
#include "../kselftest.h"
-#else
-static inline int ksft_exit_pass(void)
-{
- exit(0);
-}
-static inline int ksft_exit_fail(void)
-{
- exit(1);
-}
-#endif
-
-
/* clear NTP time_status & time_state */
int clear_time_state(void)
diff --git a/tools/testing/selftests/timers/mqueue-lat.c b/tools/testing/selftests/timers/mqueue-lat.c
index a2a3924d0b41..1867db5d6f5e 100644
--- a/tools/testing/selftests/timers/mqueue-lat.c
+++ b/tools/testing/selftests/timers/mqueue-lat.c
@@ -29,18 +29,7 @@
#include <signal.h>
#include <errno.h>
#include <mqueue.h>
-#ifdef KTEST
#include "../kselftest.h"
-#else
-static inline int ksft_exit_pass(void)
-{
- exit(0);
-}
-static inline int ksft_exit_fail(void)
-{
- exit(1);
-}
-#endif
#define NSEC_PER_SEC 1000000000ULL
diff --git a/tools/testing/selftests/timers/nanosleep.c b/tools/testing/selftests/timers/nanosleep.c
index ff942ff7c9b3..8adb0bb51d4d 100644
--- a/tools/testing/selftests/timers/nanosleep.c
+++ b/tools/testing/selftests/timers/nanosleep.c
@@ -27,18 +27,7 @@
#include <sys/timex.h>
#include <string.h>
#include <signal.h>
-#ifdef KTEST
#include "../kselftest.h"
-#else
-static inline int ksft_exit_pass(void)
-{
- exit(0);
-}
-static inline int ksft_exit_fail(void)
-{
- exit(1);
-}
-#endif
#define NSEC_PER_SEC 1000000000ULL
diff --git a/tools/testing/selftests/timers/nsleep-lat.c b/tools/testing/selftests/timers/nsleep-lat.c
index 2d7898fda0f1..c3c3dc10db17 100644
--- a/tools/testing/selftests/timers/nsleep-lat.c
+++ b/tools/testing/selftests/timers/nsleep-lat.c
@@ -24,18 +24,7 @@
#include <sys/timex.h>
#include <string.h>
#include <signal.h>
-#ifdef KTEST
#include "../kselftest.h"
-#else
-static inline int ksft_exit_pass(void)
-{
- exit(0);
-}
-static inline int ksft_exit_fail(void)
-{
- exit(1);
-}
-#endif
#define NSEC_PER_SEC 1000000000ULL
diff --git a/tools/testing/selftests/timers/raw_skew.c b/tools/testing/selftests/timers/raw_skew.c
index 30906bfd9c1b..ca6cd146aafe 100644
--- a/tools/testing/selftests/timers/raw_skew.c
+++ b/tools/testing/selftests/timers/raw_skew.c
@@ -25,19 +25,7 @@
#include <sys/time.h>
#include <sys/timex.h>
#include <time.h>
-#ifdef KTEST
#include "../kselftest.h"
-#else
-static inline int ksft_exit_pass(void)
-{
- exit(0);
-}
-static inline int ksft_exit_fail(void)
-{
- exit(1);
-}
-#endif
-
#define CLOCK_MONOTONIC_RAW 4
#define NSEC_PER_SEC 1000000000LL
diff --git a/tools/testing/selftests/timers/rtctest.c b/tools/testing/selftests/timers/rtctest.c
index f61170f7b024..411eff625e66 100644
--- a/tools/testing/selftests/timers/rtctest.c
+++ b/tools/testing/selftests/timers/rtctest.c
@@ -221,6 +221,11 @@ test_READ:
/* Read the current alarm settings */
retval = ioctl(fd, RTC_ALM_READ, &rtc_tm);
if (retval == -1) {
+ if (errno == EINVAL) {
+ fprintf(stderr,
+ "\n...EINVAL reading current alarm setting.\n");
+ goto test_PIE;
+ }
perror("RTC_ALM_READ ioctl");
exit(errno);
}
@@ -231,7 +236,7 @@ test_READ:
/* Enable alarm interrupts */
retval = ioctl(fd, RTC_AIE_ON, 0);
if (retval == -1) {
- if (errno == EINVAL) {
+ if (errno == EINVAL || errno == EIO) {
fprintf(stderr,
"\n...Alarm IRQs not supported.\n");
goto test_PIE;
diff --git a/tools/testing/selftests/timers/set-2038.c b/tools/testing/selftests/timers/set-2038.c
index c8a7e14446b1..688cfd81b531 100644
--- a/tools/testing/selftests/timers/set-2038.c
+++ b/tools/testing/selftests/timers/set-2038.c
@@ -27,18 +27,7 @@
#include <unistd.h>
#include <time.h>
#include <sys/time.h>
-#ifdef KTEST
#include "../kselftest.h"
-#else
-static inline int ksft_exit_pass(void)
-{
- exit(0);
-}
-static inline int ksft_exit_fail(void)
-{
- exit(1);
-}
-#endif
#define NSEC_PER_SEC 1000000000LL
diff --git a/tools/testing/selftests/timers/set-tai.c b/tools/testing/selftests/timers/set-tai.c
index dc88dbc8831f..70fed27d8fd3 100644
--- a/tools/testing/selftests/timers/set-tai.c
+++ b/tools/testing/selftests/timers/set-tai.c
@@ -23,18 +23,7 @@
#include <string.h>
#include <signal.h>
#include <unistd.h>
-#ifdef KTEST
#include "../kselftest.h"
-#else
-static inline int ksft_exit_pass(void)
-{
- exit(0);
-}
-static inline int ksft_exit_fail(void)
-{
- exit(1);
-}
-#endif
int set_tai(int offset)
{
diff --git a/tools/testing/selftests/timers/set-timer-lat.c b/tools/testing/selftests/timers/set-timer-lat.c
index 15434da23b04..9c92b7bd5641 100644
--- a/tools/testing/selftests/timers/set-timer-lat.c
+++ b/tools/testing/selftests/timers/set-timer-lat.c
@@ -28,18 +28,7 @@
#include <signal.h>
#include <stdlib.h>
#include <pthread.h>
-#ifdef KTEST
#include "../kselftest.h"
-#else
-static inline int ksft_exit_pass(void)
-{
- exit(0);
-}
-static inline int ksft_exit_fail(void)
-{
- exit(1);
-}
-#endif
#define CLOCK_REALTIME 0
#define CLOCK_MONOTONIC 1
diff --git a/tools/testing/selftests/timers/set-tz.c b/tools/testing/selftests/timers/set-tz.c
index f4184928b16b..877fd5532fee 100644
--- a/tools/testing/selftests/timers/set-tz.c
+++ b/tools/testing/selftests/timers/set-tz.c
@@ -23,18 +23,7 @@
#include <string.h>
#include <signal.h>
#include <unistd.h>
-#ifdef KTEST
#include "../kselftest.h"
-#else
-static inline int ksft_exit_pass(void)
-{
- exit(0);
-}
-static inline int ksft_exit_fail(void)
-{
- exit(1);
-}
-#endif
int set_tz(int min, int dst)
{
diff --git a/tools/testing/selftests/timers/skew_consistency.c b/tools/testing/selftests/timers/skew_consistency.c
index 2a996e072259..022b711c78ee 100644
--- a/tools/testing/selftests/timers/skew_consistency.c
+++ b/tools/testing/selftests/timers/skew_consistency.c
@@ -35,18 +35,7 @@
#include <stdlib.h>
#include <string.h>
#include <sys/wait.h>
-#ifdef KTEST
#include "../kselftest.h"
-#else
-static inline int ksft_exit_pass(void)
-{
- exit(0);
-}
-static inline int ksft_exit_fail(void)
-{
- exit(1);
-}
-#endif
#define NSEC_PER_SEC 1000000000LL
diff --git a/tools/testing/selftests/timers/threadtest.c b/tools/testing/selftests/timers/threadtest.c
index e632e116f05e..759c9c06f1a0 100644
--- a/tools/testing/selftests/timers/threadtest.c
+++ b/tools/testing/selftests/timers/threadtest.c
@@ -21,19 +21,7 @@
#include <stdlib.h>
#include <sys/time.h>
#include <pthread.h>
-#ifdef KTEST
#include "../kselftest.h"
-#else
-static inline int ksft_exit_pass(void)
-{
- exit(0);
-}
-static inline int ksft_exit_fail(void)
-{
- exit(1);
-}
-#endif
-
/* serializes shared list access */
pthread_mutex_t list_lock = PTHREAD_MUTEX_INITIALIZER;
diff --git a/tools/testing/selftests/timers/valid-adjtimex.c b/tools/testing/selftests/timers/valid-adjtimex.c
index 60fe3c569bd9..d9d3ab93b31a 100644
--- a/tools/testing/selftests/timers/valid-adjtimex.c
+++ b/tools/testing/selftests/timers/valid-adjtimex.c
@@ -32,18 +32,7 @@
#include <string.h>
#include <signal.h>
#include <unistd.h>
-#ifdef KTEST
#include "../kselftest.h"
-#else
-static inline int ksft_exit_pass(void)
-{
- exit(0);
-}
-static inline int ksft_exit_fail(void)
-{
- exit(1);
-}
-#endif
#define NSEC_PER_SEC 1000000000LL
#define USEC_PER_SEC 1000000LL
diff --git a/tools/testing/selftests/watchdog/watchdog-test.c b/tools/testing/selftests/watchdog/watchdog-test.c
index a74c9d739d07..a1391be2dc1e 100644
--- a/tools/testing/selftests/watchdog/watchdog-test.c
+++ b/tools/testing/selftests/watchdog/watchdog-test.c
@@ -9,12 +9,25 @@
#include <unistd.h>
#include <fcntl.h>
#include <signal.h>
+#include <getopt.h>
#include <sys/ioctl.h>
#include <linux/types.h>
#include <linux/watchdog.h>
+#define DEFAULT_PING_RATE 1
+
int fd;
const char v = 'V';
+static const char sopts[] = "bdehp:t:";
+static const struct option lopts[] = {
+ {"bootstatus", no_argument, NULL, 'b'},
+ {"disable", no_argument, NULL, 'd'},
+ {"enable", no_argument, NULL, 'e'},
+ {"help", no_argument, NULL, 'h'},
+ {"pingrate", required_argument, NULL, 'p'},
+ {"timeout", required_argument, NULL, 't'},
+ {NULL, no_argument, NULL, 0x0}
+};
/*
* This function simply sends an IOCTL to the driver, which in turn ticks
@@ -23,12 +36,12 @@ const char v = 'V';
*/
static void keep_alive(void)
{
- int dummy;
- int ret;
+ int dummy;
+ int ret;
- ret = ioctl(fd, WDIOC_KEEPALIVE, &dummy);
- if (!ret)
- printf(".");
+ ret = ioctl(fd, WDIOC_KEEPALIVE, &dummy);
+ if (!ret)
+ printf(".");
}
/*
@@ -38,75 +51,110 @@ static void keep_alive(void)
static void term(int sig)
{
- int ret = write(fd, &v, 1);
-
- close(fd);
- if (ret < 0)
- printf("\nStopping watchdog ticks failed (%d)...\n", errno);
- else
- printf("\nStopping watchdog ticks...\n");
- exit(0);
+ int ret = write(fd, &v, 1);
+
+ close(fd);
+ if (ret < 0)
+ printf("\nStopping watchdog ticks failed (%d)...\n", errno);
+ else
+ printf("\nStopping watchdog ticks...\n");
+ exit(0);
+}
+
+static void usage(char *progname)
+{
+ printf("Usage: %s [options]\n", progname);
+ printf(" -b, --bootstatus Get last boot status (Watchdog/POR)\n");
+ printf(" -d, --disable Turn off the watchdog timer\n");
+ printf(" -e, --enable Turn on the watchdog timer\n");
+ printf(" -h, --help Print the help message\n");
+ printf(" -p, --pingrate=P Set ping rate to P seconds (default %d)\n", DEFAULT_PING_RATE);
+ printf(" -t, --timeout=T Set timeout to T seconds\n");
+ printf("\n");
+ printf("Parameters are parsed left-to-right in real-time.\n");
+ printf("Example: %s -d -t 10 -p 5 -e\n", progname);
}
int main(int argc, char *argv[])
{
- int flags;
- unsigned int ping_rate = 1;
- int ret;
- int i;
-
- setbuf(stdout, NULL);
-
- fd = open("/dev/watchdog", O_WRONLY);
-
- if (fd == -1) {
- printf("Watchdog device not enabled.\n");
- exit(-1);
- }
-
- for (i = 1; i < argc; i++) {
- if (!strncasecmp(argv[i], "-d", 2)) {
- flags = WDIOS_DISABLECARD;
- ret = ioctl(fd, WDIOC_SETOPTIONS, &flags);
- if (!ret)
- printf("Watchdog card disabled.\n");
- } else if (!strncasecmp(argv[i], "-e", 2)) {
- flags = WDIOS_ENABLECARD;
- ret = ioctl(fd, WDIOC_SETOPTIONS, &flags);
- if (!ret)
- printf("Watchdog card enabled.\n");
- } else if (!strncasecmp(argv[i], "-t", 2) && argv[2]) {
- flags = atoi(argv[i + 1]);
- ret = ioctl(fd, WDIOC_SETTIMEOUT, &flags);
- if (!ret)
- printf("Watchdog timeout set to %u seconds.\n", flags);
- i++;
- } else if (!strncasecmp(argv[i], "-p", 2) && argv[2]) {
- ping_rate = strtoul(argv[i + 1], NULL, 0);
- printf("Watchdog ping rate set to %u seconds.\n", ping_rate);
- i++;
- } else {
- printf("-d to disable, -e to enable, -t <n> to set "
- "the timeout,\n-p <n> to set the ping rate, and ");
- printf("run by itself to tick the card.\n");
- printf("Parameters are parsed left-to-right in real-time.\n");
- printf("Example: %s -d -t 10 -p 5 -e\n", argv[0]);
- goto end;
- }
- }
-
- printf("Watchdog Ticking Away!\n");
-
- signal(SIGINT, term);
-
- while(1) {
- keep_alive();
- sleep(ping_rate);
- }
+ int flags;
+ unsigned int ping_rate = DEFAULT_PING_RATE;
+ int ret;
+ int c;
+ int oneshot = 0;
+
+ setbuf(stdout, NULL);
+
+ fd = open("/dev/watchdog", O_WRONLY);
+
+ if (fd == -1) {
+ printf("Watchdog device not enabled.\n");
+ exit(-1);
+ }
+
+ while ((c = getopt_long(argc, argv, sopts, lopts, NULL)) != -1) {
+ switch (c) {
+ case 'b':
+ flags = 0;
+ oneshot = 1;
+ ret = ioctl(fd, WDIOC_GETBOOTSTATUS, &flags);
+ if (!ret)
+ printf("Last boot is caused by: %s.\n", (flags != 0) ?
+ "Watchdog" : "Power-On-Reset");
+ else
+ printf("WDIOC_GETBOOTSTATUS errno '%s'\n", strerror(errno));
+ break;
+ case 'd':
+ flags = WDIOS_DISABLECARD;
+ ret = ioctl(fd, WDIOC_SETOPTIONS, &flags);
+ if (!ret)
+ printf("Watchdog card disabled.\n");
+ else
+ printf("WDIOS_DISABLECARD errno '%s'\n", strerror(errno));
+ break;
+ case 'e':
+ flags = WDIOS_ENABLECARD;
+ ret = ioctl(fd, WDIOC_SETOPTIONS, &flags);
+ if (!ret)
+ printf("Watchdog card enabled.\n");
+ else
+ printf("WDIOS_ENABLECARD errno '%s'\n", strerror(errno));
+ break;
+ case 'p':
+ ping_rate = strtoul(optarg, NULL, 0);
+ if (!ping_rate)
+ ping_rate = DEFAULT_PING_RATE;
+ printf("Watchdog ping rate set to %u seconds.\n", ping_rate);
+ break;
+ case 't':
+ flags = strtoul(optarg, NULL, 0);
+ ret = ioctl(fd, WDIOC_SETTIMEOUT, &flags);
+ if (!ret)
+ printf("Watchdog timeout set to %u seconds.\n", flags);
+ else
+ printf("WDIOC_SETTIMEOUT errno '%s'\n", strerror(errno));
+ break;
+ default:
+ usage(argv[0]);
+ goto end;
+ }
+ }
+
+ if (oneshot)
+ goto end;
+
+ printf("Watchdog Ticking Away!\n");
+
+ signal(SIGINT, term);
+
+ while (1) {
+ keep_alive();
+ sleep(ping_rate);
+ }
end:
- ret = write(fd, &v, 1);
- if (ret < 0)
- printf("Stopping watchdog ticks failed (%d)...\n", errno);
- close(fd);
- return 0;
+ ret = write(fd, &v, 1);
+ if (ret < 0)
+ printf("Stopping watchdog ticks failed (%d)...\n", errno);
+ close(fd);
+ return 0;
}
diff --git a/tools/testing/selftests/x86/mpx-mini-test.c b/tools/testing/selftests/x86/mpx-mini-test.c
index a8df159a8924..ec0f6b45ce8b 100644
--- a/tools/testing/selftests/x86/mpx-mini-test.c
+++ b/tools/testing/selftests/x86/mpx-mini-test.c
@@ -391,8 +391,7 @@ void handler(int signum, siginfo_t *si, void *vucontext)
br_count++;
dprintf1("#BR 0x%jx (total seen: %d)\n", status, br_count);
-#define __SI_FAULT (3 << 16)
-#define SEGV_BNDERR (__SI_FAULT|3) /* failed address bound checks */
+#define SEGV_BNDERR 3 /* failed address bound checks */
dprintf2("Saw a #BR! status 0x%jx at %016lx br_reason: %jx\n",
status, ip, br_reason);
diff --git a/tools/testing/selftests/x86/protection_keys.c b/tools/testing/selftests/x86/protection_keys.c
index 3237bc010e1c..23927845518d 100644
--- a/tools/testing/selftests/x86/protection_keys.c
+++ b/tools/testing/selftests/x86/protection_keys.c
@@ -212,19 +212,18 @@ void dump_mem(void *dumpme, int len_bytes)
}
}
-#define __SI_FAULT (3 << 16)
-#define SEGV_BNDERR (__SI_FAULT|3) /* failed address bound checks */
-#define SEGV_PKUERR (__SI_FAULT|4)
+#define SEGV_BNDERR 3 /* failed address bound checks */
+#define SEGV_PKUERR 4
static char *si_code_str(int si_code)
{
- if (si_code & SEGV_MAPERR)
+ if (si_code == SEGV_MAPERR)
return "SEGV_MAPERR";
- if (si_code & SEGV_ACCERR)
+ if (si_code == SEGV_ACCERR)
return "SEGV_ACCERR";
- if (si_code & SEGV_BNDERR)
+ if (si_code == SEGV_BNDERR)
return "SEGV_BNDERR";
- if (si_code & SEGV_PKUERR)
+ if (si_code == SEGV_PKUERR)
return "SEGV_PKUERR";
return "UNKNOWN";
}
OpenPOWER on IntegriCloud