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

tracing: Fix polling on trace_pipe_raw

The trace_pipe_raw never implemented polling and this was casing
issues for several utilities. This is now implemented.

Blocked reads still are on the TODO list.

Reported-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Tested-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Signed-off-by: Steven Rostedt <rostedt@goodmis.org>

authored by

Steven Rostedt and committed by
Steven Rostedt
cc60cdc9 189e5784

+51 -27
+51 -27
kernel/trace/trace.c
··· 3555 3555 } 3556 3556 3557 3557 static unsigned int 3558 - tracing_poll_pipe(struct file *filp, poll_table *poll_table) 3558 + trace_poll(struct trace_iterator *iter, struct file *filp, poll_table *poll_table) 3559 3559 { 3560 - struct trace_iterator *iter = filp->private_data; 3561 - 3562 3560 if (trace_flags & TRACE_ITER_BLOCK) { 3563 3561 /* 3564 3562 * Always select as readable when in blocking mode ··· 3565 3567 } else { 3566 3568 if (!trace_empty(iter)) 3567 3569 return POLLIN | POLLRDNORM; 3570 + trace_wakeup_needed = true; 3568 3571 poll_wait(filp, &trace_wait, poll_table); 3569 3572 if (!trace_empty(iter)) 3570 3573 return POLLIN | POLLRDNORM; 3571 3574 3572 3575 return 0; 3573 3576 } 3577 + } 3578 + 3579 + static unsigned int 3580 + tracing_poll_pipe(struct file *filp, poll_table *poll_table) 3581 + { 3582 + struct trace_iterator *iter = filp->private_data; 3583 + 3584 + return trace_poll(iter, filp, poll_table); 3574 3585 } 3575 3586 3576 3587 /* ··· 4369 4362 #endif /* CONFIG_TRACER_SNAPSHOT */ 4370 4363 4371 4364 struct ftrace_buffer_info { 4372 - struct trace_array *tr; 4365 + struct trace_iterator iter; 4373 4366 void *spare; 4374 - int cpu; 4375 4367 unsigned int read; 4376 4368 }; 4377 4369 ··· 4387 4381 if (!info) 4388 4382 return -ENOMEM; 4389 4383 4390 - info->tr = tr; 4391 - info->cpu = tc->cpu; 4392 - info->spare = NULL; 4384 + info->iter.tr = tr; 4385 + info->iter.cpu_file = tc->cpu; 4386 + info->spare = NULL; 4393 4387 /* Force reading ring buffer for first read */ 4394 - info->read = (unsigned int)-1; 4388 + info->read = (unsigned int)-1; 4395 4389 4396 4390 filp->private_data = info; 4397 4391 4398 4392 return nonseekable_open(inode, filp); 4393 + } 4394 + 4395 + static unsigned int 4396 + tracing_buffers_poll(struct file *filp, poll_table *poll_table) 4397 + { 4398 + struct ftrace_buffer_info *info = filp->private_data; 4399 + struct trace_iterator *iter = &info->iter; 4400 + 4401 + return trace_poll(iter, filp, poll_table); 4399 4402 } 4400 4403 4401 4404 static ssize_t ··· 4412 4397 size_t count, loff_t *ppos) 4413 4398 { 4414 4399 struct ftrace_buffer_info *info = filp->private_data; 4400 + struct trace_iterator *iter = &info->iter; 4415 4401 ssize_t ret; 4416 4402 size_t size; 4417 4403 ··· 4420 4404 return 0; 4421 4405 4422 4406 if (!info->spare) 4423 - info->spare = ring_buffer_alloc_read_page(info->tr->buffer, info->cpu); 4407 + info->spare = ring_buffer_alloc_read_page(iter->tr->buffer, iter->cpu_file); 4424 4408 if (!info->spare) 4425 4409 return -ENOMEM; 4426 4410 ··· 4428 4412 if (info->read < PAGE_SIZE) 4429 4413 goto read; 4430 4414 4431 - trace_access_lock(info->cpu); 4432 - ret = ring_buffer_read_page(info->tr->buffer, 4415 + trace_access_lock(iter->cpu_file); 4416 + ret = ring_buffer_read_page(iter->tr->buffer, 4433 4417 &info->spare, 4434 4418 count, 4435 - info->cpu, 0); 4436 - trace_access_unlock(info->cpu); 4419 + iter->cpu_file, 0); 4420 + trace_access_unlock(iter->cpu_file); 4437 4421 if (ret < 0) 4438 4422 return 0; 4439 4423 ··· 4458 4442 static int tracing_buffers_release(struct inode *inode, struct file *file) 4459 4443 { 4460 4444 struct ftrace_buffer_info *info = file->private_data; 4445 + struct trace_iterator *iter = &info->iter; 4461 4446 4462 4447 if (info->spare) 4463 - ring_buffer_free_read_page(info->tr->buffer, info->spare); 4448 + ring_buffer_free_read_page(iter->tr->buffer, info->spare); 4464 4449 kfree(info); 4465 4450 4466 4451 return 0; ··· 4528 4511 unsigned int flags) 4529 4512 { 4530 4513 struct ftrace_buffer_info *info = file->private_data; 4514 + struct trace_iterator *iter = &info->iter; 4531 4515 struct partial_page partial_def[PIPE_DEF_BUFFERS]; 4532 4516 struct page *pages_def[PIPE_DEF_BUFFERS]; 4533 4517 struct splice_pipe_desc spd = { ··· 4559 4541 len &= PAGE_MASK; 4560 4542 } 4561 4543 4562 - trace_access_lock(info->cpu); 4563 - entries = ring_buffer_entries_cpu(info->tr->buffer, info->cpu); 4544 + again: 4545 + trace_access_lock(iter->cpu_file); 4546 + entries = ring_buffer_entries_cpu(iter->tr->buffer, iter->cpu_file); 4564 4547 4565 4548 for (i = 0; i < pipe->buffers && len && entries; i++, len -= PAGE_SIZE) { 4566 4549 struct page *page; ··· 4572 4553 break; 4573 4554 4574 4555 ref->ref = 1; 4575 - ref->buffer = info->tr->buffer; 4576 - ref->page = ring_buffer_alloc_read_page(ref->buffer, info->cpu); 4556 + ref->buffer = iter->tr->buffer; 4557 + ref->page = ring_buffer_alloc_read_page(ref->buffer, iter->cpu_file); 4577 4558 if (!ref->page) { 4578 4559 kfree(ref); 4579 4560 break; 4580 4561 } 4581 4562 4582 4563 r = ring_buffer_read_page(ref->buffer, &ref->page, 4583 - len, info->cpu, 1); 4564 + len, iter->cpu_file, 1); 4584 4565 if (r < 0) { 4585 4566 ring_buffer_free_read_page(ref->buffer, ref->page); 4586 4567 kfree(ref); ··· 4604 4585 spd.nr_pages++; 4605 4586 *ppos += PAGE_SIZE; 4606 4587 4607 - entries = ring_buffer_entries_cpu(info->tr->buffer, info->cpu); 4588 + entries = ring_buffer_entries_cpu(iter->tr->buffer, iter->cpu_file); 4608 4589 } 4609 4590 4610 - trace_access_unlock(info->cpu); 4591 + trace_access_unlock(iter->cpu_file); 4611 4592 spd.nr_pages = i; 4612 4593 4613 4594 /* did we read anything? */ 4614 4595 if (!spd.nr_pages) { 4615 - if ((file->f_flags & O_NONBLOCK) || (flags & SPLICE_F_NONBLOCK)) 4596 + if ((file->f_flags & O_NONBLOCK) || (flags & SPLICE_F_NONBLOCK)) { 4616 4597 ret = -EAGAIN; 4617 - else 4618 - ret = 0; 4619 - /* TODO: block */ 4620 - goto out; 4598 + goto out; 4599 + } 4600 + default_wait_pipe(iter); 4601 + if (signal_pending(current)) { 4602 + ret = -EINTR; 4603 + goto out; 4604 + } 4605 + goto again; 4621 4606 } 4622 4607 4623 4608 ret = splice_to_pipe(pipe, &spd); ··· 4633 4610 static const struct file_operations tracing_buffers_fops = { 4634 4611 .open = tracing_buffers_open, 4635 4612 .read = tracing_buffers_read, 4613 + .poll = tracing_buffers_poll, 4636 4614 .release = tracing_buffers_release, 4637 4615 .splice_read = tracing_buffers_splice_read, 4638 4616 .llseek = no_llseek,