All of lore.kernel.org
 help / color / mirror / Atom feed
From: Ingo Molnar <mingo@kernel.org>
To: David Ahern <dsahern@gmail.com>
Cc: acme@ghostprotocols.net, linux-kernel@vger.kernel.org,
	jolsa@redhat.com, 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 5/5] perf record: Handle out of space failures writing data with mmap
Date: Tue, 12 Nov 2013 22:19:26 +0100	[thread overview]
Message-ID: <20131112211926.GD25913@gmail.com> (raw)
In-Reply-To: <1384267617-3446-6-git-send-email-dsahern@gmail.com>


* David Ahern <dsahern@gmail.com> wrote:

> If the filesystem where a file is written using mmap fills perf record
> gets a SIGBUS and terminated. Handle the SIGBUS by using longjmp to
> bounce out of the memcpy and fail the write.
> 
> Signed-off-by: David Ahern <dsahern@gmail.com>
> Cc: Ingo Molnar <mingo@kernel.org>
> Cc: Frederic Weisbecker <fweisbec@gmail.com>
> Cc: Peter Zijlstra <peterz@infradead.org>
> Cc: Jiri Olsa <jolsa@redhat.com>
> Cc: Namhyung Kim <namhyung@kernel.org>
> Cc: Mike Galbraith <efault@gmx.de>
> Cc: Stephane Eranian <eranian@google.com>
> ---
>  tools/perf/builtin-record.c | 22 ++++++++++++++++------
>  1 file changed, 16 insertions(+), 6 deletions(-)
> 
> diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c
> index 1a4fa5df215b..48d6535d144f 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);

So this isn't very robust, because it assumes that all sources of SIGBUS 
are due to that memcpy() hitting -ENOSPC...

There are several failure modes:

 - If mmap_jmp is not set yet and we get a SIGBUS is some other place, 
   then the longjmp() result will be undefined.

 - If mmap_jmp environment is set, but we've returned from 
   do_mmap_output() already, then the result will be undefined - likely a 
   non-obvious crash.

So at minimum we need a flag that tells us whether the jump environment is 
valid or not - i.e. whether we are executing inside the protected region 
or not - and only do the longjmp() if that flag is set.

Is there really no other way to handle the -ENOSPC case robustly? I guess 
not because the memcpy() really needs memory to write to, but I thought 
I'd ask ...

Thanks,

	Ingo

  reply	other threads:[~2013-11-12 21:19 UTC|newest]

Thread overview: 42+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2013-11-12 14:46 [PATCH 0/5] perf record: mmap output file - v5 David Ahern
2013-11-12 14:46 ` [PATCH 1/5] perf record: Fix segfault with --no-mmap-pages David Ahern
2013-11-12 21:57   ` [tip:perf/urgent] " tip-bot for David Ahern
2013-11-12 14:46 ` [PATCH 2/5] perf tool: Round mmap pages to power 2 - v2 David Ahern
2013-11-12 21:57   ` [tip:perf/urgent] perf evlist: " tip-bot for David Ahern
2013-11-12 14:46 ` [PATCH 3/5] perf tool: Refactor mmap_pages parsing David Ahern
2013-11-12 21:57   ` [tip:perf/urgent] perf evlist: " tip-bot for David Ahern
2013-11-12 14:46 ` [PATCH 4/5] perf record: mmap output file - v5 David Ahern
2013-11-12 14:57   ` Peter Zijlstra
2013-11-12 15:07     ` Arnaldo Carvalho de Melo
2013-11-12 15:19       ` Peter Zijlstra
2013-11-12 15:36         ` David Ahern
2013-11-12 21:11           ` Ingo Molnar
2013-11-13 11:34             ` Peter Zijlstra
2013-11-13 11:50               ` Ingo Molnar
2013-11-13 12:16                 ` Peter Zijlstra
2013-11-13 14:29                 ` David Ahern
2013-11-15 16:41               ` David Ahern
2013-11-18  9:01                 ` Peter Zijlstra
2013-11-18  9:40                   ` Ingo Molnar
2013-11-19  0:24                     ` Namhyung Kim
2013-11-19  0:34                       ` David Ahern
2013-11-19  1:48                         ` Namhyung Kim
2013-11-19  2:02                         ` Namhyung Kim
2013-11-19  2:13                         ` Namhyung Kim
2013-11-19  2:17                           ` David Ahern
2013-11-19  2:30                             ` Namhyung Kim
2013-11-19  2:33                               ` David Ahern
2013-11-19  2:36                                 ` Namhyung Kim
2013-11-19  6:58                                 ` Ingo Molnar
2013-11-19 11:48                                   ` Peter Zijlstra
2013-11-19 11:49                                     ` Peter Zijlstra
2013-11-19 13:13                                       ` Ingo Molnar
2013-11-19 13:45                                         ` Peter Zijlstra
2013-11-19 15:31                                           ` Ingo Molnar
2013-11-19 16:09                                             ` David Ahern
2013-11-19 16:14                                               ` Ingo Molnar
2013-11-19 12:08                         ` Peter Zijlstra
2013-11-19  6:54                       ` Ingo Molnar
2013-11-12 14:46 ` [PATCH 5/5] perf record: Handle out of space failures writing data with mmap David Ahern
2013-11-12 21:19   ` Ingo Molnar [this message]
2013-11-13 14:33     ` 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=20131112211926.GD25913@gmail.com \
    --to=mingo@kernel.org \
    --cc=acme@ghostprotocols.net \
    --cc=dsahern@gmail.com \
    --cc=efault@gmx.de \
    --cc=eranian@google.com \
    --cc=fweisbec@gmail.com \
    --cc=jolsa@redhat.com \
    --cc=linux-kernel@vger.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.