diff options
Diffstat (limited to 'kernel/trace/trace.c')
| -rw-r--r-- | kernel/trace/trace.c | 29 | 
1 files changed, 16 insertions, 13 deletions
| diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c index dade4c9559cc..7bc56762ca35 100644 --- a/kernel/trace/trace.c +++ b/kernel/trace/trace.c @@ -5124,19 +5124,20 @@ tracing_read_pipe(struct file *filp, char __user *ubuf,  	struct trace_iterator *iter = filp->private_data;  	ssize_t sret; -	/* return any leftover data */ -	sret = trace_seq_to_user(&iter->seq, ubuf, cnt); -	if (sret != -EBUSY) -		return sret; - -	trace_seq_init(&iter->seq); -  	/*  	 * Avoid more than one consumer on a single file descriptor  	 * This is just a matter of traces coherency, the ring buffer itself  	 * is protected.  	 */  	mutex_lock(&iter->mutex); + +	/* return any leftover data */ +	sret = trace_seq_to_user(&iter->seq, ubuf, cnt); +	if (sret != -EBUSY) +		goto out; + +	trace_seq_init(&iter->seq); +  	if (iter->trace->read) {  		sret = iter->trace->read(iter, filp, ubuf, cnt, ppos);  		if (sret) @@ -6163,9 +6164,6 @@ tracing_buffers_splice_read(struct file *file, loff_t *ppos,  		return -EBUSY;  #endif -	if (splice_grow_spd(pipe, &spd)) -		return -ENOMEM; -  	if (*ppos & (PAGE_SIZE - 1))  		return -EINVAL; @@ -6175,6 +6173,9 @@ tracing_buffers_splice_read(struct file *file, loff_t *ppos,  		len &= PAGE_MASK;  	} +	if (splice_grow_spd(pipe, &spd)) +		return -ENOMEM; +   again:  	trace_access_lock(iter->cpu_file);  	entries = ring_buffer_entries_cpu(iter->trace_buffer->buffer, iter->cpu_file); @@ -6232,19 +6233,21 @@ tracing_buffers_splice_read(struct file *file, loff_t *ppos,  	/* did we read anything? */  	if (!spd.nr_pages) {  		if (ret) -			return ret; +			goto out; +		ret = -EAGAIN;  		if ((file->f_flags & O_NONBLOCK) || (flags & SPLICE_F_NONBLOCK)) -			return -EAGAIN; +			goto out;  		ret = wait_on_pipe(iter, true);  		if (ret) -			return ret; +			goto out;  		goto again;  	}  	ret = splice_to_pipe(pipe, &spd); +out:  	splice_shrink_spd(&spd);  	return ret; |