From 1a77e2bd8c89a37703dc9de18a7b552ad76e1c12 Mon Sep 17 00:00:00 2001 From: John Stultz Date: Wed, 1 Jun 2016 11:53:27 -0700 Subject: kselftests: timers: Add set-tz test case Mika Westerberg reported a erroneous change in the error checking of settimeofday, so I wanted to add a test to ensure we don't trip over this again. Cc: Mika Westerberg Cc: Baolin Wang Cc: Thomas Gleixner Cc: Shuah Khan Cc: Arnd Bergmann Cc: Ingo Molnar Cc: Richard Cochran Cc: Prarit Bhargava Signed-off-by: John Stultz Signed-off-by: Shuah Khan --- tools/testing/selftests/timers/Makefile | 3 +- tools/testing/selftests/timers/set-tz.c | 119 ++++++++++++++++++++++++++++++++ 2 files changed, 121 insertions(+), 1 deletion(-) create mode 100644 tools/testing/selftests/timers/set-tz.c (limited to 'tools') diff --git a/tools/testing/selftests/timers/Makefile b/tools/testing/selftests/timers/Makefile index 4a1be1b75a7f..1d5556869137 100644 --- a/tools/testing/selftests/timers/Makefile +++ b/tools/testing/selftests/timers/Makefile @@ -10,7 +10,7 @@ TEST_PROGS = posix_timers nanosleep nsleep-lat set-timer-lat mqueue-lat \ TEST_PROGS_EXTENDED = alarmtimer-suspend valid-adjtimex adjtick change_skew \ skew_consistency clocksource-switch leap-a-day \ - leapcrash set-tai set-2038 + leapcrash set-tai set-2038 set-tz bins = $(TEST_PROGS) $(TEST_PROGS_EXTENDED) @@ -30,6 +30,7 @@ run_destructive_tests: run_tests ./clocksource-switch ./leap-a-day -s -i 10 ./leapcrash + ./set-tz ./set-tai ./set-2038 diff --git a/tools/testing/selftests/timers/set-tz.c b/tools/testing/selftests/timers/set-tz.c new file mode 100644 index 000000000000..f4184928b16b --- /dev/null +++ b/tools/testing/selftests/timers/set-tz.c @@ -0,0 +1,119 @@ +/* Set tz value + * by: John Stultz + * (C) Copyright Linaro 2016 + * Licensed under the GPLv2 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + + +#include +#include +#include +#include +#include +#include +#include +#include +#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) +{ + struct timezone tz; + + tz.tz_minuteswest = min; + tz.tz_dsttime = dst; + + return settimeofday(0, &tz); +} + +int get_tz_min(void) +{ + struct timezone tz; + struct timeval tv; + + memset(&tz, 0, sizeof(tz)); + gettimeofday(&tv, &tz); + return tz.tz_minuteswest; +} + +int get_tz_dst(void) +{ + struct timezone tz; + struct timeval tv; + + memset(&tz, 0, sizeof(tz)); + gettimeofday(&tv, &tz); + return tz.tz_dsttime; +} + +int main(int argc, char **argv) +{ + int i, ret; + int min, dst; + + min = get_tz_min(); + dst = get_tz_dst(); + printf("tz_minuteswest started at %i, dst at %i\n", min, dst); + + printf("Checking tz_minuteswest can be properly set: "); + for (i = -15*60; i < 15*60; i += 30) { + ret = set_tz(i, dst); + ret = get_tz_min(); + if (ret != i) { + printf("[FAILED] expected: %i got %i\n", i, ret); + goto err; + } + } + printf("[OK]\n"); + + printf("Checking invalid tz_minuteswest values are caught: "); + + if (!set_tz(-15*60-1, dst)) { + printf("[FAILED] %i didn't return failure!\n", -15*60-1); + goto err; + } + + if (!set_tz(15*60+1, dst)) { + printf("[FAILED] %i didn't return failure!\n", 15*60+1); + goto err; + } + + if (!set_tz(-24*60, dst)) { + printf("[FAILED] %i didn't return failure!\n", -24*60); + goto err; + } + + if (!set_tz(24*60, dst)) { + printf("[FAILED] %i didn't return failure!\n", 24*60); + goto err; + } + + printf("[OK]\n"); + + set_tz(min, dst); + return ksft_exit_pass(); + +err: + set_tz(min, dst); + return ksft_exit_fail(); +} -- cgit v1.2.3 From f80eb4289491f6ddb0788636ce0bd6f5d3a2012a Mon Sep 17 00:00:00 2001 From: Yannick Brosseau Date: Wed, 15 Jun 2016 11:36:12 -0700 Subject: selftests/exec: Makefile is a run-time dependency, add it to the install list The execveat test try to exec the Makefile file and expect an EACCES results. When running the test in the installed destination it would fail with ENOENT since the file is not there. Add Makefile to the TEST_FILES list so it's copied at install time. Signed-off-by: Yannick Brosseau Signed-off-by: Shuah Khan --- tools/testing/selftests/exec/Makefile | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'tools') diff --git a/tools/testing/selftests/exec/Makefile b/tools/testing/selftests/exec/Makefile index 4e400eb83657..d4300602bf37 100644 --- a/tools/testing/selftests/exec/Makefile +++ b/tools/testing/selftests/exec/Makefile @@ -18,7 +18,8 @@ execveat.denatured: execveat $(CC) $(CFLAGS) -o $@ $^ TEST_PROGS := execveat -TEST_FILES := $(DEPS) +# Makefile is a run-time dependency, since it's accessed by the execveat test +TEST_FILES := $(DEPS) Makefile include ../lib.mk -- cgit v1.2.3 From 16c19a2e983346c547501795aadffde1977b058d Mon Sep 17 00:00:00 2001 From: Jack Miller Date: Thu, 9 Jun 2016 12:31:10 +1000 Subject: selftests/powerpc: Load Monitor Register Tests Adds two tests. One is a simple test to ensure that the new registers LMRR and LMSER are properly maintained. The other actually uses the existing EBB test infrastructure to test that LMRR and LMSER behave as documented. Signed-off-by: Jack Miller Signed-off-by: Michael Neuling Signed-off-by: Michael Ellerman --- tools/testing/selftests/powerpc/pmu/ebb/.gitignore | 2 + tools/testing/selftests/powerpc/pmu/ebb/Makefile | 2 +- tools/testing/selftests/powerpc/pmu/ebb/ebb_lmr.c | 143 +++++++++++++++++++++ tools/testing/selftests/powerpc/pmu/ebb/ebb_lmr.h | 39 ++++++ .../selftests/powerpc/pmu/ebb/ebb_lmr_regs.c | 37 ++++++ tools/testing/selftests/powerpc/reg.h | 5 + 6 files changed, 227 insertions(+), 1 deletion(-) create mode 100644 tools/testing/selftests/powerpc/pmu/ebb/ebb_lmr.c create mode 100644 tools/testing/selftests/powerpc/pmu/ebb/ebb_lmr.h create mode 100644 tools/testing/selftests/powerpc/pmu/ebb/ebb_lmr_regs.c (limited to 'tools') diff --git a/tools/testing/selftests/powerpc/pmu/ebb/.gitignore b/tools/testing/selftests/powerpc/pmu/ebb/.gitignore index 42bddbed8b64..44b7df14a936 100644 --- a/tools/testing/selftests/powerpc/pmu/ebb/.gitignore +++ b/tools/testing/selftests/powerpc/pmu/ebb/.gitignore @@ -20,3 +20,5 @@ back_to_back_ebbs_test lost_exception_test no_handler_test cycles_with_mmcr2_test +ebb_lmr +ebb_lmr_regs \ No newline at end of file diff --git a/tools/testing/selftests/powerpc/pmu/ebb/Makefile b/tools/testing/selftests/powerpc/pmu/ebb/Makefile index 8d2279c4bb4b..6b0453e60d53 100644 --- a/tools/testing/selftests/powerpc/pmu/ebb/Makefile +++ b/tools/testing/selftests/powerpc/pmu/ebb/Makefile @@ -14,7 +14,7 @@ TEST_PROGS := reg_access_test event_attributes_test cycles_test \ fork_cleanup_test ebb_on_child_test \ ebb_on_willing_child_test back_to_back_ebbs_test \ lost_exception_test no_handler_test \ - cycles_with_mmcr2_test + cycles_with_mmcr2_test ebb_lmr ebb_lmr_regs all: $(TEST_PROGS) diff --git a/tools/testing/selftests/powerpc/pmu/ebb/ebb_lmr.c b/tools/testing/selftests/powerpc/pmu/ebb/ebb_lmr.c new file mode 100644 index 000000000000..c47ebd55ba4d --- /dev/null +++ b/tools/testing/selftests/powerpc/pmu/ebb/ebb_lmr.c @@ -0,0 +1,143 @@ +/* + * Copyright 2016, Jack Miller, IBM Corp. + * Licensed under GPLv2. + */ + +#include +#include + +#include "ebb.h" +#include "ebb_lmr.h" + +#define SIZE (32 * 1024 * 1024) /* 32M */ +#define LM_SIZE 0 /* Smallest encoding, 32M */ + +#define SECTIONS 64 /* 1 per bit in LMSER */ +#define SECTION_SIZE (SIZE / SECTIONS) +#define SECTION_LONGS (SECTION_SIZE / sizeof(long)) + +static unsigned long *test_mem; + +static int lmr_count = 0; + +void ebb_lmr_handler(void) +{ + lmr_count++; +} + +void ldmx_full_section(unsigned long *mem, int section) +{ + unsigned long *ptr; + int i; + + for (i = 0; i < SECTION_LONGS; i++) { + ptr = &mem[(SECTION_LONGS * section) + i]; + ldmx((unsigned long) &ptr); + ebb_lmr_reset(); + } +} + +unsigned long section_masks[] = { + 0x8000000000000000, + 0xFF00000000000000, + 0x0000000F70000000, + 0x8000000000000001, + 0xF0F0F0F0F0F0F0F0, + 0x0F0F0F0F0F0F0F0F, + 0x0 +}; + +int ebb_lmr_section_test(unsigned long *mem) +{ + unsigned long *mask = section_masks; + int i; + + for (; *mask; mask++) { + mtspr(SPRN_LMSER, *mask); + printf("Testing mask 0x%016lx\n", mfspr(SPRN_LMSER)); + + for (i = 0; i < 64; i++) { + lmr_count = 0; + ldmx_full_section(mem, i); + if (*mask & (1UL << (63 - i))) + FAIL_IF(lmr_count != SECTION_LONGS); + else + FAIL_IF(lmr_count); + } + } + + return 0; +} + +int ebb_lmr(void) +{ + int i; + + SKIP_IF(!lmr_is_supported()); + + setup_ebb_handler(ebb_lmr_handler); + + ebb_global_enable(); + + FAIL_IF(posix_memalign((void **)&test_mem, SIZE, SIZE) != 0); + + mtspr(SPRN_LMSER, 0); + + FAIL_IF(mfspr(SPRN_LMSER) != 0); + + mtspr(SPRN_LMRR, ((unsigned long)test_mem | LM_SIZE)); + + FAIL_IF(mfspr(SPRN_LMRR) != ((unsigned long)test_mem | LM_SIZE)); + + /* Read every single byte to ensure we get no false positives */ + for (i = 0; i < SECTIONS; i++) + ldmx_full_section(test_mem, i); + + FAIL_IF(lmr_count != 0); + + /* Turn on the first section */ + + mtspr(SPRN_LMSER, (1UL << 63)); + FAIL_IF(mfspr(SPRN_LMSER) != (1UL << 63)); + + /* Enable LM (BESCR) */ + + mtspr(SPRN_BESCR, mfspr(SPRN_BESCR) | BESCR_LME); + FAIL_IF(!(mfspr(SPRN_BESCR) & BESCR_LME)); + + ldmx((unsigned long)&test_mem); + + FAIL_IF(lmr_count != 1); // exactly one exception + FAIL_IF(mfspr(SPRN_BESCR) & BESCR_LME); // LM now disabled + FAIL_IF(!(mfspr(SPRN_BESCR) & BESCR_LMEO)); // occurred bit set + + printf("Simple LMR EBB OK\n"); + + /* This shouldn't cause an EBB since it's been disabled */ + ldmx((unsigned long)&test_mem); + FAIL_IF(lmr_count != 1); + + printf("LMR disable on EBB OK\n"); + + ebb_lmr_reset(); + + /* This should cause an EBB or reset is broken */ + ldmx((unsigned long)&test_mem); + FAIL_IF(lmr_count != 2); + + printf("LMR reset EBB OK\n"); + + ebb_lmr_reset(); + + return ebb_lmr_section_test(test_mem); +} + +int main(void) +{ + int ret = test_harness(ebb_lmr, "ebb_lmr"); + + if (test_mem) + free(test_mem); + + return ret; +} diff --git a/tools/testing/selftests/powerpc/pmu/ebb/ebb_lmr.h b/tools/testing/selftests/powerpc/pmu/ebb/ebb_lmr.h new file mode 100644 index 000000000000..ef50abd557cd --- /dev/null +++ b/tools/testing/selftests/powerpc/pmu/ebb/ebb_lmr.h @@ -0,0 +1,39 @@ +#ifndef _SELFTESTS_POWERPC_PMU_EBB_LMR_H +#define _SELFTESTS_POWERPC_PMU_EBB_LMR_H + +#include "reg.h" + +#ifndef PPC_FEATURE2_ARCH_3_00 +#define PPC_FEATURE2_ARCH_3_00 0x00800000 +#endif + +#define lmr_is_supported() have_hwcap2(PPC_FEATURE2_ARCH_3_00) + +static inline void ebb_lmr_reset(void) +{ + unsigned long bescr = mfspr(SPRN_BESCR); + bescr &= ~(BESCR_LMEO); + bescr |= BESCR_LME; + mtspr(SPRN_BESCR, bescr); +} + +#define LDMX(t, a, b)\ + (0x7c00026a | \ + (((t) & 0x1f) << 21) | \ + (((a) & 0x1f) << 16) | \ + (((b) & 0x1f) << 11)) + +static inline unsigned long ldmx(unsigned long address) +{ + unsigned long ret; + + asm volatile ("mr 9, %1\r\n" + ".long " __stringify(LDMX(9, 0, 9)) "\r\n" + "mr %0, 9\r\n":"=r"(ret) + :"r"(address) + :"r9"); + + return ret; +} + +#endif diff --git a/tools/testing/selftests/powerpc/pmu/ebb/ebb_lmr_regs.c b/tools/testing/selftests/powerpc/pmu/ebb/ebb_lmr_regs.c new file mode 100644 index 000000000000..aff4241fd88a --- /dev/null +++ b/tools/testing/selftests/powerpc/pmu/ebb/ebb_lmr_regs.c @@ -0,0 +1,37 @@ +/* + * Copyright 2016, Jack Miller, IBM Corp. + * Licensed under GPLv2. + */ + +#include +#include +#include + +#include "ebb.h" +#include "ebb_lmr.h" + +#define CHECKS 10000 + +int ebb_lmr_regs(void) +{ + int i; + + SKIP_IF(!lmr_is_supported()); + + ebb_global_enable(); + + for (i = 0; i < CHECKS; i++) { + mtspr(SPRN_LMRR, i << 25); // skip size and rsvd bits + mtspr(SPRN_LMSER, i); + + FAIL_IF(mfspr(SPRN_LMRR) != (i << 25)); + FAIL_IF(mfspr(SPRN_LMSER) != i); + } + + return 0; +} + +int main(void) +{ + return test_harness(ebb_lmr_regs, "ebb_lmr_regs"); +} diff --git a/tools/testing/selftests/powerpc/reg.h b/tools/testing/selftests/powerpc/reg.h index 65bfdeeebdee..fddf368ed82f 100644 --- a/tools/testing/selftests/powerpc/reg.h +++ b/tools/testing/selftests/powerpc/reg.h @@ -34,6 +34,11 @@ #define BESCR_PMEO 0x1 /* PMU Event-based exception Occurred */ #define BESCR_PME (0x1ul << 32) /* PMU Event-based exception Enable */ +#define BESCR_LME (0x1ul << 34) /* Load Monitor Enable */ +#define BESCR_LMEO (0x1ul << 2) /* Load Monitor Exception Occurred */ + +#define SPRN_LMRR 813 /* Load Monitor Region Register */ +#define SPRN_LMSER 814 /* Load Monitor Section Enable Register */ #define SPRN_PMC1 771 #define SPRN_PMC2 772 -- cgit v1.2.3 From cd26fca202f9a720d90e00ac2dbb7c4d0544f748 Mon Sep 17 00:00:00 2001 From: Andrey Smirnov Date: Tue, 21 Jun 2016 00:22:48 -0700 Subject: rtc: rtctest: Change alarm IRQ support detection For old style drivers, call a call to ioctl(..., RTC_ALM_SET, ...): - char/ds1302.c will always return -EINVAL - char/genrtc.c: will always return -EINVAL - char/rtc.c will succeed regardless if IRQs are supported or not - char/efirtc.c will always return -EINVAL - input/misc/hp_sdc_rtc.c ... that ioctl code is a good lesson about ifdefing code out and punting implementation ... and it will always return -EINVAL For new style rtc drivers, a call to ioctl(..., RTC_ALM_SET, ...) never results in a call to __rtc_set_alarm, since struct rtc_wkalarm passed to rtc_set_alarm has 'enabled' field set to 0. This means that rtc->ops->set_alarm driver hook is never called in that ioctl. Since no driver code interaction happens as a part of that call, using its results to ascertain properties of the driver is not going to work. To remedy this - use the result of RTC_AIE_ON to make the judgement. This patch also changes ENOTTY to EINVAL as an error code value that would tell us that IRQs are not supported. There are three reason for this: - As mentioned above old style driver never returns ENOTTY for this ioctl - In it's code __rtc_set_alarm() returns -EINVAL if rtc->ops->set_alarm method is not provided by the driver, so one reason for change is to be consistent with that code path. - A call to ioctl(..., RTC_UIE_ON, ...) will result in a call to rtc_update_irq_enable() and then __rtc_set_alarm(), which, if IRQs are not supported by the driver, will result in a non-zero error code. Returning ENOTTY in that case would: a) Not be consistent with other codepaths of rtc_update_irq_enable, for example the check of rtc->uie_unsupported b) Would break update IRQ emulation code since that codpath expects EINVAL c) Would break test's logic for feature support detection in the case of RTC_UIE_ON ioctl Signed-off-by: Andrey Smirnov Signed-off-by: Alexandre Belloni --- tools/testing/selftests/timers/rtctest.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) (limited to 'tools') diff --git a/tools/testing/selftests/timers/rtctest.c b/tools/testing/selftests/timers/rtctest.c index 624bce51b27d..0cb46285ccf4 100644 --- a/tools/testing/selftests/timers/rtctest.c +++ b/tools/testing/selftests/timers/rtctest.c @@ -144,11 +144,12 @@ test_READ: retval = ioctl(fd, RTC_ALM_SET, &rtc_tm); if (retval == -1) { - if (errno == ENOTTY) { + if (errno == EINVAL) { fprintf(stderr, "\n...Alarm IRQs not supported.\n"); goto test_PIE; } + perror("RTC_ALM_SET ioctl"); exit(errno); } @@ -166,6 +167,12 @@ test_READ: /* Enable alarm interrupts */ retval = ioctl(fd, RTC_AIE_ON, 0); if (retval == -1) { + if (errno == EINVAL) { + fprintf(stderr, + "\n...Alarm IRQs not supported.\n"); + goto test_PIE; + } + perror("RTC_AIE_ON ioctl"); exit(errno); } -- cgit v1.2.3 From 519efa98051717479ff3d0b6be996e112e7a87ff Mon Sep 17 00:00:00 2001 From: Andrey Smirnov Date: Tue, 21 Jun 2016 00:22:49 -0700 Subject: rtc: rtctest: Change no IRQ detection for RTC_IRQP_READ A call to ioctl(..., RTC_IRQP_READ, ...) should never result in ENOTTY. All new style RTC drivers implement it and all of the old style drivers return EINVAL when they don't support periodic IRQs. Signed-off-by: Andrey Smirnov Signed-off-by: Alexandre Belloni --- tools/testing/selftests/timers/rtctest.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'tools') diff --git a/tools/testing/selftests/timers/rtctest.c b/tools/testing/selftests/timers/rtctest.c index 0cb46285ccf4..97beadf548b0 100644 --- a/tools/testing/selftests/timers/rtctest.c +++ b/tools/testing/selftests/timers/rtctest.c @@ -200,7 +200,7 @@ test_PIE: retval = ioctl(fd, RTC_IRQP_READ, &tmp); if (retval == -1) { /* not all RTCs support periodic IRQs */ - if (errno == ENOTTY) { + if (errno == EINVAL) { fprintf(stderr, "\nNo periodic IRQ support\n"); goto done; } -- cgit v1.2.3 From 0a553cbabd369c52b921fced5e1a1ea3e60e0e0d Mon Sep 17 00:00:00 2001 From: Andrey Smirnov Date: Tue, 21 Jun 2016 00:22:50 -0700 Subject: rtc: rtctest: Change no IRQ detection for RTC_IRQP_SET A call to ioctl(..., RTC_IRQP_SET, ...) should never result in ENOTTY. All new style RTC drivers implement it and all of the old style drivers return EINVAL when they don't support periodic IRQs. Signed-off-by: Andrey Smirnov Signed-off-by: Alexandre Belloni --- tools/testing/selftests/timers/rtctest.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'tools') diff --git a/tools/testing/selftests/timers/rtctest.c b/tools/testing/selftests/timers/rtctest.c index 97beadf548b0..4230d3052e5d 100644 --- a/tools/testing/selftests/timers/rtctest.c +++ b/tools/testing/selftests/timers/rtctest.c @@ -218,7 +218,7 @@ test_PIE: retval = ioctl(fd, RTC_IRQP_SET, tmp); if (retval == -1) { /* not all RTCs can change their periodic IRQ rate */ - if (errno == ENOTTY) { + if (errno == EINVAL) { fprintf(stderr, "\n...Periodic IRQ rate is fixed\n"); goto done; -- cgit v1.2.3 From 3aefd1febd882a76e21ca8f61ade03b9c1a2c719 Mon Sep 17 00:00:00 2001 From: SeongJae Park Date: Sat, 18 Jun 2016 18:28:39 +0900 Subject: selftests/lib: set printf.sh executable Test for test_printf module fails always because the test program, printf.sh, has no execution permission. This commit adds execution permission to it. Signed-off-by: SeongJae Park Acked-by: Kees Cook Signed-off-by: Shuah Khan --- tools/testing/selftests/lib/printf.sh | 0 1 file changed, 0 insertions(+), 0 deletions(-) mode change 100644 => 100755 tools/testing/selftests/lib/printf.sh (limited to 'tools') diff --git a/tools/testing/selftests/lib/printf.sh b/tools/testing/selftests/lib/printf.sh old mode 100644 new mode 100755 -- cgit v1.2.3 From ee65735dd5acecbf335f9aa32e3b129a1de9e184 Mon Sep 17 00:00:00 2001 From: Yannick Brosseau Date: Mon, 20 Jun 2016 08:07:21 -0700 Subject: selftests/vm: write strlen length instead of sizeof to nr_hugepages When setting back the initial value to nr_hugepages, the test was writing a length sizeof of the string and checking that strlen was writen. Since those values are not the same, use strlen in both place instead. Also make the error messages more explicit to help in future debugging. Signed-off-by: Yannick Brosseau Signed-off-by: Shuah Khan --- tools/testing/selftests/vm/compaction_test.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'tools') diff --git a/tools/testing/selftests/vm/compaction_test.c b/tools/testing/selftests/vm/compaction_test.c index 932ff577ffc0..6d1437f895b8 100644 --- a/tools/testing/selftests/vm/compaction_test.c +++ b/tools/testing/selftests/vm/compaction_test.c @@ -101,7 +101,7 @@ int check_compaction(unsigned long mem_free, unsigned int hugepage_size) /* Start with the initial condition of 0 huge pages*/ if (write(fd, "0", sizeof(char)) != sizeof(char)) { - perror("Failed to write to /proc/sys/vm/nr_hugepages\n"); + perror("Failed to write 0 to /proc/sys/vm/nr_hugepages\n"); goto close_fd; } @@ -110,14 +110,14 @@ int check_compaction(unsigned long mem_free, unsigned int hugepage_size) /* Request a large number of huge pages. The Kernel will allocate as much as it can */ if (write(fd, "100000", (6*sizeof(char))) != (6*sizeof(char))) { - perror("Failed to write to /proc/sys/vm/nr_hugepages\n"); + perror("Failed to write 100000 to /proc/sys/vm/nr_hugepages\n"); goto close_fd; } lseek(fd, 0, SEEK_SET); if (read(fd, nr_hugepages, sizeof(nr_hugepages)) <= 0) { - perror("Failed to read from /proc/sys/vm/nr_hugepages\n"); + perror("Failed to re-read from /proc/sys/vm/nr_hugepages\n"); goto close_fd; } @@ -136,9 +136,9 @@ int check_compaction(unsigned long mem_free, unsigned int hugepage_size) printf("No of huge pages allocated = %d\n", (atoi(nr_hugepages))); - if (write(fd, initial_nr_hugepages, sizeof(initial_nr_hugepages)) + if (write(fd, initial_nr_hugepages, strlen(initial_nr_hugepages)) != strlen(initial_nr_hugepages)) { - perror("Failed to write to /proc/sys/vm/nr_hugepages\n"); + perror("Failed to write value to /proc/sys/vm/nr_hugepages\n"); goto close_fd; } -- cgit v1.2.3 From bff124682eaa784596672bdd344b9b0f646035a2 Mon Sep 17 00:00:00 2001 From: Yannick Brosseau Date: Mon, 20 Jun 2016 14:27:10 -0700 Subject: selftests/vm: Don't mlockall MCL_CURRENT in on-fault-limit test The default MEMLOCK limit is not big enough to accomodate all the current pages of the test program process, so the test fails at this step. By removing the MCL_CURRENT flag, we allow the mlockall call to succeed. The mmap is twice the size of the current limit, so it will still fail as expected. Signed-off-by: Yannick Brosseau Signed-off-by: Shuah Khan --- tools/testing/selftests/vm/on-fault-limit.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'tools') diff --git a/tools/testing/selftests/vm/on-fault-limit.c b/tools/testing/selftests/vm/on-fault-limit.c index 245acccce42d..0ae458f32fdb 100644 --- a/tools/testing/selftests/vm/on-fault-limit.c +++ b/tools/testing/selftests/vm/on-fault-limit.c @@ -20,7 +20,7 @@ static int test_limit(void) return ret; } - if (mlockall(MCL_CURRENT | MCL_ONFAULT | MCL_FUTURE)) { + if (mlockall(MCL_ONFAULT | MCL_FUTURE)) { perror("mlockall"); return ret; } -- cgit v1.2.3 From e9c0d44f5328ba844f7e037791b9cc72ee3ef964 Mon Sep 17 00:00:00 2001 From: Shuah Khan Date: Fri, 17 Jun 2016 18:05:05 -0600 Subject: selftests: media_device_test change it to randomize loop count Change it to randomize the loop count instead of hardcoded number of times ioctl is called. Signed-off-by: Shuah Khan --- .../testing/selftests/media_tests/media_device_test.c | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) (limited to 'tools') diff --git a/tools/testing/selftests/media_tests/media_device_test.c b/tools/testing/selftests/media_tests/media_device_test.c index cbf53a032ab5..5d49943e77d0 100644 --- a/tools/testing/selftests/media_tests/media_device_test.c +++ b/tools/testing/selftests/media_tests/media_device_test.c @@ -1,5 +1,5 @@ /* - * media_devkref_test.c - Media Controller Device Kref API Test + * media_device_test.c - Media Controller Device ioctl loop Test * * Copyright (c) 2016 Shuah Khan * Copyright (c) 2016 Samsung Electronics Co., Ltd. @@ -35,13 +35,14 @@ #include #include #include +#include #include int main(int argc, char **argv) { int opt; char media_device[256]; - int count = 0; + int count; struct media_device_info mdi; int ret; int fd; @@ -69,6 +70,10 @@ int main(int argc, char **argv) exit(-1); } + /* Generate random number of interations */ + srand((unsigned int) time(NULL)); + count = rand(); + /* Open Media device and keep it open */ fd = open(media_device, O_RDWR); if (fd == -1) { @@ -82,14 +87,16 @@ int main(int argc, char **argv) "other Oops in the dmesg. Enable KaSan kernel\n" "config option for use-after-free error detection.\n\n"); - while (count < 100) { + printf("Running test for %d iternations\n", count); + + while (count > 0) { ret = ioctl(fd, MEDIA_IOC_DEVICE_INFO, &mdi); if (ret < 0) printf("Media Device Info errno %s\n", strerror(errno)); else - printf("Media device model %s driver %s\n", - mdi.model, mdi.driver); + printf("Media device model %s driver %s - count %d\n", + mdi.model, mdi.driver, count); sleep(10); - count++; + count--; } } -- cgit v1.2.3 From b96da0fc54ffeca53dbab231ae845ad093785cc7 Mon Sep 17 00:00:00 2001 From: Shuah Khan Date: Fri, 17 Jun 2016 18:06:36 -0600 Subject: selftests: add media_device_open test Add a new media test to open, run ioctl, and close the media device file. Signed-off-by: Shuah Khan --- tools/testing/selftests/media_tests/Makefile | 4 +- .../selftests/media_tests/media_device_open.c | 81 ++++++++++++++++++++++ 2 files changed, 83 insertions(+), 2 deletions(-) create mode 100644 tools/testing/selftests/media_tests/media_device_open.c (limited to 'tools') diff --git a/tools/testing/selftests/media_tests/Makefile b/tools/testing/selftests/media_tests/Makefile index 7071bcc1d066..177256aa4e0a 100644 --- a/tools/testing/selftests/media_tests/Makefile +++ b/tools/testing/selftests/media_tests/Makefile @@ -1,7 +1,7 @@ -TEST_PROGS := media_device_test +TEST_PROGS := media_device_test media_device_open all: $(TEST_PROGS) include ../lib.mk clean: - rm -fr media_device_test + rm -fr media_device_test media_device_open diff --git a/tools/testing/selftests/media_tests/media_device_open.c b/tools/testing/selftests/media_tests/media_device_open.c new file mode 100644 index 000000000000..44343c091a20 --- /dev/null +++ b/tools/testing/selftests/media_tests/media_device_open.c @@ -0,0 +1,81 @@ +/* + * media_device_open.c - Media Controller Device Open Test + * + * Copyright (c) 2016 Shuah Khan + * Copyright (c) 2016 Samsung Electronics Co., Ltd. + * + * This file is released under the GPLv2. + */ + +/* + * This file adds a test for Media Controller API. + * This test should be run as root and should not be + * included in the Kselftest run. This test should be + * run when hardware and driver that makes use Media + * Controller API are present in the system. + * + * This test opens user specified Media Device and calls + * MEDIA_IOC_DEVICE_INFO ioctl, closes the file, and exits. + * + * Usage: + * sudo ./media_device_open -d /dev/mediaX + * + * Run this test is a loop and run bind/unbind on the driver. +*/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +int main(int argc, char **argv) +{ + int opt; + char media_device[256]; + int count = 0; + struct media_device_info mdi; + int ret; + int fd; + + if (argc < 2) { + printf("Usage: %s [-d ]\n", argv[0]); + exit(-1); + } + + /* Process arguments */ + while ((opt = getopt(argc, argv, "d:")) != -1) { + switch (opt) { + case 'd': + strncpy(media_device, optarg, sizeof(media_device) - 1); + media_device[sizeof(media_device)-1] = '\0'; + break; + default: + printf("Usage: %s [-d ]\n", argv[0]); + exit(-1); + } + } + + if (getuid() != 0) { + printf("Please run the test as root - Exiting.\n"); + exit(-1); + } + + /* Open Media device and keep it open */ + fd = open(media_device, O_RDWR); + if (fd == -1) { + printf("Media Device open errno %s\n", strerror(errno)); + exit(-1); + } + + ret = ioctl(fd, MEDIA_IOC_DEVICE_INFO, &mdi); + if (ret < 0) + printf("Media Device Info errno %s\n", strerror(errno)); + else + printf("Media device model %s driver %s\n", + mdi.model, mdi.driver); +} -- cgit v1.2.3 From fe8777a8a0a144dee2eb59d00664184f1e49db4a Mon Sep 17 00:00:00 2001 From: Shuah Khan Date: Fri, 17 Jun 2016 18:12:04 -0600 Subject: selftests: add media controller regression test scripts and document Add regression test scripts open_loop_test.sh, and bind_unbind_sample.sh. Also add regression_test.txt that describes the regression test procedure. Signed-off-by: Shuah Khan --- .../selftests/media_tests/bind_unbind_sample.sh | 12 ++++++ .../selftests/media_tests/open_loop_test.sh | 10 +++++ .../selftests/media_tests/regression_test.txt | 43 ++++++++++++++++++++++ 3 files changed, 65 insertions(+) create mode 100755 tools/testing/selftests/media_tests/bind_unbind_sample.sh create mode 100755 tools/testing/selftests/media_tests/open_loop_test.sh create mode 100644 tools/testing/selftests/media_tests/regression_test.txt (limited to 'tools') diff --git a/tools/testing/selftests/media_tests/bind_unbind_sample.sh b/tools/testing/selftests/media_tests/bind_unbind_sample.sh new file mode 100755 index 000000000000..9f362f10631a --- /dev/null +++ b/tools/testing/selftests/media_tests/bind_unbind_sample.sh @@ -0,0 +1,12 @@ +#!/bin/bash +# Find device number in /sys/bus/usb/drivers/drivername +# Edit this file to update the driver numer and name +# Example test for uvcvideo driver +#i=0 +# while :; do +# i=$((i+1)) +# echo 1-5:1.0 > /sys/bus/usb/drivers/uvcvideo/unbind; +# echo 1-5:1.0 > /sys/bus/usb/drivers/uvcvideo/bind; +# clear +# echo $i +#done diff --git a/tools/testing/selftests/media_tests/open_loop_test.sh b/tools/testing/selftests/media_tests/open_loop_test.sh new file mode 100755 index 000000000000..dcd3c17efc17 --- /dev/null +++ b/tools/testing/selftests/media_tests/open_loop_test.sh @@ -0,0 +1,10 @@ +#!/bin/bash + i=0 +file=/dev/media$1 + while :; do + echo $file + i=$((i+1)) + R=$(./media_device_open -d $file); + # clear + echo -e "Loop $i\n$R" + done diff --git a/tools/testing/selftests/media_tests/regression_test.txt b/tools/testing/selftests/media_tests/regression_test.txt new file mode 100644 index 000000000000..2627367681f7 --- /dev/null +++ b/tools/testing/selftests/media_tests/regression_test.txt @@ -0,0 +1,43 @@ +Testing for regressions in Media Controller API register, ioctl, syscall, +and unregister paths. There have a few problems that result in user-after +free on media_device, media_devnode, and cdev pointers when the driver is +unbound while ioctl is in progress. + +Test Procedure: + +Run bin/unbind loop while ioctls are in progress. +Run rmmod and modprobe. +Disconnect the device. + +Setup: + +Build media_device_test +cd tools/testing/selftests/media_tests +make + +Regressions test for cdev user-after free error on /dev/mediaX when driver +is unbound: + +Start media_device_test to regression test media devnode dynamic alloc +and cdev user-after-free fixes. This opens media dev files and sits in +a loop running media ioctl MEDIA_IOC_DEVICE_INFO command once every 10 +seconds. The idea is when device file goes away, media devnode and cdev +should stick around until this test exits. + +The test for a random number of iterations or until user kills it with a +sleep 10 in between the ioctl calls. + +sudo ./media_device_test -d /dev/mediaX + +Regression test for media_devnode unregister race with ioctl_syscall: + +Start 6 open_loop_test.sh tests with different /dev/mediaX files. When +device file goes away after unbind, device file name changes. Start the +test with possible device names. If we start with /dev/media0 for example, +after unbind, /dev/media1 or /dev/media2 could get created. The idea is +keep ioctls going while bind/unbind runs. + +Copy bind_unbind_sample.txt and make changes to specify the driver name +and number to run bind and unbind. Start the bind_unbind.sh + +Run dmesg looking for any user-after free errors or mutex lock errors. -- cgit v1.2.3 From cde07f453bedd529c9ab7d57535e45f7e90a5c83 Mon Sep 17 00:00:00 2001 From: Shuah Khan Date: Fri, 17 Jun 2016 18:17:15 -0600 Subject: selftests: media_tests - Add media_device_open to .gitignore Add media_device_open to .gitignore Signed-off-by: Shuah Khan --- tools/testing/selftests/media_tests/.gitignore | 1 + 1 file changed, 1 insertion(+) (limited to 'tools') diff --git a/tools/testing/selftests/media_tests/.gitignore b/tools/testing/selftests/media_tests/.gitignore index 1c0711708b98..faf5891fbc54 100644 --- a/tools/testing/selftests/media_tests/.gitignore +++ b/tools/testing/selftests/media_tests/.gitignore @@ -1 +1,2 @@ media_device_test +media_device_open -- cgit v1.2.3 From d4ecdff2ecdb5c01c46f2a6b1bf3f161279b330e Mon Sep 17 00:00:00 2001 From: Cyril Bur Date: Tue, 1 Mar 2016 15:26:36 +1100 Subject: selftests/powerpc/pmu: Use signed long to read perf_event_paranoid Excerpt from man 2 perf_event_open: /proc/sys/kernel/perf_event_paranoid The perf_event_paranoid file can be set to restrict access to the performance counters. 2 allow only user-space measurements. 1 allow both kernel and user measurements (default). 0 allow access to CPU-specific data but not raw tracepoint samples. -1 no restrictions. require_paranoia_below() should return 0 if perf_event_paranoid is below a specified level, the value from perf_event_paranoid is read into an unsigned long so the incorrect value is returned when perf_event_paranoid is set to -1. Without this patch applied there is the same number of selftests/powerpc which skip when /proc/sys/kernel/perf_event_paranoid is set to 1 or -1 but no skips when set to zero. With this patch applied there are no skipped selftests/powerpc test when /proc/sys/kernel/perf_event_paranoid is set to 0 or -1. Signed-off-by: Cyril Bur Signed-off-by: Michael Ellerman --- tools/testing/selftests/powerpc/pmu/lib.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'tools') diff --git a/tools/testing/selftests/powerpc/pmu/lib.c b/tools/testing/selftests/powerpc/pmu/lib.c index a361ad3334ce..8b992fa5b478 100644 --- a/tools/testing/selftests/powerpc/pmu/lib.c +++ b/tools/testing/selftests/powerpc/pmu/lib.c @@ -190,7 +190,7 @@ int parse_proc_maps(void) bool require_paranoia_below(int level) { - unsigned long current; + long current; char *end, buf[16]; FILE *f; int rc; @@ -208,7 +208,7 @@ bool require_paranoia_below(int level) goto out_close; } - current = strtoul(buf, &end, 10); + current = strtol(buf, &end, 10); if (end == buf) { printf("Couldn't parse " PARANOID_PATH "?\n"); @@ -216,7 +216,7 @@ bool require_paranoia_below(int level) } if (current >= level) - goto out; + goto out_close; rc = 0; out_close: -- cgit v1.2.3 From 94fa56a96a39914551694673fdb483b8924b0e56 Mon Sep 17 00:00:00 2001 From: Cyril Bur Date: Fri, 4 Mar 2016 10:06:39 +1100 Subject: selftests/powerpc: Fix usage message in context_switch When we inverted the behaviour of the flags we forgot to update the usage message. Fixes: 51c21e72eb99 ("selftests/powerpc: Make context_switch touch FP/altivec/vector by default") Signed-off-by: Cyril Bur Signed-off-by: Michael Ellerman --- tools/testing/selftests/powerpc/benchmarks/context_switch.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'tools') diff --git a/tools/testing/selftests/powerpc/benchmarks/context_switch.c b/tools/testing/selftests/powerpc/benchmarks/context_switch.c index 7b785941adec..e6af382a305a 100644 --- a/tools/testing/selftests/powerpc/benchmarks/context_switch.c +++ b/tools/testing/selftests/powerpc/benchmarks/context_switch.c @@ -369,11 +369,11 @@ static void usage(void) fprintf(stderr, "\t\t--process\tUse processes (default threads)\n"); fprintf(stderr, "\t\t--timeout=X\tDuration in seconds to run (default 30)\n"); fprintf(stderr, "\t\t--vdso\t\ttouch VDSO\n"); - fprintf(stderr, "\t\t--fp\t\ttouch FP\n"); + fprintf(stderr, "\t\t--no-fp\t\tDon't touch FP\n"); #ifdef __powerpc__ - fprintf(stderr, "\t\t--altivec\ttouch altivec\n"); + fprintf(stderr, "\t\t--no-altivec\tDon't touch altivec\n"); #endif - fprintf(stderr, "\t\t--vector\ttouch vector\n"); + fprintf(stderr, "\t\t--no-vector\tDon't touch vector\n"); } int main(int argc, char *argv[]) -- cgit v1.2.3 From f2418ae8a81760b4dec8d5e3e7f1faf45c422e9d Mon Sep 17 00:00:00 2001 From: Cyril Bur Date: Fri, 4 Mar 2016 10:06:40 +1100 Subject: selftests/powerpc: Fix generation of vector instructions/types in context_switch Currently it doesn't appear the resulting binary actually uses any Altivec or VSX instructions the solution is to explicitly tell GCC to use vector instructions and use vector types in the code. Part of this this issue can be GCC version specific: GCC 4.9.x is happy to use Altivec and VSX instructions if altivec.h is includedi (and possibly if vector types are used), this also means that 4.9.x will use VSX instructions even if only -maltivec is passed. It is also possible that Altivec instructions will be used even without -maltivec or -mabi=altivec. GCC 5.2.x complains about the lack of -maltivec parameter if altivec.h is included and will not use VSX unless -mvsx is present on commandline. GCC 5.3.0 has a regression that means __attribute__((__target__("no-vsx")) fails to build. A fix is targeted for 5.4. Furthermore LTO (Link Time Optimisation) doesn't play well with __attribute__((__target__("no-vsx")), LTO can cause GCC to forget about the attribute and compile with VSX instructions regardless. Be wary when enabling -flfo for this test. Signed-off-by: Cyril Bur Signed-off-by: Michael Ellerman --- tools/testing/selftests/powerpc/benchmarks/Makefile | 1 + tools/testing/selftests/powerpc/benchmarks/context_switch.c | 11 ++++++++--- 2 files changed, 9 insertions(+), 3 deletions(-) (limited to 'tools') diff --git a/tools/testing/selftests/powerpc/benchmarks/Makefile b/tools/testing/selftests/powerpc/benchmarks/Makefile index 912445ff7ce7..6816fc2140cb 100644 --- a/tools/testing/selftests/powerpc/benchmarks/Makefile +++ b/tools/testing/selftests/powerpc/benchmarks/Makefile @@ -7,6 +7,7 @@ all: $(TEST_PROGS) $(TEST_PROGS): ../harness.c context_switch: ../utils.c +context_switch: CFLAGS += -maltivec -mvsx -mabi=altivec context_switch: LDLIBS += -lpthread include ../../lib.mk diff --git a/tools/testing/selftests/powerpc/benchmarks/context_switch.c b/tools/testing/selftests/powerpc/benchmarks/context_switch.c index e6af382a305a..a36883ad48a4 100644 --- a/tools/testing/selftests/powerpc/benchmarks/context_switch.c +++ b/tools/testing/selftests/powerpc/benchmarks/context_switch.c @@ -25,7 +25,9 @@ #include #include #include - +#ifdef __powerpc__ +#include +#endif #include "../utils.h" static unsigned int timeout = 30; @@ -37,12 +39,15 @@ static int touch_fp = 1; double fp; static int touch_vector = 1; -typedef int v4si __attribute__ ((vector_size (16))); -v4si a, b, c; +vector int a, b, c; #ifdef __powerpc__ static int touch_altivec = 1; +/* + * Note: LTO (Link Time Optimisation) doesn't play well with this function + * attribute. Be very careful enabling LTO for this test. + */ static void __attribute__((__target__("no-vsx"))) altivec_touch_fn(void) { c = a + b; -- cgit v1.2.3 From 0c63e8b7b97fb72ef38c8edbfbe751d3602e03a1 Mon Sep 17 00:00:00 2001 From: Michael Ellerman Date: Thu, 2 Jun 2016 22:02:01 +1000 Subject: selftests/powerpc: Import Anton's mmap & futex micro benchmarks These are useful little loops for smoke testing performance. Signed-off-by: Anton Blanchard Signed-off-by: Michael Ellerman --- .../selftests/powerpc/benchmarks/.gitignore | 2 ++ .../testing/selftests/powerpc/benchmarks/Makefile | 2 +- .../selftests/powerpc/benchmarks/futex_bench.c | 42 ++++++++++++++++++++++ .../selftests/powerpc/benchmarks/mmap_bench.c | 41 +++++++++++++++++++++ 4 files changed, 86 insertions(+), 1 deletion(-) create mode 100644 tools/testing/selftests/powerpc/benchmarks/futex_bench.c create mode 100644 tools/testing/selftests/powerpc/benchmarks/mmap_bench.c (limited to 'tools') diff --git a/tools/testing/selftests/powerpc/benchmarks/.gitignore b/tools/testing/selftests/powerpc/benchmarks/.gitignore index 6fa673316ac2..bce49ebd869e 100644 --- a/tools/testing/selftests/powerpc/benchmarks/.gitignore +++ b/tools/testing/selftests/powerpc/benchmarks/.gitignore @@ -1,2 +1,4 @@ gettimeofday context_switch +mmap_bench +futex_bench \ No newline at end of file diff --git a/tools/testing/selftests/powerpc/benchmarks/Makefile b/tools/testing/selftests/powerpc/benchmarks/Makefile index 6816fc2140cb..a9adfb7de78f 100644 --- a/tools/testing/selftests/powerpc/benchmarks/Makefile +++ b/tools/testing/selftests/powerpc/benchmarks/Makefile @@ -1,4 +1,4 @@ -TEST_PROGS := gettimeofday context_switch +TEST_PROGS := gettimeofday context_switch mmap_bench futex_bench CFLAGS += -O2 diff --git a/tools/testing/selftests/powerpc/benchmarks/futex_bench.c b/tools/testing/selftests/powerpc/benchmarks/futex_bench.c new file mode 100644 index 000000000000..2fc711d9150d --- /dev/null +++ b/tools/testing/selftests/powerpc/benchmarks/futex_bench.c @@ -0,0 +1,42 @@ +/* + * Copyright 2016, Anton Blanchard, Michael Ellerman, IBM Corp. + * Licensed under GPLv2. + */ + +#define _GNU_SOURCE + +#include +#include +#include +#include +#include + +#include "utils.h" + +#define ITERATIONS 100000000 + +#define futex(A, B, C, D, E, F) syscall(__NR_futex, A, B, C, D, E, F) + +int test_futex(void) +{ + struct timespec ts_start, ts_end; + unsigned long i = ITERATIONS; + + clock_gettime(CLOCK_MONOTONIC, &ts_start); + + while (i--) { + unsigned int addr = 0; + futex(&addr, FUTEX_WAKE, 1, NULL, NULL, 0); + } + + clock_gettime(CLOCK_MONOTONIC, &ts_end); + + printf("time = %.6f\n", ts_end.tv_sec - ts_start.tv_sec + (ts_end.tv_nsec - ts_start.tv_nsec) / 1e9); + + return 0; +} + +int main(void) +{ + return test_harness(test_futex, "futex_bench"); +} diff --git a/tools/testing/selftests/powerpc/benchmarks/mmap_bench.c b/tools/testing/selftests/powerpc/benchmarks/mmap_bench.c new file mode 100644 index 000000000000..8d084a2d6e74 --- /dev/null +++ b/tools/testing/selftests/powerpc/benchmarks/mmap_bench.c @@ -0,0 +1,41 @@ +/* + * Copyright 2016, Anton Blanchard, Michael Ellerman, IBM Corp. + * Licensed under GPLv2. + */ + +#include +#include +#include +#include + +#include "utils.h" + +#define ITERATIONS 5000000 + +#define MEMSIZE (128 * 1024 * 1024) + +int test_mmap(void) +{ + struct timespec ts_start, ts_end; + unsigned long i = ITERATIONS; + + clock_gettime(CLOCK_MONOTONIC, &ts_start); + + while (i--) { + char *c = mmap(NULL, MEMSIZE, PROT_READ|PROT_WRITE, + MAP_PRIVATE|MAP_ANONYMOUS, -1, 0); + FAIL_IF(c == MAP_FAILED); + munmap(c, MEMSIZE); + } + + clock_gettime(CLOCK_MONOTONIC, &ts_end); + + printf("time = %.6f\n", ts_end.tv_sec - ts_start.tv_sec + (ts_end.tv_nsec - ts_start.tv_nsec) / 1e9); + + return 0; +} + +int main(void) +{ + return test_harness(test_mmap, "mmap_bench"); +} -- cgit v1.2.3 From 4375088072295b09cc5d9bf7a8cd2333b608492a Mon Sep 17 00:00:00 2001 From: Chris Smart Date: Fri, 17 Jun 2016 09:34:47 +1000 Subject: selftests/powerpc: Test unaligned copy and paste Test that an ISA 3.0 compliant machine performing an unaligned copy, copy_first, paste or paste_last is sent a SIGBUS. Signed-off-by: Chris Smart Signed-off-by: Michael Ellerman --- tools/testing/selftests/powerpc/Makefile | 3 +- .../testing/selftests/powerpc/alignment/.gitignore | 5 ++ tools/testing/selftests/powerpc/alignment/Makefile | 10 ++++ .../powerpc/alignment/copy_first_unaligned.c | 41 +++++++++++++ .../alignment/copy_paste_unaligned_common.c | 53 +++++++++++++++++ .../alignment/copy_paste_unaligned_common.h | 26 +++++++++ .../selftests/powerpc/alignment/copy_unaligned.c | 41 +++++++++++++ .../powerpc/alignment/paste_last_unaligned.c | 43 ++++++++++++++ .../selftests/powerpc/alignment/paste_unaligned.c | 43 ++++++++++++++ tools/testing/selftests/powerpc/instructions.h | 68 ++++++++++++++++++++++ 10 files changed, 332 insertions(+), 1 deletion(-) create mode 100644 tools/testing/selftests/powerpc/alignment/.gitignore create mode 100644 tools/testing/selftests/powerpc/alignment/Makefile create mode 100644 tools/testing/selftests/powerpc/alignment/copy_first_unaligned.c create mode 100644 tools/testing/selftests/powerpc/alignment/copy_paste_unaligned_common.c create mode 100644 tools/testing/selftests/powerpc/alignment/copy_paste_unaligned_common.h create mode 100644 tools/testing/selftests/powerpc/alignment/copy_unaligned.c create mode 100644 tools/testing/selftests/powerpc/alignment/paste_last_unaligned.c create mode 100644 tools/testing/selftests/powerpc/alignment/paste_unaligned.c create mode 100644 tools/testing/selftests/powerpc/instructions.h (limited to 'tools') diff --git a/tools/testing/selftests/powerpc/Makefile b/tools/testing/selftests/powerpc/Makefile index 4ca83fe80654..3c40c9d0e6c7 100644 --- a/tools/testing/selftests/powerpc/Makefile +++ b/tools/testing/selftests/powerpc/Makefile @@ -12,7 +12,8 @@ CFLAGS := -Wall -O2 -Wall -Werror -DGIT_VERSION='"$(GIT_VERSION)"' -I$(CURDIR) $ export CFLAGS -SUB_DIRS = benchmarks \ +SUB_DIRS = alignment \ + benchmarks \ copyloops \ context_switch \ dscr \ diff --git a/tools/testing/selftests/powerpc/alignment/.gitignore b/tools/testing/selftests/powerpc/alignment/.gitignore new file mode 100644 index 000000000000..1d980e3d7039 --- /dev/null +++ b/tools/testing/selftests/powerpc/alignment/.gitignore @@ -0,0 +1,5 @@ +copy_unaligned +copy_first_unaligned +paste_unaligned +paste_last_unaligned +copy_paste_unaligned_common diff --git a/tools/testing/selftests/powerpc/alignment/Makefile b/tools/testing/selftests/powerpc/alignment/Makefile new file mode 100644 index 000000000000..ad6a4e49da91 --- /dev/null +++ b/tools/testing/selftests/powerpc/alignment/Makefile @@ -0,0 +1,10 @@ +TEST_PROGS := copy_unaligned copy_first_unaligned paste_unaligned paste_last_unaligned + +all: $(TEST_PROGS) + +$(TEST_PROGS): ../harness.c ../utils.c copy_paste_unaligned_common.c + +include ../../lib.mk + +clean: + rm -f $(TEST_PROGS) diff --git a/tools/testing/selftests/powerpc/alignment/copy_first_unaligned.c b/tools/testing/selftests/powerpc/alignment/copy_first_unaligned.c new file mode 100644 index 000000000000..47b73b3a08bd --- /dev/null +++ b/tools/testing/selftests/powerpc/alignment/copy_first_unaligned.c @@ -0,0 +1,41 @@ +/* + * Copyright 2016, Chris Smart, IBM Corporation. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version + * 2 of the License, or (at your option) any later version. + * + * Calls to copy_first which are not 128-byte aligned should be + * caught and sent a SIGBUS. + * + */ + +#include +#include +#include "utils.h" +#include "instructions.h" +#include "copy_paste_unaligned_common.h" + +unsigned int expected_instruction = PPC_INST_COPY_FIRST; +unsigned int instruction_mask = 0xfc2007fe; + +int test_copy_first_unaligned(void) +{ + /* Only run this test on a P9 or later */ + SKIP_IF(!have_hwcap2(PPC_FEATURE2_ARCH_3_00)); + + /* Register our signal handler with SIGBUS */ + setup_signal_handler(); + + /* +1 makes buf unaligned */ + copy_first(cacheline_buf+1); + + /* We should not get here */ + return 1; +} + +int main(int argc, char *argv[]) +{ + return test_harness(test_copy_first_unaligned, "test_copy_first_unaligned"); +} diff --git a/tools/testing/selftests/powerpc/alignment/copy_paste_unaligned_common.c b/tools/testing/selftests/powerpc/alignment/copy_paste_unaligned_common.c new file mode 100644 index 000000000000..d35fa5f5d2d3 --- /dev/null +++ b/tools/testing/selftests/powerpc/alignment/copy_paste_unaligned_common.c @@ -0,0 +1,53 @@ +/* + * Copyright 2016, Chris Smart, IBM Corporation. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version + * 2 of the License, or (at your option) any later version. + * + * Common code for copy, copy_first, paste and paste_last unaligned + * tests. + * + */ + +#include +#include +#include +#include "utils.h" +#include "instructions.h" +#include "copy_paste_unaligned_common.h" + +unsigned int expected_instruction; +unsigned int instruction_mask; + +char cacheline_buf[128] __cacheline_aligned; + +void signal_action_handler(int signal_num, siginfo_t *info, void *ptr) +{ + ucontext_t *ctx = ptr; +#if defined(__powerpc64__) + unsigned int *pc = (unsigned int *)ctx->uc_mcontext.gp_regs[PT_NIP]; +#else + unsigned int *pc = (unsigned int *)ctx->uc_mcontext.uc_regs->gregs[PT_NIP]; +#endif + + /* + * Check that the signal was on the correct instruction, using a + * mask because the compiler assigns the register at RB. + */ + if ((*pc & instruction_mask) == expected_instruction) + _exit(0); /* We hit the right instruction */ + + _exit(1); +} + +void setup_signal_handler(void) +{ + struct sigaction signal_action; + + memset(&signal_action, 0, sizeof(signal_action)); + signal_action.sa_sigaction = signal_action_handler; + signal_action.sa_flags = SA_SIGINFO; + sigaction(SIGBUS, &signal_action, NULL); +} diff --git a/tools/testing/selftests/powerpc/alignment/copy_paste_unaligned_common.h b/tools/testing/selftests/powerpc/alignment/copy_paste_unaligned_common.h new file mode 100644 index 000000000000..053899fe506e --- /dev/null +++ b/tools/testing/selftests/powerpc/alignment/copy_paste_unaligned_common.h @@ -0,0 +1,26 @@ +/* + * Copyright 2016, Chris Smart, IBM Corporation. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version + * 2 of the License, or (at your option) any later version. + * + * Declarations for common code for copy, copy_first, paste and + * paste_last unaligned tests. + * + */ + +#ifndef _SELFTESTS_POWERPC_COPY_PASTE_H +#define _SELFTESTS_POWERPC_COPY_PASTE_H + +#include + +int main(int argc, char *argv[]); +void signal_action_handler(int signal_num, siginfo_t *info, void *ptr); +void setup_signal_handler(void); +extern char cacheline_buf[128] __cacheline_aligned; +extern unsigned int expected_instruction; +extern unsigned int instruction_mask; + +#endif /* _SELFTESTS_POWERPC_COPY_PASTE_H */ diff --git a/tools/testing/selftests/powerpc/alignment/copy_unaligned.c b/tools/testing/selftests/powerpc/alignment/copy_unaligned.c new file mode 100644 index 000000000000..3a4e26461554 --- /dev/null +++ b/tools/testing/selftests/powerpc/alignment/copy_unaligned.c @@ -0,0 +1,41 @@ +/* + * Copyright 2016, Chris Smart, IBM Corporation. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version + * 2 of the License, or (at your option) any later version. + * + * Calls to copy which are not 128-byte aligned should be caught + * and sent a SIGBUS. + * + */ + +#include +#include +#include "utils.h" +#include "instructions.h" +#include "copy_paste_unaligned_common.h" + +unsigned int expected_instruction = PPC_INST_COPY; +unsigned int instruction_mask = 0xfc0007fe; + +int test_copy_unaligned(void) +{ + /* Only run this test on a P9 or later */ + SKIP_IF(!have_hwcap2(PPC_FEATURE2_ARCH_3_00)); + + /* Register our signal handler with SIGBUS */ + setup_signal_handler(); + + /* +1 makes buf unaligned */ + copy(cacheline_buf+1); + + /* We should not get here */ + return 1; +} + +int main(int argc, char *argv[]) +{ + return test_harness(test_copy_unaligned, "test_copy_unaligned"); +} diff --git a/tools/testing/selftests/powerpc/alignment/paste_last_unaligned.c b/tools/testing/selftests/powerpc/alignment/paste_last_unaligned.c new file mode 100644 index 000000000000..6e0ad045fcc3 --- /dev/null +++ b/tools/testing/selftests/powerpc/alignment/paste_last_unaligned.c @@ -0,0 +1,43 @@ +/* + * Copyright 2016, Chris Smart, IBM Corporation. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version + * 2 of the License, or (at your option) any later version. + * + * Calls to paste_last which are not 128-byte aligned should be + * caught and sent a SIGBUS. + * + */ + +#include +#include +#include "utils.h" +#include "instructions.h" +#include "copy_paste_unaligned_common.h" + +unsigned int expected_instruction = PPC_INST_PASTE_LAST; +unsigned int instruction_mask = 0xfc2007ff; + +int test_paste_last_unaligned(void) +{ + /* Only run this test on a P9 or later */ + SKIP_IF(!have_hwcap2(PPC_FEATURE2_ARCH_3_00)); + + /* Register our signal handler with SIGBUS */ + setup_signal_handler(); + + copy(cacheline_buf); + + /* +1 makes buf unaligned */ + paste_last(cacheline_buf+1); + + /* We should not get here */ + return 1; +} + +int main(int argc, char *argv[]) +{ + return test_harness(test_paste_last_unaligned, "test_paste_last_unaligned"); +} diff --git a/tools/testing/selftests/powerpc/alignment/paste_unaligned.c b/tools/testing/selftests/powerpc/alignment/paste_unaligned.c new file mode 100644 index 000000000000..6f982b45e4bd --- /dev/null +++ b/tools/testing/selftests/powerpc/alignment/paste_unaligned.c @@ -0,0 +1,43 @@ +/* + * Copyright 2016, Chris Smart, IBM Corporation. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version + * 2 of the License, or (at your option) any later version. + * + * Calls to paste which are not 128-byte aligned should be caught + * and sent a SIGBUS. + * + */ + +#include +#include +#include "utils.h" +#include "instructions.h" +#include "copy_paste_unaligned_common.h" + +unsigned int expected_instruction = PPC_INST_PASTE; +unsigned int instruction_mask = 0xfc0007fe; + +int test_paste_unaligned(void) +{ + /* Only run this test on a P9 or later */ + SKIP_IF(!have_hwcap2(PPC_FEATURE2_ARCH_3_00)); + + /* Register our signal handler with SIGBUS */ + setup_signal_handler(); + + copy(cacheline_buf); + + /* +1 makes buf unaligned */ + paste(cacheline_buf+1); + + /* We should not get here */ + return 1; +} + +int main(int argc, char *argv[]) +{ + return test_harness(test_paste_unaligned, "test_paste_unaligned"); +} diff --git a/tools/testing/selftests/powerpc/instructions.h b/tools/testing/selftests/powerpc/instructions.h new file mode 100644 index 000000000000..0fb0bd3b28c9 --- /dev/null +++ b/tools/testing/selftests/powerpc/instructions.h @@ -0,0 +1,68 @@ +#ifndef _SELFTESTS_POWERPC_INSTRUCTIONS_H +#define _SELFTESTS_POWERPC_INSTRUCTIONS_H + +#include +#include + +/* This defines the "copy" instruction from Power ISA 3.0 Book II, section 4.4. */ +#define __COPY(RA, RB, L) \ + (0x7c00060c | (RA) << (31-15) | (RB) << (31-20) | (L) << (31-10)) +#define COPY(RA, RB, L) \ + .long __COPY((RA), (RB), (L)) + +static inline void copy(void *i) +{ + asm volatile(str(COPY(0, %0, 0))";" + : + : "b" (i) + : "memory" + ); +} + +static inline void copy_first(void *i) +{ + asm volatile(str(COPY(0, %0, 1))";" + : + : "b" (i) + : "memory" + ); +} + +/* This defines the "paste" instruction from Power ISA 3.0 Book II, section 4.4. */ +#define __PASTE(RA, RB, L, RC) \ + (0x7c00070c | (RA) << (31-15) | (RB) << (31-20) | (L) << (31-10) | (RC) << (31-31)) +#define PASTE(RA, RB, L, RC) \ + .long __PASTE((RA), (RB), (L), (RC)) + +static inline int paste(void *i) +{ + int cr; + + asm volatile(str(PASTE(0, %1, 0, 0))";" + "mfcr %0;" + : "=r" (cr) + : "b" (i) + : "memory" + ); + return cr; +} + +static inline int paste_last(void *i) +{ + int cr; + + asm volatile(str(PASTE(0, %1, 1, 1))";" + "mfcr %0;" + : "=r" (cr) + : "b" (i) + : "memory" + ); + return cr; +} + +#define PPC_INST_COPY __COPY(0, 0, 0) +#define PPC_INST_COPY_FIRST __COPY(0, 0, 1) +#define PPC_INST_PASTE __PASTE(0, 0, 0, 0) +#define PPC_INST_PASTE_LAST __PASTE(0, 0, 1, 1) + +#endif /* _SELFTESTS_POWERPC_INSTRUCTIONS_H */ -- cgit v1.2.3 From bc5c0a0d7fa94777acb9e8857177d9e4586df12f Mon Sep 17 00:00:00 2001 From: Michael Ellerman Date: Wed, 6 Jul 2016 15:17:34 +1000 Subject: selftests/powerpc: Use "Delta" rather than "Error" in normal output Use "Delta" to refer to the difference between measurements, rather than "Error", so scripts that look for "Error" aren't confused into thinking there was a failure. Signed-off-by: Michael Ellerman --- tools/testing/selftests/powerpc/pmu/ebb/instruction_count_test.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'tools') diff --git a/tools/testing/selftests/powerpc/pmu/ebb/instruction_count_test.c b/tools/testing/selftests/powerpc/pmu/ebb/instruction_count_test.c index 5da355135df2..ae9a79086111 100644 --- a/tools/testing/selftests/powerpc/pmu/ebb/instruction_count_test.c +++ b/tools/testing/selftests/powerpc/pmu/ebb/instruction_count_test.c @@ -51,7 +51,7 @@ static int do_count_loop(struct event *event, uint64_t instructions, printf("Looped for %lu instructions, overhead %lu\n", instructions, overhead); printf("Expected %lu\n", expected); printf("Actual %llu\n", event->result.value); - printf("Error %ld, %f%%\n", difference, percentage); + printf("Delta %ld, %f%%\n", difference, percentage); printf("Took %d EBBs\n", ebb_state.stats.ebb_count); } -- cgit v1.2.3 From 24af8c5a52a70bbfd275f59836feadd9b9ebc83b Mon Sep 17 00:00:00 2001 From: Michael Ellerman Date: Mon, 11 Jul 2016 15:25:18 +1000 Subject: selftests/powerpc: Add a test for PROT_SAO PROT_SAO is a powerpc-specific flag to mmap(), and we rely on arch specific logic to allow it to be passed to mmap(). Add a small test to ensure mmap() accepts PROT_SAO. We don't have a good way to test that it actually causes the mapping to be created with the right flags, so for now we just touch the mapping so it's faulted in. In future we might be able to do something better. Signed-off-by: Michael Ellerman --- tools/testing/selftests/powerpc/mm/.gitignore | 1 + tools/testing/selftests/powerpc/mm/Makefile | 4 ++- tools/testing/selftests/powerpc/mm/prot_sao.c | 42 +++++++++++++++++++++++++++ tools/testing/selftests/powerpc/utils.h | 5 ++++ 4 files changed, 51 insertions(+), 1 deletion(-) create mode 100644 tools/testing/selftests/powerpc/mm/prot_sao.c (limited to 'tools') diff --git a/tools/testing/selftests/powerpc/mm/.gitignore b/tools/testing/selftests/powerpc/mm/.gitignore index b43ade0ec861..e715a3f2fbf4 100644 --- a/tools/testing/selftests/powerpc/mm/.gitignore +++ b/tools/testing/selftests/powerpc/mm/.gitignore @@ -1,3 +1,4 @@ hugetlb_vs_thp_test subpage_prot tempfile +prot_sao \ No newline at end of file diff --git a/tools/testing/selftests/powerpc/mm/Makefile b/tools/testing/selftests/powerpc/mm/Makefile index ee179e22308c..3bdb96eae558 100644 --- a/tools/testing/selftests/powerpc/mm/Makefile +++ b/tools/testing/selftests/powerpc/mm/Makefile @@ -1,13 +1,15 @@ noarg: $(MAKE) -C ../ -TEST_PROGS := hugetlb_vs_thp_test subpage_prot +TEST_PROGS := hugetlb_vs_thp_test subpage_prot prot_sao TEST_FILES := tempfile all: $(TEST_PROGS) $(TEST_FILES) $(TEST_PROGS): ../harness.c +prot_sao: ../utils.c + include ../../lib.mk tempfile: diff --git a/tools/testing/selftests/powerpc/mm/prot_sao.c b/tools/testing/selftests/powerpc/mm/prot_sao.c new file mode 100644 index 000000000000..611530d43fa9 --- /dev/null +++ b/tools/testing/selftests/powerpc/mm/prot_sao.c @@ -0,0 +1,42 @@ +/* + * Copyright 2016, Michael Ellerman, IBM Corp. + * Licensed under GPLv2. + */ + +#include +#include +#include +#include + +#include + +#include "utils.h" + +#define SIZE (64 * 1024) + +int test_prot_sao(void) +{ + char *p; + + /* 2.06 or later should support SAO */ + SKIP_IF(!have_hwcap(PPC_FEATURE_ARCH_2_06)); + + /* + * Ensure we can ask for PROT_SAO. + * We can't really verify that it does the right thing, but at least we + * confirm the kernel will accept it. + */ + p = mmap(NULL, SIZE, PROT_READ | PROT_WRITE | PROT_SAO, + MAP_ANONYMOUS | MAP_PRIVATE, -1, 0); + FAIL_IF(p == MAP_FAILED); + + /* Write to the mapping, to at least cause a fault */ + memset(p, 0xaa, SIZE); + + return 0; +} + +int main(void) +{ + return test_harness(test_prot_sao, "prot-sao"); +} diff --git a/tools/testing/selftests/powerpc/utils.h b/tools/testing/selftests/powerpc/utils.h index a985cfaa535e..fbd33e52ef8f 100644 --- a/tools/testing/selftests/powerpc/utils.h +++ b/tools/testing/selftests/powerpc/utils.h @@ -27,6 +27,11 @@ int test_harness(int (test_function)(void), char *name); extern void *get_auxv_entry(int type); int pick_online_cpu(void); +static inline bool have_hwcap(unsigned long ftr) +{ + return ((unsigned long)get_auxv_entry(AT_HWCAP) & ftr) == ftr; +} + static inline bool have_hwcap2(unsigned long ftr2) { return ((unsigned long)get_auxv_entry(AT_HWCAP2) & ftr2) == ftr2; -- cgit v1.2.3 From a431b946db581d6a121d035a887d370cdc4b8dea Mon Sep 17 00:00:00 2001 From: Cyril Bur Date: Wed, 29 Jun 2016 21:41:51 +1000 Subject: selftests/powerpc: exec() with suspended transaction Perform an exec() class syscall with a suspended transaction. This is a test for the bug we fixed in 8e96a87c5431 ("powerpc/tm: Always reclaim in start_thread() for exec() class syscalls"). Signed-off-by: Cyril Bur [mpe: Fix build errors, use a single binary for the test] Signed-off-by: Michael Ellerman --- tools/testing/selftests/powerpc/tm/.gitignore | 1 + tools/testing/selftests/powerpc/tm/Makefile | 7 ++- tools/testing/selftests/powerpc/tm/tm-exec.c | 70 +++++++++++++++++++++++++ tools/testing/selftests/powerpc/tm/tm-syscall.c | 15 ------ tools/testing/selftests/powerpc/tm/tm.h | 23 +++++++- 5 files changed, 98 insertions(+), 18 deletions(-) create mode 100644 tools/testing/selftests/powerpc/tm/tm-exec.c (limited to 'tools') diff --git a/tools/testing/selftests/powerpc/tm/.gitignore b/tools/testing/selftests/powerpc/tm/.gitignore index bb942db845bf..82c0a9ce6e74 100644 --- a/tools/testing/selftests/powerpc/tm/.gitignore +++ b/tools/testing/selftests/powerpc/tm/.gitignore @@ -6,3 +6,4 @@ tm-vmxcopy tm-fork tm-tar tm-tmspr +tm-exec diff --git a/tools/testing/selftests/powerpc/tm/Makefile b/tools/testing/selftests/powerpc/tm/Makefile index d0505dbd22d5..9d301d785d9e 100644 --- a/tools/testing/selftests/powerpc/tm/Makefile +++ b/tools/testing/selftests/powerpc/tm/Makefile @@ -1,11 +1,14 @@ -TEST_PROGS := tm-resched-dscr tm-syscall tm-signal-msr-resv tm-signal-stack tm-vmxcopy tm-fork tm-tar tm-tmspr +TEST_PROGS := tm-resched-dscr tm-syscall tm-signal-msr-resv tm-signal-stack \ + tm-vmxcopy tm-fork tm-tar tm-tmspr tm-exec tm-execed all: $(TEST_PROGS) $(TEST_PROGS): ../harness.c ../utils.c +CFLAGS += -mhtm + tm-syscall: tm-syscall-asm.S -tm-syscall: CFLAGS += -mhtm -I../../../../../usr/include +tm-syscall: CFLAGS += -I../../../../../usr/include tm-tmspr: CFLAGS += -pthread include ../../lib.mk diff --git a/tools/testing/selftests/powerpc/tm/tm-exec.c b/tools/testing/selftests/powerpc/tm/tm-exec.c new file mode 100644 index 000000000000..3d27fa0ece04 --- /dev/null +++ b/tools/testing/selftests/powerpc/tm/tm-exec.c @@ -0,0 +1,70 @@ +/* + * Copyright 2016, Cyril Bur, IBM Corp. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version + * 2 of the License, or (at your option) any later version. + * + * Syscalls can be performed provided the transactions are suspended. + * The exec() class of syscall is unique as a new process is loaded. + * + * It makes little sense for after an exec() call for the previously + * suspended transaction to still exist. + */ + +#define _GNU_SOURCE +#include +#include +#include +#include +#include +#include +#include +#include + +#include "utils.h" +#include "tm.h" + +static char *path; + +static int test_exec(void) +{ + SKIP_IF(!have_htm()); + + asm __volatile__( + "tbegin.;" + "blt 1f; " + "tsuspend.;" + "1: ;" + : : : "memory"); + + execl(path, "tm-exec", "--child", NULL); + + /* Shouldn't get here */ + perror("execl() failed"); + return 1; +} + +static int after_exec(void) +{ + asm __volatile__( + "tbegin.;" + "blt 1f;" + "tsuspend.;" + "1: ;" + : : : "memory"); + + FAIL_IF(failure_is_nesting()); + return 0; +} + +int main(int argc, char *argv[]) +{ + path = argv[0]; + + if (argc > 1 && strcmp(argv[1], "--child") == 0) + return after_exec(); + + return test_harness(test_exec, "tm_exec"); +} diff --git a/tools/testing/selftests/powerpc/tm/tm-syscall.c b/tools/testing/selftests/powerpc/tm/tm-syscall.c index 60560cb20e38..454b965a2db3 100644 --- a/tools/testing/selftests/powerpc/tm/tm-syscall.c +++ b/tools/testing/selftests/powerpc/tm/tm-syscall.c @@ -27,21 +27,6 @@ unsigned retries = 0; #define TEST_DURATION 10 /* seconds */ #define TM_RETRIES 100 -long failure_code(void) -{ - return __builtin_get_texasru() >> 24; -} - -bool failure_is_persistent(void) -{ - return (failure_code() & TM_CAUSE_PERSISTENT) == TM_CAUSE_PERSISTENT; -} - -bool failure_is_syscall(void) -{ - return (failure_code() & TM_CAUSE_SYSCALL) == TM_CAUSE_SYSCALL; -} - pid_t getppid_tm(bool suspend) { int i; diff --git a/tools/testing/selftests/powerpc/tm/tm.h b/tools/testing/selftests/powerpc/tm/tm.h index 24144b25772c..60318bad7d7a 100644 --- a/tools/testing/selftests/powerpc/tm/tm.h +++ b/tools/testing/selftests/powerpc/tm/tm.h @@ -6,8 +6,9 @@ #ifndef _SELFTESTS_POWERPC_TM_TM_H #define _SELFTESTS_POWERPC_TM_TM_H -#include +#include #include +#include #include "../utils.h" @@ -31,4 +32,24 @@ static inline bool have_htm_nosc(void) #endif } +static inline long failure_code(void) +{ + return __builtin_get_texasru() >> 24; +} + +static inline bool failure_is_persistent(void) +{ + return (failure_code() & TM_CAUSE_PERSISTENT) == TM_CAUSE_PERSISTENT; +} + +static inline bool failure_is_syscall(void) +{ + return (failure_code() & TM_CAUSE_SYSCALL) == TM_CAUSE_SYSCALL; +} + +static inline bool failure_is_nesting(void) +{ + return (__builtin_get_texasru() & 0x400000); +} + #endif /* _SELFTESTS_POWERPC_TM_TM_H */ -- cgit v1.2.3 From d78388dbec256b179f1c42e714cf4acf630067c6 Mon Sep 17 00:00:00 2001 From: Shuah Khan Date: Fri, 22 Jul 2016 15:29:50 -0600 Subject: selftests: media_tests add a new video device test Add a new video device test that opens user specified Video Device and calls video ioctls in a loop once every 10 seconds. This test is intended for testing device removal and driver unbind while an ioctl is active. Clean device removal and driver unbind is expected without any use-after-free and panics. Signed-off-by: Shuah Khan --- tools/testing/selftests/media_tests/.gitignore | 1 + tools/testing/selftests/media_tests/Makefile | 4 +- .../selftests/media_tests/video_device_test.c | 100 +++++++++++++++++++++ 3 files changed, 103 insertions(+), 2 deletions(-) create mode 100644 tools/testing/selftests/media_tests/video_device_test.c (limited to 'tools') diff --git a/tools/testing/selftests/media_tests/.gitignore b/tools/testing/selftests/media_tests/.gitignore index faf5891fbc54..8745eba39012 100644 --- a/tools/testing/selftests/media_tests/.gitignore +++ b/tools/testing/selftests/media_tests/.gitignore @@ -1,2 +1,3 @@ media_device_test media_device_open +video_device_test diff --git a/tools/testing/selftests/media_tests/Makefile b/tools/testing/selftests/media_tests/Makefile index 177256aa4e0a..6b34a0199468 100644 --- a/tools/testing/selftests/media_tests/Makefile +++ b/tools/testing/selftests/media_tests/Makefile @@ -1,7 +1,7 @@ -TEST_PROGS := media_device_test media_device_open +TEST_PROGS := media_device_test media_device_open video_device_test all: $(TEST_PROGS) include ../lib.mk clean: - rm -fr media_device_test media_device_open + rm -fr media_device_test media_device_open video_device_test diff --git a/tools/testing/selftests/media_tests/video_device_test.c b/tools/testing/selftests/media_tests/video_device_test.c new file mode 100644 index 000000000000..66d419c28653 --- /dev/null +++ b/tools/testing/selftests/media_tests/video_device_test.c @@ -0,0 +1,100 @@ +/* + * video_device_test - Video Device Test + * + * Copyright (c) 2016 Shuah Khan + * Copyright (c) 2016 Samsung Electronics Co., Ltd. + * + * This file is released under the GPLv2. + */ + +/* + * This file adds a test for Video Device. This test should not be included + * in the Kselftest run. This test should be run when hardware and driver + * that makes use of V4L2 API is present. + * + * This test opens user specified Video Device and calls video ioctls in a + * loop once every 10 seconds. + * + * Usage: + * sudo ./video_device_test -d /dev/videoX + * + * While test is running, remove the device or unbind the driver and + * ensure there are no use after free errors and other Oops in the + * dmesg. + * When possible, enable KaSan kernel config option for use-after-free + * error detection. +*/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +int main(int argc, char **argv) +{ + int opt; + char video_dev[256]; + int count; + struct v4l2_tuner vtuner; + struct v4l2_capability vcap; + int ret; + int fd; + + if (argc < 2) { + printf("Usage: %s [-d ]\n", argv[0]); + exit(-1); + } + + /* Process arguments */ + while ((opt = getopt(argc, argv, "d:")) != -1) { + switch (opt) { + case 'd': + strncpy(video_dev, optarg, sizeof(video_dev) - 1); + video_dev[sizeof(video_dev)-1] = '\0'; + break; + default: + printf("Usage: %s [-d ]\n", argv[0]); + exit(-1); + } + } + + /* Generate random number of interations */ + srand((unsigned int) time(NULL)); + count = rand(); + + /* Open Video device and keep it open */ + fd = open(video_dev, O_RDWR); + if (fd == -1) { + printf("Video Device open errno %s\n", strerror(errno)); + exit(-1); + } + + printf("\nNote:\n" + "While test is running, remove the device or unbind\n" + "driver and ensure there are no use after free errors\n" + "and other Oops in the dmesg. When possible, enable KaSan\n" + "kernel config option for use-after-free error detection.\n\n"); + + while (count > 0) { + ret = ioctl(fd, VIDIOC_QUERYCAP, &vcap); + if (ret < 0) + printf("VIDIOC_QUERYCAP errno %s\n", strerror(errno)); + else + printf("Video device driver %s\n", vcap.driver); + + ret = ioctl(fd, VIDIOC_G_TUNER, &vtuner); + if (ret < 0) + printf("VIDIOC_G_TUNER, errno %s\n", strerror(errno)); + else + printf("type %d rangelow %d rangehigh %d\n", + vtuner.type, vtuner.rangelow, vtuner.rangehigh); + sleep(10); + count--; + } +} -- cgit v1.2.3 From 7c48dcfd32b45b69aa8d5e81108fff8c7a2272ed Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Thu, 28 Jul 2016 18:33:20 -0300 Subject: perf evsel: Introduce constructor for cycles event That is the default used when no events is specified in tools, separate it so that simpler tools that need no evlist can use it directly. Cc: Adrian Hunter Cc: David Ahern Cc: Jiri Olsa Cc: Namhyung Kim Cc: Wang Nan Link: http://lkml.kernel.org/n/tip-67mwuthscwroz88x9pswcqyv@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/evlist.c | 22 ++-------------------- tools/perf/util/evsel.c | 28 ++++++++++++++++++++++++++++ tools/perf/util/evsel.h | 2 ++ 3 files changed, 32 insertions(+), 20 deletions(-) (limited to 'tools') diff --git a/tools/perf/util/evlist.c b/tools/perf/util/evlist.c index 2a40b8e1def7..097b3ed77fdd 100644 --- a/tools/perf/util/evlist.c +++ b/tools/perf/util/evlist.c @@ -239,31 +239,13 @@ void perf_event_attr__set_max_precise_ip(struct perf_event_attr *attr) int perf_evlist__add_default(struct perf_evlist *evlist) { - struct perf_event_attr attr = { - .type = PERF_TYPE_HARDWARE, - .config = PERF_COUNT_HW_CPU_CYCLES, - }; - struct perf_evsel *evsel; - - event_attr_init(&attr); + struct perf_evsel *evsel = perf_evsel__new_cycles(); - perf_event_attr__set_max_precise_ip(&attr); - - evsel = perf_evsel__new(&attr); if (evsel == NULL) - goto error; - - /* use asprintf() because free(evsel) assumes name is allocated */ - if (asprintf(&evsel->name, "cycles%.*s", - attr.precise_ip ? attr.precise_ip + 1 : 0, ":ppp") < 0) - goto error_free; + return -ENOMEM; perf_evlist__add(evlist, evsel); return 0; -error_free: - perf_evsel__delete(evsel); -error: - return -ENOMEM; } int perf_evlist__add_dummy(struct perf_evlist *evlist) diff --git a/tools/perf/util/evsel.c b/tools/perf/util/evsel.c index 8c54df61fe64..4c2b31dc4e4d 100644 --- a/tools/perf/util/evsel.c +++ b/tools/perf/util/evsel.c @@ -253,6 +253,34 @@ struct perf_evsel *perf_evsel__new_idx(struct perf_event_attr *attr, int idx) return evsel; } +struct perf_evsel *perf_evsel__new_cycles(void) +{ + struct perf_event_attr attr = { + .type = PERF_TYPE_HARDWARE, + .config = PERF_COUNT_HW_CPU_CYCLES, + }; + struct perf_evsel *evsel; + + event_attr_init(&attr); + + perf_event_attr__set_max_precise_ip(&attr); + + evsel = perf_evsel__new(&attr); + if (evsel == NULL) + goto out; + + /* use asprintf() because free(evsel) assumes name is allocated */ + if (asprintf(&evsel->name, "cycles%.*s", + attr.precise_ip ? attr.precise_ip + 1 : 0, ":ppp") < 0) + goto error_free; +out: + return evsel; +error_free: + perf_evsel__delete(evsel); + evsel = NULL; + goto out; +} + /* * Returns pointer with encoded error via interface. */ diff --git a/tools/perf/util/evsel.h b/tools/perf/util/evsel.h index 8a4a6c9f1480..4d44129e050b 100644 --- a/tools/perf/util/evsel.h +++ b/tools/perf/util/evsel.h @@ -175,6 +175,8 @@ static inline struct perf_evsel *perf_evsel__newtp(const char *sys, const char * return perf_evsel__newtp_idx(sys, name, 0); } +struct perf_evsel *perf_evsel__new_cycles(void); + struct event_format *event_format__new(const char *sys, const char *name); void perf_evsel__init(struct perf_evsel *evsel, -- cgit v1.2.3 From 9955d0be161a9baa241ae7b98426a4c705cb21cb Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Wed, 15 Jun 2016 15:48:08 -0300 Subject: perf annotate: Use pipe + fork instead of popen We will need to redirect the stderr as well, so open code popen as a starting point. Cc: Adrian Hunter Cc: David Ahern Cc: Jiri Olsa Cc: Namhyung Kim Cc: Wang Nan Link: http://lkml.kernel.org/n/tip-k0zt9svg4bswiglem7ornts4@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/annotate.c | 39 +++++++++++++++++++++++++++++++++++---- 1 file changed, 35 insertions(+), 4 deletions(-) (limited to 'tools') diff --git a/tools/perf/util/annotate.c b/tools/perf/util/annotate.c index e9825fe825fd..2dd396a1f64b 100644 --- a/tools/perf/util/annotate.c +++ b/tools/perf/util/annotate.c @@ -1134,8 +1134,10 @@ int symbol__annotate(struct symbol *sym, struct map *map, size_t privsize) char symfs_filename[PATH_MAX]; struct kcore_extract kce; bool delete_extract = false; + int stdout_fd[2]; int lineno = 0; int nline; + pid_t pid; if (filename) symbol__join_symfs(symfs_filename, filename); @@ -1258,9 +1260,32 @@ fallback: pr_debug("Executing: %s\n", command); - file = popen(command, "r"); + err = -1; + if (pipe(stdout_fd) < 0) { + pr_err("Failure creating the pipe to run %s\n", command); + goto out_remove_tmp; + } + + pid = fork(); + if (pid < 0) { + pr_err("Failure forking to run %s\n", command); + goto out_close_stdout; + } + + if (pid == 0) { + close(stdout_fd[0]); + dup2(stdout_fd[1], 1); + close(stdout_fd[1]); + execl("/bin/sh", "sh", "-c", command, NULL); + perror(command); + exit(-1); + } + + close(stdout_fd[1]); + + file = fdopen(stdout_fd[0], "r"); if (!file) { - pr_err("Failure running %s\n", command); + pr_err("Failure creating FILE stream for %s\n", command); /* * If we were using debug info should retry with * original binary. @@ -1286,9 +1311,11 @@ fallback: if (dso__is_kcore(dso)) delete_last_nop(sym); - pclose(file); - + fclose(file); + err = 0; out_remove_tmp: + close(stdout_fd[0]); + if (dso__needs_decompress(dso)) unlink(symfs_filename); out_free_filename: @@ -1297,6 +1324,10 @@ out_free_filename: if (free_filename) free(filename); return err; + +out_close_stdout: + close(stdout_fd[1]); + goto out_remove_tmp; } static void insert_source_line(struct rb_root *root, struct source_line *src_line) -- cgit v1.2.3 From ce92834407a465c25c0be1a4a0339c625e44c4db Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Fri, 29 Jul 2016 11:54:35 -0300 Subject: perf target: str_error_r() always returns the buffer it receives So no need for checking if it uses the strerror_r() GNU variant error reporting mechanism, i.e. if it returns a pointer to a immutable string internal to glibc. Cc: Adrian Hunter Cc: David Ahern Cc: Jiri Olsa Cc: Namhyung Kim Cc: Wang Nan Fixes: c8b5f2c96d1b ("tools: Introduce str_error_r()") Link: http://lkml.kernel.org/n/tip-xr83cd4y4r3cn6tq6w4f59jb@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/target.c | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) (limited to 'tools') diff --git a/tools/perf/util/target.c b/tools/perf/util/target.c index 8cdcf4641c51..21c4d9b23c24 100644 --- a/tools/perf/util/target.c +++ b/tools/perf/util/target.c @@ -122,11 +122,7 @@ int target__strerror(struct target *target, int errnum, BUG_ON(buflen == 0); if (errnum >= 0) { - const char *err = str_error_r(errnum, buf, buflen); - - if (err != buf) - scnprintf(buf, buflen, "%s", err); - + str_error_r(errnum, buf, buflen); return 0; } -- cgit v1.2.3 From 5cb725a9723aebb248106ff7f8c6c7253b24bbb1 Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Fri, 29 Jul 2016 16:44:56 -0300 Subject: perf annotate: Rename symbol__annotate() to symbol__disassemble() This function will not annotate anything, it will just disassembly the given map->dso and symbol. It currently does this by parsing the output of 'objdump --disassemble', but this could conceivably be done using a library or an offshot of the kernel's instruction decoder (arch/x86/lib/inat.c), etc. Cc: Adrian Hunter Cc: David Ahern Cc: Jiri Olsa Cc: Namhyung Kim Cc: Wang Nan Link: http://lkml.kernel.org/n/tip-2xpfl4bfnrd6x584b390qok7@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/builtin-top.c | 2 +- tools/perf/ui/browsers/annotate.c | 2 +- tools/perf/ui/gtk/annotate.c | 2 +- tools/perf/util/annotate.c | 4 ++-- tools/perf/util/annotate.h | 2 +- 5 files changed, 6 insertions(+), 6 deletions(-) (limited to 'tools') diff --git a/tools/perf/builtin-top.c b/tools/perf/builtin-top.c index bd108683fcb8..823dbbbf82a9 100644 --- a/tools/perf/builtin-top.c +++ b/tools/perf/builtin-top.c @@ -128,7 +128,7 @@ static int perf_top__parse_source(struct perf_top *top, struct hist_entry *he) return err; } - err = symbol__annotate(sym, map, 0); + err = symbol__disassemble(sym, map, 0); if (err == 0) { out_assign: top->sym_filter_entry = he; diff --git a/tools/perf/ui/browsers/annotate.c b/tools/perf/ui/browsers/annotate.c index 29dc6d20364e..f4d6a8a962af 100644 --- a/tools/perf/ui/browsers/annotate.c +++ b/tools/perf/ui/browsers/annotate.c @@ -1050,7 +1050,7 @@ int symbol__tui_annotate(struct symbol *sym, struct map *map, (nr_pcnt - 1); } - if (symbol__annotate(sym, map, sizeof_bdl) < 0) { + if (symbol__disassemble(sym, map, sizeof_bdl) < 0) { ui__error("%s", ui_helpline__last_msg); goto out_free_offsets; } diff --git a/tools/perf/ui/gtk/annotate.c b/tools/perf/ui/gtk/annotate.c index 9c7ff8d31b27..35e4b9e28c8d 100644 --- a/tools/perf/ui/gtk/annotate.c +++ b/tools/perf/ui/gtk/annotate.c @@ -166,7 +166,7 @@ static int symbol__gtk_annotate(struct symbol *sym, struct map *map, if (map->dso->annotate_warned) return -1; - if (symbol__annotate(sym, map, 0) < 0) { + if (symbol__disassemble(sym, map, 0) < 0) { ui__error("%s", ui_helpline__current); return -1; } diff --git a/tools/perf/util/annotate.c b/tools/perf/util/annotate.c index 2dd396a1f64b..4f47b6069197 100644 --- a/tools/perf/util/annotate.c +++ b/tools/perf/util/annotate.c @@ -1123,7 +1123,7 @@ static void delete_last_nop(struct symbol *sym) } } -int symbol__annotate(struct symbol *sym, struct map *map, size_t privsize) +int symbol__disassemble(struct symbol *sym, struct map *map, size_t privsize) { struct dso *dso = map->dso; char *filename = dso__build_id_filename(dso, NULL, 0); @@ -1694,7 +1694,7 @@ int symbol__tty_annotate(struct symbol *sym, struct map *map, struct rb_root source_line = RB_ROOT; u64 len; - if (symbol__annotate(sym, map, 0) < 0) + if (symbol__disassemble(sym, map, 0) < 0) return -1; len = symbol__size(sym); diff --git a/tools/perf/util/annotate.h b/tools/perf/util/annotate.h index a23084f54128..b0750d8bee1f 100644 --- a/tools/perf/util/annotate.h +++ b/tools/perf/util/annotate.h @@ -155,7 +155,7 @@ int hist_entry__inc_addr_samples(struct hist_entry *he, int evidx, u64 addr); int symbol__alloc_hist(struct symbol *sym); void symbol__annotate_zero_histograms(struct symbol *sym); -int symbol__annotate(struct symbol *sym, struct map *map, size_t privsize); +int symbol__disassemble(struct symbol *sym, struct map *map, size_t privsize); int symbol__annotate_init(struct map *map, struct symbol *sym); int symbol__annotate_printf(struct symbol *sym, struct map *map, -- cgit v1.2.3 From ee51d851392e1fe3e8be30b3c5847f34da343424 Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Fri, 29 Jul 2016 16:27:18 -0300 Subject: perf annotate: Introduce strerror for handling symbol__disassemble() errors We were just using pr_error() which makes it difficult for non stdio UIs to provide errors using its widgets, as they need to somehow catch what was passed to pr_error(). Fix it by introducing a __strerror() interface like the ones used elsewhere, for instance target__strerror(). This is just the initial step, more work will be done, but first some error handling bugs noticed while working on this need to be dealt with. Cc: Adrian Hunter Cc: David Ahern Cc: Jiri Olsa Cc: Namhyung Kim Cc: Wang Nan Link: http://lkml.kernel.org/n/tip-dgd22zl2xg7x4vcnoa83jxfb@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/builtin-top.c | 4 +++ tools/perf/ui/browsers/annotate.c | 9 ++++-- tools/perf/ui/gtk/annotate.c | 8 +++-- tools/perf/util/annotate.c | 68 ++++++++++++++++++++++++--------------- tools/perf/util/annotate.h | 20 ++++++++++++ 5 files changed, 78 insertions(+), 31 deletions(-) (limited to 'tools') diff --git a/tools/perf/builtin-top.c b/tools/perf/builtin-top.c index 823dbbbf82a9..418ed94756d3 100644 --- a/tools/perf/builtin-top.c +++ b/tools/perf/builtin-top.c @@ -132,6 +132,10 @@ static int perf_top__parse_source(struct perf_top *top, struct hist_entry *he) if (err == 0) { out_assign: top->sym_filter_entry = he; + } else { + char msg[BUFSIZ]; + symbol__strerror_disassemble(sym, map, err, msg, sizeof(msg)); + pr_err("Couldn't annotate %s: %s\n", sym->name, msg); } pthread_mutex_unlock(¬es->lock); diff --git a/tools/perf/ui/browsers/annotate.c b/tools/perf/ui/browsers/annotate.c index f4d6a8a962af..2e2d10022355 100644 --- a/tools/perf/ui/browsers/annotate.c +++ b/tools/perf/ui/browsers/annotate.c @@ -1026,7 +1026,7 @@ int symbol__tui_annotate(struct symbol *sym, struct map *map, .use_navkeypressed = true, }, }; - int ret = -1; + int ret = -1, err; int nr_pcnt = 1; size_t sizeof_bdl = sizeof(struct browser_disasm_line); @@ -1050,8 +1050,11 @@ int symbol__tui_annotate(struct symbol *sym, struct map *map, (nr_pcnt - 1); } - if (symbol__disassemble(sym, map, sizeof_bdl) < 0) { - ui__error("%s", ui_helpline__last_msg); + err = symbol__disassemble(sym, map, sizeof_bdl); + if (err) { + char msg[BUFSIZ]; + symbol__strerror_disassemble(sym, map, err, msg, sizeof(msg)); + ui__error("Couldn't annotate %s:\n%s", sym->name, msg); goto out_free_offsets; } diff --git a/tools/perf/ui/gtk/annotate.c b/tools/perf/ui/gtk/annotate.c index 35e4b9e28c8d..42d319927762 100644 --- a/tools/perf/ui/gtk/annotate.c +++ b/tools/perf/ui/gtk/annotate.c @@ -162,12 +162,16 @@ static int symbol__gtk_annotate(struct symbol *sym, struct map *map, GtkWidget *notebook; GtkWidget *scrolled_window; GtkWidget *tab_label; + int err; if (map->dso->annotate_warned) return -1; - if (symbol__disassemble(sym, map, 0) < 0) { - ui__error("%s", ui_helpline__current); + err = symbol__disassemble(sym, map, 0); + if (err) { + char msg[BUFSIZ]; + symbol__strerror_disassemble(sym, map, err, msg, sizeof(msg)); + ui__error("Couldn't annotate %s: %s\n", sym->name, msg); return -1; } diff --git a/tools/perf/util/annotate.c b/tools/perf/util/annotate.c index 4f47b6069197..4982ed487e96 100644 --- a/tools/perf/util/annotate.c +++ b/tools/perf/util/annotate.c @@ -1123,6 +1123,45 @@ static void delete_last_nop(struct symbol *sym) } } +int symbol__strerror_disassemble(struct symbol *sym __maybe_unused, struct map *map, + int errnum, char *buf, size_t buflen) +{ + struct dso *dso = map->dso; + + BUG_ON(buflen == 0); + + if (errnum >= 0) { + str_error_r(errnum, buf, buflen); + return 0; + } + + switch (errnum) { + case SYMBOL_ANNOTATE_ERRNO__NO_VMLINUX: { + char bf[SBUILD_ID_SIZE + 15] = " with build id "; + char *build_id_msg = NULL; + + if (dso->has_build_id) { + build_id__sprintf(dso->build_id, + sizeof(dso->build_id), bf + 15); + build_id_msg = bf; + } + scnprintf(buf, buflen, + "No vmlinux file%s\nwas found in the path.\n\n" + "Note that annotation using /proc/kcore requires CAP_SYS_RAWIO capability.\n\n" + "Please use:\n\n" + " perf buildid-cache -vu vmlinux\n\n" + "or:\n\n" + " --vmlinux vmlinux\n", build_id_msg ?: ""); + } + break; + default: + scnprintf(buf, buflen, "Internal error: Invalid %d error code\n", errnum); + break; + } + + return 0; +} + int symbol__disassemble(struct symbol *sym, struct map *map, size_t privsize) { struct dso *dso = map->dso; @@ -1143,11 +1182,8 @@ int symbol__disassemble(struct symbol *sym, struct map *map, size_t privsize) symbol__join_symfs(symfs_filename, filename); if (filename == NULL) { - if (dso->has_build_id) { - pr_err("Can't annotate %s: not enough memory\n", - sym->name); - return -ENOMEM; - } + if (dso->has_build_id) + return ENOMEM; goto fallback; } else if (dso__is_kcore(dso)) { goto fallback; @@ -1168,27 +1204,7 @@ fallback: if (dso->symtab_type == DSO_BINARY_TYPE__KALLSYMS && !dso__is_kcore(dso)) { - char bf[SBUILD_ID_SIZE + 15] = " with build id "; - char *build_id_msg = NULL; - - if (dso->annotate_warned) - goto out_free_filename; - - if (dso->has_build_id) { - build_id__sprintf(dso->build_id, - sizeof(dso->build_id), bf + 15); - build_id_msg = bf; - } - err = -ENOENT; - dso->annotate_warned = 1; - pr_err("Can't annotate %s:\n\n" - "No vmlinux file%s\nwas found in the path.\n\n" - "Note that annotation using /proc/kcore requires CAP_SYS_RAWIO capability.\n\n" - "Please use:\n\n" - " perf buildid-cache -vu vmlinux\n\n" - "or:\n\n" - " --vmlinux vmlinux\n", - sym->name, build_id_msg ?: ""); + err = SYMBOL_ANNOTATE_ERRNO__NO_VMLINUX; goto out_free_filename; } diff --git a/tools/perf/util/annotate.h b/tools/perf/util/annotate.h index b0750d8bee1f..f67ccb027561 100644 --- a/tools/perf/util/annotate.h +++ b/tools/perf/util/annotate.h @@ -157,6 +157,26 @@ void symbol__annotate_zero_histograms(struct symbol *sym); int symbol__disassemble(struct symbol *sym, struct map *map, size_t privsize); +enum symbol_disassemble_errno { + SYMBOL_ANNOTATE_ERRNO__SUCCESS = 0, + + /* + * Choose an arbitrary negative big number not to clash with standard + * errno since SUS requires the errno has distinct positive values. + * See 'Issue 6' in the link below. + * + * http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/errno.h.html + */ + __SYMBOL_ANNOTATE_ERRNO__START = -10000, + + SYMBOL_ANNOTATE_ERRNO__NO_VMLINUX = __SYMBOL_ANNOTATE_ERRNO__START, + + __SYMBOL_ANNOTATE_ERRNO__END, +}; + +int symbol__strerror_disassemble(struct symbol *sym, struct map *map, + int errnum, char *buf, size_t buflen); + int symbol__annotate_init(struct map *map, struct symbol *sym); int symbol__annotate_printf(struct symbol *sym, struct map *map, struct perf_evsel *evsel, bool full_paths, -- cgit v1.2.3 From c17c17e8c26a5d44b3a8a6ef8c55233d72eed6c0 Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Mon, 1 Aug 2016 18:49:13 -0300 Subject: perf annotate: Plug filename string leak If dso__build_id_filename(..., NULL, ...) returns !NULL its because it allocated it, so, when reaching the 'if (dso__is_kcore()) test, we already checked that and were just "fallbacking" to using dso->long_name, but without freeing filename, thus leaking it. Fix it by adding the dso__is_kcore() test to the 'or' group just after it, the one containing the full fallback code, including freeing the filename. Cc: Adrian Hunter Cc: David Ahern Cc: Jiri Olsa Cc: Namhyung Kim Cc: Wang Nan Fixes: ee205503f233 ("perf tools: Fix annotation with kcore") Link: http://lkml.kernel.org/n/tip-qi4rpjq8yo6myvg99kkgt0xz@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/annotate.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'tools') diff --git a/tools/perf/util/annotate.c b/tools/perf/util/annotate.c index 4982ed487e96..4024d309bb00 100644 --- a/tools/perf/util/annotate.c +++ b/tools/perf/util/annotate.c @@ -1185,9 +1185,8 @@ int symbol__disassemble(struct symbol *sym, struct map *map, size_t privsize) if (dso->has_build_id) return ENOMEM; goto fallback; - } else if (dso__is_kcore(dso)) { - goto fallback; - } else if (readlink(symfs_filename, command, sizeof(command)) < 0 || + } else if (dso__is_kcore(dso) || + readlink(symfs_filename, command, sizeof(command)) < 0 || strstr(command, DSO__NAME_KALLSYMS) || access(symfs_filename, R_OK)) { free(filename); -- cgit v1.2.3 From b581c01fff646b5075d65359c8667de9c667da9e Mon Sep 17 00:00:00 2001 From: Namhyung Kim Date: Tue, 2 Aug 2016 11:43:17 +0900 Subject: perf tools: Fix build failure on perl script context On my Archlinux machine, perf faild to build like below: CC scripts/perl/Perf-Trace-Util/Context.o In file included from /usr/lib/perl5/core/perl/CORE/perl.h:3905:0, from Context.xs:23: /usr/lib/perl5/core/perl/CORE/inline.h: In function : /usr/lib/perl5/core/perl/CORE/cop.h:612:13: warning: declaration of 'av' shadows a previous local [-Werror-shadow] AV *av =3D GvAV(PL_defgv); ^ /usr/lib/perl5/core/perl/CORE/inline.h:526:5: note: in expansion of macro 'CX_POP_SAVEARRAY' CX_POP_SAVEARRAY(cx); ^~~~~~~~~~~~~~~~ In file included from /usr/lib/perl5/core/perl/CORE/perl.h:5853:0, from Context.xs:23: /usr/lib/perl5/core/perl/CORE/inline.h:518:9: note: shadowed declaration is here AV *av; ^~ What I did to fix is adding '-Wno-shadow' as the error message said it's the cause of the failure. Since it's from the perl (not perf) code base, we don't have the control so I just wanted to ignore the warning when compiling perl scripting code. Committer note: This also fixes the build on Fedora Rawhide. Signed-off-by: Namhyung Kim Tested-by: Arnaldo Carvalho de Melo Cc: Jiri Olsa Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/20160802024317.31725-1-namhyung@kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/scripts/perl/Perf-Trace-Util/Build | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'tools') diff --git a/tools/perf/scripts/perl/Perf-Trace-Util/Build b/tools/perf/scripts/perl/Perf-Trace-Util/Build index 928e110179cb..34faecf774ae 100644 --- a/tools/perf/scripts/perl/Perf-Trace-Util/Build +++ b/tools/perf/scripts/perl/Perf-Trace-Util/Build @@ -1,3 +1,5 @@ libperf-y += Context.o -CFLAGS_Context.o += $(PERL_EMBED_CCOPTS) -Wno-redundant-decls -Wno-strict-prototypes -Wno-unused-parameter -Wno-nested-externs -Wno-undef -Wno-switch-default +CFLAGS_Context.o += $(PERL_EMBED_CCOPTS) -Wno-redundant-decls -Wno-strict-prototypes +CFLAGS_Context.o += -Wno-unused-parameter -Wno-nested-externs -Wno-undef +CFLAGS_Context.o += -Wno-switch-default -Wno-shadow -- cgit v1.2.3 From 979a70a237efb68e15b1cee36f9f92037e71d1fd Mon Sep 17 00:00:00 2001 From: Namhyung Kim Date: Tue, 2 Aug 2016 14:01:47 +0900 Subject: tools lib traceevent: Ignore generated library files Signed-off-by: Namhyung Kim Cc: David Ahern Cc: Jiri Olsa Cc: Peter Zijlstra Cc: Steven Rostedt Link: http://lkml.kernel.org/r/20160802050148.3413-1-namhyung@kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/lib/traceevent/.gitignore | 1 + 1 file changed, 1 insertion(+) (limited to 'tools') diff --git a/tools/lib/traceevent/.gitignore b/tools/lib/traceevent/.gitignore index 3c60335fe7be..9e9f25fb1922 100644 --- a/tools/lib/traceevent/.gitignore +++ b/tools/lib/traceevent/.gitignore @@ -1,2 +1,3 @@ TRACEEVENT-CFLAGS libtraceevent-dynamic-list +libtraceevent.so.* -- cgit v1.2.3 From 98c032967a299ee4bf14ef19eded02b65df32e6f Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Tue, 2 Aug 2016 13:33:02 +0200 Subject: tools lib: Add bitmap_alloc function Adding bitmap_alloc function to dynamically allocate bitmap. Signed-off-by: Jiri Olsa Cc: David Ahern Cc: Jiri Olsa Cc: Namhyung Kim Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/20160802113302.GA7479@krava Signed-off-by: Arnaldo Carvalho de Melo --- tools/include/linux/bitmap.h | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'tools') diff --git a/tools/include/linux/bitmap.h b/tools/include/linux/bitmap.h index 28f5493da491..60c44b615902 100644 --- a/tools/include/linux/bitmap.h +++ b/tools/include/linux/bitmap.h @@ -3,6 +3,7 @@ #include #include +#include #define DECLARE_BITMAP(name,bits) \ unsigned long name[BITS_TO_LONGS(bits)] @@ -65,4 +66,13 @@ static inline int test_and_set_bit(int nr, unsigned long *addr) return (old & mask) != 0; } +/** + * bitmap_alloc - Allocate bitmap + * @nr: Bit to set + */ +static inline unsigned long *bitmap_alloc(int nbits) +{ + return calloc(1, BITS_TO_LONGS(nbits) * sizeof(unsigned long)); +} + #endif /* _PERF_BITOPS_H */ -- cgit v1.2.3 From 820d12b70f91a19eb4a3152b9dd4ea9aee194a36 Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Mon, 1 Aug 2016 20:02:30 +0200 Subject: tools lib: Add bitmap_scnprintf function Add support to print bitmap list. Code mostly taken from kernel's bitmap_list_string. Signed-off-by: Jiri Olsa Cc: David Ahern Cc: Namhyung Kim Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/1470074555-24889-3-git-send-email-jolsa@kernel.org [ s/bitmap_snprintf/bitmap_scnprintf/g as it is a scnprintf wrapper, having the same semantics wrt return value ] Signed-off-by: Arnaldo Carvalho de Melo --- tools/include/linux/bitmap.h | 10 ++++++++++ tools/lib/bitmap.c | 29 +++++++++++++++++++++++++++++ 2 files changed, 39 insertions(+) (limited to 'tools') diff --git a/tools/include/linux/bitmap.h b/tools/include/linux/bitmap.h index 60c44b615902..1cdded0041a8 100644 --- a/tools/include/linux/bitmap.h +++ b/tools/include/linux/bitmap.h @@ -75,4 +75,14 @@ static inline unsigned long *bitmap_alloc(int nbits) return calloc(1, BITS_TO_LONGS(nbits) * sizeof(unsigned long)); } +/* + * bitmap_scnprintf - print bitmap list into buffer + * @bitmap: bitmap + * @nbits: size of bitmap + * @buf: buffer to store output + * @size: size of @buf + */ +size_t bitmap_scnprintf(unsigned long *bitmap, int nbits, + char *buf, size_t size); + #endif /* _PERF_BITOPS_H */ diff --git a/tools/lib/bitmap.c b/tools/lib/bitmap.c index 0a1adc1111fd..5c7e3185507c 100644 --- a/tools/lib/bitmap.c +++ b/tools/lib/bitmap.c @@ -29,3 +29,32 @@ void __bitmap_or(unsigned long *dst, const unsigned long *bitmap1, for (k = 0; k < nr; k++) dst[k] = bitmap1[k] | bitmap2[k]; } + +size_t bitmap_scnprintf(unsigned long *bitmap, int nbits, + char *buf, size_t size) +{ + /* current bit is 'cur', most recently seen range is [rbot, rtop] */ + int cur, rbot, rtop; + bool first = true; + size_t ret = 0; + + rbot = cur = find_first_bit(bitmap, nbits); + while (cur < nbits) { + rtop = cur; + cur = find_next_bit(bitmap, nbits, cur + 1); + if (cur < nbits && cur <= rtop + 1) + continue; + + if (!first) + ret += scnprintf(buf + ret, size - ret, ","); + + first = false; + + ret += scnprintf(buf + ret, size - ret, "%d", rbot); + if (rbot < rtop) + ret += scnprintf(buf + ret, size - ret, "-%d", rtop); + + rbot = cur; + } + return ret; +} -- cgit v1.2.3 From 741c74f55e8a66f3bc5bbc29dc162c952759e47b Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Mon, 1 Aug 2016 20:02:31 +0200 Subject: tools lib: Add bitmap_and function Add support to perform logical and on bitmaps. Code taken from kernel's include/linux/bitmap.h. Signed-off-by: Jiri Olsa Cc: David Ahern Cc: Namhyung Kim Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/1470074555-24889-4-git-send-email-jolsa@kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/include/linux/bitmap.h | 17 +++++++++++++++++ tools/lib/bitmap.c | 15 +++++++++++++++ 2 files changed, 32 insertions(+) (limited to 'tools') diff --git a/tools/include/linux/bitmap.h b/tools/include/linux/bitmap.h index 1cdded0041a8..43c1c5021e4b 100644 --- a/tools/include/linux/bitmap.h +++ b/tools/include/linux/bitmap.h @@ -11,6 +11,8 @@ int __bitmap_weight(const unsigned long *bitmap, int bits); void __bitmap_or(unsigned long *dst, const unsigned long *bitmap1, const unsigned long *bitmap2, int bits); +int __bitmap_and(unsigned long *dst, const unsigned long *bitmap1, + const unsigned long *bitmap2, unsigned int bits); #define BITMAP_FIRST_WORD_MASK(start) (~0UL << ((start) & (BITS_PER_LONG - 1))) @@ -85,4 +87,19 @@ static inline unsigned long *bitmap_alloc(int nbits) size_t bitmap_scnprintf(unsigned long *bitmap, int nbits, char *buf, size_t size); +/** + * bitmap_and - Do logical and on bitmaps + * @dst: resulting bitmap + * @src1: operand 1 + * @src2: operand 2 + * @nbits: size of bitmap + */ +static inline int bitmap_and(unsigned long *dst, const unsigned long *src1, + const unsigned long *src2, unsigned int nbits) +{ + if (small_const_nbits(nbits)) + return (*dst = *src1 & *src2 & BITMAP_LAST_WORD_MASK(nbits)) != 0; + return __bitmap_and(dst, src1, src2, nbits); +} + #endif /* _PERF_BITOPS_H */ diff --git a/tools/lib/bitmap.c b/tools/lib/bitmap.c index 5c7e3185507c..38748b0e342f 100644 --- a/tools/lib/bitmap.c +++ b/tools/lib/bitmap.c @@ -58,3 +58,18 @@ size_t bitmap_scnprintf(unsigned long *bitmap, int nbits, } return ret; } + +int __bitmap_and(unsigned long *dst, const unsigned long *bitmap1, + const unsigned long *bitmap2, unsigned int bits) +{ + unsigned int k; + unsigned int lim = bits/BITS_PER_LONG; + unsigned long result = 0; + + for (k = 0; k < lim; k++) + result |= (dst[k] = bitmap1[k] & bitmap2[k]); + if (bits % BITS_PER_LONG) + result |= (dst[k] = bitmap1[k] & bitmap2[k] & + BITMAP_LAST_WORD_MASK(bits)); + return result != 0; +} -- cgit v1.2.3 From ff3e33b075fe45c669e2cb27489d570e29d3abeb Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Mon, 1 Aug 2016 20:02:32 +0200 Subject: perf tests: Add test for bitmap_scnprintf function Automatically test the bitmap_scnprintf function. Signed-off-by: Jiri Olsa Tested-by: Arnaldo Carvalho de Melo Cc: David Ahern Cc: Namhyung Kim Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/1470074555-24889-5-git-send-email-jolsa@kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/tests/Build | 1 + tools/perf/tests/bitmap.c | 53 +++++++++++++++++++++++++++++++++++++++++ tools/perf/tests/builtin-test.c | 4 ++++ tools/perf/tests/tests.h | 1 + 4 files changed, 59 insertions(+) create mode 100644 tools/perf/tests/bitmap.c (limited to 'tools') diff --git a/tools/perf/tests/Build b/tools/perf/tests/Build index cb20ae1c0d35..dc51bc570e51 100644 --- a/tools/perf/tests/Build +++ b/tools/perf/tests/Build @@ -41,6 +41,7 @@ perf-y += event-times.o perf-y += backward-ring-buffer.o perf-y += sdt.o perf-y += is_printable_array.o +perf-y += bitmap.o $(OUTPUT)tests/llvm-src-base.c: tests/bpf-script-example.c tests/Build $(call rule_mkdir) diff --git a/tools/perf/tests/bitmap.c b/tools/perf/tests/bitmap.c new file mode 100644 index 000000000000..9abe6c13090f --- /dev/null +++ b/tools/perf/tests/bitmap.c @@ -0,0 +1,53 @@ +#include +#include +#include "tests.h" +#include "cpumap.h" +#include "debug.h" + +#define NBITS 100 + +static unsigned long *get_bitmap(const char *str, int nbits) +{ + struct cpu_map *map = cpu_map__new(str); + unsigned long *bm = NULL; + int i; + + bm = bitmap_alloc(nbits); + + if (map && bm) { + bitmap_zero(bm, nbits); + + for (i = 0; i < map->nr; i++) + set_bit(map->map[i], bm); + } + + if (map) + cpu_map__put(map); + return bm; +} + +static int test_bitmap(const char *str) +{ + unsigned long *bm = get_bitmap(str, NBITS); + char buf[100]; + int ret; + + bitmap_scnprintf(bm, NBITS, buf, sizeof(buf)); + pr_debug("bitmap: %s\n", buf); + + ret = !strcmp(buf, str); + free(bm); + return ret; +} + +int test__bitmap_print(int subtest __maybe_unused) +{ + TEST_ASSERT_VAL("failed to convert map", test_bitmap("1")); + TEST_ASSERT_VAL("failed to convert map", test_bitmap("1,5")); + TEST_ASSERT_VAL("failed to convert map", test_bitmap("1,3,5,7,9,11,13,15,17,19,21-40")); + TEST_ASSERT_VAL("failed to convert map", test_bitmap("2-5")); + TEST_ASSERT_VAL("failed to convert map", test_bitmap("1,3-6,8-10,24,35-37")); + TEST_ASSERT_VAL("failed to convert map", test_bitmap("1,3-6,8-10,24,35-37")); + TEST_ASSERT_VAL("failed to convert map", test_bitmap("1-10,12-20,22-30,32-40")); + return 0; +} diff --git a/tools/perf/tests/builtin-test.c b/tools/perf/tests/builtin-test.c index 10eb30686c9c..778668a2a966 100644 --- a/tools/perf/tests/builtin-test.c +++ b/tools/perf/tests/builtin-test.c @@ -225,6 +225,10 @@ static struct test generic_tests[] = { .desc = "Test is_printable_array function", .func = test__is_printable_array, }, + { + .desc = "Test bitmap print", + .func = test__bitmap_print, + }, { .func = NULL, }, diff --git a/tools/perf/tests/tests.h b/tools/perf/tests/tests.h index 9bfc0e06c61a..7c196c585472 100644 --- a/tools/perf/tests/tests.h +++ b/tools/perf/tests/tests.h @@ -90,6 +90,7 @@ int test__backward_ring_buffer(int subtest); int test__cpu_map_print(int subtest); int test__sdt_event(int subtest); int test__is_printable_array(int subtest); +int test__bitmap_print(int subtest); #if defined(__arm__) || defined(__aarch64__) #ifdef HAVE_DWARF_UNWIND_SUPPORT -- cgit v1.2.3 From 4842576cd857887ddfed58f452af38b9457639d7 Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Mon, 1 Aug 2016 20:02:33 +0200 Subject: perf tools: Move config/Makefile into Makefile.config There's no reason to keep it in separate directory now when we moved out the rest of the files. Signed-off-by: Jiri Olsa Cc: David Ahern Cc: Namhyung Kim Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/1470074555-24889-6-git-send-email-jolsa@kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/Makefile.config | 874 +++++++++++++++++++++++++++++++++++++++++++++ tools/perf/Makefile.perf | 6 +- tools/perf/config/Makefile | 874 --------------------------------------------- 3 files changed, 877 insertions(+), 877 deletions(-) create mode 100644 tools/perf/Makefile.config delete mode 100644 tools/perf/config/Makefile (limited to 'tools') diff --git a/tools/perf/Makefile.config b/tools/perf/Makefile.config new file mode 100644 index 000000000000..24803c58049a --- /dev/null +++ b/tools/perf/Makefile.config @@ -0,0 +1,874 @@ + +ifeq ($(src-perf),) +src-perf := $(srctree)/tools/perf +endif + +ifeq ($(obj-perf),) +obj-perf := $(OUTPUT) +endif + +ifneq ($(obj-perf),) +obj-perf := $(abspath $(obj-perf))/ +endif + +$(shell printf "" > $(OUTPUT).config-detected) +detected = $(shell echo "$(1)=y" >> $(OUTPUT).config-detected) +detected_var = $(shell echo "$(1)=$($(1))" >> $(OUTPUT).config-detected) + +CFLAGS := $(EXTRA_CFLAGS) $(EXTRA_WARNINGS) + +include $(srctree)/tools/scripts/Makefile.arch + +$(call detected_var,ARCH) + +NO_PERF_REGS := 1 + +# Additional ARCH settings for ppc +ifeq ($(ARCH),powerpc) + NO_PERF_REGS := 0 + LIBUNWIND_LIBS := -lunwind -lunwind-ppc64 +endif + +# Additional ARCH settings for x86 +ifeq ($(ARCH),x86) + $(call detected,CONFIG_X86) + ifeq (${IS_64_BIT}, 1) + CFLAGS += -DHAVE_ARCH_X86_64_SUPPORT -DHAVE_SYSCALL_TABLE -I$(OUTPUT)arch/x86/include/generated + ARCH_INCLUDE = ../../arch/x86/lib/memcpy_64.S ../../arch/x86/lib/memset_64.S + LIBUNWIND_LIBS = -lunwind -lunwind-x86_64 + $(call detected,CONFIG_X86_64) + else + LIBUNWIND_LIBS = -lunwind-x86 -llzma -lunwind + endif + NO_PERF_REGS := 0 +endif + +ifeq ($(ARCH),arm) + NO_PERF_REGS := 0 + LIBUNWIND_LIBS = -lunwind -lunwind-arm +endif + +ifeq ($(ARCH),arm64) + NO_PERF_REGS := 0 + LIBUNWIND_LIBS = -lunwind -lunwind-aarch64 +endif + +ifeq ($(NO_PERF_REGS),0) + $(call detected,CONFIG_PERF_REGS) +endif + +# So far there's only x86 and arm libdw unwind support merged in perf. +# Disable it on all other architectures in case libdw unwind +# support is detected in system. Add supported architectures +# to the check. +ifneq ($(ARCH),$(filter $(ARCH),x86 arm)) + NO_LIBDW_DWARF_UNWIND := 1 +endif + +ifeq ($(LIBUNWIND_LIBS),) + NO_LIBUNWIND := 1 +endif +# +# For linking with debug library, run like: +# +# make DEBUG=1 LIBUNWIND_DIR=/opt/libunwind/ +# + +libunwind_arch_set_flags = $(eval $(libunwind_arch_set_flags_code)) +define libunwind_arch_set_flags_code + FEATURE_CHECK_CFLAGS-libunwind-$(1) = -I$(LIBUNWIND_DIR)/include + FEATURE_CHECK_LDFLAGS-libunwind-$(1) = -L$(LIBUNWIND_DIR)/lib +endef + +ifdef LIBUNWIND_DIR + LIBUNWIND_CFLAGS = -I$(LIBUNWIND_DIR)/include + LIBUNWIND_LDFLAGS = -L$(LIBUNWIND_DIR)/lib + LIBUNWIND_ARCHS = x86 x86_64 arm aarch64 debug-frame-arm debug-frame-aarch64 + $(foreach libunwind_arch,$(LIBUNWIND_ARCHS),$(call libunwind_arch_set_flags,$(libunwind_arch))) +endif + +# Set per-feature check compilation flags +FEATURE_CHECK_CFLAGS-libunwind = $(LIBUNWIND_CFLAGS) +FEATURE_CHECK_LDFLAGS-libunwind = $(LIBUNWIND_LDFLAGS) $(LIBUNWIND_LIBS) +FEATURE_CHECK_CFLAGS-libunwind-debug-frame = $(LIBUNWIND_CFLAGS) +FEATURE_CHECK_LDFLAGS-libunwind-debug-frame = $(LIBUNWIND_LDFLAGS) $(LIBUNWIND_LIBS) + +ifeq ($(NO_PERF_REGS),0) + CFLAGS += -DHAVE_PERF_REGS_SUPPORT +endif + +# for linking with debug library, run like: +# make DEBUG=1 LIBDW_DIR=/opt/libdw/ +ifdef LIBDW_DIR + LIBDW_CFLAGS := -I$(LIBDW_DIR)/include + LIBDW_LDFLAGS := -L$(LIBDW_DIR)/lib +endif +FEATURE_CHECK_CFLAGS-libdw-dwarf-unwind := $(LIBDW_CFLAGS) +FEATURE_CHECK_LDFLAGS-libdw-dwarf-unwind := $(LIBDW_LDFLAGS) -ldw + +# for linking with debug library, run like: +# make DEBUG=1 LIBBABELTRACE_DIR=/opt/libbabeltrace/ +ifdef LIBBABELTRACE_DIR + LIBBABELTRACE_CFLAGS := -I$(LIBBABELTRACE_DIR)/include + LIBBABELTRACE_LDFLAGS := -L$(LIBBABELTRACE_DIR)/lib +endif +FEATURE_CHECK_CFLAGS-libbabeltrace := $(LIBBABELTRACE_CFLAGS) +FEATURE_CHECK_LDFLAGS-libbabeltrace := $(LIBBABELTRACE_LDFLAGS) -lbabeltrace-ctf + +FEATURE_CHECK_CFLAGS-bpf = -I. -I$(srctree)/tools/include -I$(srctree)/tools/arch/$(ARCH)/include/uapi -I$(srctree)/tools/include/uapi +# include ARCH specific config +-include $(src-perf)/arch/$(ARCH)/Makefile + +ifdef PERF_HAVE_ARCH_REGS_QUERY_REGISTER_OFFSET + CFLAGS += -DHAVE_ARCH_REGS_QUERY_REGISTER_OFFSET +endif + +include $(srctree)/tools/scripts/utilities.mak + +ifeq ($(call get-executable,$(FLEX)),) + dummy := $(error Error: $(FLEX) is missing on this system, please install it) +endif + +ifeq ($(call get-executable,$(BISON)),) + dummy := $(error Error: $(BISON) is missing on this system, please install it) +endif + +# Treat warnings as errors unless directed not to +ifneq ($(WERROR),0) + CFLAGS += -Werror +endif + +ifndef DEBUG + DEBUG := 0 +endif + +ifeq ($(DEBUG),0) + CFLAGS += -O6 +endif + +ifdef PARSER_DEBUG + PARSER_DEBUG_BISON := -t + PARSER_DEBUG_FLEX := -d + CFLAGS += -DPARSER_DEBUG + $(call detected_var,PARSER_DEBUG_BISON) + $(call detected_var,PARSER_DEBUG_FLEX) +endif + +# Try different combinations to accommodate systems that only have +# python[2][-config] in weird combinations but always preferring +# python2 and python2-config as per pep-0394. If we catch a +# python[-config] in version 3, the version check will kill it. +PYTHON2 := $(if $(call get-executable,python2),python2,python) +override PYTHON := $(call get-executable-or-default,PYTHON,$(PYTHON2)) +PYTHON2_CONFIG := \ + $(if $(call get-executable,$(PYTHON)-config),$(PYTHON)-config,python-config) +override PYTHON_CONFIG := \ + $(call get-executable-or-default,PYTHON_CONFIG,$(PYTHON2_CONFIG)) + +PYTHON_CONFIG_SQ := $(call shell-sq,$(PYTHON_CONFIG)) + +PYTHON_EMBED_LDOPTS := $(shell $(PYTHON_CONFIG_SQ) --ldflags 2>/dev/null) +PYTHON_EMBED_CCOPTS := $(shell $(PYTHON_CONFIG_SQ) --cflags 2>/dev/null) + +FEATURE_CHECK_CFLAGS-libpython := $(PYTHON_EMBED_CCOPTS) +FEATURE_CHECK_LDFLAGS-libpython := $(PYTHON_EMBED_LDOPTS) +FEATURE_CHECK_CFLAGS-libpython-version := $(PYTHON_EMBED_CCOPTS) +FEATURE_CHECK_LDFLAGS-libpython-version := $(PYTHON_EMBED_LDOPTS) + +CFLAGS += -fno-omit-frame-pointer +CFLAGS += -ggdb3 +CFLAGS += -funwind-tables +CFLAGS += -Wall +CFLAGS += -Wextra +CFLAGS += -std=gnu99 + +# Enforce a non-executable stack, as we may regress (again) in the future by +# adding assembler files missing the .GNU-stack linker note. +LDFLAGS += -Wl,-z,noexecstack + +EXTLIBS = -lpthread -lrt -lm -ldl + +ifeq ($(FEATURES_DUMP),) +include $(srctree)/tools/build/Makefile.feature +else +include $(FEATURES_DUMP) +endif + +ifeq ($(feature-stackprotector-all), 1) + CFLAGS += -fstack-protector-all +endif + +ifeq ($(DEBUG),0) + ifeq ($(feature-fortify-source), 1) + CFLAGS += -D_FORTIFY_SOURCE=2 + endif +endif + +CFLAGS += -I$(src-perf)/util/include +CFLAGS += -I$(src-perf)/arch/$(ARCH)/include +CFLAGS += -I$(srctree)/tools/include/uapi +CFLAGS += -I$(srctree)/tools/include/ +CFLAGS += -I$(srctree)/tools/arch/$(ARCH)/include/uapi +CFLAGS += -I$(srctree)/tools/arch/$(ARCH)/include/ +CFLAGS += -I$(srctree)/tools/arch/$(ARCH)/ + +# $(obj-perf) for generated common-cmds.h +# $(obj-perf)/util for generated bison/flex headers +ifneq ($(OUTPUT),) +CFLAGS += -I$(obj-perf)/util +CFLAGS += -I$(obj-perf) +endif + +CFLAGS += -I$(src-perf)/util +CFLAGS += -I$(src-perf) +CFLAGS += -I$(srctree)/tools/lib/ + +CFLAGS += -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 -D_GNU_SOURCE + +ifeq ($(feature-sync-compare-and-swap), 1) + CFLAGS += -DHAVE_SYNC_COMPARE_AND_SWAP_SUPPORT +endif + +ifeq ($(feature-pthread-attr-setaffinity-np), 1) + CFLAGS += -DHAVE_PTHREAD_ATTR_SETAFFINITY_NP +endif + +ifndef NO_BIONIC + $(call feature_check,bionic) + ifeq ($(feature-bionic), 1) + BIONIC := 1 + EXTLIBS := $(filter-out -lrt,$(EXTLIBS)) + EXTLIBS := $(filter-out -lpthread,$(EXTLIBS)) + endif +endif + +ifdef NO_LIBELF + NO_DWARF := 1 + NO_DEMANGLE := 1 + NO_LIBUNWIND := 1 + NO_LIBDW_DWARF_UNWIND := 1 + NO_LIBBPF := 1 +else + ifeq ($(feature-libelf), 0) + ifeq ($(feature-glibc), 1) + LIBC_SUPPORT := 1 + endif + ifeq ($(BIONIC),1) + LIBC_SUPPORT := 1 + endif + ifeq ($(LIBC_SUPPORT),1) + msg := $(warning No libelf found, disables 'probe' tool and BPF support in 'perf record', please install libelf-dev, libelf-devel or elfutils-libelf-devel); + + NO_LIBELF := 1 + NO_DWARF := 1 + NO_DEMANGLE := 1 + NO_LIBUNWIND := 1 + NO_LIBDW_DWARF_UNWIND := 1 + NO_LIBBPF := 1 + else + ifneq ($(filter s% -static%,$(LDFLAGS),),) + msg := $(error No static glibc found, please install glibc-static); + else + msg := $(error No gnu/libc-version.h found, please install glibc-dev[el]); + endif + endif + else + ifndef NO_LIBDW_DWARF_UNWIND + ifneq ($(feature-libdw-dwarf-unwind),1) + NO_LIBDW_DWARF_UNWIND := 1 + msg := $(warning No libdw DWARF unwind found, Please install elfutils-devel/libdw-dev >= 0.158 and/or set LIBDW_DIR); + endif + endif + ifneq ($(feature-dwarf), 1) + msg := $(warning No libdw.h found or old libdw.h found or elfutils is older than 0.138, disables dwarf support. Please install new elfutils-devel/libdw-dev); + NO_DWARF := 1 + else + ifneq ($(feature-dwarf_getlocations), 1) + msg := $(warning Old libdw.h, finding variables at given 'perf probe' point will not work, install elfutils-devel/libdw-dev >= 0.157); + else + CFLAGS += -DHAVE_DWARF_GETLOCATIONS + endif # dwarf_getlocations + endif # Dwarf support + endif # libelf support +endif # NO_LIBELF + +ifdef NO_DWARF + NO_LIBDW_DWARF_UNWIND := 1 +endif + +ifndef NO_LIBELF + CFLAGS += -DHAVE_LIBELF_SUPPORT + EXTLIBS += -lelf + $(call detected,CONFIG_LIBELF) + + ifeq ($(feature-libelf-mmap), 1) + CFLAGS += -DHAVE_LIBELF_MMAP_SUPPORT + endif + + ifeq ($(feature-libelf-getphdrnum), 1) + CFLAGS += -DHAVE_ELF_GETPHDRNUM_SUPPORT + endif + + ifeq ($(feature-libelf-gelf_getnote), 1) + CFLAGS += -DHAVE_GELF_GETNOTE_SUPPORT + else + msg := $(warning gelf_getnote() not found on libelf, SDT support disabled); + endif + + ifeq ($(feature-libelf-getshdrstrndx), 1) + CFLAGS += -DHAVE_ELF_GETSHDRSTRNDX_SUPPORT + endif + + ifndef NO_DWARF + ifeq ($(origin PERF_HAVE_DWARF_REGS), undefined) + msg := $(warning DWARF register mappings have not been defined for architecture $(ARCH), DWARF support disabled); + NO_DWARF := 1 + else + CFLAGS += -DHAVE_DWARF_SUPPORT $(LIBDW_CFLAGS) + LDFLAGS += $(LIBDW_LDFLAGS) + DWARFLIBS := -ldw + ifeq ($(findstring -static,${LDFLAGS}),-static) + DWARFLIBS += -lelf -lebl -lz -llzma -lbz2 + endif + EXTLIBS += ${DWARFLIBS} + $(call detected,CONFIG_DWARF) + endif # PERF_HAVE_DWARF_REGS + endif # NO_DWARF + + ifndef NO_LIBBPF + ifeq ($(feature-bpf), 1) + CFLAGS += -DHAVE_LIBBPF_SUPPORT + $(call detected,CONFIG_LIBBPF) + endif + + ifndef NO_DWARF + ifdef PERF_HAVE_ARCH_REGS_QUERY_REGISTER_OFFSET + CFLAGS += -DHAVE_BPF_PROLOGUE + $(call detected,CONFIG_BPF_PROLOGUE) + else + msg := $(warning BPF prologue is not supported by architecture $(ARCH), missing regs_query_register_offset()); + endif + else + msg := $(warning DWARF support is off, BPF prologue is disabled); + endif + + endif # NO_LIBBPF +endif # NO_LIBELF + +ifndef NO_SDT + ifneq ($(feature-sdt), 1) + msg := $(warning No sys/sdt.h found, no SDT events are defined, please install systemtap-sdt-devel or systemtap-sdt-dev); + NO_SDT := 1; + else + CFLAGS += -DHAVE_SDT_EVENT + $(call detected,CONFIG_SDT_EVENT) + endif +endif + +ifdef PERF_HAVE_JITDUMP + ifndef NO_DWARF + $(call detected,CONFIG_JITDUMP) + CFLAGS += -DHAVE_JITDUMP + endif +endif + +ifeq ($(ARCH),powerpc) + ifndef NO_DWARF + CFLAGS += -DHAVE_SKIP_CALLCHAIN_IDX + endif +endif + +ifndef NO_LIBUNWIND + have_libunwind := + + ifeq ($(feature-libunwind-x86), 1) + $(call detected,CONFIG_LIBUNWIND_X86) + CFLAGS += -DHAVE_LIBUNWIND_X86_SUPPORT + LDFLAGS += -lunwind-x86 + EXTLIBS_LIBUNWIND += -lunwind-x86 + have_libunwind = 1 + endif + + ifeq ($(feature-libunwind-aarch64), 1) + $(call detected,CONFIG_LIBUNWIND_AARCH64) + CFLAGS += -DHAVE_LIBUNWIND_AARCH64_SUPPORT + LDFLAGS += -lunwind-aarch64 + EXTLIBS_LIBUNWIND += -lunwind-aarch64 + have_libunwind = 1 + $(call feature_check,libunwind-debug-frame-aarch64) + ifneq ($(feature-libunwind-debug-frame-aarch64), 1) + msg := $(warning No debug_frame support found in libunwind-aarch64); + CFLAGS += -DNO_LIBUNWIND_DEBUG_FRAME_AARCH64 + endif + endif + + ifneq ($(feature-libunwind), 1) + msg := $(warning No libunwind found. Please install libunwind-dev[el] >= 1.1 and/or set LIBUNWIND_DIR); + NO_LOCAL_LIBUNWIND := 1 + else + have_libunwind := 1 + $(call detected,CONFIG_LOCAL_LIBUNWIND) + endif + + ifneq ($(have_libunwind), 1) + NO_LIBUNWIND := 1 + endif +else + NO_LOCAL_LIBUNWIND := 1 +endif + +ifndef NO_LIBBPF + ifneq ($(feature-bpf), 1) + msg := $(warning BPF API too old. Please install recent kernel headers. BPF support in 'perf record' is disabled.) + NO_LIBBPF := 1 + endif +endif + +dwarf-post-unwind := 1 +dwarf-post-unwind-text := BUG + +# setup DWARF post unwinder +ifdef NO_LIBUNWIND + ifdef NO_LIBDW_DWARF_UNWIND + msg := $(warning Disabling post unwind, no support found.); + dwarf-post-unwind := 0 + else + dwarf-post-unwind-text := libdw + $(call detected,CONFIG_LIBDW_DWARF_UNWIND) + endif +else + dwarf-post-unwind-text := libunwind + $(call detected,CONFIG_LIBUNWIND) + # Enable libunwind support by default. + ifndef NO_LIBDW_DWARF_UNWIND + NO_LIBDW_DWARF_UNWIND := 1 + endif +endif + +ifeq ($(dwarf-post-unwind),1) + CFLAGS += -DHAVE_DWARF_UNWIND_SUPPORT + $(call detected,CONFIG_DWARF_UNWIND) +else + NO_DWARF_UNWIND := 1 +endif + +ifndef NO_LOCAL_LIBUNWIND + ifeq ($(ARCH),$(filter $(ARCH),arm arm64)) + $(call feature_check,libunwind-debug-frame) + ifneq ($(feature-libunwind-debug-frame), 1) + msg := $(warning No debug_frame support found in libunwind); + CFLAGS += -DNO_LIBUNWIND_DEBUG_FRAME + endif + else + # non-ARM has no dwarf_find_debug_frame() function: + CFLAGS += -DNO_LIBUNWIND_DEBUG_FRAME + endif + EXTLIBS += $(LIBUNWIND_LIBS) + LDFLAGS += $(LIBUNWIND_LIBS) +endif + +ifndef NO_LIBUNWIND + CFLAGS += -DHAVE_LIBUNWIND_SUPPORT + CFLAGS += $(LIBUNWIND_CFLAGS) + LDFLAGS += $(LIBUNWIND_LDFLAGS) + EXTLIBS += $(EXTLIBS_LIBUNWIND) +endif + +ifndef NO_LIBAUDIT + ifneq ($(feature-libaudit), 1) + msg := $(warning No libaudit.h found, disables 'trace' tool, please install audit-libs-devel or libaudit-dev); + NO_LIBAUDIT := 1 + else + CFLAGS += -DHAVE_LIBAUDIT_SUPPORT + EXTLIBS += -laudit + $(call detected,CONFIG_AUDIT) + endif +endif + +ifndef NO_LIBCRYPTO + ifneq ($(feature-libcrypto), 1) + msg := $(warning No libcrypto.h found, disables jitted code injection, please install libssl-devel or libssl-dev); + NO_LIBCRYPTO := 1 + else + CFLAGS += -DHAVE_LIBCRYPTO_SUPPORT + EXTLIBS += -lcrypto + $(call detected,CONFIG_CRYPTO) + endif +endif + +ifdef NO_NEWT + NO_SLANG=1 +endif + +ifndef NO_SLANG + ifneq ($(feature-libslang), 1) + msg := $(warning slang not found, disables TUI support. Please install slang-devel, libslang-dev or libslang2-dev); + NO_SLANG := 1 + else + # Fedora has /usr/include/slang/slang.h, but ubuntu /usr/include/slang.h + CFLAGS += -I/usr/include/slang + CFLAGS += -DHAVE_SLANG_SUPPORT + EXTLIBS += -lslang + $(call detected,CONFIG_SLANG) + endif +endif + +ifndef NO_GTK2 + FLAGS_GTK2=$(CFLAGS) $(LDFLAGS) $(EXTLIBS) $(shell $(PKG_CONFIG) --libs --cflags gtk+-2.0 2>/dev/null) + ifneq ($(feature-gtk2), 1) + msg := $(warning GTK2 not found, disables GTK2 support. Please install gtk2-devel or libgtk2.0-dev); + NO_GTK2 := 1 + else + ifeq ($(feature-gtk2-infobar), 1) + GTK_CFLAGS := -DHAVE_GTK_INFO_BAR_SUPPORT + endif + CFLAGS += -DHAVE_GTK2_SUPPORT + GTK_CFLAGS += $(shell $(PKG_CONFIG) --cflags gtk+-2.0 2>/dev/null) + GTK_LIBS := $(shell $(PKG_CONFIG) --libs gtk+-2.0 2>/dev/null) + EXTLIBS += -ldl + endif +endif + +grep-libs = $(filter -l%,$(1)) +strip-libs = $(filter-out -l%,$(1)) + +ifdef NO_LIBPERL + CFLAGS += -DNO_LIBPERL +else + PERL_EMBED_LDOPTS = $(shell perl -MExtUtils::Embed -e ldopts 2>/dev/null) + PERL_EMBED_LDFLAGS = $(call strip-libs,$(PERL_EMBED_LDOPTS)) + PERL_EMBED_LIBADD = $(call grep-libs,$(PERL_EMBED_LDOPTS)) + PERL_EMBED_CCOPTS = `perl -MExtUtils::Embed -e ccopts 2>/dev/null` + FLAGS_PERL_EMBED=$(PERL_EMBED_CCOPTS) $(PERL_EMBED_LDOPTS) + + ifneq ($(feature-libperl), 1) + CFLAGS += -DNO_LIBPERL + NO_LIBPERL := 1 + msg := $(warning Missing perl devel files. Disabling perl scripting support, please install perl-ExtUtils-Embed/libperl-dev); + else + LDFLAGS += $(PERL_EMBED_LDFLAGS) + EXTLIBS += $(PERL_EMBED_LIBADD) + $(call detected,CONFIG_LIBPERL) + endif +endif + +ifeq ($(feature-timerfd), 1) + CFLAGS += -DHAVE_TIMERFD_SUPPORT +else + msg := $(warning No timerfd support. Disables 'perf kvm stat live'); +endif + +disable-python = $(eval $(disable-python_code)) +define disable-python_code + CFLAGS += -DNO_LIBPYTHON + $(warning $1) + NO_LIBPYTHON := 1 +endef + +ifdef NO_LIBPYTHON + $(call disable-python,Python support disabled by user) +else + + ifndef PYTHON + $(call disable-python,No python interpreter was found: disables Python support - please install python-devel/python-dev) + else + PYTHON_WORD := $(call shell-wordify,$(PYTHON)) + + ifndef PYTHON_CONFIG + $(call disable-python,No 'python-config' tool was found: disables Python support - please install python-devel/python-dev) + else + + PYTHON_CONFIG_SQ := $(call shell-sq,$(PYTHON_CONFIG)) + + PYTHON_EMBED_LDOPTS := $(shell $(PYTHON_CONFIG_SQ) --ldflags 2>/dev/null) + PYTHON_EMBED_LDFLAGS := $(call strip-libs,$(PYTHON_EMBED_LDOPTS)) + PYTHON_EMBED_LIBADD := $(call grep-libs,$(PYTHON_EMBED_LDOPTS)) -lutil + PYTHON_EMBED_CCOPTS := $(shell $(PYTHON_CONFIG_SQ) --cflags 2>/dev/null) + FLAGS_PYTHON_EMBED := $(PYTHON_EMBED_CCOPTS) $(PYTHON_EMBED_LDOPTS) + + ifneq ($(feature-libpython), 1) + $(call disable-python,No 'Python.h' (for Python 2.x support) was found: disables Python support - please install python-devel/python-dev) + else + + ifneq ($(feature-libpython-version), 1) + $(warning Python 3 is not yet supported; please set) + $(warning PYTHON and/or PYTHON_CONFIG appropriately.) + $(warning If you also have Python 2 installed, then) + $(warning try something like:) + $(warning $(and ,)) + $(warning $(and ,) make PYTHON=python2) + $(warning $(and ,)) + $(warning Otherwise, disable Python support entirely:) + $(warning $(and ,)) + $(warning $(and ,) make NO_LIBPYTHON=1) + $(warning $(and ,)) + $(error $(and ,)) + else + LDFLAGS += $(PYTHON_EMBED_LDFLAGS) + EXTLIBS += $(PYTHON_EMBED_LIBADD) + LANG_BINDINGS += $(obj-perf)python/perf.so + $(call detected,CONFIG_LIBPYTHON) + endif + endif + endif + endif +endif + +ifeq ($(feature-libbfd), 1) + EXTLIBS += -lbfd + + # call all detections now so we get correct + # status in VF output + $(call feature_check,liberty) + $(call feature_check,liberty-z) + $(call feature_check,cplus-demangle) + + ifeq ($(feature-liberty), 1) + EXTLIBS += -liberty + else + ifeq ($(feature-liberty-z), 1) + EXTLIBS += -liberty -lz + endif + endif +endif + +ifdef NO_DEMANGLE + CFLAGS += -DNO_DEMANGLE +else + ifdef HAVE_CPLUS_DEMANGLE_SUPPORT + EXTLIBS += -liberty + CFLAGS += -DHAVE_CPLUS_DEMANGLE_SUPPORT + else + ifneq ($(feature-libbfd), 1) + ifneq ($(feature-liberty), 1) + ifneq ($(feature-liberty-z), 1) + # we dont have neither HAVE_CPLUS_DEMANGLE_SUPPORT + # or any of 'bfd iberty z' trinity + ifeq ($(feature-cplus-demangle), 1) + EXTLIBS += -liberty + CFLAGS += -DHAVE_CPLUS_DEMANGLE_SUPPORT + else + msg := $(warning No bfd.h/libbfd found, please install binutils-dev[el]/zlib-static/libiberty-dev to gain symbol demangling) + CFLAGS += -DNO_DEMANGLE + endif + endif + endif + endif + endif +endif + +ifneq ($(filter -lbfd,$(EXTLIBS)),) + CFLAGS += -DHAVE_LIBBFD_SUPPORT +endif + +ifndef NO_ZLIB + ifeq ($(feature-zlib), 1) + CFLAGS += -DHAVE_ZLIB_SUPPORT + EXTLIBS += -lz + $(call detected,CONFIG_ZLIB) + else + NO_ZLIB := 1 + endif +endif + +ifndef NO_LZMA + ifeq ($(feature-lzma), 1) + CFLAGS += -DHAVE_LZMA_SUPPORT + EXTLIBS += -llzma + $(call detected,CONFIG_LZMA) + else + msg := $(warning No liblzma found, disables xz kernel module decompression, please install xz-devel/liblzma-dev); + NO_LZMA := 1 + endif +endif + +ifndef NO_BACKTRACE + ifeq ($(feature-backtrace), 1) + CFLAGS += -DHAVE_BACKTRACE_SUPPORT + endif +endif + +ifndef NO_LIBNUMA + ifeq ($(feature-libnuma), 0) + msg := $(warning No numa.h found, disables 'perf bench numa mem' benchmark, please install numactl-devel/libnuma-devel/libnuma-dev); + NO_LIBNUMA := 1 + else + ifeq ($(feature-numa_num_possible_cpus), 0) + msg := $(warning Old numa library found, disables 'perf bench numa mem' benchmark, please install numactl-devel/libnuma-devel/libnuma-dev >= 2.0.8); + NO_LIBNUMA := 1 + else + CFLAGS += -DHAVE_LIBNUMA_SUPPORT + EXTLIBS += -lnuma + $(call detected,CONFIG_NUMA) + endif + endif +endif + +ifdef HAVE_KVM_STAT_SUPPORT + CFLAGS += -DHAVE_KVM_STAT_SUPPORT +endif + +ifeq (${IS_64_BIT}, 1) + ifndef NO_PERF_READ_VDSO32 + $(call feature_check,compile-32) + ifeq ($(feature-compile-32), 1) + CFLAGS += -DHAVE_PERF_READ_VDSO32 + else + NO_PERF_READ_VDSO32 := 1 + endif + endif + ifneq ($(ARCH), x86) + NO_PERF_READ_VDSOX32 := 1 + endif + ifndef NO_PERF_READ_VDSOX32 + $(call feature_check,compile-x32) + ifeq ($(feature-compile-x32), 1) + CFLAGS += -DHAVE_PERF_READ_VDSOX32 + else + NO_PERF_READ_VDSOX32 := 1 + endif + endif +else + NO_PERF_READ_VDSO32 := 1 + NO_PERF_READ_VDSOX32 := 1 +endif + +ifdef LIBBABELTRACE + $(call feature_check,libbabeltrace) + ifeq ($(feature-libbabeltrace), 1) + CFLAGS += -DHAVE_LIBBABELTRACE_SUPPORT $(LIBBABELTRACE_CFLAGS) + LDFLAGS += $(LIBBABELTRACE_LDFLAGS) + EXTLIBS += -lbabeltrace-ctf + $(call detected,CONFIG_LIBBABELTRACE) + else + msg := $(warning No libbabeltrace found, disables 'perf data' CTF format support, please install libbabeltrace-dev[el]/libbabeltrace-ctf-dev); + endif +endif + +ifndef NO_AUXTRACE + ifeq ($(feature-get_cpuid), 0) + msg := $(warning Your gcc lacks the __get_cpuid() builtin, disables support for auxtrace/Intel PT, please install a newer gcc); + NO_AUXTRACE := 1 + else + $(call detected,CONFIG_AUXTRACE) + CFLAGS += -DHAVE_AUXTRACE_SUPPORT + endif +endif + +# Among the variables below, these: +# perfexecdir +# template_dir +# mandir +# infodir +# htmldir +# ETC_PERFCONFIG (but not sysconfdir) +# can be specified as a relative path some/where/else; +# this is interpreted as relative to $(prefix) and "perf" at +# runtime figures out where they are based on the path to the executable. +# This can help installing the suite in a relocatable way. + +# Make the path relative to DESTDIR, not to prefix +ifndef DESTDIR +prefix ?= $(HOME) +endif +bindir_relative = bin +bindir = $(abspath $(prefix)/$(bindir_relative)) +mandir = share/man +infodir = share/info +perfexecdir = libexec/perf-core +sharedir = $(prefix)/share +template_dir = share/perf-core/templates +STRACE_GROUPS_DIR = share/perf-core/strace/groups +htmldir = share/doc/perf-doc +tipdir = share/doc/perf-tip +srcdir = $(srctree)/tools/perf +ifeq ($(prefix),/usr) +sysconfdir = /etc +ETC_PERFCONFIG = $(sysconfdir)/perfconfig +else +sysconfdir = $(prefix)/etc +ETC_PERFCONFIG = etc/perfconfig +endif +ifndef lib +ifeq ($(ARCH)$(IS_64_BIT), x861) +lib = lib64 +else +lib = lib +endif +endif # lib +libdir = $(prefix)/$(lib) + +# Shell quote (do not use $(call) to accommodate ancient setups); +ETC_PERFCONFIG_SQ = $(subst ','\'',$(ETC_PERFCONFIG)) +STRACE_GROUPS_DIR_SQ = $(subst ','\'',$(STRACE_GROUPS_DIR)) +DESTDIR_SQ = $(subst ','\'',$(DESTDIR)) +bindir_SQ = $(subst ','\'',$(bindir)) +mandir_SQ = $(subst ','\'',$(mandir)) +infodir_SQ = $(subst ','\'',$(infodir)) +perfexecdir_SQ = $(subst ','\'',$(perfexecdir)) +template_dir_SQ = $(subst ','\'',$(template_dir)) +htmldir_SQ = $(subst ','\'',$(htmldir)) +tipdir_SQ = $(subst ','\'',$(tipdir)) +prefix_SQ = $(subst ','\'',$(prefix)) +sysconfdir_SQ = $(subst ','\'',$(sysconfdir)) +libdir_SQ = $(subst ','\'',$(libdir)) +srcdir_SQ = $(subst ','\'',$(srcdir)) + +ifneq ($(filter /%,$(firstword $(perfexecdir))),) +perfexec_instdir = $(perfexecdir) +STRACE_GROUPS_INSTDIR = $(STRACE_GROUPS_DIR) +tip_instdir = $(tipdir) +else +perfexec_instdir = $(prefix)/$(perfexecdir) +STRACE_GROUPS_INSTDIR = $(prefix)/$(STRACE_GROUPS_DIR) +tip_instdir = $(prefix)/$(tipdir) +endif +perfexec_instdir_SQ = $(subst ','\'',$(perfexec_instdir)) +STRACE_GROUPS_INSTDIR_SQ = $(subst ','\'',$(STRACE_GROUPS_INSTDIR)) +tip_instdir_SQ = $(subst ','\'',$(tip_instdir)) + +# If we install to $(HOME) we keep the traceevent default: +# $(HOME)/.traceevent/plugins +# Otherwise we install plugins into the global $(libdir). +ifdef DESTDIR +plugindir=$(libdir)/traceevent/plugins +plugindir_SQ= $(subst ','\'',$(plugindir)) +endif + +print_var = $(eval $(print_var_code)) $(info $(MSG)) +define print_var_code + MSG = $(shell printf '...%30s: %s' $(1) $($(1))) +endef + +ifeq ($(VF),1) + $(call print_var,prefix) + $(call print_var,bindir) + $(call print_var,libdir) + $(call print_var,sysconfdir) + $(call print_var,LIBUNWIND_DIR) + $(call print_var,LIBDW_DIR) + + ifeq ($(dwarf-post-unwind),1) + $(call feature_print_text,"DWARF post unwind library", $(dwarf-post-unwind-text)) + endif + $(info ) +endif + +$(call detected_var,bindir_SQ) +$(call detected_var,PYTHON_WORD) +ifneq ($(OUTPUT),) +$(call detected_var,OUTPUT) +endif +$(call detected_var,htmldir_SQ) +$(call detected_var,infodir_SQ) +$(call detected_var,mandir_SQ) +$(call detected_var,ETC_PERFCONFIG_SQ) +$(call detected_var,STRACE_GROUPS_DIR_SQ) +$(call detected_var,prefix_SQ) +$(call detected_var,perfexecdir_SQ) +$(call detected_var,tipdir_SQ) +$(call detected_var,srcdir_SQ) +$(call detected_var,LIBDIR) +$(call detected_var,GTK_CFLAGS) +$(call detected_var,PERL_EMBED_CCOPTS) +$(call detected_var,PYTHON_EMBED_CCOPTS) diff --git a/tools/perf/Makefile.perf b/tools/perf/Makefile.perf index 6641abb97f0a..2d9087501633 100644 --- a/tools/perf/Makefile.perf +++ b/tools/perf/Makefile.perf @@ -161,7 +161,7 @@ TRACE_EVENT_DIR = $(srctree)/tools/lib/traceevent/ BPF_DIR = $(srctree)/tools/lib/bpf/ SUBCMD_DIR = $(srctree)/tools/lib/subcmd/ -# include config/Makefile by default and rule out +# include Makefile.config by default and rule out # non-config cases config := 1 @@ -183,7 +183,7 @@ ifeq ($(filter feature-dump,$(MAKECMDGOALS)),feature-dump) FEATURE_TESTS := all endif endif -include config/Makefile +include Makefile.config endif ifeq ($(config),0) @@ -706,7 +706,7 @@ $(INSTALL_DOC_TARGETS): ### Cleaning rules # -# This is here, not in config/Makefile, because config/Makefile does +# This is here, not in Makefile.config, because Makefile.config does # not get included for the clean target: # config-clean: diff --git a/tools/perf/config/Makefile b/tools/perf/config/Makefile deleted file mode 100644 index 24803c58049a..000000000000 --- a/tools/perf/config/Makefile +++ /dev/null @@ -1,874 +0,0 @@ - -ifeq ($(src-perf),) -src-perf := $(srctree)/tools/perf -endif - -ifeq ($(obj-perf),) -obj-perf := $(OUTPUT) -endif - -ifneq ($(obj-perf),) -obj-perf := $(abspath $(obj-perf))/ -endif - -$(shell printf "" > $(OUTPUT).config-detected) -detected = $(shell echo "$(1)=y" >> $(OUTPUT).config-detected) -detected_var = $(shell echo "$(1)=$($(1))" >> $(OUTPUT).config-detected) - -CFLAGS := $(EXTRA_CFLAGS) $(EXTRA_WARNINGS) - -include $(srctree)/tools/scripts/Makefile.arch - -$(call detected_var,ARCH) - -NO_PERF_REGS := 1 - -# Additional ARCH settings for ppc -ifeq ($(ARCH),powerpc) - NO_PERF_REGS := 0 - LIBUNWIND_LIBS := -lunwind -lunwind-ppc64 -endif - -# Additional ARCH settings for x86 -ifeq ($(ARCH),x86) - $(call detected,CONFIG_X86) - ifeq (${IS_64_BIT}, 1) - CFLAGS += -DHAVE_ARCH_X86_64_SUPPORT -DHAVE_SYSCALL_TABLE -I$(OUTPUT)arch/x86/include/generated - ARCH_INCLUDE = ../../arch/x86/lib/memcpy_64.S ../../arch/x86/lib/memset_64.S - LIBUNWIND_LIBS = -lunwind -lunwind-x86_64 - $(call detected,CONFIG_X86_64) - else - LIBUNWIND_LIBS = -lunwind-x86 -llzma -lunwind - endif - NO_PERF_REGS := 0 -endif - -ifeq ($(ARCH),arm) - NO_PERF_REGS := 0 - LIBUNWIND_LIBS = -lunwind -lunwind-arm -endif - -ifeq ($(ARCH),arm64) - NO_PERF_REGS := 0 - LIBUNWIND_LIBS = -lunwind -lunwind-aarch64 -endif - -ifeq ($(NO_PERF_REGS),0) - $(call detected,CONFIG_PERF_REGS) -endif - -# So far there's only x86 and arm libdw unwind support merged in perf. -# Disable it on all other architectures in case libdw unwind -# support is detected in system. Add supported architectures -# to the check. -ifneq ($(ARCH),$(filter $(ARCH),x86 arm)) - NO_LIBDW_DWARF_UNWIND := 1 -endif - -ifeq ($(LIBUNWIND_LIBS),) - NO_LIBUNWIND := 1 -endif -# -# For linking with debug library, run like: -# -# make DEBUG=1 LIBUNWIND_DIR=/opt/libunwind/ -# - -libunwind_arch_set_flags = $(eval $(libunwind_arch_set_flags_code)) -define libunwind_arch_set_flags_code - FEATURE_CHECK_CFLAGS-libunwind-$(1) = -I$(LIBUNWIND_DIR)/include - FEATURE_CHECK_LDFLAGS-libunwind-$(1) = -L$(LIBUNWIND_DIR)/lib -endef - -ifdef LIBUNWIND_DIR - LIBUNWIND_CFLAGS = -I$(LIBUNWIND_DIR)/include - LIBUNWIND_LDFLAGS = -L$(LIBUNWIND_DIR)/lib - LIBUNWIND_ARCHS = x86 x86_64 arm aarch64 debug-frame-arm debug-frame-aarch64 - $(foreach libunwind_arch,$(LIBUNWIND_ARCHS),$(call libunwind_arch_set_flags,$(libunwind_arch))) -endif - -# Set per-feature check compilation flags -FEATURE_CHECK_CFLAGS-libunwind = $(LIBUNWIND_CFLAGS) -FEATURE_CHECK_LDFLAGS-libunwind = $(LIBUNWIND_LDFLAGS) $(LIBUNWIND_LIBS) -FEATURE_CHECK_CFLAGS-libunwind-debug-frame = $(LIBUNWIND_CFLAGS) -FEATURE_CHECK_LDFLAGS-libunwind-debug-frame = $(LIBUNWIND_LDFLAGS) $(LIBUNWIND_LIBS) - -ifeq ($(NO_PERF_REGS),0) - CFLAGS += -DHAVE_PERF_REGS_SUPPORT -endif - -# for linking with debug library, run like: -# make DEBUG=1 LIBDW_DIR=/opt/libdw/ -ifdef LIBDW_DIR - LIBDW_CFLAGS := -I$(LIBDW_DIR)/include - LIBDW_LDFLAGS := -L$(LIBDW_DIR)/lib -endif -FEATURE_CHECK_CFLAGS-libdw-dwarf-unwind := $(LIBDW_CFLAGS) -FEATURE_CHECK_LDFLAGS-libdw-dwarf-unwind := $(LIBDW_LDFLAGS) -ldw - -# for linking with debug library, run like: -# make DEBUG=1 LIBBABELTRACE_DIR=/opt/libbabeltrace/ -ifdef LIBBABELTRACE_DIR - LIBBABELTRACE_CFLAGS := -I$(LIBBABELTRACE_DIR)/include - LIBBABELTRACE_LDFLAGS := -L$(LIBBABELTRACE_DIR)/lib -endif -FEATURE_CHECK_CFLAGS-libbabeltrace := $(LIBBABELTRACE_CFLAGS) -FEATURE_CHECK_LDFLAGS-libbabeltrace := $(LIBBABELTRACE_LDFLAGS) -lbabeltrace-ctf - -FEATURE_CHECK_CFLAGS-bpf = -I. -I$(srctree)/tools/include -I$(srctree)/tools/arch/$(ARCH)/include/uapi -I$(srctree)/tools/include/uapi -# include ARCH specific config --include $(src-perf)/arch/$(ARCH)/Makefile - -ifdef PERF_HAVE_ARCH_REGS_QUERY_REGISTER_OFFSET - CFLAGS += -DHAVE_ARCH_REGS_QUERY_REGISTER_OFFSET -endif - -include $(srctree)/tools/scripts/utilities.mak - -ifeq ($(call get-executable,$(FLEX)),) - dummy := $(error Error: $(FLEX) is missing on this system, please install it) -endif - -ifeq ($(call get-executable,$(BISON)),) - dummy := $(error Error: $(BISON) is missing on this system, please install it) -endif - -# Treat warnings as errors unless directed not to -ifneq ($(WERROR),0) - CFLAGS += -Werror -endif - -ifndef DEBUG - DEBUG := 0 -endif - -ifeq ($(DEBUG),0) - CFLAGS += -O6 -endif - -ifdef PARSER_DEBUG - PARSER_DEBUG_BISON := -t - PARSER_DEBUG_FLEX := -d - CFLAGS += -DPARSER_DEBUG - $(call detected_var,PARSER_DEBUG_BISON) - $(call detected_var,PARSER_DEBUG_FLEX) -endif - -# Try different combinations to accommodate systems that only have -# python[2][-config] in weird combinations but always preferring -# python2 and python2-config as per pep-0394. If we catch a -# python[-config] in version 3, the version check will kill it. -PYTHON2 := $(if $(call get-executable,python2),python2,python) -override PYTHON := $(call get-executable-or-default,PYTHON,$(PYTHON2)) -PYTHON2_CONFIG := \ - $(if $(call get-executable,$(PYTHON)-config),$(PYTHON)-config,python-config) -override PYTHON_CONFIG := \ - $(call get-executable-or-default,PYTHON_CONFIG,$(PYTHON2_CONFIG)) - -PYTHON_CONFIG_SQ := $(call shell-sq,$(PYTHON_CONFIG)) - -PYTHON_EMBED_LDOPTS := $(shell $(PYTHON_CONFIG_SQ) --ldflags 2>/dev/null) -PYTHON_EMBED_CCOPTS := $(shell $(PYTHON_CONFIG_SQ) --cflags 2>/dev/null) - -FEATURE_CHECK_CFLAGS-libpython := $(PYTHON_EMBED_CCOPTS) -FEATURE_CHECK_LDFLAGS-libpython := $(PYTHON_EMBED_LDOPTS) -FEATURE_CHECK_CFLAGS-libpython-version := $(PYTHON_EMBED_CCOPTS) -FEATURE_CHECK_LDFLAGS-libpython-version := $(PYTHON_EMBED_LDOPTS) - -CFLAGS += -fno-omit-frame-pointer -CFLAGS += -ggdb3 -CFLAGS += -funwind-tables -CFLAGS += -Wall -CFLAGS += -Wextra -CFLAGS += -std=gnu99 - -# Enforce a non-executable stack, as we may regress (again) in the future by -# adding assembler files missing the .GNU-stack linker note. -LDFLAGS += -Wl,-z,noexecstack - -EXTLIBS = -lpthread -lrt -lm -ldl - -ifeq ($(FEATURES_DUMP),) -include $(srctree)/tools/build/Makefile.feature -else -include $(FEATURES_DUMP) -endif - -ifeq ($(feature-stackprotector-all), 1) - CFLAGS += -fstack-protector-all -endif - -ifeq ($(DEBUG),0) - ifeq ($(feature-fortify-source), 1) - CFLAGS += -D_FORTIFY_SOURCE=2 - endif -endif - -CFLAGS += -I$(src-perf)/util/include -CFLAGS += -I$(src-perf)/arch/$(ARCH)/include -CFLAGS += -I$(srctree)/tools/include/uapi -CFLAGS += -I$(srctree)/tools/include/ -CFLAGS += -I$(srctree)/tools/arch/$(ARCH)/include/uapi -CFLAGS += -I$(srctree)/tools/arch/$(ARCH)/include/ -CFLAGS += -I$(srctree)/tools/arch/$(ARCH)/ - -# $(obj-perf) for generated common-cmds.h -# $(obj-perf)/util for generated bison/flex headers -ifneq ($(OUTPUT),) -CFLAGS += -I$(obj-perf)/util -CFLAGS += -I$(obj-perf) -endif - -CFLAGS += -I$(src-perf)/util -CFLAGS += -I$(src-perf) -CFLAGS += -I$(srctree)/tools/lib/ - -CFLAGS += -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 -D_GNU_SOURCE - -ifeq ($(feature-sync-compare-and-swap), 1) - CFLAGS += -DHAVE_SYNC_COMPARE_AND_SWAP_SUPPORT -endif - -ifeq ($(feature-pthread-attr-setaffinity-np), 1) - CFLAGS += -DHAVE_PTHREAD_ATTR_SETAFFINITY_NP -endif - -ifndef NO_BIONIC - $(call feature_check,bionic) - ifeq ($(feature-bionic), 1) - BIONIC := 1 - EXTLIBS := $(filter-out -lrt,$(EXTLIBS)) - EXTLIBS := $(filter-out -lpthread,$(EXTLIBS)) - endif -endif - -ifdef NO_LIBELF - NO_DWARF := 1 - NO_DEMANGLE := 1 - NO_LIBUNWIND := 1 - NO_LIBDW_DWARF_UNWIND := 1 - NO_LIBBPF := 1 -else - ifeq ($(feature-libelf), 0) - ifeq ($(feature-glibc), 1) - LIBC_SUPPORT := 1 - endif - ifeq ($(BIONIC),1) - LIBC_SUPPORT := 1 - endif - ifeq ($(LIBC_SUPPORT),1) - msg := $(warning No libelf found, disables 'probe' tool and BPF support in 'perf record', please install libelf-dev, libelf-devel or elfutils-libelf-devel); - - NO_LIBELF := 1 - NO_DWARF := 1 - NO_DEMANGLE := 1 - NO_LIBUNWIND := 1 - NO_LIBDW_DWARF_UNWIND := 1 - NO_LIBBPF := 1 - else - ifneq ($(filter s% -static%,$(LDFLAGS),),) - msg := $(error No static glibc found, please install glibc-static); - else - msg := $(error No gnu/libc-version.h found, please install glibc-dev[el]); - endif - endif - else - ifndef NO_LIBDW_DWARF_UNWIND - ifneq ($(feature-libdw-dwarf-unwind),1) - NO_LIBDW_DWARF_UNWIND := 1 - msg := $(warning No libdw DWARF unwind found, Please install elfutils-devel/libdw-dev >= 0.158 and/or set LIBDW_DIR); - endif - endif - ifneq ($(feature-dwarf), 1) - msg := $(warning No libdw.h found or old libdw.h found or elfutils is older than 0.138, disables dwarf support. Please install new elfutils-devel/libdw-dev); - NO_DWARF := 1 - else - ifneq ($(feature-dwarf_getlocations), 1) - msg := $(warning Old libdw.h, finding variables at given 'perf probe' point will not work, install elfutils-devel/libdw-dev >= 0.157); - else - CFLAGS += -DHAVE_DWARF_GETLOCATIONS - endif # dwarf_getlocations - endif # Dwarf support - endif # libelf support -endif # NO_LIBELF - -ifdef NO_DWARF - NO_LIBDW_DWARF_UNWIND := 1 -endif - -ifndef NO_LIBELF - CFLAGS += -DHAVE_LIBELF_SUPPORT - EXTLIBS += -lelf - $(call detected,CONFIG_LIBELF) - - ifeq ($(feature-libelf-mmap), 1) - CFLAGS += -DHAVE_LIBELF_MMAP_SUPPORT - endif - - ifeq ($(feature-libelf-getphdrnum), 1) - CFLAGS += -DHAVE_ELF_GETPHDRNUM_SUPPORT - endif - - ifeq ($(feature-libelf-gelf_getnote), 1) - CFLAGS += -DHAVE_GELF_GETNOTE_SUPPORT - else - msg := $(warning gelf_getnote() not found on libelf, SDT support disabled); - endif - - ifeq ($(feature-libelf-getshdrstrndx), 1) - CFLAGS += -DHAVE_ELF_GETSHDRSTRNDX_SUPPORT - endif - - ifndef NO_DWARF - ifeq ($(origin PERF_HAVE_DWARF_REGS), undefined) - msg := $(warning DWARF register mappings have not been defined for architecture $(ARCH), DWARF support disabled); - NO_DWARF := 1 - else - CFLAGS += -DHAVE_DWARF_SUPPORT $(LIBDW_CFLAGS) - LDFLAGS += $(LIBDW_LDFLAGS) - DWARFLIBS := -ldw - ifeq ($(findstring -static,${LDFLAGS}),-static) - DWARFLIBS += -lelf -lebl -lz -llzma -lbz2 - endif - EXTLIBS += ${DWARFLIBS} - $(call detected,CONFIG_DWARF) - endif # PERF_HAVE_DWARF_REGS - endif # NO_DWARF - - ifndef NO_LIBBPF - ifeq ($(feature-bpf), 1) - CFLAGS += -DHAVE_LIBBPF_SUPPORT - $(call detected,CONFIG_LIBBPF) - endif - - ifndef NO_DWARF - ifdef PERF_HAVE_ARCH_REGS_QUERY_REGISTER_OFFSET - CFLAGS += -DHAVE_BPF_PROLOGUE - $(call detected,CONFIG_BPF_PROLOGUE) - else - msg := $(warning BPF prologue is not supported by architecture $(ARCH), missing regs_query_register_offset()); - endif - else - msg := $(warning DWARF support is off, BPF prologue is disabled); - endif - - endif # NO_LIBBPF -endif # NO_LIBELF - -ifndef NO_SDT - ifneq ($(feature-sdt), 1) - msg := $(warning No sys/sdt.h found, no SDT events are defined, please install systemtap-sdt-devel or systemtap-sdt-dev); - NO_SDT := 1; - else - CFLAGS += -DHAVE_SDT_EVENT - $(call detected,CONFIG_SDT_EVENT) - endif -endif - -ifdef PERF_HAVE_JITDUMP - ifndef NO_DWARF - $(call detected,CONFIG_JITDUMP) - CFLAGS += -DHAVE_JITDUMP - endif -endif - -ifeq ($(ARCH),powerpc) - ifndef NO_DWARF - CFLAGS += -DHAVE_SKIP_CALLCHAIN_IDX - endif -endif - -ifndef NO_LIBUNWIND - have_libunwind := - - ifeq ($(feature-libunwind-x86), 1) - $(call detected,CONFIG_LIBUNWIND_X86) - CFLAGS += -DHAVE_LIBUNWIND_X86_SUPPORT - LDFLAGS += -lunwind-x86 - EXTLIBS_LIBUNWIND += -lunwind-x86 - have_libunwind = 1 - endif - - ifeq ($(feature-libunwind-aarch64), 1) - $(call detected,CONFIG_LIBUNWIND_AARCH64) - CFLAGS += -DHAVE_LIBUNWIND_AARCH64_SUPPORT - LDFLAGS += -lunwind-aarch64 - EXTLIBS_LIBUNWIND += -lunwind-aarch64 - have_libunwind = 1 - $(call feature_check,libunwind-debug-frame-aarch64) - ifneq ($(feature-libunwind-debug-frame-aarch64), 1) - msg := $(warning No debug_frame support found in libunwind-aarch64); - CFLAGS += -DNO_LIBUNWIND_DEBUG_FRAME_AARCH64 - endif - endif - - ifneq ($(feature-libunwind), 1) - msg := $(warning No libunwind found. Please install libunwind-dev[el] >= 1.1 and/or set LIBUNWIND_DIR); - NO_LOCAL_LIBUNWIND := 1 - else - have_libunwind := 1 - $(call detected,CONFIG_LOCAL_LIBUNWIND) - endif - - ifneq ($(have_libunwind), 1) - NO_LIBUNWIND := 1 - endif -else - NO_LOCAL_LIBUNWIND := 1 -endif - -ifndef NO_LIBBPF - ifneq ($(feature-bpf), 1) - msg := $(warning BPF API too old. Please install recent kernel headers. BPF support in 'perf record' is disabled.) - NO_LIBBPF := 1 - endif -endif - -dwarf-post-unwind := 1 -dwarf-post-unwind-text := BUG - -# setup DWARF post unwinder -ifdef NO_LIBUNWIND - ifdef NO_LIBDW_DWARF_UNWIND - msg := $(warning Disabling post unwind, no support found.); - dwarf-post-unwind := 0 - else - dwarf-post-unwind-text := libdw - $(call detected,CONFIG_LIBDW_DWARF_UNWIND) - endif -else - dwarf-post-unwind-text := libunwind - $(call detected,CONFIG_LIBUNWIND) - # Enable libunwind support by default. - ifndef NO_LIBDW_DWARF_UNWIND - NO_LIBDW_DWARF_UNWIND := 1 - endif -endif - -ifeq ($(dwarf-post-unwind),1) - CFLAGS += -DHAVE_DWARF_UNWIND_SUPPORT - $(call detected,CONFIG_DWARF_UNWIND) -else - NO_DWARF_UNWIND := 1 -endif - -ifndef NO_LOCAL_LIBUNWIND - ifeq ($(ARCH),$(filter $(ARCH),arm arm64)) - $(call feature_check,libunwind-debug-frame) - ifneq ($(feature-libunwind-debug-frame), 1) - msg := $(warning No debug_frame support found in libunwind); - CFLAGS += -DNO_LIBUNWIND_DEBUG_FRAME - endif - else - # non-ARM has no dwarf_find_debug_frame() function: - CFLAGS += -DNO_LIBUNWIND_DEBUG_FRAME - endif - EXTLIBS += $(LIBUNWIND_LIBS) - LDFLAGS += $(LIBUNWIND_LIBS) -endif - -ifndef NO_LIBUNWIND - CFLAGS += -DHAVE_LIBUNWIND_SUPPORT - CFLAGS += $(LIBUNWIND_CFLAGS) - LDFLAGS += $(LIBUNWIND_LDFLAGS) - EXTLIBS += $(EXTLIBS_LIBUNWIND) -endif - -ifndef NO_LIBAUDIT - ifneq ($(feature-libaudit), 1) - msg := $(warning No libaudit.h found, disables 'trace' tool, please install audit-libs-devel or libaudit-dev); - NO_LIBAUDIT := 1 - else - CFLAGS += -DHAVE_LIBAUDIT_SUPPORT - EXTLIBS += -laudit - $(call detected,CONFIG_AUDIT) - endif -endif - -ifndef NO_LIBCRYPTO - ifneq ($(feature-libcrypto), 1) - msg := $(warning No libcrypto.h found, disables jitted code injection, please install libssl-devel or libssl-dev); - NO_LIBCRYPTO := 1 - else - CFLAGS += -DHAVE_LIBCRYPTO_SUPPORT - EXTLIBS += -lcrypto - $(call detected,CONFIG_CRYPTO) - endif -endif - -ifdef NO_NEWT - NO_SLANG=1 -endif - -ifndef NO_SLANG - ifneq ($(feature-libslang), 1) - msg := $(warning slang not found, disables TUI support. Please install slang-devel, libslang-dev or libslang2-dev); - NO_SLANG := 1 - else - # Fedora has /usr/include/slang/slang.h, but ubuntu /usr/include/slang.h - CFLAGS += -I/usr/include/slang - CFLAGS += -DHAVE_SLANG_SUPPORT - EXTLIBS += -lslang - $(call detected,CONFIG_SLANG) - endif -endif - -ifndef NO_GTK2 - FLAGS_GTK2=$(CFLAGS) $(LDFLAGS) $(EXTLIBS) $(shell $(PKG_CONFIG) --libs --cflags gtk+-2.0 2>/dev/null) - ifneq ($(feature-gtk2), 1) - msg := $(warning GTK2 not found, disables GTK2 support. Please install gtk2-devel or libgtk2.0-dev); - NO_GTK2 := 1 - else - ifeq ($(feature-gtk2-infobar), 1) - GTK_CFLAGS := -DHAVE_GTK_INFO_BAR_SUPPORT - endif - CFLAGS += -DHAVE_GTK2_SUPPORT - GTK_CFLAGS += $(shell $(PKG_CONFIG) --cflags gtk+-2.0 2>/dev/null) - GTK_LIBS := $(shell $(PKG_CONFIG) --libs gtk+-2.0 2>/dev/null) - EXTLIBS += -ldl - endif -endif - -grep-libs = $(filter -l%,$(1)) -strip-libs = $(filter-out -l%,$(1)) - -ifdef NO_LIBPERL - CFLAGS += -DNO_LIBPERL -else - PERL_EMBED_LDOPTS = $(shell perl -MExtUtils::Embed -e ldopts 2>/dev/null) - PERL_EMBED_LDFLAGS = $(call strip-libs,$(PERL_EMBED_LDOPTS)) - PERL_EMBED_LIBADD = $(call grep-libs,$(PERL_EMBED_LDOPTS)) - PERL_EMBED_CCOPTS = `perl -MExtUtils::Embed -e ccopts 2>/dev/null` - FLAGS_PERL_EMBED=$(PERL_EMBED_CCOPTS) $(PERL_EMBED_LDOPTS) - - ifneq ($(feature-libperl), 1) - CFLAGS += -DNO_LIBPERL - NO_LIBPERL := 1 - msg := $(warning Missing perl devel files. Disabling perl scripting support, please install perl-ExtUtils-Embed/libperl-dev); - else - LDFLAGS += $(PERL_EMBED_LDFLAGS) - EXTLIBS += $(PERL_EMBED_LIBADD) - $(call detected,CONFIG_LIBPERL) - endif -endif - -ifeq ($(feature-timerfd), 1) - CFLAGS += -DHAVE_TIMERFD_SUPPORT -else - msg := $(warning No timerfd support. Disables 'perf kvm stat live'); -endif - -disable-python = $(eval $(disable-python_code)) -define disable-python_code - CFLAGS += -DNO_LIBPYTHON - $(warning $1) - NO_LIBPYTHON := 1 -endef - -ifdef NO_LIBPYTHON - $(call disable-python,Python support disabled by user) -else - - ifndef PYTHON - $(call disable-python,No python interpreter was found: disables Python support - please install python-devel/python-dev) - else - PYTHON_WORD := $(call shell-wordify,$(PYTHON)) - - ifndef PYTHON_CONFIG - $(call disable-python,No 'python-config' tool was found: disables Python support - please install python-devel/python-dev) - else - - PYTHON_CONFIG_SQ := $(call shell-sq,$(PYTHON_CONFIG)) - - PYTHON_EMBED_LDOPTS := $(shell $(PYTHON_CONFIG_SQ) --ldflags 2>/dev/null) - PYTHON_EMBED_LDFLAGS := $(call strip-libs,$(PYTHON_EMBED_LDOPTS)) - PYTHON_EMBED_LIBADD := $(call grep-libs,$(PYTHON_EMBED_LDOPTS)) -lutil - PYTHON_EMBED_CCOPTS := $(shell $(PYTHON_CONFIG_SQ) --cflags 2>/dev/null) - FLAGS_PYTHON_EMBED := $(PYTHON_EMBED_CCOPTS) $(PYTHON_EMBED_LDOPTS) - - ifneq ($(feature-libpython), 1) - $(call disable-python,No 'Python.h' (for Python 2.x support) was found: disables Python support - please install python-devel/python-dev) - else - - ifneq ($(feature-libpython-version), 1) - $(warning Python 3 is not yet supported; please set) - $(warning PYTHON and/or PYTHON_CONFIG appropriately.) - $(warning If you also have Python 2 installed, then) - $(warning try something like:) - $(warning $(and ,)) - $(warning $(and ,) make PYTHON=python2) - $(warning $(and ,)) - $(warning Otherwise, disable Python support entirely:) - $(warning $(and ,)) - $(warning $(and ,) make NO_LIBPYTHON=1) - $(warning $(and ,)) - $(error $(and ,)) - else - LDFLAGS += $(PYTHON_EMBED_LDFLAGS) - EXTLIBS += $(PYTHON_EMBED_LIBADD) - LANG_BINDINGS += $(obj-perf)python/perf.so - $(call detected,CONFIG_LIBPYTHON) - endif - endif - endif - endif -endif - -ifeq ($(feature-libbfd), 1) - EXTLIBS += -lbfd - - # call all detections now so we get correct - # status in VF output - $(call feature_check,liberty) - $(call feature_check,liberty-z) - $(call feature_check,cplus-demangle) - - ifeq ($(feature-liberty), 1) - EXTLIBS += -liberty - else - ifeq ($(feature-liberty-z), 1) - EXTLIBS += -liberty -lz - endif - endif -endif - -ifdef NO_DEMANGLE - CFLAGS += -DNO_DEMANGLE -else - ifdef HAVE_CPLUS_DEMANGLE_SUPPORT - EXTLIBS += -liberty - CFLAGS += -DHAVE_CPLUS_DEMANGLE_SUPPORT - else - ifneq ($(feature-libbfd), 1) - ifneq ($(feature-liberty), 1) - ifneq ($(feature-liberty-z), 1) - # we dont have neither HAVE_CPLUS_DEMANGLE_SUPPORT - # or any of 'bfd iberty z' trinity - ifeq ($(feature-cplus-demangle), 1) - EXTLIBS += -liberty - CFLAGS += -DHAVE_CPLUS_DEMANGLE_SUPPORT - else - msg := $(warning No bfd.h/libbfd found, please install binutils-dev[el]/zlib-static/libiberty-dev to gain symbol demangling) - CFLAGS += -DNO_DEMANGLE - endif - endif - endif - endif - endif -endif - -ifneq ($(filter -lbfd,$(EXTLIBS)),) - CFLAGS += -DHAVE_LIBBFD_SUPPORT -endif - -ifndef NO_ZLIB - ifeq ($(feature-zlib), 1) - CFLAGS += -DHAVE_ZLIB_SUPPORT - EXTLIBS += -lz - $(call detected,CONFIG_ZLIB) - else - NO_ZLIB := 1 - endif -endif - -ifndef NO_LZMA - ifeq ($(feature-lzma), 1) - CFLAGS += -DHAVE_LZMA_SUPPORT - EXTLIBS += -llzma - $(call detected,CONFIG_LZMA) - else - msg := $(warning No liblzma found, disables xz kernel module decompression, please install xz-devel/liblzma-dev); - NO_LZMA := 1 - endif -endif - -ifndef NO_BACKTRACE - ifeq ($(feature-backtrace), 1) - CFLAGS += -DHAVE_BACKTRACE_SUPPORT - endif -endif - -ifndef NO_LIBNUMA - ifeq ($(feature-libnuma), 0) - msg := $(warning No numa.h found, disables 'perf bench numa mem' benchmark, please install numactl-devel/libnuma-devel/libnuma-dev); - NO_LIBNUMA := 1 - else - ifeq ($(feature-numa_num_possible_cpus), 0) - msg := $(warning Old numa library found, disables 'perf bench numa mem' benchmark, please install numactl-devel/libnuma-devel/libnuma-dev >= 2.0.8); - NO_LIBNUMA := 1 - else - CFLAGS += -DHAVE_LIBNUMA_SUPPORT - EXTLIBS += -lnuma - $(call detected,CONFIG_NUMA) - endif - endif -endif - -ifdef HAVE_KVM_STAT_SUPPORT - CFLAGS += -DHAVE_KVM_STAT_SUPPORT -endif - -ifeq (${IS_64_BIT}, 1) - ifndef NO_PERF_READ_VDSO32 - $(call feature_check,compile-32) - ifeq ($(feature-compile-32), 1) - CFLAGS += -DHAVE_PERF_READ_VDSO32 - else - NO_PERF_READ_VDSO32 := 1 - endif - endif - ifneq ($(ARCH), x86) - NO_PERF_READ_VDSOX32 := 1 - endif - ifndef NO_PERF_READ_VDSOX32 - $(call feature_check,compile-x32) - ifeq ($(feature-compile-x32), 1) - CFLAGS += -DHAVE_PERF_READ_VDSOX32 - else - NO_PERF_READ_VDSOX32 := 1 - endif - endif -else - NO_PERF_READ_VDSO32 := 1 - NO_PERF_READ_VDSOX32 := 1 -endif - -ifdef LIBBABELTRACE - $(call feature_check,libbabeltrace) - ifeq ($(feature-libbabeltrace), 1) - CFLAGS += -DHAVE_LIBBABELTRACE_SUPPORT $(LIBBABELTRACE_CFLAGS) - LDFLAGS += $(LIBBABELTRACE_LDFLAGS) - EXTLIBS += -lbabeltrace-ctf - $(call detected,CONFIG_LIBBABELTRACE) - else - msg := $(warning No libbabeltrace found, disables 'perf data' CTF format support, please install libbabeltrace-dev[el]/libbabeltrace-ctf-dev); - endif -endif - -ifndef NO_AUXTRACE - ifeq ($(feature-get_cpuid), 0) - msg := $(warning Your gcc lacks the __get_cpuid() builtin, disables support for auxtrace/Intel PT, please install a newer gcc); - NO_AUXTRACE := 1 - else - $(call detected,CONFIG_AUXTRACE) - CFLAGS += -DHAVE_AUXTRACE_SUPPORT - endif -endif - -# Among the variables below, these: -# perfexecdir -# template_dir -# mandir -# infodir -# htmldir -# ETC_PERFCONFIG (but not sysconfdir) -# can be specified as a relative path some/where/else; -# this is interpreted as relative to $(prefix) and "perf" at -# runtime figures out where they are based on the path to the executable. -# This can help installing the suite in a relocatable way. - -# Make the path relative to DESTDIR, not to prefix -ifndef DESTDIR -prefix ?= $(HOME) -endif -bindir_relative = bin -bindir = $(abspath $(prefix)/$(bindir_relative)) -mandir = share/man -infodir = share/info -perfexecdir = libexec/perf-core -sharedir = $(prefix)/share -template_dir = share/perf-core/templates -STRACE_GROUPS_DIR = share/perf-core/strace/groups -htmldir = share/doc/perf-doc -tipdir = share/doc/perf-tip -srcdir = $(srctree)/tools/perf -ifeq ($(prefix),/usr) -sysconfdir = /etc -ETC_PERFCONFIG = $(sysconfdir)/perfconfig -else -sysconfdir = $(prefix)/etc -ETC_PERFCONFIG = etc/perfconfig -endif -ifndef lib -ifeq ($(ARCH)$(IS_64_BIT), x861) -lib = lib64 -else -lib = lib -endif -endif # lib -libdir = $(prefix)/$(lib) - -# Shell quote (do not use $(call) to accommodate ancient setups); -ETC_PERFCONFIG_SQ = $(subst ','\'',$(ETC_PERFCONFIG)) -STRACE_GROUPS_DIR_SQ = $(subst ','\'',$(STRACE_GROUPS_DIR)) -DESTDIR_SQ = $(subst ','\'',$(DESTDIR)) -bindir_SQ = $(subst ','\'',$(bindir)) -mandir_SQ = $(subst ','\'',$(mandir)) -infodir_SQ = $(subst ','\'',$(infodir)) -perfexecdir_SQ = $(subst ','\'',$(perfexecdir)) -template_dir_SQ = $(subst ','\'',$(template_dir)) -htmldir_SQ = $(subst ','\'',$(htmldir)) -tipdir_SQ = $(subst ','\'',$(tipdir)) -prefix_SQ = $(subst ','\'',$(prefix)) -sysconfdir_SQ = $(subst ','\'',$(sysconfdir)) -libdir_SQ = $(subst ','\'',$(libdir)) -srcdir_SQ = $(subst ','\'',$(srcdir)) - -ifneq ($(filter /%,$(firstword $(perfexecdir))),) -perfexec_instdir = $(perfexecdir) -STRACE_GROUPS_INSTDIR = $(STRACE_GROUPS_DIR) -tip_instdir = $(tipdir) -else -perfexec_instdir = $(prefix)/$(perfexecdir) -STRACE_GROUPS_INSTDIR = $(prefix)/$(STRACE_GROUPS_DIR) -tip_instdir = $(prefix)/$(tipdir) -endif -perfexec_instdir_SQ = $(subst ','\'',$(perfexec_instdir)) -STRACE_GROUPS_INSTDIR_SQ = $(subst ','\'',$(STRACE_GROUPS_INSTDIR)) -tip_instdir_SQ = $(subst ','\'',$(tip_instdir)) - -# If we install to $(HOME) we keep the traceevent default: -# $(HOME)/.traceevent/plugins -# Otherwise we install plugins into the global $(libdir). -ifdef DESTDIR -plugindir=$(libdir)/traceevent/plugins -plugindir_SQ= $(subst ','\'',$(plugindir)) -endif - -print_var = $(eval $(print_var_code)) $(info $(MSG)) -define print_var_code - MSG = $(shell printf '...%30s: %s' $(1) $($(1))) -endef - -ifeq ($(VF),1) - $(call print_var,prefix) - $(call print_var,bindir) - $(call print_var,libdir) - $(call print_var,sysconfdir) - $(call print_var,LIBUNWIND_DIR) - $(call print_var,LIBDW_DIR) - - ifeq ($(dwarf-post-unwind),1) - $(call feature_print_text,"DWARF post unwind library", $(dwarf-post-unwind-text)) - endif - $(info ) -endif - -$(call detected_var,bindir_SQ) -$(call detected_var,PYTHON_WORD) -ifneq ($(OUTPUT),) -$(call detected_var,OUTPUT) -endif -$(call detected_var,htmldir_SQ) -$(call detected_var,infodir_SQ) -$(call detected_var,mandir_SQ) -$(call detected_var,ETC_PERFCONFIG_SQ) -$(call detected_var,STRACE_GROUPS_DIR_SQ) -$(call detected_var,prefix_SQ) -$(call detected_var,perfexecdir_SQ) -$(call detected_var,tipdir_SQ) -$(call detected_var,srcdir_SQ) -$(call detected_var,LIBDIR) -$(call detected_var,GTK_CFLAGS) -$(call detected_var,PERL_EMBED_CCOPTS) -$(call detected_var,PYTHON_EMBED_CCOPTS) -- cgit v1.2.3 From 52c5cc363f2c5f50e88d2d340c039cc72797d69a Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Mon, 1 Aug 2016 20:02:34 +0200 Subject: perf hists: Introduce output_resort_cb method When dealing with nested hist entries it's helpful to have a way to resort those nested objects. Adding optional callback call into output_resort function and following new interface function: typedef int (*hists__resort_cb_t)(struct hist_entry *he); void hists__output_resort_cb(struct hists *hists, struct ui_progress *prog, hists__resort_cb_t cb); Signed-off-by: Jiri Olsa Cc: David Ahern Cc: Namhyung Kim Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/1470074555-24889-7-git-send-email-jolsa@kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/hist.c | 15 ++++++++++++--- tools/perf/util/hist.h | 4 ++++ 2 files changed, 16 insertions(+), 3 deletions(-) (limited to 'tools') diff --git a/tools/perf/util/hist.c b/tools/perf/util/hist.c index a18d142cdca3..de15dbcdcecf 100644 --- a/tools/perf/util/hist.c +++ b/tools/perf/util/hist.c @@ -1672,7 +1672,7 @@ static void __hists__insert_output_entry(struct rb_root *entries, } static void output_resort(struct hists *hists, struct ui_progress *prog, - bool use_callchain) + bool use_callchain, hists__resort_cb_t cb) { struct rb_root *root; struct rb_node *next; @@ -1711,6 +1711,9 @@ static void output_resort(struct hists *hists, struct ui_progress *prog, n = rb_entry(next, struct hist_entry, rb_node_in); next = rb_next(&n->rb_node_in); + if (cb && cb(n)) + continue; + __hists__insert_output_entry(&hists->entries, n, min_callchain_hits, use_callchain); hists__inc_stats(hists, n); @@ -1731,12 +1734,18 @@ void perf_evsel__output_resort(struct perf_evsel *evsel, struct ui_progress *pro else use_callchain = symbol_conf.use_callchain; - output_resort(evsel__hists(evsel), prog, use_callchain); + output_resort(evsel__hists(evsel), prog, use_callchain, NULL); } void hists__output_resort(struct hists *hists, struct ui_progress *prog) { - output_resort(hists, prog, symbol_conf.use_callchain); + output_resort(hists, prog, symbol_conf.use_callchain, NULL); +} + +void hists__output_resort_cb(struct hists *hists, struct ui_progress *prog, + hists__resort_cb_t cb) +{ + output_resort(hists, prog, symbol_conf.use_callchain, cb); } static bool can_goto_child(struct hist_entry *he, enum hierarchy_move_dir hmd) diff --git a/tools/perf/util/hist.h b/tools/perf/util/hist.h index 49aa4fac148f..0a1edf1ab450 100644 --- a/tools/perf/util/hist.h +++ b/tools/perf/util/hist.h @@ -153,8 +153,12 @@ int hist_entry__snprintf_alignment(struct hist_entry *he, struct perf_hpp *hpp, struct perf_hpp_fmt *fmt, int printed); void hist_entry__delete(struct hist_entry *he); +typedef int (*hists__resort_cb_t)(struct hist_entry *he); + void perf_evsel__output_resort(struct perf_evsel *evsel, struct ui_progress *prog); void hists__output_resort(struct hists *hists, struct ui_progress *prog); +void hists__output_resort_cb(struct hists *hists, struct ui_progress *prog, + hists__resort_cb_t cb); int hists__collapse_resort(struct hists *hists, struct ui_progress *prog); void hists__decay_entries(struct hists *hists, bool zap_user, bool zap_kernel); -- cgit v1.2.3 From b6f35ed774aeaf441e66cfa243fd1dff1321d69e Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Mon, 1 Aug 2016 20:02:35 +0200 Subject: perf record: Add --sample-cpu option Adding --sample-cpu option to be able to explicitly enable CPU sample type. Currently it's only enable implicitly in case the target is cpu related. It will be useful for following c2c record tool. Signed-off-by: Jiri Olsa Cc: David Ahern Cc: Namhyung Kim Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/1470074555-24889-8-git-send-email-jolsa@kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/Documentation/perf-record.txt | 3 +++ tools/perf/builtin-record.c | 1 + tools/perf/perf.h | 1 + tools/perf/util/evsel.c | 2 +- 4 files changed, 6 insertions(+), 1 deletion(-) (limited to 'tools') diff --git a/tools/perf/Documentation/perf-record.txt b/tools/perf/Documentation/perf-record.txt index 69966abf65d1..379a2bed07c0 100644 --- a/tools/perf/Documentation/perf-record.txt +++ b/tools/perf/Documentation/perf-record.txt @@ -192,6 +192,9 @@ OPTIONS --period:: Record the sample period. +--sample-cpu:: + Record the sample cpu. + -n:: --no-samples:: Don't sample. diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c index 8f2c16d9275f..6355902fbfc8 100644 --- a/tools/perf/builtin-record.c +++ b/tools/perf/builtin-record.c @@ -1434,6 +1434,7 @@ 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, "sample-cpu", &record.opts.sample_cpu, "Record the sample cpu"), OPT_BOOLEAN_SET('T', "timestamp", &record.opts.sample_time, &record.opts.sample_time_set, "Record the sample timestamps"), diff --git a/tools/perf/perf.h b/tools/perf/perf.h index a7e0f1497244..cb0f1356ff81 100644 --- a/tools/perf/perf.h +++ b/tools/perf/perf.h @@ -52,6 +52,7 @@ struct record_opts { bool sample_weight; bool sample_time; bool sample_time_set; + bool sample_cpu; bool period; bool running_time; bool full_auxtrace; diff --git a/tools/perf/util/evsel.c b/tools/perf/util/evsel.c index 4c2b31dc4e4d..d9b80ef881cd 100644 --- a/tools/perf/util/evsel.c +++ b/tools/perf/util/evsel.c @@ -882,7 +882,7 @@ void perf_evsel__config(struct perf_evsel *evsel, struct record_opts *opts, perf_evsel__set_sample_bit(evsel, REGS_INTR); } - if (target__has_cpu(&opts->target)) + if (target__has_cpu(&opts->target) || opts->sample_cpu) perf_evsel__set_sample_bit(evsel, CPU); if (opts->period) -- cgit v1.2.3 From b2d0dbf09772d091368261ce95db3afce45d994d Mon Sep 17 00:00:00 2001 From: Jan Stancek Date: Tue, 12 Jan 2016 11:07:44 +0100 Subject: perf tests: objdump output can contain multi byte chunks objdump's raw insn output can vary across architectures on the number of bytes per chunk (bpc) displayed and their endianness. The code-reading test relied on reading objdump output as 1 bpc. Kaixu Xia reported test failure on ARM64, where objdump displays 4 bpc: 70c48: f90027bf str xzr, [x29,#72] 70c4c: 91224000 add x0, x0, #0x890 70c50: f90023a0 str x0, [x29,#64] This patch adds support to read raw insn output for any bpc length. In case of 2+ bpc it also guesses objdump's display endian. Reported-and-Tested-by: Kaixu Xia Signed-off-by: Jan Stancek Acked-by: Adrian Hunter Cc: Corey Ashford Cc: David Ahern Cc: Frederic Weisbecker Cc: Jiri Olsa Cc: Namhyung Kim Cc: Paul Mackerras Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/07f0f7bcbda78deb423298708ef9b6a54d6b92bd.1452592712.git.jstancek@redhat.com [ Fix up pr_fmt() call to use %zd for size_t variables, fixing the build on Ubuntu cross-compiling to armhf and ppc64 ] Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/tests/code-reading.c | 100 ++++++++++++++++++++++++++++------------ 1 file changed, 71 insertions(+), 29 deletions(-) (limited to 'tools') diff --git a/tools/perf/tests/code-reading.c b/tools/perf/tests/code-reading.c index 68a69a195545..2af156a8d4e5 100644 --- a/tools/perf/tests/code-reading.c +++ b/tools/perf/tests/code-reading.c @@ -33,44 +33,86 @@ static unsigned int hex(char c) return c - 'A' + 10; } -static size_t read_objdump_line(const char *line, size_t line_len, void *buf, - size_t len) +static size_t read_objdump_chunk(const char **line, unsigned char **buf, + size_t *buf_len) { - const char *p; - size_t i, j = 0; - - /* Skip to a colon */ - p = strchr(line, ':'); - if (!p) - return 0; - i = p + 1 - line; + size_t bytes_read = 0; + unsigned char *chunk_start = *buf; /* Read bytes */ - while (j < len) { + while (*buf_len > 0) { char c1, c2; - /* Skip spaces */ - for (; i < line_len; i++) { - if (!isspace(line[i])) - break; - } /* Get 2 hex digits */ - if (i >= line_len || !isxdigit(line[i])) + c1 = *(*line)++; + if (!isxdigit(c1)) break; - c1 = line[i++]; - if (i >= line_len || !isxdigit(line[i])) + c2 = *(*line)++; + if (!isxdigit(c2)) break; - c2 = line[i++]; - /* Followed by a space */ - if (i < line_len && line[i] && !isspace(line[i])) + + /* Store byte and advance buf */ + **buf = (hex(c1) << 4) | hex(c2); + (*buf)++; + (*buf_len)--; + bytes_read++; + + /* End of chunk? */ + if (isspace(**line)) break; - /* Store byte */ - *(unsigned char *)buf = (hex(c1) << 4) | hex(c2); - buf += 1; - j++; } + + /* + * objdump will display raw insn as LE if code endian + * is LE and bytes_per_chunk > 1. In that case reverse + * the chunk we just read. + * + * see disassemble_bytes() at binutils/objdump.c for details + * how objdump chooses display endian) + */ + if (bytes_read > 1 && !bigendian()) { + unsigned char *chunk_end = chunk_start + bytes_read - 1; + unsigned char tmp; + + while (chunk_start < chunk_end) { + tmp = *chunk_start; + *chunk_start = *chunk_end; + *chunk_end = tmp; + chunk_start++; + chunk_end--; + } + } + + return bytes_read; +} + +static size_t read_objdump_line(const char *line, unsigned char *buf, + size_t buf_len) +{ + const char *p; + size_t ret, bytes_read = 0; + + /* Skip to a colon */ + p = strchr(line, ':'); + if (!p) + return 0; + p++; + + /* Skip initial spaces */ + while (*p) { + if (!isspace(*p)) + break; + p++; + } + + do { + ret = read_objdump_chunk(&p, &buf, &buf_len); + bytes_read += ret; + p++; + } while (ret > 0); + /* return number of successfully read bytes */ - return j; + return bytes_read; } static int read_objdump_output(FILE *f, void *buf, size_t *len, u64 start_addr) @@ -95,7 +137,7 @@ static int read_objdump_output(FILE *f, void *buf, size_t *len, u64 start_addr) } /* read objdump data into temporary buffer */ - read_bytes = read_objdump_line(line, ret, tmp, sizeof(tmp)); + read_bytes = read_objdump_line(line, tmp, sizeof(tmp)); if (!read_bytes) continue; @@ -152,7 +194,7 @@ static int read_via_objdump(const char *filename, u64 addr, void *buf, ret = read_objdump_output(f, buf, &len, addr); if (len) { - pr_debug("objdump read too few bytes\n"); + pr_debug("objdump read too few bytes: %zd\n", len); if (!ret) ret = len; } -- cgit v1.2.3 From 117dec978cf64e8e96f13d0cf4891ff77c9acf55 Mon Sep 17 00:00:00 2001 From: Valdis Kletnieks Date: Tue, 2 Aug 2016 14:02:28 -0700 Subject: tools/testing/radix-tree/linux/gfp.h: fix bitrotted value Apparently, the tools/testing version dates to a few flags ago, and we've sprouted 4 new ones since. Keep in sync with the value in the main tree... Link: http://lkml.kernel.org/r/23400.1469702675@turing-police.cc.vt.edu Signed-off-by: Valdis Kletnieks Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- tools/testing/radix-tree/linux/gfp.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'tools') diff --git a/tools/testing/radix-tree/linux/gfp.h b/tools/testing/radix-tree/linux/gfp.h index 0e37f7a760eb..5201b915f631 100644 --- a/tools/testing/radix-tree/linux/gfp.h +++ b/tools/testing/radix-tree/linux/gfp.h @@ -1,7 +1,7 @@ #ifndef _GFP_H #define _GFP_H -#define __GFP_BITS_SHIFT 22 +#define __GFP_BITS_SHIFT 26 #define __GFP_BITS_MASK ((gfp_t)((1 << __GFP_BITS_SHIFT) - 1)) #define __GFP_WAIT 1 #define __GFP_ACCOUNT 0 -- cgit v1.2.3 From c369e0a1a8fa6ca80e6c37c8735d9427b623ae62 Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Tue, 2 Aug 2016 16:48:19 -0300 Subject: perf tests bpf: Use SyS_epoll_wait alias Something made the sys_epoll_wait() function alias not to be found in the vmlinux DWARF info, being found only in /proc/kallsyms, which made the BPF perf tests to fail: [root@jouet ~]# perf test BPF 37: Test BPF filter : 37.1: Test basic BPF filtering : FAILED! 37.2: Test BPF prologue generation : Skip 37.3: Test BPF relocation checker : Skip [root@jouet ~]# Using -v we can see it is failing to find DWARF info for the probed function, sys_epoll_wait, which we can find in /proc/kallsyms but not in vmlinux with CONFIG_DEBUG_INFO: [root@jouet ~]# grep -w sys_epoll_wait /proc/kallsyms ffffffffbd295b50 T sys_epoll_wait [root@jouet ~]# [root@jouet ~]# readelf -wi /lib/modules/4.7.0+/build/vmlinux | grep -w sys_epoll_wait [root@jouet ~]# If we try to use perf probe: [root@jouet ~]# perf probe sys_epoll_wait Failed to find debug information for address ffffffffbd295b50 Probe point 'sys_epoll_wait' not found. Error: Failed to add events. [root@jouet ~]# It all works if we use SyS_epoll_wait, that is just an alias to the probed function: [root@jouet ~]# grep -i sys_epoll_wait /proc/kallsyms ffffffffbd295b50 T SyS_epoll_wait ffffffffbd295b50 T sys_epoll_wait [root@jouet ~]# So use it: [root@jouet ~]# perf test BPF 37: Test BPF filter : 37.1: Test basic BPF filtering : Ok 37.2: Test BPF prologue generation : Ok 37.3: Test BPF relocation checker : Ok [root@jouet ~]# Further info: [root@jouet ~]# gcc --version gcc (GCC) 6.1.1 20160621 (Red Hat 6.1.1-3) [acme@jouet linux]$ cat /etc/fedora-release Fedora release 24 (Twenty Four) Investigation as to why it fails is still underway, but it was always going from sys_epoll_wait to SyS_epoll_wait when looking up the DWARF info in vmlinux, and this is what is breaking now. Switching to use SyS_epoll_wait allows this test to proceed and test the BPF code it was designed for, so lets have this in to allow passing this test while we fix the root cause. Cc: Adrian Hunter Cc: Alexei Starovoitov Cc: David Ahern Cc: Jiri Olsa Cc: Namhyung Kim Cc: Wang Nan Link: http://lkml.kernel.org/n/tip-7hekjp0bodwjbb419sl2b55h@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/tests/bpf-script-example.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'tools') diff --git a/tools/perf/tests/bpf-script-example.c b/tools/perf/tests/bpf-script-example.c index e53bc91fa260..268e5f8e4aa2 100644 --- a/tools/perf/tests/bpf-script-example.c +++ b/tools/perf/tests/bpf-script-example.c @@ -31,8 +31,8 @@ struct bpf_map_def SEC("maps") flip_table = { .max_entries = 1, }; -SEC("func=sys_epoll_wait") -int bpf_func__sys_epoll_wait(void *ctx) +SEC("func=SyS_epoll_wait") +int bpf_func__SyS_epoll_wait(void *ctx) { int ind =0; int *flag = bpf_map_lookup_elem(&flip_table, &ind); -- cgit v1.2.3 From a9c59ef77458b27221e71506cdf1bd31a06afb19 Mon Sep 17 00:00:00 2001 From: Logan Gunthorpe Date: Mon, 20 Jun 2016 13:15:12 -0600 Subject: ntb_test: Add a selftest script for the NTB subsystem This script automates testing doorbells, scratchpads and memory windows for an NTB device. It can be run locally, with the NTB looped back to the same host or use SSH to remotely control the second host. In the single host case, the script just needs to be passed two arguments: a PCI ID for each side of the link. In the two host case the -r option must be used to specify the remote hostname (which must be SSH accessible and should probably have ssh-keys exchanged). A sample run looks like this: $ sudo ./ntb_test.sh 0000:03:00.1 0000:83:00.1 -p 29 Starting ntb_tool tests... Running link tests on: 0000:03:00.1 / 0000:83:00.1 Passed Running link tests on: 0000:83:00.1 / 0000:03:00.1 Passed Running db tests on: 0000:03:00.1 / 0000:83:00.1 Passed Running db tests on: 0000:83:00.1 / 0000:03:00.1 Passed Running spad tests on: 0000:03:00.1 / 0000:83:00.1 Passed Running spad tests on: 0000:83:00.1 / 0000:03:00.1 Passed Running mw0 tests on: 0000:03:00.1 / 0000:83:00.1 Passed Running mw0 tests on: 0000:83:00.1 / 0000:03:00.1 Passed Running mw1 tests on: 0000:03:00.1 / 0000:83:00.1 Passed Running mw1 tests on: 0000:83:00.1 / 0000:03:00.1 Passed Starting ntb_pingpong tests... Running ping pong tests on: 0000:03:00.1 / 0000:83:00.1 Passed Starting ntb_perf tests... Running local perf test without DMA 0: copied 536870912 bytes in 164453 usecs, 3264 MBytes/s Passed Running remote perf test without DMA 0: copied 536870912 bytes in 164453 usecs, 3264 MBytes/s Passed Signed-off-by: Logan Gunthorpe Acked-by: Shuah Khan Acked-by: Allen Hubbe Signed-off-by: Jon Mason --- tools/testing/selftests/ntb/ntb_test.sh | 422 ++++++++++++++++++++++++++++++++ 1 file changed, 422 insertions(+) create mode 100755 tools/testing/selftests/ntb/ntb_test.sh (limited to 'tools') diff --git a/tools/testing/selftests/ntb/ntb_test.sh b/tools/testing/selftests/ntb/ntb_test.sh new file mode 100755 index 000000000000..a676d3eefefb --- /dev/null +++ b/tools/testing/selftests/ntb/ntb_test.sh @@ -0,0 +1,422 @@ +#!/bin/bash +# Copyright (c) 2016 Microsemi. All Rights Reserved. +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 2 of +# the License, or (at your option) any later version. +# +# This program is distributed in the hope that it would be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# Author: Logan Gunthorpe + +REMOTE_HOST= +LIST_DEVS=FALSE + +DEBUGFS=${DEBUGFS-/sys/kernel/debug} + +PERF_RUN_ORDER=32 +MAX_MW_SIZE=0 +RUN_DMA_TESTS= +DONT_CLEANUP= +MW_SIZE=65536 + +function show_help() +{ + echo "Usage: $0 [OPTIONS] LOCAL_DEV REMOTE_DEV" + echo "Run tests on a pair of NTB endpoints." + echo + echo "If the NTB device loops back to the same host then," + echo "just specifying the two PCI ids on the command line is" + echo "sufficient. Otherwise, if the NTB link spans two hosts" + echo "use the -r option to specify the hostname for the remote" + echo "device. SSH will then be used to test the remote side." + echo "An SSH key between the root users of the host would then" + echo "be highly recommended." + echo + echo "Options:" + echo " -C don't cleanup ntb modules on exit" + echo " -d run dma tests" + echo " -h show this help message" + echo " -l list available local and remote PCI ids" + echo " -r REMOTE_HOST specify the remote's hostname to connect" + echo " to for the test (using ssh)" + echo " -p NUM ntb_perf run order (default: $PERF_RUN_ORDER)" + echo " -w max_mw_size maxmium memory window size" + echo +} + +function parse_args() +{ + OPTIND=0 + while getopts "Cdhlm:r:p:w:" opt; do + case "$opt" in + C) DONT_CLEANUP=1 ;; + d) RUN_DMA_TESTS=1 ;; + h) show_help; exit 0 ;; + l) LIST_DEVS=TRUE ;; + m) MW_SIZE=${OPTARG} ;; + r) REMOTE_HOST=${OPTARG} ;; + p) PERF_RUN_ORDER=${OPTARG} ;; + w) MAX_MW_SIZE=${OPTARG} ;; + \?) + echo "Invalid option: -$OPTARG" >&2 + exit 1 + ;; + esac + done +} + +parse_args "$@" +shift $((OPTIND-1)) +LOCAL_DEV=$1 +shift +parse_args "$@" +shift $((OPTIND-1)) +REMOTE_DEV=$1 +shift +parse_args "$@" + +set -e + +function _modprobe() +{ + modprobe "$@" +} + +function split_remote() +{ + VPATH=$1 + REMOTE= + + if [[ "$VPATH" == *":/"* ]]; then + REMOTE=${VPATH%%:*} + VPATH=${VPATH#*:} + fi +} + +function read_file() +{ + split_remote $1 + if [[ "$REMOTE" != "" ]]; then + ssh "$REMOTE" cat "$VPATH" + else + cat "$VPATH" + fi +} + +function write_file() +{ + split_remote $2 + VALUE=$1 + + if [[ "$REMOTE" != "" ]]; then + ssh "$REMOTE" "echo \"$VALUE\" > \"$VPATH\"" + else + echo "$VALUE" > "$VPATH" + fi +} + +function link_test() +{ + LOC=$1 + REM=$2 + EXP=0 + + echo "Running link tests on: $(basename $LOC) / $(basename $REM)" + + if ! write_file "N" "$LOC/link" 2> /dev/null; then + echo " Unsupported" + return + fi + + write_file "N" "$LOC/link_event" + + if [[ $(read_file "$REM/link") != "N" ]]; then + echo "Expected remote link to be down in $REM/link" >&2 + exit -1 + fi + + write_file "Y" "$LOC/link" + write_file "Y" "$LOC/link_event" + + echo " Passed" +} + +function doorbell_test() +{ + LOC=$1 + REM=$2 + EXP=0 + + echo "Running db tests on: $(basename $LOC) / $(basename $REM)" + + write_file "c 0xFFFFFFFF" "$REM/db" + + for ((i=1; i <= 8; i++)); do + let DB=$(read_file "$REM/db") || true + if [[ "$DB" != "$EXP" ]]; then + echo "Doorbell doesn't match expected value $EXP " \ + "in $REM/db" >&2 + exit -1 + fi + + let "MASK=1 << ($i-1)" || true + let "EXP=$EXP | $MASK" || true + write_file "s $MASK" "$LOC/peer_db" + done + + echo " Passed" +} + +function read_spad() +{ + VPATH=$1 + IDX=$2 + + ROW=($(read_file "$VPATH" | grep -e "^$IDX")) + let VAL=${ROW[1]} || true + echo $VAL +} + +function scratchpad_test() +{ + LOC=$1 + REM=$2 + CNT=$(read_file "$LOC/spad" | wc -l) + + echo "Running spad tests on: $(basename $LOC) / $(basename $REM)" + + for ((i = 0; i < $CNT; i++)); do + VAL=$RANDOM + write_file "$i $VAL" "$LOC/peer_spad" + RVAL=$(read_spad "$REM/spad" $i) + + if [[ "$VAL" != "$RVAL" ]]; then + echo "Scratchpad doesn't match expected value $VAL " \ + "in $REM/spad, got $RVAL" >&2 + exit -1 + fi + + done + + echo " Passed" +} + +function write_mw() +{ + split_remote $2 + + if [[ "$REMOTE" != "" ]]; then + ssh "$REMOTE" \ + dd if=/dev/urandom "of=$VPATH" 2> /dev/null || true + else + dd if=/dev/urandom "of=$VPATH" 2> /dev/null || true + fi +} + +function mw_test() +{ + IDX=$1 + LOC=$2 + REM=$3 + + echo "Running $IDX tests on: $(basename $LOC) / $(basename $REM)" + + write_mw "$LOC/$IDX" + + split_remote "$LOC/$IDX" + if [[ "$REMOTE" == "" ]]; then + A=$VPATH + else + A=/tmp/ntb_test.$$.A + ssh "$REMOTE" cat "$VPATH" > "$A" + fi + + split_remote "$REM/peer_$IDX" + if [[ "$REMOTE" == "" ]]; then + B=$VPATH + else + B=/tmp/ntb_test.$$.B + ssh "$REMOTE" cat "$VPATH" > "$B" + fi + + cmp -n $MW_SIZE "$A" "$B" + if [[ $? != 0 ]]; then + echo "Memory window $MW did not match!" >&2 + fi + + if [[ "$A" == "/tmp/*" ]]; then + rm "$A" + fi + + if [[ "$B" == "/tmp/*" ]]; then + rm "$B" + fi + + echo " Passed" +} + +function pingpong_test() +{ + LOC=$1 + REM=$2 + + echo "Running ping pong tests on: $(basename $LOC) / $(basename $REM)" + + LOC_START=$(read_file $LOC/count) + REM_START=$(read_file $REM/count) + + sleep 7 + + LOC_END=$(read_file $LOC/count) + REM_END=$(read_file $REM/count) + + if [[ $LOC_START == $LOC_END ]] || [[ $REM_START == $REM_END ]]; then + echo "Ping pong counter not incrementing!" >&2 + exit 1 + fi + + echo " Passed" +} + +function perf_test() +{ + USE_DMA=$1 + + if [[ $USE_DMA == "1" ]]; then + WITH="with" + else + WITH="without" + fi + + _modprobe ntb_perf run_order=$PERF_RUN_ORDER \ + max_mw_size=$MAX_MW_SIZE use_dma=$USE_DMA + + echo "Running local perf test $WITH DMA" + write_file "" $LOCAL_PERF/run + echo -n " " + read_file $LOCAL_PERF/run + echo " Passed" + + echo "Running remote perf test $WITH DMA" + write_file "" $REMOTE_PERF/run + echo -n " " + read_file $LOCAL_PERF/run + echo " Passed" + + _modprobe -r ntb_perf +} + +function ntb_tool_tests() +{ + LOCAL_TOOL=$DEBUGFS/ntb_tool/$LOCAL_DEV + REMOTE_TOOL=$REMOTE_HOST:$DEBUGFS/ntb_tool/$REMOTE_DEV + + echo "Starting ntb_tool tests..." + + _modprobe ntb_tool + + write_file Y $LOCAL_TOOL/link_event + write_file Y $REMOTE_TOOL/link_event + + link_test $LOCAL_TOOL $REMOTE_TOOL + link_test $REMOTE_TOOL $LOCAL_TOOL + + for PEER_TRANS in $(ls $LOCAL_TOOL/peer_trans*); do + PT=$(basename $PEER_TRANS) + write_file $MW_SIZE $LOCAL_TOOL/$PT + write_file $MW_SIZE $REMOTE_TOOL/$PT + done + + doorbell_test $LOCAL_TOOL $REMOTE_TOOL + doorbell_test $REMOTE_TOOL $LOCAL_TOOL + scratchpad_test $LOCAL_TOOL $REMOTE_TOOL + scratchpad_test $REMOTE_TOOL $LOCAL_TOOL + + for MW in $(ls $LOCAL_TOOL/mw*); do + MW=$(basename $MW) + + mw_test $MW $LOCAL_TOOL $REMOTE_TOOL + mw_test $MW $REMOTE_TOOL $LOCAL_TOOL + done + + _modprobe -r ntb_tool +} + +function ntb_pingpong_tests() +{ + LOCAL_PP=$DEBUGFS/ntb_pingpong/$LOCAL_DEV + REMOTE_PP=$REMOTE_HOST:$DEBUGFS/ntb_pingpong/$REMOTE_DEV + + echo "Starting ntb_pingpong tests..." + + _modprobe ntb_pingpong + + pingpong_test $LOCAL_PP $REMOTE_PP + + _modprobe -r ntb_pingpong +} + +function ntb_perf_tests() +{ + LOCAL_PERF=$DEBUGFS/ntb_perf/$LOCAL_DEV + REMOTE_PERF=$REMOTE_HOST:$DEBUGFS/ntb_perf/$REMOTE_DEV + + echo "Starting ntb_perf tests..." + + perf_test 0 + + if [[ $RUN_DMA_TESTS ]]; then + perf_test 1 + fi +} + +function cleanup() +{ + set +e + _modprobe -r ntb_tool 2> /dev/null + _modprobe -r ntb_perf 2> /dev/null + _modprobe -r ntb_pingpong 2> /dev/null + _modprobe -r ntb_transport 2> /dev/null + set -e +} + +cleanup + +if ! [[ $$DONT_CLEANUP ]]; then + trap cleanup EXIT +fi + +if [ "$(id -u)" != "0" ]; then + echo "This script must be run as root" 1>&2 + exit 1 +fi + +if [[ "$LIST_DEVS" == TRUE ]]; then + echo "Local Devices:" + ls -1 /sys/bus/ntb/devices + echo + + if [[ "$REMOTE_HOST" != "" ]]; then + echo "Remote Devices:" + ssh $REMOTE_HOST ls -1 /sys/bus/ntb/devices + fi + + exit 0 +fi + +if [[ "$LOCAL_DEV" == $"" ]] || [[ "$REMOTE_DEV" == $"" ]]; then + show_help + exit 1 +fi + +ntb_tool_tests +echo +ntb_pingpong_tests +echo +ntb_perf_tests +echo -- cgit v1.2.3