[lttng-dev] [RFC PATCH lttng-tools] Fix mmap for large subbuffers and handle EINTR

Mathieu Desnoyers mathieu.desnoyers at efficios.com
Fri Jul 6 09:31:29 EDT 2012


* David Goulet (dgoulet at efficios.com) wrote:
> -----BEGIN PGP SIGNED MESSAGE-----
> Hash: SHA1
> 
> Comments below.
> 
> On 04/07/12 12:10 PM, Mathieu Desnoyers wrote:
> > With large subbuffer (packet) size, if write() returns before copying the
> > entire packet for mmap buffers, the consumerd restarts the write 
> > infinitely, which is not good at all.
> > 
> > This affects both lttng-ust (in default mmap mode) and lttng-kernel (but 
> > only for mmap buffers, which is not the default).
> > 
> > This issue would show up with large subbuffer size.
> > 
> > We need to handle this case, as well as EINTR errors (which need to restart
> > write).
> > 
> > Also fixing the return value of mmap read functions, which were returning
> > the amount of data written by the last invocation of write() rather than
> > the total number of bytes written. splice use had the same issue.
> > 
> > Also now consider a write() that returns more bytes than requested as an 
> > error.
> > 
> > Moreover, assigning error = ret after failed splice and write was a 
> > mistake: error is holding the actual error value. ret just holds -1.
> > 
> > This needs testing. Feedback is welcome.
> > 
> > Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers at efficios.com> --- diff
> > --git a/src/common/kernel-consumer/kernel-consumer.c
> > b/src/common/kernel-consumer/kernel-consumer.c index bbc31f8..eca710d
> > 100644 --- a/src/common/kernel-consumer/kernel-consumer.c +++
> > b/src/common/kernel-consumer/kernel-consumer.c @@ -49,7 +49,7 @@ ssize_t
> > lttng_kconsumer_on_read_subbuffer_mmap( struct lttng_consumer_stream
> > *stream, unsigned long len) { unsigned long mmap_offset; -	ssize_t ret =
> > 0; +	ssize_t ret = 0, written = 0; off_t orig_offset =
> > stream->out_fd_offset; int fd = stream->wait_fd; int outfd =
> > stream->out_fd; @@ -64,25 +64,34 @@ ssize_t
> > lttng_kconsumer_on_read_subbuffer_mmap(
> 
> Just before going into the while() loop, there is a call to
> kernctl_get_mmap_read_offset() and, on failure, it goes to the "end:" label
> without setting "written" to a negative value.

OK, fixed.

> 
> > 
> > while (len > 0) { ret = write(outfd, stream->mmap_base + mmap_offset,
> > len); -		if (ret >= len) { -			len = 0; -		} else if (ret < 0) { -			errno
> > = -ret; +		if (ret < 0) { +			if (errno == EINTR) { +				/* restart the
> > interrupted system call */ +				continue; +			} else { +				perror("Error
> > in file write"); +				if (written == 0) { +					written = ret; +				} +
> > goto end; +			} +		} else if (ret > len) { perror("Error in file write"); +
> > written += ret; goto end;
> 
> I'm not sure this case is very useful... write() can not possibly return more
> than "len" (the size_t count argument). If it does, I'm pretty sure the whole
> Linux system will not go very well... hehe. The same applies for splice(),
> checking is ret > len is basically safe guarding the syscall which I don't
> think is necessary.

Better safe than sorry ;) Especially for splice(), given that we
implement our own splice actor, it's better to check for even the
assumed kernel behavior.

> 
> However, according to the man page write(2), a return value of 0 coupled with
> a regular file can return an error status:
> 
>        If  count  is  zero  and  fd refers to a regular file, then write() may
>        return a failure status if one of the errors below is detected.  If  no
>        errors  are  detected,  0  will  be  returned without causing any other
>        effect.  If count is zero and fd refers to a file other than a  regular
>        file, the results are not specified.
> 
> We might want to add a zero/errno check instead.

Done.

> 
> For testing, I can tell you that this patch fixes mmap network streaming (soon
> to be merged upstream) where the old code did not worked.

Great! Will post the updated version in a jiffy.

Thanks,

Mathieu

-- 
Mathieu Desnoyers
Operating System Efficiency R&D Consultant
EfficiOS Inc.
http://www.efficios.com



More information about the lttng-dev mailing list