All of lore.kernel.org
 help / color / mirror / Atom feed
From: Jiri Olsa <jolsa@kernel.org>
To: Ingo Molnar <mingo@kernel.org>,
	Peter Zijlstra <a.p.zijlstra@chello.nl>,
	Arnaldo Carvalho de Melo <acme@kernel.org>
Cc: lkml <linux-kernel@vger.kernel.org>,
	Namhyung Kim <namhyung@kernel.org>,
	David Ahern <dsahern@gmail.com>, Andi Kleen <ak@linux.intel.com>,
	Milind Chabbi <chabbi.milind@gmail.com>,
	Alexander Shishkin <alexander.shishkin@linux.intel.com>,
	Michael Ellerman <mpe@ellerman.id.au>,
	Hari Bathini <hbathini@linux.vnet.ibm.com>,
	Jin Yao <yao.jin@linux.intel.com>,
	Kan Liang <kan.liang@intel.com>,
	Sukadev Bhattiprolu <sukadev@linux.vnet.ibm.com>,
	Oleg Nesterov <onestero@redhat.com>,
	Will Deacon <will.deacon@arm.com>
Subject: [PATCH 8/8] perf tests: Add breakpoint accounting/modify test
Date: Mon, 12 Mar 2018 14:45:48 +0100	[thread overview]
Message-ID: <20180312134548.31532-9-jolsa@kernel.org> (raw)
In-Reply-To: <20180312134548.31532-1-jolsa@kernel.org>

Adding test that:
  - detects the number of watch/break-points,
    skip test if any is missing
  - detects PERF_EVENT_IOC_MODIFY_ATTRIBUTES ioctl,
    skip test if it's missing
  - detects if watchpoints and breakpoints share
    same slots
  - create all possible watchpoints on cpu 0
  - change one of it to breakpoint
  - in case wp and bp do not share slots,
    we create another watchpoint to ensure
    the slot accounting is correct

Signed-off-by: Jiri Olsa <jolsa@kernel.org>
---
 tools/perf/tests/Build          |   1 +
 tools/perf/tests/bp_account.c   | 195 ++++++++++++++++++++++++++++++++++++++++
 tools/perf/tests/builtin-test.c |   4 +
 tools/perf/tests/tests.h        |   1 +
 4 files changed, 201 insertions(+)
 create mode 100644 tools/perf/tests/bp_account.c

diff --git a/tools/perf/tests/Build b/tools/perf/tests/Build
index 45782220ac23..6c108fa79ae3 100644
--- a/tools/perf/tests/Build
+++ b/tools/perf/tests/Build
@@ -20,6 +20,7 @@ perf-y += hists_cumulate.o
 perf-y += python-use.o
 perf-y += bp_signal.o
 perf-y += bp_signal_overflow.o
+perf-y += bp_account.o
 perf-y += task-exit.o
 perf-y += sw-clock.o
 perf-y += mmap-thread-lookup.o
