Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > linux.kernel > #1710103 > unrolled thread

[PATCH v2 01/19] perf, tools: Save max_x, max_y in xyarray

Started byAndi Kleen <andi@firstfloor.org>
First post2017-08-12 01:40 +0200
Last post2017-08-24 10:30 +0200
Articles 13 — 5 participants

Back to article view | Back to linux.kernel


Contents

  [PATCH v2 01/19] perf, tools: Save max_x, max_y in xyarray Andi Kleen <andi@firstfloor.org> - 2017-08-12 01:40 +0200
    [PATCH v2 13/19] perf, tools: Print generic metric header even for failed expressions Andi Kleen <andi@firstfloor.org> - 2017-08-12 01:40 +0200
    [PATCH v2 02/19] perf, tools: Fix buffer overflow while freeing events Andi Kleen <andi@firstfloor.org> - 2017-08-12 01:40 +0200
      Re: [PATCH v2 02/19] perf, tools: Fix buffer overflow while freeing  events Jiri Olsa <jolsa@redhat.com> - 2017-08-22 10:30 +0200
      [tip:perf/core] perf evsel: Fix buffer overflow while freeing  events tip-bot for Andi Kleen <tipbot@zytor.com> - 2017-08-24 10:30 +0200
    Re: [PATCH v2 01/19] perf, tools: Save max_x, max_y in xyarray Jiri Olsa <jolsa@redhat.com> - 2017-08-14 22:20 +0200
      Re: [PATCH v2 01/19] perf, tools: Save max_x, max_y in xyarray Andi Kleen <ak@linux.intel.com> - 2017-08-14 22:40 +0200
        Re: [PATCH v2 01/19] perf, tools: Save max_x, max_y in xyarray Jiri Olsa <jolsa@redhat.com> - 2017-08-14 23:20 +0200
    Re: [PATCH v2 01/19] perf, tools: Save max_x, max_y in xyarray Jiri Olsa <jolsa@redhat.com> - 2017-08-22 10:30 +0200
      Re: [PATCH v2 01/19] perf, tools: Save max_x, max_y in xyarray Arnaldo Carvalho de Melo <acme@kernel.org> - 2017-08-22 16:50 +0200
        Re: [PATCH v2 01/19] perf, tools: Save max_x, max_y in xyarray Jiri Olsa <jolsa@redhat.com> - 2017-08-22 16:50 +0200
          Re: [PATCH v2 01/19] perf, tools: Save max_x, max_y in xyarray Arnaldo Carvalho de Melo <acme@kernel.org> - 2017-08-22 17:10 +0200
    [tip:perf/core] perf xyarray: Save max_x, max_y tip-bot for Andi Kleen <tipbot@zytor.com> - 2017-08-24 10:30 +0200

#1710103 — [PATCH v2 01/19] perf, tools: Save max_x, max_y in xyarray

FromAndi Kleen <andi@firstfloor.org>
Date2017-08-12 01:40 +0200
Subject[PATCH v2 01/19] perf, tools: Save max_x, max_y in xyarray
Message-ID<udrxo-1lO-5@gated-at.bofh.it>
From: Andi Kleen <ak@linux.intel.com>

Save the original array dimensions in xyarrays, so that users can retrieve them
later. Add some inline functions to access these fields.

Signed-off-by: Andi Kleen <ak@linux.intel.com>
---
 tools/perf/util/xyarray.c |  2 ++
 tools/perf/util/xyarray.h | 12 ++++++++++++
 2 files changed, 14 insertions(+)

diff --git a/tools/perf/util/xyarray.c b/tools/perf/util/xyarray.c
index 7251fdbabced..c8f415d9877b 100644
--- a/tools/perf/util/xyarray.c
+++ b/tools/perf/util/xyarray.c
@@ -12,6 +12,8 @@ struct xyarray *xyarray__new(int xlen, int ylen, size_t entry_size)
 		xy->entry_size = entry_size;
 		xy->row_size   = row_size;
 		xy->entries    = xlen * ylen;
+		xy->max_x      = xlen;
+		xy->max_y      = ylen;
 	}
 
 	return xy;
diff --git a/tools/perf/util/xyarray.h b/tools/perf/util/xyarray.h
index 7f30af371b7e..785884158137 100644
--- a/tools/perf/util/xyarray.h
+++ b/tools/perf/util/xyarray.h
@@ -7,6 +7,8 @@ struct xyarray {
 	size_t row_size;
 	size_t entry_size;
 	size_t entries;
+	size_t max_x;
+	size_t max_y;
 	char contents[];
 };
 
@@ -19,4 +21,14 @@ static inline void *xyarray__entry(struct xyarray *xy, int x, int y)
 	return &xy->contents[x * xy->row_size + y * xy->entry_size];
 }
 
+static inline int xy_max_y(struct xyarray *xy)
+{
+	return xy->max_x;
+}
+
+static inline int xy_max_x(struct xyarray *xy)
+{
+	return xy->max_y;
+}
+
 #endif /* _PERF_XYARRAY_H_ */
-- 
2.9.4

[toc] | [next] | [standalone]


#1710105 — [PATCH v2 13/19] perf, tools: Print generic metric header even for failed expressions

FromAndi Kleen <andi@firstfloor.org>
Date2017-08-12 01:40 +0200
Subject[PATCH v2 13/19] perf, tools: Print generic metric header even for failed expressions
Message-ID<udrH5-1oI-29@gated-at.bofh.it>
In reply to#1710103
From: Andi Kleen <ak@linux.intel.com>

Print the generic metric header even when the expression evaluation
failed. Otherwise an expression that fails on the first collections
due to division by zero may suddenly reappear later without
an header.

Signed-off-by: Andi Kleen <ak@linux.intel.com>
---
 tools/perf/util/stat-shadow.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/tools/perf/util/stat-shadow.c b/tools/perf/util/stat-shadow.c
index b6cbb6e67167..4ec2d8d15344 100644
--- a/tools/perf/util/stat-shadow.c
+++ b/tools/perf/util/stat-shadow.c
@@ -662,7 +662,9 @@ static void generic_metric(const char *metric_expr,
 			out->force_header ?  name : "",
 				ratio);
 		else
-			print_metric(ctxp, NULL, NULL, "", 0);
+			print_metric(ctxp, NULL, NULL,
+				     out->force_header ?
+				     (metric_name ? metric_name : name) : "", 0);
 	} else
 		print_metric(ctxp, NULL, NULL, "", 0);
 }
-- 
2.9.4

[toc] | [prev] | [next] | [standalone]


#1710106 — [PATCH v2 02/19] perf, tools: Fix buffer overflow while freeing events

