linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Arnaldo Carvalho de Melo <acme@kernel.org>
To: Ingo Molnar <mingo@kernel.org>, Thomas Gleixner <tglx@linutronix.de>
Cc: Jiri Olsa <jolsa@kernel.org>, Namhyung Kim <namhyung@kernel.org>,
	Clark Williams <williams@redhat.com>,
	linux-kernel@vger.kernel.org, linux-perf-users@vger.kernel.org,
	Alexey Budankov <alexey.budankov@linux.intel.com>,
	Alexander Shishkin <alexander.shishkin@linux.intel.com>,
	Andi Kleen <ak@linux.intel.com>,
	Peter Zijlstra <peterz@infradead.org>,
	Arnaldo Carvalho de Melo <acme@redhat.com>
Subject: [PATCH 53/73] perf record: Implement compression for AIO trace streaming
Date: Fri, 17 May 2019 16:35:51 -0300	[thread overview]
Message-ID: <20190517193611.4974-54-acme@kernel.org> (raw)
In-Reply-To: <20190517193611.4974-1-acme@kernel.org>

From: Alexey Budankov <alexey.budankov@linux.intel.com>

Compression is implemented using the functions from zstd.c. As the memory
to operate on the compression uses mmap->aio.data[] buffers. If Zstd
streaming compression API fails for some reason the data to be compressed
are just copied into the memory buffers using plain memcpy().

Compressed trace frame consists of an array of PERF_RECORD_COMPRESSED
records. Each element of the array is not longer that PERF_SAMPLE_MAX_SIZE
and consists of perf_event_header followed by the compressed chunk
that is decompressed on the loading stage.

perf_mmap__aio_push() is replaced by perf_mmap__push() which is now used
in the both serial and AIO streaming cases. perf_mmap__push() is extended
with positive return values to signify absence of data ready for
processing.

Signed-off-by: Alexey Budankov <alexey.budankov@linux.intel.com>
Reviewed-by: Jiri Olsa <jolsa@kernel.org>
Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
Cc: Andi Kleen <ak@linux.intel.com>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Link: http://lkml.kernel.org/r/77db2b2c-5d03-dbb0-aeac-c4dd92129ab9@linux.intel.com
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
---
 tools/perf/builtin-record.c | 114 ++++++++++++++++++++++++++++--------
 tools/perf/util/mmap.c      |  76 +-----------------------
 tools/perf/util/mmap.h      |  12 ----
 3 files changed, 89 insertions(+), 113 deletions(-)

diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c
index de9632c69852..a0bd9104fae6 100644
--- a/tools/perf/builtin-record.c
+++ b/tools/perf/builtin-record.c
@@ -133,6 +133,8 @@ static int record__write(struct record *rec, struct perf_mmap *map __maybe_unuse
 	return 0;
 }
 
+static int record__aio_enabled(struct record *rec);
+static int record__comp_enabled(struct record *rec);
 static size_t zstd_compress(struct perf_session *session, void *dst, size_t dst_size,
 			    void *src, size_t src_size);
 
@@ -186,9 +188,9 @@ static int record__aio_complete(struct perf_mmap *md, struct aiocb *cblock)
 	if (rem_size == 0) {
 		cblock->aio_fildes = -1;
 		/*
-		 * md->refcount is incremented in perf_mmap__push() for
-		 * every enqueued aio write request so decrement it because
-		 * the request is now complete.
+		 * md->refcount is incremented in record__aio_pushfn() for
+		 * every aio write request started in record__aio_push() so
+		 * decrement it because the request is now complete.
 		 */
 		perf_mmap__put(md);
 		rc = 1;
@@ -243,18 +245,89 @@ static int record__aio_sync(struct perf_mmap *md, bool sync_all)
 	} while (1);
 }
 