diff --git a/tools/perf/tests/bp_account.c b/tools/perf/tests/bp_account.c
new file mode 100644
index 000000000000..2f75fa0c4fef
--- /dev/null
+++ b/tools/perf/tests/bp_account.c
@@ -0,0 +1,195 @@
+/*
+ * Powerpc needs __SANE_USERSPACE_TYPES__ before <linux/types.h> to select
+ * 'int-ll64.h' and avoid compile warnings when printing __u64 with %llu.
+ */
+#define __SANE_USERSPACE_TYPES__
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <string.h>
+#include <sys/ioctl.h>
+#include <time.h>
+#include <fcntl.h>
+#include <signal.h>
+#include <sys/mman.h>
+#include <linux/compiler.h>
+#include <linux/hw_breakpoint.h>
+#include <sys/ioctl.h>
+
+#include "tests.h"
+#include "debug.h"
+#include "perf.h"
+#include "cloexec.h"
+
+volatile long the_var;
+
+static noinline int test_function(void)
+{
+	return 0;
+}
+
+static int __event(bool is_x, void *addr, struct perf_event_attr *attr)
+{
+	int fd;
+
+	memset(attr, 0, sizeof(struct perf_event_attr));
+	attr->type = PERF_TYPE_BREAKPOINT;
+	attr->size = sizeof(struct perf_event_attr);
+
+	attr->config = 0;
+	attr->bp_type = is_x ? HW_BREAKPOINT_X : HW_BREAKPOINT_W;
+	attr->bp_addr = (unsigned long) addr;
+	attr->bp_len = sizeof(long);
+
+	attr->sample_period = 1;
+	attr->sample_type = PERF_SAMPLE_IP;
+
+	attr->exclude_kernel = 1;
+	attr->exclude_hv = 1;
+
+	fd = sys_perf_event_open(attr, -1, 0, -1,
+				 perf_event_open_cloexec_flag());
+	if (fd < 0) {
+		pr_debug("failed opening event %llx\n", attr->config);
+		return TEST_FAIL;
+	}
+
+	return fd;
+}
+
+static int wp_event(void *addr, struct perf_event_attr *attr)
+{
+	return __event(false, addr, attr);
+}
+
+static int bp_event(void *addr, struct perf_event_attr *attr)
+{
+	return __event(true, addr, attr);
+}
+
+static int bp_accounting(int wp_cnt, int share)
+{
+	struct perf_event_attr attr, attr_mod, attr_new;
+	int i, fd[wp_cnt], fd_wp, ret;
+
+	for (i = 0; i < wp_cnt; i++) {
+		fd[i] = wp_event((void *)&the_var, &attr);
+		TEST_ASSERT_VAL("failed to create wp\n", fd[i] != -1);
+		pr_debug("wp %d created\n", i);
+	}
+
+	attr_mod = attr;
+	attr_mod.bp_type = HW_BREAKPOINT_X;
+	attr_mod.bp_addr = (unsigned long) test_function;
+
+	ret = ioctl(fd[0], PERF_EVENT_IOC_MODIFY_ATTRIBUTES, &attr_mod);
+	TEST_ASSERT_VAL("failed to modify wp\n", ret == 0);
+
+	pr_debug("wp 0 modified to bp\n");
+
+	if (!share) {
+		fd_wp = wp_event((void *)&the_var, &attr_new);
+		TEST_ASSERT_VAL("failed to create max wp\n", fd_wp != -1);
+		pr_debug("wp max created\n");
+	}
+
+	for (i = 0; i < wp_cnt; i++)
+		close(fd[i]);
+
+	return 0;
+}
+
+static int detect_cnt(bool is_x)
+{
+	struct perf_event_attr attr;
+	void *addr = is_x ? test_function : (void *) &the_var;
+	int fd[100], cnt = 0, i;
+
+	while (1) {
+		fd[cnt] = __event(is_x, addr, &attr);
+
+		if (fd[cnt] < 0)
+			break;
+
+		if (cnt == 100) {
+			pr_debug("way too many debug registers, fix the test\n");
+			return 0;
+		}
+
+		cnt++;
+	}
+
+	for (i = 0; i < cnt; i++)
+		close(fd[i]);
+
+	return cnt;
+}
+
+static int detect_ioctl(void)
+{
+	struct perf_event_attr attr;
+	int fd, ret = 1;
+
+	fd = wp_event((void *) &the_var, &attr);
+	if (fd > 0) {
+		ret = ioctl(fd, PERF_EVENT_IOC_MODIFY_ATTRIBUTES, &attr);
+		close(fd);
+	}
+
+	return ret ? 0 : 1;
+}
+
+static int detect_share(int wp_cnt, int bp_cnt)
+{
+	struct perf_event_attr attr;
+	int i, fd[wp_cnt + bp_cnt], ret;
+
+	for (i = 0; i < wp_cnt; i++) {
+		fd[i] = wp_event((void *)&the_var, &attr);
+		TEST_ASSERT_VAL("failed to create wp\n", fd[i] != -1);
+	}
+
+	for (; i < (bp_cnt + wp_cnt); i++) {
+		fd[i] = bp_event((void *)test_function, &attr);
+		if (fd[i] == -1)
+			break;
+	}
+
+	ret = i != (bp_cnt + wp_cnt);
+
+	while (i--)
+		close(fd[i]);
+
+	return ret;
+}
+
+/*
+ * This test does following:
+ *   - detects the number of watch/break-points,
+ *     skip test if any is missing
+ *   - detects PERF_EVENT_IOC_MODIFY_ATTRIBUTES ioctl,
+ *     skip test if it's missing
+ *   - detects if watchpoints and breakpoints share
+ *     same slots
+ *   - create all possible watchpoints on cpu 0
+ *   - change one of it to breakpoint
+ *   - in case wp and bp do not share slots,
+ *     we create another watchpoint to ensure
+ *     the slot accounting is correct
+ */
+int test__bp_accounting(struct test *test __maybe_unused, int subtest __maybe_unused)
+{
+	int has_ioctl = detect_ioctl();
+	int wp_cnt = detect_cnt(false);
+	int bp_cnt = detect_cnt(true);
+	int share  = detect_share(wp_cnt, bp_cnt);
+
+	pr_debug("watchpoints count %d, breakpoints count %d, has_ioctl %d, share %d\n",
+		 wp_cnt, bp_cnt, has_ioctl, share);
+
+	if (!wp_cnt || !bp_cnt || !has_ioctl)
+		return TEST_SKIP;
+
+	return bp_accounting(wp_cnt, share);
+}
diff --git a/tools/perf/tests/builtin-test.c b/tools/perf/tests/builtin-test.c
index 09071ef4434f..625f5a6772af 100644
--- a/tools/perf/tests/builtin-test.c
+++ b/tools/perf/tests/builtin-test.c
@@ -116,6 +116,10 @@ static struct test generic_tests[] = {
 		.is_supported = test__bp_signal_is_supported,
 	},
 	{
+		.desc = "Breakpoint accounting",
+		.func = test__bp_accounting,
+	},
+	{
 		.desc = "Number of exit events of a simple workload",
 		.func = test__task_exit,
 	},