FromAndi Kleen <andi@firstfloor.org>
Date2017-08-12 01:40 +0200
Subject[PATCH v2 02/19] perf, tools: Fix buffer overflow while freeing events
Message-ID<udrH5-1oI-33@gated-at.bofh.it>
In reply to#1710103
From: Andi Kleen <ak@linux.intel.com>

Fix buffer overflow for

% perf stat -e msr/tsc/,cstate_core/c7-residency/ true

that causes glibc free list corruption. For some reason
it doesn't trigger in valgrind, but it is visible in AS:

=================================================================
==32681==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x603000003f5c at pc 0x0000005671ef bp 0x7ffdaaac9ac0 sp 0x7ffdaaac9ab0
READ of size 4 at 0x603000003f5c thread T0
    #0 0x5671ee in perf_evsel__close_fd util/evsel.c:1196
    #1 0x56c57a in perf_evsel__close util/evsel.c:1717
    #2 0x55ed5f in perf_evlist__close util/evlist.c:1631
    #3 0x4647e1 in __run_perf_stat /home/ak/hle/linux-hle-2.6/tools/perf/builtin-stat.c:749
    #4 0x4648e3 in run_perf_stat /home/ak/hle/linux-hle-2.6/tools/perf/builtin-stat.c:767
    #5 0x46e1bc in cmd_stat /home/ak/hle/linux-hle-2.6/tools/perf/builtin-stat.c:2785
    #6 0x52f83d in run_builtin /home/ak/hle/linux-hle-2.6/tools/perf/perf.c:296
    #7 0x52fd49 in handle_internal_command /home/ak/hle/linux-hle-2.6/tools/perf/perf.c:348
    #8 0x5300de in run_argv /home/ak/hle/linux-hle-2.6/tools/perf/perf.c:392
    #9 0x5308f3 in main /home/ak/hle/linux-hle-2.6/tools/perf/perf.c:530
    #10 0x7f0672d13400 in __libc_start_main (/lib64/libc.so.6+0x20400)
    #11 0x428419 in _start (/home/ak/hle/obj-perf/perf+0x428419)

0x603000003f5c is located 0 bytes to the right of 28-byte region [0x603000003f40,0x603000003f5c)
allocated by thread T0 here:
    #0 0x7f0675139020 in calloc (/lib64/libasan.so.3+0xc7020)
    #1 0x648a2d in zalloc util/util.h:23
    #2 0x648a88 in xyarray__new util/xyarray.c:9
    #3 0x566419 in perf_evsel__alloc_fd util/evsel.c:1039
    #4 0x56b427 in perf_evsel__open util/evsel.c:1529
    #5 0x56c620 in perf_evsel__open_per_thread util/evsel.c:1730
    #6 0x461dea in create_perf_stat_counter /home/ak/hle/linux-hle-2.6/tools/perf/builtin-stat.c:263
    #7 0x4637d7 in __run_perf_stat /home/ak/hle/linux-hle-2.6/tools/perf/builtin-stat.c:600
    #8 0x4648e3 in run_perf_stat /home/ak/hle/linux-hle-2.6/tools/perf/builtin-stat.c:767
    #9 0x46e1bc in cmd_stat /home/ak/hle/linux-hle-2.6/tools/perf/builtin-stat.c:2785
    #10 0x52f83d in run_builtin /home/ak/hle/linux-hle-2.6/tools/perf/perf.c:296
    #11 0x52fd49 in handle_internal_command /home/ak/hle/linux-hle-2.6/tools/perf/perf.c:348
    #12 0x5300de in run_argv /home/ak/hle/linux-hle-2.6/tools/perf/perf.c:392
    #13 0x5308f3 in main /home/ak/hle/linux-hle-2.6/tools/perf/perf.c:530
    #14 0x7f0672d13400 in __libc_start_main (/lib64/libc.so.6+0x20400)

The event is allocated with cpus == 1, but freed with cpus == real number
When the evsel close function walks the file descriptors it exceeds the
fd xyarray boundaries and reads random memory.

v2:
Now that xyarrays save their original dimensions we can use these
to iterate the two dimensional fd arrays. Fix some users
(close, ioctl) in evsel.c to use these fields directly. This allows simplifying
the code and dropping quite a few function arguments. Adjust
all callers by removing the unneeded arguments.

The actual perf event reading still uses the original values from
the evsel list.

Signed-off-by: Andi Kleen <ak@linux.intel.com>
---
 tools/perf/tests/openat-syscall-all-cpus.c |  2 +-
 tools/perf/tests/openat-syscall.c          |  2 +-
 tools/perf/util/evlist.c                   | 12 +++-------
 tools/perf/util/evsel.c                    | 37 ++++++++++--------------------
 tools/perf/util/evsel.h                    |  7 +++---
 5 files changed, 20 insertions(+), 40 deletions(-)

diff --git a/tools/perf/tests/openat-syscall-all-cpus.c b/tools/perf/tests/openat-syscall-all-cpus.c
index 1a74dd9fd067..c7a57ba5b061 100644
--- a/tools/perf/tests/openat-syscall-all-cpus.c
+++ b/tools/perf/tests/openat-syscall-all-cpus.c
@@ -115,7 +115,7 @@ int test__openat_syscall_event_on_all_cpus(int subtest __maybe_unused)
 
 	perf_evsel__free_counts(evsel);
 out_close_fd:
-	perf_evsel__close_fd(evsel, 1, threads->nr);
+	perf_evsel__close_fd(evsel);
 out_evsel_delete:
 	perf_evsel__delete(evsel);
 out_thread_map_delete:
diff --git a/tools/perf/tests/openat-syscall.c b/tools/perf/tests/openat-syscall.c
index e44506e21ee7..121c7317bfc7 100644
--- a/tools/perf/tests/openat-syscall.c
+++ b/tools/perf/tests/openat-syscall.c
@@ -56,7 +56,7 @@ int test__openat_syscall_event(int subtest __maybe_unused)
 
 	err = 0;
 out_close_fd:
-	perf_evsel__close_fd(evsel, 1, threads->nr);
+	perf_evsel__close_fd(evsel);
 out_evsel_delete:
 	perf_evsel__delete(evsel);
 out_thread_map_delete:
