lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Date:	Tue,  3 Mar 2015 03:54:43 -0500
From:	kan.liang@...el.com
To:	a.p.zijlstra@...llo.nl, acme@...nel.org,
	linux-kernel@...r.kernel.org
Cc:	ak@...ux.intel.com, Kan Liang <kan.liang@...el.com>
Subject: [PATCH 2/5] perf,tools: check and re-organize evsel cpu maps

From: Kan Liang <kan.liang@...el.com>

With the patch 1/5, it's possible to group read events from different
pmus. "-C" can be used to set cpu list. The cpu list may be incompatible
with pmu's cpumask.
This patch checks the event's cpu maps, and discard the incompatible cpu
maps.
event's cpu maps is saved in evsel->cpus during option parse. Then the
evlist's cpu maps is created in perf_evlist__create_maps. So the cpu
maps can be check and re-organized in perf_evlist__create_maps.
Only cpu_list need to check the cpu maps.

Signed-off-by: Kan Liang <kan.liang@...el.com>
---
 tools/perf/builtin-top.c |  6 ++--
 tools/perf/util/evlist.c | 72 ++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 75 insertions(+), 3 deletions(-)

diff --git a/tools/perf/builtin-top.c b/tools/perf/builtin-top.c
index 5fb8723..f40d1d6 100644
--- a/tools/perf/builtin-top.c
+++ b/tools/perf/builtin-top.c
@@ -1218,9 +1218,6 @@ int cmd_top(int argc, const char **argv, const char *prefix __maybe_unused)
 	if (target__none(target))
 		target->system_wide = true;
 
-	if (perf_evlist__create_maps(top.evlist, target) < 0)
-		usage_with_options(top_usage, options);
-
 	if (!top.evlist->nr_entries &&
 	    perf_evlist__add_default(top.evlist) < 0) {
 		ui__error("Not enough memory for event selector list\n");
@@ -1229,6 +1226,9 @@ int cmd_top(int argc, const char **argv, const char *prefix __maybe_unused)
 
 	symbol_conf.nr_events = top.evlist->nr_entries;
 
+	if (perf_evlist__create_maps(top.evlist, target) < 0)
+		usage_with_options(top_usage, options);
+
 	if (top.delay_secs < 1)
 		top.delay_secs = 1;
 
diff --git a/tools/perf/util/evlist.c b/tools/perf/util/evlist.c
index 8d0b623..3c6115c 100644
--- a/tools/perf/util/evlist.c
+++ b/tools/perf/util/evlist.c
@@ -1026,6 +1026,74 @@ int perf_evlist__mmap(struct perf_evlist *evlist, unsigned int pages,
 	return perf_evlist__mmap_per_cpu(evlist, &mp);
 }
 
+static int cmp_ids(const void *a, const void *b)
+{
+	return *(int *)a - *(int *)b;
+}
+
+/*
+ * Check evsel cpu map according to pmu cpumask and input
+ * Only available cpu can be stored in evsel->cpus->map.
+ */
+static int perf_evlist__check_evsel_cpus(struct perf_evlist *evlist)
+{
+	const struct cpu_map *cpus = evlist->cpus;
+	const int ncpus = cpu_map__nr(evlist->cpus);
+	struct perf_evsel *evsel;
+	int i, j, cpu_nr, tmp;
+
+	/* ensure we process id in increasing order */
+	qsort(evlist->cpus->map, evlist->cpus->nr, sizeof(int), cmp_ids);
+
+	evlist__for_each(evlist, evsel) {
+		if (!evsel->cpus)
+			continue;
+
+		cpu_nr = 0;
+		j = 0;
+		for (i = 0; i < cpu_map__nr(evsel->cpus);)  {
+
+			if (j >= ncpus) {
+				evsel->cpus->map[i++] = -1;
+				continue;
+			}
+			for (; j < ncpus; j++) {
+				if (cpus->map[j] < evsel->cpus->map[i])
+					continue;
+				if (cpus->map[j] == evsel->cpus->map[i]) {
+					cpu_nr++;
+					j++;
+					i++;
+				} else
+					evsel->cpus->map[i++] = -1;
+				break;
+			}
+		}
+
+		if (cpu_nr == cpu_map__nr(evsel->cpus))
+			continue;
+		if (cpu_nr == 0) {
+			perror("failed to create CPUs map, please check cpumask");
+			return -1;
+		}
+
+		tmp = 0;
+		for (i = 0; i < cpu_nr; i++) {
+			if (evsel->cpus->map[i] == -1) {
+				while (evsel->cpus->map[tmp] == -1) {
+					tmp++;
+					BUG_ON(tmp >= cpu_map__nr(evsel->cpus));
+				}
+				evsel->cpus->map[i] = evsel->cpus->map[tmp];
+				evsel->cpus->map[tmp] = -1;
+			}
+			tmp++;
+		}
+		evsel->cpus->nr = cpu_nr;
+	}
+	return 0;
+}
+
 int perf_evlist__create_maps(struct perf_evlist *evlist, struct target *target)
 {
 	evlist->threads = thread_map__new_str(target->pid, target->tid,
@@ -1042,6 +1110,10 @@ int perf_evlist__create_maps(struct perf_evlist *evlist, struct target *target)
 	if (evlist->cpus == NULL)
 		goto out_delete_threads;
 
+	if (target->cpu_list &&
+	   (perf_evlist__check_evsel_cpus(evlist) < 0))
+		goto out_delete_threads;
+
 	return 0;
 
 out_delete_threads:
-- 
1.8.3.1

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@...r.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