Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

tracing: Fix read blocking on trace_pipe_raw

If the ring buffer is empty, a read to trace_pipe_raw wont block.
The tracing code has the infrastructure to wake up waiting readers,
but the trace_pipe_raw doesn't take advantage of that.

When a read is done to trace_pipe_raw without the O_NONBLOCK flag
set, have the read block until there's data in the requested buffer.

Signed-off-by: Steven Rostedt <rostedt@goodmis.org>

authored by

Steven Rostedt and committed by
Steven Rostedt
b627344f cc60cdc9

+15 -3
+15 -3
kernel/trace/trace.c
··· 4389 4389 4390 4390 info->iter.tr = tr; 4391 4391 info->iter.cpu_file = tc->cpu; 4392 + info->iter.trace = tr->current_trace; 4392 4393 info->spare = NULL; 4393 4394 /* Force reading ring buffer for first read */ 4394 4395 info->read = (unsigned int)-1; ··· 4429 4428 if (info->read < PAGE_SIZE) 4430 4429 goto read; 4431 4430 4431 + again: 4432 4432 trace_access_lock(iter->cpu_file); 4433 4433 ret = ring_buffer_read_page(iter->tr->buffer, 4434 4434 &info->spare, 4435 4435 count, 4436 4436 iter->cpu_file, 0); 4437 4437 trace_access_unlock(iter->cpu_file); 4438 - if (ret < 0) 4438 + 4439 + if (ret < 0) { 4440 + if (trace_empty(iter)) { 4441 + if ((filp->f_flags & O_NONBLOCK)) 4442 + return -EAGAIN; 4443 + iter->trace->wait_pipe(iter); 4444 + if (signal_pending(current)) 4445 + return -EINTR; 4446 + goto again; 4447 + } 4439 4448 return 0; 4449 + } 4440 4450 4441 4451 info->read = 0; 4442 4452 4443 - read: 4453 + read: 4444 4454 size = PAGE_SIZE - info->read; 4445 4455 if (size > count) 4446 4456 size = count; ··· 4628 4616 ret = -EAGAIN; 4629 4617 goto out; 4630 4618 } 4631 - default_wait_pipe(iter); 4619 + iter->trace->wait_pipe(iter); 4632 4620 if (signal_pending(current)) { 4633 4621 ret = -EINTR; 4634 4622 goto out;