diff --git a/tools/perf/util/evlist.c b/tools/perf/util/evlist.c
index 078b58511595..6a0d7ffbeba0 100644
--- a/tools/perf/util/evlist.c
+++ b/tools/perf/util/evlist.c
@@ -1419,8 +1419,6 @@ int perf_evlist__apply_filters(struct perf_evlist *evlist, struct perf_evsel **e
 {
 	struct perf_evsel *evsel;
 	int err = 0;
-	const int ncpus = cpu_map__nr(evlist->cpus),
-		  nthreads = thread_map__nr(evlist->threads);
 
 	evlist__for_each_entry(evlist, evsel) {
 		if (evsel->filter == NULL)
@@ -1430,7 +1428,7 @@ int perf_evlist__apply_filters(struct perf_evlist *evlist, struct perf_evsel **e
 		 * filters only work for tracepoint event, which doesn't have cpu limit.
 		 * So evlist and evsel should always be same.
 		 */
-		err = perf_evsel__apply_filter(evsel, ncpus, nthreads, evsel->filter);
+		err = perf_evsel__apply_filter(evsel, evsel->filter);
 		if (err) {
 			*err_evsel = evsel;
 			break;
@@ -1623,13 +1621,9 @@ void perf_evlist__set_selected(struct perf_evlist *evlist,
 void perf_evlist__close(struct perf_evlist *evlist)
 {
 	struct perf_evsel *evsel;
-	int ncpus = cpu_map__nr(evlist->cpus);
-	int nthreads = thread_map__nr(evlist->threads);
 
-	evlist__for_each_entry_reverse(evlist, evsel) {
-		int n = evsel->cpus ? evsel->cpus->nr : ncpus;
-		perf_evsel__close(evsel, n, nthreads);
-	}
+	evlist__for_each_entry_reverse(evlist, evsel)
+		perf_evsel__close(evsel);
 }
 
 static int perf_evlist__create_syswide_maps(struct perf_evlist *evlist)
diff --git a/tools/perf/util/evsel.c b/tools/perf/util/evsel.c
index 3735c9e0080d..c9351564ed94 100644
--- a/tools/perf/util/evsel.c
+++ b/tools/perf/util/evsel.c
@@ -1051,16 +1051,13 @@ static int perf_evsel__alloc_fd(struct perf_evsel *evsel, int ncpus, int nthread
 	return evsel->fd != NULL ? 0 : -ENOMEM;
 }
 
-static int perf_evsel__run_ioctl(struct perf_evsel *evsel, int ncpus, int nthreads,
+static int perf_evsel__run_ioctl(struct perf_evsel *evsel,
 			  int ioc,  void *arg)
 {
 	int cpu, thread;
 
-	if (evsel->system_wide)
-		nthreads = 1;
-
-	for (cpu = 0; cpu < ncpus; cpu++) {
-		for (thread = 0; thread < nthreads; thread++) {
+	for (cpu = 0; cpu < xy_max_x(evsel->fd); cpu++) {
+		for (thread = 0; thread < xy_max_y(evsel->fd); thread++) {
 			int fd = FD(evsel, cpu, thread),
 			    err = ioctl(fd, ioc, arg);
 
@@ -1072,10 +1069,9 @@ static int perf_evsel__run_ioctl(struct perf_evsel *evsel, int ncpus, int nthrea
 	return 0;
 }
 
-int perf_evsel__apply_filter(struct perf_evsel *evsel, int ncpus, int nthreads,
-			     const char *filter)
+int perf_evsel__apply_filter(struct perf_evsel *evsel, const char *filter)
 {
-	return perf_evsel__run_ioctl(evsel, ncpus, nthreads,
+	return perf_evsel__run_ioctl(evsel,
 				     PERF_EVENT_IOC_SET_FILTER,
 				     (void *)filter);
 }
@@ -1122,20 +1118,14 @@ int perf_evsel__append_addr_filter(struct perf_evsel *evsel, const char *filter)
 
 int perf_evsel__enable(struct perf_evsel *evsel)
 {
-	int nthreads = thread_map__nr(evsel->threads);
-	int ncpus = cpu_map__nr(evsel->cpus);
-
-	return perf_evsel__run_ioctl(evsel, ncpus, nthreads,
+	return perf_evsel__run_ioctl(evsel,
 				     PERF_EVENT_IOC_ENABLE,
 				     0);
 }
 
 int perf_evsel__disable(struct perf_evsel *evsel)
 {
-	int nthreads = thread_map__nr(evsel->threads);
-	int ncpus = cpu_map__nr(evsel->cpus);
-
-	return perf_evsel__run_ioctl(evsel, ncpus, nthreads,
+	return perf_evsel__run_ioctl(evsel,
 				     PERF_EVENT_IOC_DISABLE,
 				     0);
 }
@@ -1185,15 +1175,12 @@ static void perf_evsel__free_config_terms(struct perf_evsel *evsel)
 	}
 }
 
-void perf_evsel__close_fd(struct perf_evsel *evsel, int ncpus, int nthreads)
+void perf_evsel__close_fd(struct perf_evsel *evsel)
 {
 	int cpu, thread;
 
-	if (evsel->system_wide)
-		nthreads = 1;
-
-	for (cpu = 0; cpu < ncpus; cpu++)
-		for (thread = 0; thread < nthreads; ++thread) {
+	for (cpu = 0; cpu < xy_max_x(evsel->fd); cpu++)
+		for (thread = 0; thread < xy_max_y(evsel->fd); ++thread) {
 			close(FD(evsel, cpu, thread));
 			FD(evsel, cpu, thread) = -1;
 		}
@@ -1854,12 +1841,12 @@ int perf_evsel__open(struct perf_evsel *evsel, struct cpu_map *cpus,
 	return err;
 }
 
-void perf_evsel__close(struct perf_evsel *evsel, int ncpus, int nthreads)
+void perf_evsel__close(struct perf_evsel *evsel)
 {
 	if (evsel->fd == NULL)
 		return;
 
-	perf_evsel__close_fd(evsel, ncpus, nthreads);
+	perf_evsel__close_fd(evsel);
 	perf_evsel__free_fd(evsel);
 }
 
diff --git a/tools/perf/util/evsel.h b/tools/perf/util/evsel.h
index de03c18daaf0..351d3b2d8887 100644
--- a/tools/perf/util/evsel.h
+++ b/tools/perf/util/evsel.h
@@ -226,7 +226,7 @@ const char *perf_evsel__group_name(struct perf_evsel *evsel);
 int perf_evsel__group_desc(struct perf_evsel *evsel, char *buf, size_t size);
 
 int perf_evsel__alloc_id(struct perf_evsel *evsel, int ncpus, int nthreads);
-void perf_evsel__close_fd(struct perf_evsel *evsel, int ncpus, int nthreads);
+void perf_evsel__close_fd(struct perf_evsel *evsel);
 
 void __perf_evsel__set_sample_bit(struct perf_evsel *evsel,
 				  enum perf_event_sample_format bit);
@@ -246,8 +246,7 @@ int perf_evsel__set_filter(struct perf_evsel *evsel, const char *filter);
 int perf_evsel__append_tp_filter(struct perf_evsel *evsel, const char *filter);
 int perf_evsel__append_addr_filter(struct perf_evsel *evsel,
 				   const char *filter);
-int perf_evsel__apply_filter(struct perf_evsel *evsel, int ncpus, int nthreads,
-			     const char *filter);
+int perf_evsel__apply_filter(struct perf_evsel *evsel, const char *filter);
 int perf_evsel__enable(struct perf_evsel *evsel);
 int perf_evsel__disable(struct perf_evsel *evsel);
 
@@ -257,7 +256,7 @@ int perf_evsel__open_per_thread(struct perf_evsel *evsel,
 				struct thread_map *threads);
 int perf_evsel__open(struct perf_evsel *evsel, struct cpu_map *cpus,
 		     struct thread_map *threads);
-void perf_evsel__close(struct perf_evsel *evsel, int ncpus, int nthreads);
+void perf_evsel__close(struct perf_evsel *evsel);
 
 struct perf_sample;
 
-- 
2.9.4

[toc] | [prev] | [next] | [standalone]


#1717179 — Re: [PATCH v2 02/19] perf, tools: Fix buffer overflow while freeing events

FromJiri Olsa <jolsa@redhat.com>
Date2017-08-22 10:30 +0200
SubjectRe: [PATCH v2 02/19] perf, tools: Fix buffer overflow while freeing events
Message-ID<uhcJs-8b9-11@gated-at.bofh.it>
In reply to#1710106
On Fri, Aug 11, 2017 at 04:26:17PM -0700, Andi Kleen wrote:
> From: Andi Kleen <ak@linux.intel.com>
> 
> Fix buffer overflow for
> 
> % perf stat -e msr/tsc/,cstate_core/c7-residency/ true
> 
> that causes glibc free list corruption. For some reason
> it doesn't trigger in valgrind, but it is visible in AS:
> 
> =================================================================
> ==32681==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x603000003f5c at pc 0x0000005671ef bp 0x7ffdaaac9ac0 sp 0x7ffdaaac9ab0
> READ of size 4 at 0x603000003f5c thread T0
>     #0 0x5671ee in perf_evsel__close_fd util/evsel.c:1196
>     #1 0x56c57a in perf_evsel__close util/evsel.c:1717
>     #2 0x55ed5f in perf_evlist__close util/evlist.c:1631
>     #3 0x4647e1 in __run_perf_stat /home/ak/hle/linux-hle-2.6/tools/perf/builtin-stat.c:749
>     #4 0x4648e3 in run_perf_stat /home/ak/hle/linux-hle-2.6/tools/perf/builtin-stat.c:767
>     #5 0x46e1bc in cmd_stat /home/ak/hle/linux-hle-2.6/tools/perf/builtin-stat.c:2785
>     #6 0x52f83d in run_builtin /home/ak/hle/linux-hle-2.6/tools/perf/perf.c:296
>     #7 0x52fd49 in handle_internal_command /home/ak/hle/linux-hle-2.6/tools/perf/perf.c:348
>     #8 0x5300de in run_argv /home/ak/hle/linux-hle-2.6/tools/perf/perf.c:392
>     #9 0x5308f3 in main /home/ak/hle/linux-hle-2.6/tools/perf/perf.c:530
>     #10 0x7f0672d13400 in __libc_start_main (/lib64/libc.so.6+0x20400)
>     #11 0x428419 in _start (/home/ak/hle/obj-perf/perf+0x428419)
> 
> 0x603000003f5c is located 0 bytes to the right of 28-byte region [0x603000003f40,0x603000003f5c)
> allocated by thread T0 here:
>     #0 0x7f0675139020 in calloc (/lib64/libasan.so.3+0xc7020)
>     #1 0x648a2d in zalloc util/util.h:23
>     #2 0x648a88 in xyarray__new util/xyarray.c:9
>     #3 0x566419 in perf_evsel__alloc_fd util/evsel.c:1039
>     #4 0x56b427 in perf_evsel__open util/evsel.c:1529
>     #5 0x56c620 in perf_evsel__open_per_thread util/evsel.c:1730
>     #6 0x461dea in create_perf_stat_counter /home/ak/hle/linux-hle-2.6/tools/perf/builtin-stat.c:263
>     #7 0x4637d7 in __run_perf_stat /home/ak/hle/linux-hle-2.6/tools/perf/builtin-stat.c:600
>     #8 0x4648e3 in run_perf_stat /home/ak/hle/linux-hle-2.6/tools/perf/builtin-stat.c:767
>     #9 0x46e1bc in cmd_stat /home/ak/hle/linux-hle-2.6/tools/perf/builtin-stat.c:2785
>     #10 0x52f83d in run_builtin /home/ak/hle/linux-hle-2.6/tools/perf/perf.c:296
>     #11 0x52fd49 in handle_internal_command /home/ak/hle/linux-hle-2.6/tools/perf/perf.c:348
>     #12 0x5300de in run_argv /home/ak/hle/linux-hle-2.6/tools/perf/perf.c:392
>     #13 0x5308f3 in main /home/ak/hle/linux-hle-2.6/tools/perf/perf.c:530
>     #14 0x7f0672d13400 in __libc_start_main (/lib64/libc.so.6+0x20400)
> 
> The event is allocated with cpus == 1, but freed with cpus == real number
> When the evsel close function walks the file descriptors it exceeds the
> fd xyarray boundaries and reads random memory.
> 
> v2:
> Now that xyarrays save their original dimensions we can use these
> to iterate the two dimensional fd arrays. Fix some users
> (close, ioctl) in evsel.c to use these fields directly. This allows simplifying
> the code and dropping quite a few function arguments. Adjust
> all callers by removing the unneeded arguments.
> 
> The actual perf event reading still uses the original values from
> the evsel list.

i was wondering how much code change this would be,
but it turned out not that bad ;-)

Acked-by: Jiri Olsa <jolsa@kernel.org>

thanks,
jirka

[toc] | [prev] | [next] | [standalone]


#1718963 — [tip:perf/core] perf evsel: Fix buffer overflow while freeing events

Fromtip-bot for Andi Kleen <tipbot@zytor.com>
Date2017-08-24 10:30 +0200
Subject[tip:perf/core] perf evsel: Fix buffer overflow while freeing events
Message-ID<uhVGx-405-9@gated-at.bofh.it>
In reply to#1710106
Commit-ID:  475fb533fb7d3dcf009a434f9b9ea238b93f4cb8
Gitweb:     http://git.kernel.org/tip/475fb533fb7d3dcf009a434f9b9ea238b93f4cb8
Author:     Andi Kleen <ak@linux.intel.com>
AuthorDate: Fri, 11 Aug 2017 16:26:17 -0700
Committer:  Arnaldo Carvalho de Melo <acme@redhat.com>
CommitDate: Tue, 22 Aug 2017 11:51:31 -0300

perf evsel: Fix buffer overflow while freeing events

Fix buffer overflow for:

  % perf stat -e msr/tsc/,cstate_core/c7-residency/ true

that causes glibc free list corruption. For some reason it doesn't
trigger in valgrind, but it is visible in AS:

  =================================================================
  ==32681==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x603000003f5c at pc 0x0000005671ef bp 0x7ffdaaac9ac0 sp 0x7ffdaaac9ab0
  READ of size 4 at 0x603000003f5c thread T0
    #0 0x5671ee in perf_evsel__close_fd util/evsel.c:1196
    #1 0x56c57a in perf_evsel__close util/evsel.c:1717
    #2 0x55ed5f in perf_evlist__close util/evlist.c:1631
    #3 0x4647e1 in __run_perf_stat /home/ak/hle/linux-hle-2.6/tools/perf/builtin-stat.c:749
    #4 0x4648e3 in run_perf_stat /home/ak/hle/linux-hle-2.6/tools/perf/builtin-stat.c:767
    #5 0x46e1bc in cmd_stat /home/ak/hle/linux-hle-2.6/tools/perf/builtin-stat.c:2785
    #6 0x52f83d in run_builtin /home/ak/hle/linux-hle-2.6/tools/perf/perf.c:296
    #7 0x52fd49 in handle_internal_command /home/ak/hle/linux-hle-2.6/tools/perf/perf.c:348
    #8 0x5300de in run_argv /home/ak/hle/linux-hle-2.6/tools/perf/perf.c:392
    #9 0x5308f3 in main /home/ak/hle/linux-hle-2.6/tools/perf/perf.c:530
    #10 0x7f0672d13400 in __libc_start_main (/lib64/libc.so.6+0x20400)
    #11 0x428419 in _start (/home/ak/hle/obj-perf/perf+0x428419)

  0x603000003f5c is located 0 bytes to the right of 28-byte region [0x603000003f40,0x603000003f5c)
  allocated by thread T0 here:
    #0 0x7f0675139020 in calloc (/lib64/libasan.so.3+0xc7020)
    #1 0x648a2d in zalloc util/util.h:23
    #2 0x648a88 in xyarray__new util/xyarray.c:9
    #3 0x566419 in perf_evsel__alloc_fd util/evsel.c:1039
    #4 0x56b427 in perf_evsel__open util/evsel.c:1529
    #5 0x56c620 in perf_evsel__open_per_thread util/evsel.c:1730
    #6 0x461dea in create_perf_stat_counter /home/ak/hle/linux-hle-2.6/tools/perf/builtin-stat.c:263
    #7 0x4637d7 in __run_perf_stat /home/ak/hle/linux-hle-2.6/tools/perf/builtin-stat.c:600
    #8 0x4648e3 in run_perf_stat /home/ak/hle/linux-hle-2.6/tools/perf/builtin-stat.c:767
    #9 0x46e1bc in cmd_stat /home/ak/hle/linux-hle-2.6/tools/perf/builtin-stat.c:2785
    #10 0x52f83d in run_builtin /home/ak/hle/linux-hle-2.6/tools/perf/perf.c:296
    #11 0x52fd49 in handle_internal_command /home/ak/hle/linux-hle-2.6/tools/perf/perf.c:348
    #12 0x5300de in run_argv /home/ak/hle/linux-hle-2.6/tools/perf/perf.c:392
    #13 0x5308f3 in main /home/ak/hle/linux-hle-2.6/tools/perf/perf.c:530
    #14 0x7f0672d13400 in __libc_start_main (/lib64/libc.so.6+0x20400)

The event is allocated with cpus == 1, but freed with cpus == real number
When the evsel close function walks the file descriptors it exceeds the
fd xyarray boundaries and reads random memory.

v2:

Now that xyarrays save their original dimensions we can use these to
iterate the two dimensional fd arrays. Fix some users (close, ioctl) in
evsel.c to use these fields directly. This allows simplifying the code
and dropping quite a few function arguments. Adjust all callers by
removing the unneeded arguments.

The actual perf event reading still uses the original values from the
evsel list.

Signed-off-by: Andi Kleen <ak@linux.intel.com>
Acked-by: Jiri Olsa <jolsa@kernel.org>
Link: http://lkml.kernel.org/r/20170811232634.30465-2-andi@firstfloor.org
[ Fix up xy_max_[xy]() -> xyarray__max_[xy]() ]
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
---
 tools/perf/tests/openat-syscall-all-cpus.c |  2 +-
 tools/perf/tests/openat-syscall.c          |  2 +-
 tools/perf/util/evlist.c                   | 12 +++-------
 tools/perf/util/evsel.c                    | 37 ++++++++++--------------------
 tools/perf/util/evsel.h                    |  7 +++---
 5 files changed, 20 insertions(+), 40 deletions(-)

diff --git a/tools/perf/tests/openat-syscall-all-cpus.c b/tools/perf/tests/openat-syscall-all-cpus.c
index 8726511..9cf1c35 100644
--- a/tools/perf/tests/openat-syscall-all-cpus.c
+++ b/tools/perf/tests/openat-syscall-all-cpus.c
@@ -115,7 +115,7 @@ int test__openat_syscall_event_on_all_cpus(struct test *test __maybe_unused, int
 
 	perf_evsel__free_counts(evsel);
 out_close_fd:
-	perf_evsel__close_fd(evsel, 1, threads->nr);
+	perf_evsel__close_fd(evsel);
 out_evsel_delete:
 	perf_evsel__delete(evsel);
 out_thread_map_delete:
diff --git a/tools/perf/tests/openat-syscall.c b/tools/perf/tests/openat-syscall.c
index 85bb672..9dc5c5d 100644
--- a/tools/perf/tests/openat-syscall.c
+++ b/tools/perf/tests/openat-syscall.c
@@ -56,7 +56,7 @@ int test__openat_syscall_event(struct test *test __maybe_unused, int subtest __m
 
 	err = 0;
 out_close_fd:
-	perf_evsel__close_fd(evsel, 1, threads->nr);
+	perf_evsel__close_fd(evsel);
 out_evsel_delete:
 	perf_evsel__delete(evsel);
 out_thread_map_delete:
diff --git a/tools/perf/util/evlist.c b/tools/perf/util/evlist.c
index 078b585..6a0d7ff 100644
--- a/tools/perf/util/evlist.c
+++ b/tools/perf/util/evlist.c
@@ -1419,8 +1419,6 @@ int perf_evlist__apply_filters(struct perf_evlist *evlist, struct perf_evsel **e
 {
 	struct perf_evsel *evsel;
 	int err = 0;
-	const int ncpus = cpu_map__nr(evlist->cpus),
-		  nthreads = thread_map__nr(evlist->threads);
 
 	evlist__for_each_entry(evlist, evsel) {
 		if (evsel->filter == NULL)
@@ -1430,7 +1428,7 @@ int perf_evlist__apply_filters(struct perf_evlist *evlist, struct perf_evsel **e
 		 * filters only work for tracepoint event, which doesn't have cpu limit.
 		 * So evlist and evsel should always be same.
 		 */
-		err = perf_evsel__apply_filter(evsel, ncpus, nthreads, evsel->filter);
+		err = perf_evsel__apply_filter(evsel, evsel->filter);
 		if (err) {
 			*err_evsel = evsel;
 			break;
@@ -1623,13 +1621,9 @@ void perf_evlist__set_selected(struct perf_evlist *evlist,
 void perf_evlist__close(struct perf_evlist *evlist)
 {
 	struct perf_evsel *evsel;
-	int ncpus = cpu_map__nr(evlist->cpus);
-	int nthreads = thread_map__nr(evlist->threads);
 
-	evlist__for_each_entry_reverse(evlist, evsel) {
-		int n = evsel->cpus ? evsel->cpus->nr : ncpus;
-		perf_evsel__close(evsel, n, nthreads);
-	}
+	evlist__for_each_entry_reverse(evlist, evsel)
+		perf_evsel__close(evsel);
 }
 
 static int perf_evlist__create_syswide_maps(struct perf_evlist *evlist)
diff --git a/tools/perf/util/evsel.c b/tools/perf/util/evsel.c
index 3735c9e..5dfb8bc 100644
--- a/tools/perf/util/evsel.c
+++ b/tools/perf/util/evsel.c
@@ -1051,16 +1051,13 @@ static int perf_evsel__alloc_fd(struct perf_evsel *evsel, int ncpus, int nthread
 	return evsel->fd != NULL ? 0 : -ENOMEM;
 }
 
-static int perf_evsel__run_ioctl(struct perf_evsel *evsel, int ncpus, int nthreads,
+static int perf_evsel__run_ioctl(struct perf_evsel *evsel,
 			  int ioc,  void *arg)
 {
 	int cpu, thread;
 
-	if (evsel->system_wide)
-		nthreads = 1;
-
-	for (cpu = 0; cpu < ncpus; cpu++) {
-		for (thread = 0; thread < nthreads; thread++) {
+	for (cpu = 0; cpu < xyarray__max_x(evsel->fd); cpu++) {
+		for (thread = 0; thread < xyarray__max_y(evsel->fd); thread++) {
 			int fd = FD(evsel, cpu, thread),
 			    err = ioctl(fd, ioc, arg);
 
@@ -1072,10 +1069,9 @@ static int perf_evsel__run_ioctl(struct perf_evsel *evsel, int ncpus, int nthrea
 	return 0;
 }
 
-int perf_evsel__apply_filter(struct perf_evsel *evsel, int ncpus, int nthreads,
-			     const char *filter)
+int perf_evsel__apply_filter(struct perf_evsel *evsel, const char *filter)
 {
-	return perf_evsel__run_ioctl(evsel, ncpus, nthreads,
+	return perf_evsel__run_ioctl(evsel,
 				     PERF_EVENT_IOC_SET_FILTER,
 				     (void *)filter);
 }
@@ -1122,20 +1118,14 @@ int perf_evsel__append_addr_filter(struct perf_evsel *evsel, const char *filter)
 
 int perf_evsel__enable(struct perf_evsel *evsel)
 {
-	int nthreads = thread_map__nr(evsel->threads);
-	int ncpus = cpu_map__nr(evsel->cpus);
-
-	return perf_evsel__run_ioctl(evsel, ncpus, nthreads,
+	return perf_evsel__run_ioctl(evsel,
 				     PERF_EVENT_IOC_ENABLE,
 				     0);
 }
 
 int perf_evsel__disable(struct perf_evsel *evsel)
 {
-	int nthreads = thread_map__nr(evsel->threads);
-	int ncpus = cpu_map__nr(evsel->cpus);
-
-	return perf_evsel__run_ioctl(evsel, ncpus, nthreads,
+	return perf_evsel__run_ioctl(evsel,
 				     PERF_EVENT_IOC_DISABLE,
 				     0);
 }
@@ -1185,15 +1175,12 @@ static void perf_evsel__free_config_terms(struct perf_evsel *evsel)
 	}
 }
 
-void perf_evsel__close_fd(struct perf_evsel *evsel, int ncpus, int nthreads)
+void perf_evsel__close_fd(struct perf_evsel *evsel)
 {
 	int cpu, thread;
 
-	if (evsel->system_wide)
-		nthreads = 1;
-
-	for (cpu = 0; cpu < ncpus; cpu++)
-		for (thread = 0; thread < nthreads; ++thread) {
+	for (cpu = 0; cpu < xyarray__max_x(evsel->fd); cpu++)
+		for (thread = 0; thread < xyarray__max_y(evsel->fd); ++thread) {
 			close(FD(evsel, cpu, thread));
 			FD(evsel, cpu, thread) = -1;
 		}
@@ -1854,12 +1841,12 @@ out_close:
 	return err;
 }
 
-void perf_evsel__close(struct perf_evsel *evsel, int ncpus, int nthreads)
+void perf_evsel__close(struct perf_evsel *evsel)
 {
 	if (evsel->fd == NULL)
 		return;
 
-	perf_evsel__close_fd(evsel, ncpus, nthreads);
+	perf_evsel__close_fd(evsel);
 	perf_evsel__free_fd(evsel);
 }
 
diff --git a/tools/perf/util/evsel.h b/tools/perf/util/evsel.h
index de03c18..351d3b2 100644
--- a/tools/perf/util/evsel.h
+++ b/tools/perf/util/evsel.h
@@ -226,7 +226,7 @@ const char *perf_evsel__group_name(struct perf_evsel *evsel);
 int perf_evsel__group_desc(struct perf_evsel *evsel, char *buf, size_t size);
 
 int perf_evsel__alloc_id(struct perf_evsel *evsel, int ncpus, int nthreads);
-void perf_evsel__close_fd(struct perf_evsel *evsel, int ncpus, int nthreads);
+void perf_evsel__close_fd(struct perf_evsel *evsel);
 
 void __perf_evsel__set_sample_bit(struct perf_evsel *evsel,
 				  enum perf_event_sample_format bit);
@@ -246,8 +246,7 @@ int perf_evsel__set_filter(struct perf_evsel *evsel, const char *filter);
 int perf_evsel__append_tp_filter(struct perf_evsel *evsel, const char *filter);
 int perf_evsel__append_addr_filter(struct perf_evsel *evsel,
 				   const char *filter);
-int perf_evsel__apply_filter(struct perf_evsel *evsel, int ncpus, int nthreads,
-			     const char *filter);
+int perf_evsel__apply_filter(struct perf_evsel *evsel, const char *filter);
 int perf_evsel__enable(struct perf_evsel *evsel);
 int perf_evsel__disable(struct perf_evsel *evsel);
 
@@ -257,7 +256,7 @@ int perf_evsel__open_per_thread(struct perf_evsel *evsel,
 				struct thread_map *threads);
 int perf_evsel__open(struct perf_evsel *evsel, struct cpu_map *cpus,
 		     struct thread_map *threads);
-void perf_evsel__close(struct perf_evsel *evsel, int ncpus, int nthreads);
+void perf_evsel__close(struct perf_evsel *evsel);
 
 struct perf_sample;
 

[toc] | [prev] | [next] | [standalone]


#1711413

FromJiri Olsa <jolsa@redhat.com>
Date2017-08-14 22:20 +0200
Message-ID<ueu0b-dy-31@gated-at.bofh.it>
In reply to#1710103
On Fri, Aug 11, 2017 at 04:26:16PM -0700, Andi Kleen wrote:
> From: Andi Kleen <ak@linux.intel.com>
> 
> Save the original array dimensions in xyarrays, so that users can retrieve them
> later. Add some inline functions to access these fields.

hi,
is there a branch with this?

also I recall sending feedback for some of those patches,
any changes..?

jirka

[toc] | [prev] | [next] | [standalone]


#1711426

FromAndi Kleen <ak@linux.intel.com>
Date2017-08-14 22:40 +0200
Message-ID<ueujv-jF-5@gated-at.bofh.it>
In reply to#1711413
On Mon, Aug 14, 2017 at 10:15:49PM +0200, Jiri Olsa wrote:
> On Fri, Aug 11, 2017 at 04:26:16PM -0700, Andi Kleen wrote:
> > From: Andi Kleen <ak@linux.intel.com>
> > 
> > Save the original array dimensions in xyarrays, so that users can retrieve them
> > later. Add some inline functions to access these fields.
> 
> hi,
> is there a branch with this?

Yes 

   git://git.kernel.org/pub/scm/linux/kernel/git/ak/linux-misc.git perf/metric-group-5

You didn't see the 0/0 message?

> 
> also I recall sending feedback for some of those patches,
> any changes..?

I fixed all feedback. See the individual patches.

-Andi

[toc] | [prev] | [next] | [standalone]


#1711472

FromJiri Olsa <jolsa@redhat.com>
Date2017-08-14 23:20 +0200
Message-ID<ueuWe-Mv-25@gated-at.bofh.it>
In reply to#1711426
On Mon, Aug 14, 2017 at 01:39:28PM -0700, Andi Kleen wrote:
> On Mon, Aug 14, 2017 at 10:15:49PM +0200, Jiri Olsa wrote:
> > On Fri, Aug 11, 2017 at 04:26:16PM -0700, Andi Kleen wrote:
> > > From: Andi Kleen <ak@linux.intel.com>
> > > 
> > > Save the original array dimensions in xyarrays, so that users can retrieve them
> > > later. Add some inline functions to access these fields.
> > 
> > hi,
> > is there a branch with this?
> 
> Yes 
> 
>    git://git.kernel.org/pub/scm/linux/kernel/git/ak/linux-misc.git perf/metric-group-5
> 
> You didn't see the 0/0 message?

nope, it seems like 1/19 was the In-reply-to message

6102 r   Aug 11 Andi Kleen      (1.4K) [PATCH v2 01/19] perf, tools: Save max_x, max_y in xyarray
6103 O   Aug 11 Andi Kleen      (0.6K) ├─>[PATCH v2 06/19] perf, tools: Add missing newline to expr parser error messages

> 
> > 
> > also I recall sending feedback for some of those patches,
> > any changes..?
> 
> I fixed all feedback. See the individual patches.

ok

jirka

[toc] | [prev] | [next] | [standalone]


#1717178

FromJiri Olsa <jolsa@redhat.com>
Date2017-08-22 10:30 +0200
Message-ID<uhcJs-8b9-3@gated-at.bofh.it>
In reply to#1710103
On Fri, Aug 11, 2017 at 04:26:16PM -0700, Andi Kleen wrote:
> From: Andi Kleen <ak@linux.intel.com>
> 
> Save the original array dimensions in xyarrays, so that users can retrieve them
> later. Add some inline functions to access these fields.
> 
> Signed-off-by: Andi Kleen <ak@linux.intel.com>
> ---
>  tools/perf/util/xyarray.c |  2 ++
>  tools/perf/util/xyarray.h | 12 ++++++++++++
>  2 files changed, 14 insertions(+)
> 
> diff --git a/tools/perf/util/xyarray.c b/tools/perf/util/xyarray.c
> index 7251fdbabced..c8f415d9877b 100644
> --- a/tools/perf/util/xyarray.c
> +++ b/tools/perf/util/xyarray.c
> @@ -12,6 +12,8 @@ struct xyarray *xyarray__new(int xlen, int ylen, size_t entry_size)
>  		xy->entry_size = entry_size;
>  		xy->row_size   = row_size;
>  		xy->entries    = xlen * ylen;
> +		xy->max_x      = xlen;
> +		xy->max_y      = ylen;
>  	}
>  
>  	return xy;
> diff --git a/tools/perf/util/xyarray.h b/tools/perf/util/xyarray.h
> index 7f30af371b7e..785884158137 100644
> --- a/tools/perf/util/xyarray.h
> +++ b/tools/perf/util/xyarray.h
> @@ -7,6 +7,8 @@ struct xyarray {
>  	size_t row_size;
>  	size_t entry_size;
>  	size_t entries;
> +	size_t max_x;
> +	size_t max_y;
>  	char contents[];
>  };
>  
> @@ -19,4 +21,14 @@ static inline void *xyarray__entry(struct xyarray *xy, int x, int y)
>  	return &xy->contents[x * xy->row_size + y * xy->entry_size];
>  }
>  
> +static inline int xy_max_y(struct xyarray *xy)
> +{
> +	return xy->max_x;
> +}
> +
> +static inline int xy_max_x(struct xyarray *xy)
> +{
> +	return xy->max_y;
> +}

I think you should follow the standard naming
and use xyarray__max_x and xyarray__max_y

jirka

[toc] | [prev] | [next] | [standalone]


#1717468

FromArnaldo Carvalho de Melo <acme@kernel.org>
Date2017-08-22 16:50 +0200
Message-ID<uhiFb-3Hr-1@gated-at.bofh.it>
In reply to#1717178
Em Tue, Aug 22, 2017 at 10:20:28AM +0200, Jiri Olsa escreveu:
> On Fri, Aug 11, 2017 at 04:26:16PM -0700, Andi Kleen wrote:
> > From: Andi Kleen <ak@linux.intel.com>
> > +static inline int xy_max_y(struct xyarray *xy)
> > +{
> > +	return xy->max_x;
> > +}
> > +
> > +static inline int xy_max_x(struct xyarray *xy)
> > +{
> > +	return xy->max_y;
> > +}
> 
> I think you should follow the standard naming
> and use xyarray__max_x and xyarray__max_y

Yeah, will take just a bit longer to process, I'll fix that up...

- Arnaldo

[toc] | [prev] | [next] | [standalone]


#1717470

FromJiri Olsa <jolsa@redhat.com>
Date2017-08-22 16:50 +0200
Message-ID<uhiFb-3Hr-9@gated-at.bofh.it>
In reply to#1717468
On Tue, Aug 22, 2017 at 11:40:50AM -0300, Arnaldo Carvalho de Melo wrote:
> Em Tue, Aug 22, 2017 at 10:20:28AM +0200, Jiri Olsa escreveu:
> > On Fri, Aug 11, 2017 at 04:26:16PM -0700, Andi Kleen wrote:
> > > From: Andi Kleen <ak@linux.intel.com>
> > > +static inline int xy_max_y(struct xyarray *xy)
> > > +{
> > > +	return xy->max_x;
> > > +}
> > > +
> > > +static inline int xy_max_x(struct xyarray *xy)
> > > +{
> > > +	return xy->max_y;
> > > +}
> > 
> > I think you should follow the standard naming
> > and use xyarray__max_x and xyarray__max_y
> 
> Yeah, will take just a bit longer to process, I'll fix that up...

fyi it's used in following patch

jirka

[toc] | [prev] | [next] | [standalone]


#1717484

FromArnaldo Carvalho de Melo <acme@kernel.org>
Date2017-08-22 17:10 +0200
Message-ID<uhiYz-45R-29@gated-at.bofh.it>
In reply to#1717470
Em Tue, Aug 22, 2017 at 04:44:16PM +0200, Jiri Olsa escreveu:
> On Tue, Aug 22, 2017 at 11:40:50AM -0300, Arnaldo Carvalho de Melo wrote:
> > Em Tue, Aug 22, 2017 at 10:20:28AM +0200, Jiri Olsa escreveu:
> > > On Fri, Aug 11, 2017 at 04:26:16PM -0700, Andi Kleen wrote:
> > > > From: Andi Kleen <ak@linux.intel.com>
> > > > +static inline int xy_max_y(struct xyarray *xy)
> > > > +{
> > > > +	return xy->max_x;
> > > > +}
> > > > +
> > > > +static inline int xy_max_x(struct xyarray *xy)
> > > > +{
> > > > +	return xy->max_y;
> > > > +}
> > > 
> > > I think you should follow the standard naming
> > > and use xyarray__max_x and xyarray__max_y
> > 
> > Yeah, will take just a bit longer to process, I'll fix that up...
> 
> fyi it's used in following patch

Yeah, sure, I expected it to be :-P And fixed it up accordingly :-)

- Arnaldo

[toc] | [prev] | [next] | [standalone]


#1718977 — [tip:perf/core] perf xyarray: Save max_x, max_y

Fromtip-bot for Andi Kleen <tipbot@zytor.com>
Date2017-08-24 10:30 +0200
Subject[tip:perf/core] perf xyarray: Save max_x, max_y
Message-ID<uhVGA-405-53@gated-at.bofh.it>
In reply to#1710103
Commit-ID:  d74be47673676eded2f0bb8274e752bed32c42d8
Gitweb:     http://git.kernel.org/tip/d74be47673676eded2f0bb8274e752bed32c42d8
Author:     Andi Kleen <ak@linux.intel.com>
AuthorDate: Fri, 11 Aug 2017 16:26:16 -0700
Committer:  Arnaldo Carvalho de Melo <acme@redhat.com>
CommitDate: Tue, 22 Aug 2017 11:51:28 -0300

perf xyarray: Save max_x, max_y

Save the original array dimensions in xyarrays, so that users can
retrieve them later. Add some inline functions to access these fields.

Signed-off-by: Andi Kleen <ak@linux.intel.com>
Acked-by: Jiri Olsa <jolsa@kernel.org>
Link: http://lkml.kernel.org/r/20170811232634.30465-1-andi@firstfloor.org
[ As noticed by Jiri, fix up namespacing: xy__method() -> xyarray__method() ]
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
---
 tools/perf/util/xyarray.c |  2 ++
 tools/perf/util/xyarray.h | 12 ++++++++++++
 2 files changed, 14 insertions(+)

diff --git a/tools/perf/util/xyarray.c b/tools/perf/util/xyarray.c
index 7251fdb..c8f415d 100644
--- a/tools/perf/util/xyarray.c
+++ b/tools/perf/util/xyarray.c
@@ -12,6 +12,8 @@ struct xyarray *xyarray__new(int xlen, int ylen, size_t entry_size)
 		xy->entry_size = entry_size;
 		xy->row_size   = row_size;
 		xy->entries    = xlen * ylen;
+		xy->max_x      = xlen;
+		xy->max_y      = ylen;
 	}
 
 	return xy;
diff --git a/tools/perf/util/xyarray.h b/tools/perf/util/xyarray.h
index 7f30af3..4ba726c 100644
--- a/tools/perf/util/xyarray.h
+++ b/tools/perf/util/xyarray.h
@@ -7,6 +7,8 @@ struct xyarray {
 	size_t row_size;
 	size_t entry_size;
 	size_t entries;
+	size_t max_x;
+	size_t max_y;
 	char contents[];
 };
 
@@ -19,4 +21,14 @@ static inline void *xyarray__entry(struct xyarray *xy, int x, int y)
 	return &xy->contents[x * xy->row_size + y * xy->entry_size];
 }
 
+static inline int xyarray__max_y(struct xyarray *xy)
+{
+	return xy->max_x;
+}
+
+static inline int xyarray__max_x(struct xyarray *xy)
+{
+	return xy->max_y;
+}
+
 #endif /* _PERF_XYARRAY_H_ */

[toc] | [prev] | [standalone]


Back to top | Article view | linux.kernel


csiph-web