-static int record__aio_pushfn(void *to, struct aiocb *cblock, void *bf, size_t size, off_t off)
+struct record_aio {
+	struct record	*rec;
+	void		*data;
+	size_t		size;
+};
+
+static int record__aio_pushfn(struct perf_mmap *map, void *to, void *buf, size_t size)
 {
-	struct record *rec = to;
-	int ret, trace_fd = rec->session->data->file.fd;
+	struct record_aio *aio = to;
 
-	rec->samples++;
+	/*
+	 * map->base data pointed by buf is copied into free map->aio.data[] buffer
+	 * to release space in the kernel buffer as fast as possible, calling
+	 * perf_mmap__consume() from perf_mmap__push() function.
+	 *
+	 * That lets the kernel to proceed with storing more profiling data into
+	 * the kernel buffer earlier than other per-cpu kernel buffers are handled.
+	 *
+	 * Coping can be done in two steps in case the chunk of profiling data
+	 * crosses the upper bound of the kernel buffer. In this case we first move
+	 * part of data from map->start till the upper bound and then the reminder
+	 * from the beginning of the kernel buffer till the end of the data chunk.
+	 */
 
-	ret = record__aio_write(cblock, trace_fd, bf, size, off);
+	if (record__comp_enabled(aio->rec)) {
+		size = zstd_compress(aio->rec->session, aio->data + aio->size,
+				     perf_mmap__mmap_len(map) - aio->size,
+				     buf, size);
+	} else {
+		memcpy(aio->data + aio->size, buf, size);
+	}
+
+	if (!aio->size) {
+		/*
+		 * Increment map->refcount to guard map->aio.data[] buffer
+		 * from premature deallocation because map object can be
+		 * released earlier than aio write request started on
+		 * map->aio.data[] buffer is complete.
+		 *
+		 * perf_mmap__put() is done at record__aio_complete()
+		 * after started aio request completion or at record__aio_push()
+		 * if the request failed to start.
+		 */
+		perf_mmap__get(map);
+	}
+
+	aio->size += size;
+
+	return size;
+}
+
+static int record__aio_push(struct record *rec, struct perf_mmap *map, off_t *off)
+{
+	int ret, idx;
+	int trace_fd = rec->session->data->file.fd;
+	struct record_aio aio = { .rec = rec, .size = 0 };
+
+	/*
+	 * Call record__aio_sync() to wait till map->aio.data[] buffer
+	 * becomes available after previous aio write operation.
+	 */
+
+	idx = record__aio_sync(map, false);
+	aio.data = map->aio.data[idx];
+	ret = perf_mmap__push(map, &aio, record__aio_pushfn);
+	if (ret != 0) /* ret > 0 - no data, ret < 0 - error */
+		return ret;
+
+	rec->samples++;
+	ret = record__aio_write(&(map->aio.cblocks[idx]), trace_fd, aio.data, aio.size, *off);
 	if (!ret) {
-		rec->bytes_written += size;
+		*off += aio.size;
+		rec->bytes_written += aio.size;
 		if (switch_output_size(rec))
 			trigger_hit(&switch_output_trigger);
+	} else {
+		/*
+		 * Decrement map->refcount incremented in record__aio_pushfn()
+		 * back if record__aio_write() operation failed to start, otherwise
+		 * map->refcount is decremented in record__aio_complete() after
+		 * aio write operation finishes successfully.
+		 */
+		perf_mmap__put(map);
 	}
 
 	return ret;
@@ -276,7 +349,7 @@ static void record__aio_mmap_read_sync(struct record *rec)
 	struct perf_evlist *evlist = rec->evlist;
 	struct perf_mmap *maps = evlist->mmap;
 
-	if (!rec->opts.nr_cblocks)
+	if (!record__aio_enabled(rec))
 		return;
 
 	for (i = 0; i < evlist->nr_mmaps; i++) {
@@ -310,13 +383,8 @@ static int record__aio_parse(const struct option *opt,
 #else /* HAVE_AIO_SUPPORT */
 static int nr_cblocks_max = 0;
 
-static int record__aio_sync(struct perf_mmap *md __maybe_unused, bool sync_all __maybe_unused)
-{
-	return -1;
-}
-
-static int record__aio_pushfn(void *to __maybe_unused, struct aiocb *cblock __maybe_unused,
-		void *bf __maybe_unused, size_t size __maybe_unused, off_t off __maybe_unused)
+static int record__aio_push(struct record *rec __maybe_unused, struct perf_mmap *map __maybe_unused,
+			    off_t *off __maybe_unused)
 {
 	return -1;
 }
@@ -825,7 +893,7 @@ static int record__mmap_read_evlist(struct record *rec, struct perf_evlist *evli
 	int rc = 0;
 	struct perf_mmap *maps;
 	int trace_fd = rec->data.file.fd;
-	off_t off;
+	off_t off = 0;
 
 	if (!evlist)
 		return 0;
@@ -851,20 +919,14 @@ static int record__mmap_read_evlist(struct record *rec, struct perf_evlist *evli
 				map->flush = 1;
 			}
 			if (!record__aio_enabled(rec)) {
-				if (perf_mmap__push(map, rec, record__pushfn) != 0) {
+				if (perf_mmap__push(map, rec, record__pushfn) < 0) {
 					if (synch)
 						map->flush = flush;
 					rc = -1;
 					goto out;
 				}
 			} else {
-				int idx;
-				/*
-				 * Call record__aio_sync() to wait till map->data buffer
-				 * becomes available after previous aio write request.
-				 */
-				idx = record__aio_sync(map, false);
-				if (perf_mmap__aio_push(map, rec, idx, record__aio_pushfn, &off) != 0) {
+				if (record__aio_push(rec, map, &off) < 0) {
 					record__aio_set_pos(trace_fd, off);
 					if (synch)
 						map->flush = flush;
diff --git a/tools/perf/util/mmap.c b/tools/perf/util/mmap.c
index d85e73fc82e2..868c0b0e909c 100644
--- a/tools/perf/util/mmap.c
+++ b/tools/perf/util/mmap.c
@@ -289,80 +289,6 @@ static void perf_mmap__aio_munmap(struct perf_mmap *map)
 	zfree(&map->aio.cblocks);
 	zfree(&map->aio.aiocb);
 }
-
-int perf_mmap__aio_push(struct perf_mmap *md, void *to, int idx,
-			int push(void *to, struct aiocb *cblock, void *buf, size_t size, off_t off),
-			off_t *off)
-{
-	u64 head = perf_mmap__read_head(md);
-	unsigned char *data = md->base + page_size;
-	unsigned long size, size0 = 0;
-	void *buf;
-	int rc = 0;
-
-	rc = perf_mmap__read_init(md);
-	if (rc < 0)
-		return (rc == -EAGAIN) ? 0 : -1;
-
-	/*
-	 * md->base data is copied into md->data[idx] buffer to
-	 * release space in the kernel buffer as fast as possible,
-	 * thru perf_mmap__consume() below.
-	 *
-	 * That lets the kernel to proceed with storing more
-	 * profiling data into the kernel buffer earlier than other
-	 * per-cpu kernel buffers are handled.
-	 *
-	 * Coping can be done in two steps in case the chunk of
-	 * profiling data crosses the upper bound of the kernel buffer.
-	 * In this case we first move part of data from md->start
-	 * till the upper bound and then the reminder from the
-	 * beginning of the kernel buffer till the end of
-	 * the data chunk.
-	 */
-
-	size = md->end - md->start;
-
-	if ((md->start & md->mask) + size != (md->end & md->mask)) {
-		buf = &data[md->start & md->mask];
-		size = md->mask + 1 - (md->start & md->mask);
-		md->start += size;
-		memcpy(md->aio.data[idx], buf, size);
-		size0 = size;
-	}
-
-	buf = &data[md->start & md->mask];
-	size = md->end - md->start;
-	md->start += size;
-	memcpy(md->aio.data[idx] + size0, buf, size);
-
-	/*
-	 * Increment md->refcount to guard md->data[idx] buffer
-	 * from premature deallocation because md object can be
-	 * released earlier than aio write request started
-	 * on mmap->data[idx] is complete.
-	 *
-	 * perf_mmap__put() is done at record__aio_complete()
-	 * after started request completion.
-	 */
-	perf_mmap__get(md);
-
-	md->prev = head;
-	perf_mmap__consume(md);
-
-	rc = push(to, &md->aio.cblocks[idx], md->aio.data[idx], size0 + size, *off);
-	if (!rc) {
-		*off += size0 + size;
-	} else {
-		/*
-		 * Decrement md->refcount back if aio write
-		 * operation failed to start.
-		 */
-		perf_mmap__put(md);
-	}
-
-	return rc;
-}
 #else /* !HAVE_AIO_SUPPORT */
 static int perf_mmap__aio_enabled(struct perf_mmap *map __maybe_unused)
 {
@@ -566,7 +492,7 @@ int perf_mmap__push(struct perf_mmap *md, void *to,
 
 	rc = perf_mmap__read_init(md);
 	if (rc < 0)
-		return (rc == -EAGAIN) ? 0 : -1;
+		return (rc == -EAGAIN) ? 1 : -1;
 
 	size = md->end - md->start;
 
diff --git a/tools/perf/util/mmap.h b/tools/perf/util/mmap.h
index 4e2f58d95c1f..274ce389cd84 100644
--- a/tools/perf/util/mmap.h
+++ b/tools/perf/util/mmap.h
@@ -101,18 +101,6 @@ union perf_event *perf_mmap__read_event(struct perf_mmap *map);
 
 int perf_mmap__push(struct perf_mmap *md, void *to,
 		    int push(struct perf_mmap *map, void *to, void *buf, size_t size));
-#ifdef HAVE_AIO_SUPPORT
-int perf_mmap__aio_push(struct perf_mmap *md, void *to, int idx,
-			int push(void *to, struct aiocb *cblock, void *buf, size_t size, off_t off),
-			off_t *off);
-#else
-static inline int perf_mmap__aio_push(struct perf_mmap *md __maybe_unused, void *to __maybe_unused, int idx __maybe_unused,
-	int push(void *to, struct aiocb *cblock, void *buf, size_t size, off_t off) __maybe_unused,
-	off_t *off __maybe_unused)
-{
-	return 0;
-}
-#endif
 
 size_t perf_mmap__mmap_len(struct perf_mmap *map);
 
-- 
2.20.1


  parent reply	other threads:[~2019-05-17 19:40 UTC|newest]

Thread overview: 80+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-05-17 19:34 [GIT PULL] perf/core improvements and fixes Arnaldo Carvalho de Melo
2019-05-17 19:34 ` [PATCH 01/73] perf annotate: Remove hist__account_cycles() from callback Arnaldo Carvalho de Melo
2019-05-17 19:35 ` [PATCH 02/73] perf test: Fix spelling mistake "leadking" -> "leaking" Arnaldo Carvalho de Melo
2019-05-17 19:35 ` [PATCH 03/73] csky: Add support for libdw Arnaldo Carvalho de Melo
2019-05-17 19:35 ` [PATCH 04/73] tools lib traceevent: Remove hard coded install paths from pkg-config file Arnaldo Carvalho de Melo
2019-05-17 19:35 ` [PATCH 05/73] perf tools: Speed up report for perf compiled with linwunwind Arnaldo Carvalho de Melo
2019-05-17 19:35 ` [PATCH 06/73] tools arch: Update arch/x86/lib/memcpy_64.S copy used in 'perf bench mem memcpy' Arnaldo Carvalho de Melo
2019-05-17 19:35 ` [PATCH 07/73] tools arch uapi: Sync the x86 kvm.h copy Arnaldo Carvalho de Melo
2019-05-17 19:35 ` [PATCH 08/73] tools x86 uapi asm: Sync the pt_regs.h copy with the kernel sources Arnaldo Carvalho de Melo
2019-05-17 19:35 ` [PATCH 09/73] tools pci: Do not delete pcitest.sh in 'make clean' Arnaldo Carvalho de Melo
2019-05-17 19:35 ` [PATCH 10/73] perf record: Fix suggestion to get list of registers usable with --user-regs and --intr-regs Arnaldo Carvalho de Melo
2019-05-17 19:35 ` [PATCH 11/73] perf parse-regs: Improve error output when faced with unknown register name Arnaldo Carvalho de Melo
2019-05-17 19:35 ` [PATCH 12/73] perf tools x86: Add support for recording and printing XMM registers Arnaldo Carvalho de Melo
2019-05-17 19:35 ` [PATCH 13/73] perf scripts python: exported-sql-viewer.py: Move view creation Arnaldo Carvalho de Melo
2019-05-17 19:35 ` [PATCH 14/73] perf scripts python: exported-sql-viewer.py: Fix error when shrinking / enlarging font Arnaldo Carvalho de Melo
2019-05-17 19:35 ` [PATCH 15/73] perf scripts python: exported-sql-viewer.py: Add tree level Arnaldo Carvalho de Melo
2019-05-17 19:35 ` [PATCH 16/73] perf scripts python: exported-sql-viewer.py: Add copy to clipboard Arnaldo Carvalho de Melo
2019-05-17 19:35 ` [PATCH 17/73] perf scripts python: exported-sql-viewer.py: Add context menu Arnaldo Carvalho de Melo
2019-05-17 19:35 ` [PATCH 18/73] perf scripts python: exported-sql-viewer.py: Add 'About' dialog box Arnaldo Carvalho de Melo
2019-05-17 19:35 ` [PATCH 19/73] perf vendor events intel: Add uncore_upi JSON support Arnaldo Carvalho de Melo
2019-05-17 19:35 ` [PATCH 20/73] perf machine: Null-terminate version char array upon fgets(/proc/version) error Arnaldo Carvalho de Melo
2019-05-18  0:05   ` Donald Yandt
2019-05-20 14:46     ` Arnaldo Carvalho de Melo
2019-05-17 19:35 ` [PATCH 21/73] tools lib traceevent: Introduce man pages Arnaldo Carvalho de Melo
2019-05-17 19:35 ` [PATCH 22/73] tools lib traceevent: Add support for man pages with multiple names Arnaldo Carvalho de Melo
2019-05-17 19:35 ` [PATCH 23/73] tools lib traceevent: Man pages for tep_handler related APIs Arnaldo Carvalho de Melo
2019-05-17 19:35 ` [PATCH 24/73] tools lib traceevent: Man page for header_page APIs Arnaldo Carvalho de Melo
2019-05-17 19:35 ` [PATCH 25/73] tools lib traceevent: Man page for get/set cpus APIs Arnaldo Carvalho de Melo
2019-05-17 19:35 ` [PATCH 26/73] tools lib traceevent: Man page for file endian APIs Arnaldo Carvalho de Melo
2019-05-17 19:35 ` [PATCH 27/73] tools lib traceevent: Man page for host " Arnaldo Carvalho de Melo
2019-05-17 19:35 ` [PATCH 28/73] tools lib traceevent: Man page for page size APIs Arnaldo Carvalho de Melo
2019-05-17 19:35 ` [PATCH 29/73] tools lib traceevent: Man page for tep_strerror() Arnaldo Carvalho de Melo
2019-05-17 19:35 ` [PATCH 30/73] tools lib traceevent: Man pages for event handler APIs Arnaldo Carvalho de Melo
2019-05-17 19:35 ` [PATCH 31/73] tools lib traceevent: Man pages for function related libtraceevent APIs Arnaldo Carvalho de Melo
2019-05-17 19:35 ` [PATCH 32/73] tools lib traceevent: Man pages for registering print function Arnaldo Carvalho de Melo
2019-05-17 19:35 ` [PATCH 33/73] tools lib traceevent: Man page for tep_read_number() Arnaldo Carvalho de Melo
2019-05-17 19:35 ` [PATCH 34/73] tools lib traceevent: Man pages for event find APIs Arnaldo Carvalho de Melo
2019-05-17 19:35 ` [PATCH 35/73] tools lib traceevent: Man page for list events APIs Arnaldo Carvalho de Melo
2019-05-17 19:35 ` [PATCH 36/73] tools lib traceevent: Man pages for libtraceevent event get APIs Arnaldo Carvalho de Melo
2019-05-17 19:35 ` [PATCH 37/73] tools lib traceevent: Man pages for find field APIs Arnaldo Carvalho de Melo
2019-05-17 19:35 ` [PATCH 38/73] tools lib traceevent: Man pages for get field value APIs Arnaldo Carvalho de Melo
2019-05-17 19:35 ` [PATCH 39/73] tools lib traceevent: Man pages for print field APIs Arnaldo Carvalho de Melo
2019-05-17 19:35 ` [PATCH 40/73] tools lib traceevent: Man page for tep_read_number_field() Arnaldo Carvalho de Melo
2019-05-17 19:35 ` [PATCH 41/73] tools lib traceevent: Man pages for event fields APIs Arnaldo Carvalho de Melo
2019-05-17 19:35 ` [PATCH 42/73] tools lib traceevent: Man pages for event filter APIs Arnaldo Carvalho de Melo
2019-05-17 19:35 ` [PATCH 43/73] tools lib traceevent: Man pages for parse event APIs Arnaldo Carvalho de Melo
2019-05-17 19:35 ` [PATCH 44/73] tools lib traceevent: Man page for tep_parse_header_page() Arnaldo Carvalho de Melo
2019-05-17 19:35 ` [PATCH 45/73] tools lib traceevent: Man pages for APIs used to extract common fields from a record Arnaldo Carvalho de Melo
2019-05-17 19:35 ` [PATCH 46/73] tools lib traceevent: Man pages for trace sequences APIs Arnaldo Carvalho de Melo
2019-05-17 19:35 ` [PATCH 47/73] perf build tests: Add NO_LIBZSTD=1 to make_minimal Arnaldo Carvalho de Melo
2019-05-17 19:35 ` [PATCH 48/73] perf session: Define 'bytes_transferred' and 'bytes_compressed' metrics Arnaldo Carvalho de Melo
2019-05-17 19:35 ` [PATCH 49/73] perf record: Implement COMPRESSED event record and its attributes Arnaldo Carvalho de Melo
2019-05-17 19:35 ` [PATCH 50/73] perf mmap: Implement dedicated memory buffer for data compression Arnaldo Carvalho de Melo
2019-05-17 19:35 ` [PATCH 51/73] perf tools: Introduce Zstd streaming based compression API Arnaldo Carvalho de Melo
2019-05-17 19:35 ` [PATCH 52/73] perf record: Implement compression for serial trace streaming Arnaldo Carvalho de Melo
2019-05-17 19:35 ` Arnaldo Carvalho de Melo [this message]
2019-05-17 19:35 ` [PATCH 54/73] perf report: Add stub processing of compressed events for -D Arnaldo Carvalho de Melo
2019-05-17 19:35 ` [PATCH 55/73] perf record: Implement -z,--compression_level[=<n>] option Arnaldo Carvalho de Melo
2019-05-17 19:35 ` [PATCH 56/73] perf report: Implement perf.data record decompression Arnaldo Carvalho de Melo
2019-05-17 19:35 ` [PATCH 57/73] perf inject: Enable COMPRESSED " Arnaldo Carvalho de Melo
2019-05-17 19:35 ` [PATCH 58/73] perf tests: Implement Zstd comp/decomp integration test Arnaldo Carvalho de Melo
2019-05-17 19:35 ` [PATCH 59/73] perf test zstd: Fixup verbose mode output Arnaldo Carvalho de Melo
2019-05-17 19:35 ` [PATCH 60/73] perf jevents: Remove unused variable Arnaldo Carvalho de Melo
2019-05-17 19:35 ` [PATCH 61/73] perf vendor events arm64: Remove [[:xdigit:]] wildcard Arnaldo Carvalho de Melo
2019-05-17 19:36 ` [PATCH 62/73] perf vendor events arm64: Map Brahma-B53 CPUID to cortex-a53 events Arnaldo Carvalho de Melo
2019-05-17 19:36 ` [PATCH 63/73] perf vendor events arm64: Add Cortex-A57 and Cortex-A72 events Arnaldo Carvalho de Melo
2019-05-17 19:36 ` [PATCH 64/73] perf parse-regs: Split parse_regs Arnaldo Carvalho de Melo
2019-05-17 19:36 ` [PATCH 65/73] perf parse-regs: Add generic support for arch__intr/user_reg_mask() Arnaldo Carvalho de Melo
2019-05-17 19:36 ` [PATCH 66/73] perf regs x86: Add X86 specific arch__intr_reg_mask() Arnaldo Carvalho de Melo
2019-05-17 19:36 ` [PATCH 67/73] perf intel-pt: Fix instructions sampling rate Arnaldo Carvalho de Melo
2019-05-17 19:36 ` [PATCH 68/73] perf intel-pt: Fix improved sample timestamp Arnaldo Carvalho de Melo
2019-05-17 19:36 ` [PATCH 69/73] perf intel-pt: Fix sample timestamp wrt non-taken branches Arnaldo Carvalho de Melo
2019-05-17 19:36 ` [PATCH 70/73] perf docs: Add description for stderr Arnaldo Carvalho de Melo
2019-05-17 19:36 ` [PATCH 71/73] perf tools: Add a 'percore' event qualifier Arnaldo Carvalho de Melo
2019-05-17 19:36 ` [PATCH 72/73] perf stat: Factor out aggregate counts printing Arnaldo Carvalho de Melo
2019-05-17 19:36 ` [PATCH 73/73] perf stat: Support 'percore' event qualifier Arnaldo Carvalho de Melo
2019-05-18  8:27 ` [GIT PULL] perf/core improvements and fixes Ingo Molnar
2019-05-18  8:42 ` [PATCH] tools/headers: Synchronize kernel ABI headers Ingo Molnar
2019-05-18 13:39   ` Arnaldo Carvalho de Melo
2019-05-18 17:12     ` Ingo Molnar

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=20190517193611.4974-54-acme@kernel.org \
    --to=acme@kernel.org \
    --cc=acme@redhat.com \
    --cc=ak@linux.intel.com \
    --cc=alexander.shishkin@linux.intel.com \
    --cc=alexey.budankov@linux.intel.com \
    --cc=jolsa@kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-perf-users@vger.kernel.org \
    --cc=mingo@kernel.org \
    --cc=namhyung@kernel.org \
    --cc=peterz@infradead.org \
    --cc=tglx@linutronix.de \
    --cc=williams@redhat.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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).