diff --git a/tools/perf/tests/tests.h b/tools/perf/tests/tests.h
index 2e169819e647..a9760e790563 100644
--- a/tools/perf/tests/tests.h
+++ b/tools/perf/tests/tests.h
@@ -58,6 +58,7 @@ int test__hists_link(struct test *test, int subtest);
 int test__python_use(struct test *test, int subtest);
 int test__bp_signal(struct test *test, int subtest);
 int test__bp_signal_overflow(struct test *test, int subtest);
+int test__bp_accounting(struct test *test, int subtest);
 int test__task_exit(struct test *test, int subtest);
 int test__mem(struct test *test, int subtest);
 int test__sw_clock_freq(struct test *test, int subtest);
-- 
2.13.6

  parent reply	other threads:[~2018-03-12 13:46 UTC|newest]

Thread overview: 25+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2018-03-12 13:45 [PATCHv3 0/8] hw_breakpoint: Breakpoint modification fixes and new modify ioctl Jiri Olsa
2018-03-12 13:45 ` [PATCH 1/8] hw_breakpoint: Pass bp_type directly as find_slot_idx argument Jiri Olsa
2018-03-13  6:18   ` [tip:perf/core] hw_breakpoint: Pass bp_type directly as find_slot_idx() argument tip-bot for Jiri Olsa
2018-03-12 13:45 ` [PATCH 2/8] hw_breakpoint: Pass bp_type argument to __reserve_bp_slot|__release_bp_slot Jiri Olsa
2018-03-13  6:19   ` [tip:perf/core] hw_breakpoint: Pass bp_type argument to __reserve_bp_slot|__release_bp_slot() tip-bot for Jiri Olsa
2018-03-12 13:45 ` [PATCH 3/8] hw_breakpoint: Add modify_bp_slot function Jiri Olsa
2018-03-13  6:19   ` [tip:perf/core] hw_breakpoint: Add modify_bp_slot() function tip-bot for Jiri Olsa
2018-03-12 13:45 ` [PATCH 4/8] hw_breakpoint: Factor out __modify_user_hw_breakpoint function Jiri Olsa
2018-03-13  6:20   ` [tip:perf/core] hw_breakpoint: Factor out __modify_user_hw_breakpoint() function tip-bot for Jiri Olsa
2018-03-12 13:45 ` [PATCH 5/8] hw_breakpoint: Add perf_event_attr fields check in __modify_user_hw_breakpoint Jiri Olsa
2018-03-13  6:20   ` [tip:perf/core] hw_breakpoint: Add perf_event_attr fields check in __modify_user_hw_breakpoint() tip-bot for Jiri Olsa
2018-03-12 13:45 ` [PATCH 6/8] perf/core: Move perf_event_attr::sample_max_stack into perf_copy_attr Jiri Olsa
2018-03-13  6:21   ` [tip:perf/core] perf/core: Move perf_event_attr::sample_max_stack into perf_copy_attr() tip-bot for Jiri Olsa
2018-03-12 13:45 ` [PATCH 7/8] perf/core: fast breakpoint modification via _IOC_MODIFY_ATTRIBUTES Jiri Olsa
2018-03-13  6:21   ` [tip:perf/core] perf/core: Implement " tip-bot for Milind Chabbi
2018-03-13 15:14   ` tip-bot for Milind Chabbi
2018-03-12 13:45 ` Jiri Olsa [this message]
2018-03-13  6:22   ` [tip:perf/core] perf tests: Add breakpoint accounting/modify test tip-bot for Jiri Olsa
2018-03-13 15:13   ` tip-bot for Jiri Olsa
2018-03-13  6:37 ` [PATCHv3 0/8] hw_breakpoint: Breakpoint modification fixes and new modify ioctl Ingo Molnar
2018-03-13  9:28   ` Jiri Olsa
2018-03-13  9:50     ` Jiri Olsa
2018-03-14  8:45       ` [PATCH] hw_breakpoint: Fix build for disabled CONFIG_HAVE_HW_BREAKPOINT Jiri Olsa
2018-03-14 12:28         ` Ingo Molnar
  -- strict thread matches above, loose matches on Subject: below --
2017-11-29  8:38 [PATCHv2 0/8] hw_breakpoint: Breakpoint modification fixes and new modify ioctl Jiri Olsa
2017-11-29  8:38 ` [PATCH 8/8] perf tests: Add breakpoint accounting/modify test Jiri Olsa

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20180312134548.31532-9-jolsa@kernel.org \
    --to=jolsa@kernel.org \
    --cc=a.p.zijlstra@chello.nl \
    --cc=acme@kernel.org \
    --cc=ak@linux.intel.com \
    --cc=alexander.shishkin@linux.intel.com \
    --cc=chabbi.milind@gmail.com \
    --cc=dsahern@gmail.com \
    --cc=hbathini@linux.vnet.ibm.com \
    --cc=kan.liang@intel.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=mingo@kernel.org \
    --cc=mpe@ellerman.id.au \
    --cc=namhyung@kernel.org \
    --cc=onestero@redhat.com \
    --cc=sukadev@linux.vnet.ibm.com \
    --cc=will.deacon@arm.com \
    --cc=yao.jin@linux.intel.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.