All of lore.kernel.org
 help / color / mirror / Atom feed
From: David Ahern <dsahern@gmail.com>
To: Jiri Olsa <jolsa@redhat.com>
Cc: acme@ghostprotocols.net, linux-kernel@vger.kernel.org,
	mingo@kernel.org, Frederic Weisbecker <fweisbec@gmail.com>,
	Peter Zijlstra <peterz@infradead.org>,
	Namhyung Kim <namhyung@kernel.org>,
	Mike Galbraith <efault@gmx.de>,
	Stephane Eranian <eranian@google.com>
Subject: Re: [PATCH 2/2] perf record: mmap output file - v4
Date: Fri, 08 Nov 2013 09:52:17 -0700	[thread overview]
Message-ID: <527D16C1.3070206@gmail.com> (raw)
In-Reply-To: <20131108093455.GA1230@krava.brq.redhat.com>

[-- Attachment #1: Type: text/plain, Size: 1131 bytes --]

On 11/8/13, 2:34 AM, Jiri Olsa wrote:
>> +	if (ftruncate(fd, len) != 0)
>> +		pr_err("ftruncate failed\n");
>
> I think we should fail here and dont let the finishing
> code run on probably corrupted file.
>
> the code that process build IDs could even get stuck

Yes, I'll fix that in v5.

It also got me to thinking about failure scenarios -- like out of space. 
I was looking at this path using a size-limited tmpfs (max 1M) and 
writing perf.data into it.

Today (without this mmap output page) if the write() fails due to lack 
of space then perf emits the message:
   failed to write perf data, error: No space left on device

and stops — killing the workload too. Trying to read and process the 
perf.data file fails with a SIGBUS error.  I just sent a patch this 
addresses that problem.

Using that patch as a start point and moving to mmap-based output if the 
filesystem runs out of space the memcpy generates a SIGBUS and we need 
to jump out of the memcpy. The attached fixes that problem.

Any objections to using a sigjmp? Other option is to die in the signal 
handler.  That option is harder to clean up.

David




[-- Attachment #2: perf-record-handle-mmap-write-failure.patch --]
[-- Type: text/plain, Size: 2021 bytes --]

diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c
index 947970e182a5..b50f384d9a36 100644
--- a/tools/perf/builtin-record.c
+++ b/tools/perf/builtin-record.c
@@ -29,9 +29,11 @@
 #include <unistd.h>
 #include <sched.h>
 #include <sys/mman.h>
+#include <setjmp.h>
 
 /* output file mmap'ed N chunks at a time */
 #define MMAP_OUTPUT_SIZE   (64*1024*1024)
+sigjmp_buf mmap_jmp;
 
 #ifndef HAVE_ON_EXIT_SUPPORT
 #ifndef ATEXIT_MAX
@@ -141,6 +143,7 @@ static int do_mmap_output(struct perf_record *rec, void *buf, size_t size)
 {
 	u64 remaining;
 	off_t offset;
+	volatile size_t total_len = 0;
 
 	if (rec->mmap.addr == NULL) {
 next_segment:
@@ -157,20 +160,23 @@ next_segment:
 	 * space write what we can then go back and create the
 	 * next segment
 	 */
-	if (size > remaining) {
-		memcpy(rec->mmap.addr + rec->mmap.offset, buf, remaining);
+	if (setjmp(mmap_jmp) != 0) {
+		pr_err("mmap copy failed.\n");
+		return -1;
+	}
+	if (size-total_len > remaining) {
+		memcpy(rec->mmap.addr + rec->mmap.offset, buf+total_len, remaining);
 		rec->bytes_written += remaining;
 
-		size -= remaining;
-		buf  += remaining;
+		total_len += remaining;
 
 		munmap(rec->mmap.addr, rec->mmap.out_size);
 		goto next_segment;
 	}
 
 	/* more data to copy and it fits in the current segment */
-	if (size) {
-		memcpy(rec->mmap.addr + rec->mmap.offset, buf, size);
+	if (size - total_len) {
+		memcpy(rec->mmap.addr + rec->mmap.offset, buf+total_len, size-total_len);
 		rec->bytes_written += size;
 		rec->mmap.offset += size;
 	}
@@ -272,6 +278,9 @@ static void sig_handler(int sig)
 	if (sig == SIGCHLD)
 		child_finished = 1;
 
+	if (sig == SIGBUS)
+		longjmp(mmap_jmp, 1);
+
 	done = 1;
 	signr = sig;
 }
@@ -526,6 +535,7 @@ static int __cmd_record(struct perf_record *rec, int argc, const char **argv)
 	signal(SIGINT, sig_handler);
 	signal(SIGUSR1, sig_handler);
 	signal(SIGTERM, sig_handler);
+	signal(SIGBUS, sig_handler);
 
 	session = perf_session__new(file, false, NULL);
 	if (session == NULL) {

  reply	other threads:[~2013-11-08 16:52 UTC|newest]

Thread overview: 11+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2013-11-08  4:23 [PATCH 0/2] perf: mmap output file - v4 David Ahern
2013-11-08  4:23 ` [PATCH 1/2] perf record: Move existing write_output into helper function David Ahern
2013-11-12 21:55   ` [tip:perf/urgent] " tip-bot for David Ahern
2013-11-08  4:23 ` [PATCH 2/2] perf record: mmap output file - v4 David Ahern
2013-11-08  9:34   ` Jiri Olsa
2013-11-08 16:52     ` David Ahern [this message]
2013-11-11 11:29   ` Ingo Molnar
2013-11-11 14:58     ` Arnaldo Carvalho de Melo
2013-11-11 15:17       ` David Ahern
2013-11-11 20:41         ` Ingo Molnar
2013-11-11 20:44           ` David Ahern

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=527D16C1.3070206@gmail.com \
    --to=dsahern@gmail.com \
    --cc=acme@ghostprotocols.net \
    --cc=efault@gmx.de \
    --cc=eranian@google.com \
    --cc=fweisbec@gmail.com \
    --cc=jolsa@redhat.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=mingo@kernel.org \
    --cc=namhyung@kernel.org \
    --cc=peterz@infradead.org \
    /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.