aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/trace/trace.c
diff options
context:
space:
mode:
authorSteven Rostedt <srostedt@redhat.com>2013-02-28 09:17:16 -0500
committerSteven Rostedt <rostedt@goodmis.org>2013-03-15 00:34:49 -0400
commitcc60cdc952be09bca5b0bff9fefc7aa6185c3049 (patch)
treed16c601f5848b556b3f02487a74af0835ede82fa /kernel/trace/trace.c
parent189e5784f6c5e001a84127b83f03bc76a8bfb1ec (diff)
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>
Diffstat (limited to 'kernel/trace/trace.c')
-rw-r--r--kernel/trace/trace.c78
1 files changed, 51 insertions, 27 deletions
diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c
index 598a7aa7d0ae..4a6e461273a9 100644
--- a/kernel/trace/trace.c
+++ b/kernel/trace/trace.c
@@ -3555,10 +3555,8 @@ static int tracing_release_pipe(struct inode *inode, struct file *file)
3555} 3555}
3556 3556
3557static unsigned int 3557static unsigned int
3558tracing_poll_pipe(struct file *filp, poll_table *poll_table) 3558trace_poll(struct trace_iterator *iter, struct file *filp, poll_table *poll_table)
3559{ 3559{
3560 struct trace_iterator *iter = filp->private_data;
3561
3562 if (trace_flags & TRACE_ITER_BLOCK) { 3560 if (trace_flags & TRACE_ITER_BLOCK) {
3563 /* 3561 /*
3564 * Always select as readable when in blocking mode 3562 * Always select as readable when in blocking mode
@@ -3567,6 +3565,7 @@ tracing_poll_pipe(struct file *filp, poll_table *poll_table)
3567 } else { 3565 } else {
3568 if (!trace_empty(iter)) 3566 if (!trace_empty(iter))
3569 return POLLIN | POLLRDNORM; 3567 return POLLIN | POLLRDNORM;
3568 trace_wakeup_needed = true;
3570 poll_wait(filp, &trace_wait, poll_table); 3569 poll_wait(filp, &trace_wait, poll_table);
3571 if (!trace_empty(iter)) 3570 if (!trace_empty(iter))
3572 return POLLIN | POLLRDNORM; 3571 return POLLIN | POLLRDNORM;
@@ -3575,6 +3574,14 @@ tracing_poll_pipe(struct file *filp, poll_table *poll_table)
3575 } 3574 }
3576} 3575}
3577 3576
3577static unsigned int
3578tracing_poll_pipe(struct file *filp, poll_table *poll_table)
3579{
3580 struct trace_iterator *iter = filp->private_data;
3581
3582 return trace_poll(iter, filp, poll_table);
3583}
3584
3578/* 3585/*
3579 * This is a make-shift waitqueue. 3586 * This is a make-shift waitqueue.
3580 * A tracer might use this callback on some rare cases: 3587 * A tracer might use this callback on some rare cases:
@@ -4362,9 +4369,8 @@ static const struct file_operations snapshot_fops = {
4362#endif /* CONFIG_TRACER_SNAPSHOT */ 4369#endif /* CONFIG_TRACER_SNAPSHOT */
4363 4370
4364struct ftrace_buffer_info { 4371struct ftrace_buffer_info {
4365 struct trace_array *tr; 4372 struct trace_iterator iter;
4366 void *spare; 4373 void *spare;
4367 int cpu;
4368 unsigned int read; 4374 unsigned int read;
4369}; 4375};
4370 4376
@@ -4381,22 +4387,32 @@ static int tracing_buffers_open(struct inode *inode, struct file *filp)
4381 if (!info) 4387 if (!info)
4382 return -ENOMEM; 4388 return -ENOMEM;
4383 4389
4384 info->tr = tr; 4390 info->iter.tr = tr;
4385 info->cpu = tc->cpu; 4391 info->iter.cpu_file = tc->cpu;
4386 info->spare = NULL; 4392 info->spare = NULL;
4387 /* Force reading ring buffer for first read */ 4393 /* Force reading ring buffer for first read */
4388 info->read = (unsigned int)-1; 4394 info->read = (unsigned int)-1;
4389 4395
4390 filp->private_data = info; 4396 filp->private_data = info;
4391 4397
4392 return nonseekable_open(inode, filp); 4398 return nonseekable_open(inode, filp);
4393} 4399}
4394 4400
4401static unsigned int
4402tracing_buffers_poll(struct file *filp, poll_table *poll_table)
4403{
4404 struct ftrace_buffer_info *info = filp->private_data;
4405 struct trace_iterator *iter = &info->iter;
4406
4407 return trace_poll(iter, filp, poll_table);
4408}
4409
4395static ssize_t 4410static ssize_t
4396tracing_buffers_read(struct file *filp, char __user *ubuf, 4411tracing_buffers_read(struct file *filp, char __user *ubuf,
4397 size_t count, loff_t *ppos) 4412 size_t count, loff_t *ppos)
4398{ 4413{
4399 struct ftrace_buffer_info *info = filp->private_data; 4414 struct ftrace_buffer_info *info = filp->private_data;
4415 struct trace_iterator *iter = &info->iter;
4400 ssize_t ret; 4416 ssize_t ret;
4401 size_t size; 4417 size_t size;
4402 4418
@@ -4404,7 +4420,7 @@ tracing_buffers_read(struct file *filp, char __user *ubuf,
4404 return 0; 4420 return 0;
4405 4421
4406 if (!info->spare) 4422 if (!info->spare)
4407 info->spare = ring_buffer_alloc_read_page(info->tr->buffer, info->cpu); 4423 info->spare = ring_buffer_alloc_read_page(iter->tr->buffer, iter->cpu_file);
4408 if (!info->spare) 4424 if (!info->spare)
4409 return -ENOMEM; 4425 return -ENOMEM;
4410 4426
@@ -4412,12 +4428,12 @@ tracing_buffers_read(struct file *filp, char __user *ubuf,
4412 if (info->read < PAGE_SIZE) 4428 if (info->read < PAGE_SIZE)
4413 goto read; 4429 goto read;
4414 4430
4415 trace_access_lock(info->cpu); 4431 trace_access_lock(iter->cpu_file);
4416 ret = ring_buffer_read_page(info->tr->buffer, 4432 ret = ring_buffer_read_page(iter->tr->buffer,
4417 &info->spare, 4433 &info->spare,
4418 count, 4434 count,
4419 info->cpu, 0); 4435 iter->cpu_file, 0);
4420 trace_access_unlock(info->cpu); 4436 trace_access_unlock(iter->cpu_file);
4421 if (ret < 0) 4437 if (ret < 0)
4422 return 0; 4438 return 0;
4423 4439
@@ -4442,9 +4458,10 @@ read:
4442static int tracing_buffers_release(struct inode *inode, struct file *file) 4458static int tracing_buffers_release(struct inode *inode, struct file *file)
4443{ 4459{
4444 struct ftrace_buffer_info *info = file->private_data; 4460 struct ftrace_buffer_info *info = file->private_data;
4461 struct trace_iterator *iter = &info->iter;
4445 4462
4446 if (info->spare) 4463 if (info->spare)
4447 ring_buffer_free_read_page(info->tr->buffer, info->spare); 4464 ring_buffer_free_read_page(iter->tr->buffer, info->spare);
4448 kfree(info); 4465 kfree(info);
4449 4466
4450 return 0; 4467 return 0;
@@ -4511,6 +4528,7 @@ tracing_buffers_splice_read(struct file *file, loff_t *ppos,
4511 unsigned int flags) 4528 unsigned int flags)
4512{ 4529{
4513 struct ftrace_buffer_info *info = file->private_data; 4530 struct ftrace_buffer_info *info = file->private_data;
4531 struct trace_iterator *iter = &info->iter;
4514 struct partial_page partial_def[PIPE_DEF_BUFFERS]; 4532 struct partial_page partial_def[PIPE_DEF_BUFFERS];
4515 struct page *pages_def[PIPE_DEF_BUFFERS]; 4533 struct page *pages_def[PIPE_DEF_BUFFERS];
4516 struct splice_pipe_desc spd = { 4534 struct splice_pipe_desc spd = {
@@ -4541,8 +4559,9 @@ tracing_buffers_splice_read(struct file *file, loff_t *ppos,
4541 len &= PAGE_MASK; 4559 len &= PAGE_MASK;
4542 } 4560 }
4543 4561
4544 trace_access_lock(info->cpu); 4562 again:
4545 entries = ring_buffer_entries_cpu(info->tr->buffer, info->cpu); 4563 trace_access_lock(iter->cpu_file);
4564 entries = ring_buffer_entries_cpu(iter->tr->buffer, iter->cpu_file);
4546 4565
4547 for (i = 0; i < pipe->buffers && len && entries; i++, len -= PAGE_SIZE) { 4566 for (i = 0; i < pipe->buffers && len && entries; i++, len -= PAGE_SIZE) {
4548 struct page *page; 4567 struct page *page;
@@ -4553,15 +4572,15 @@ tracing_buffers_splice_read(struct file *file, loff_t *ppos,
4553 break; 4572 break;
4554 4573
4555 ref->ref = 1; 4574 ref->ref = 1;
4556 ref->buffer = info->tr->buffer; 4575 ref->buffer = iter->tr->buffer;
4557 ref->page = ring_buffer_alloc_read_page(ref->buffer, info->cpu); 4576 ref->page = ring_buffer_alloc_read_page(ref->buffer, iter->cpu_file);
4558 if (!ref->page) { 4577 if (!ref->page) {
4559 kfree(ref); 4578 kfree(ref);
4560 break; 4579 break;
4561 } 4580 }
4562 4581
4563 r = ring_buffer_read_page(ref->buffer, &ref->page, 4582 r = ring_buffer_read_page(ref->buffer, &ref->page,
4564 len, info->cpu, 1); 4583 len, iter->cpu_file, 1);
4565 if (r < 0) { 4584 if (r < 0) {
4566 ring_buffer_free_read_page(ref->buffer, ref->page); 4585 ring_buffer_free_read_page(ref->buffer, ref->page);
4567 kfree(ref); 4586 kfree(ref);
@@ -4585,20 +4604,24 @@ tracing_buffers_splice_read(struct file *file, loff_t *ppos,
4585 spd.nr_pages++; 4604 spd.nr_pages++;
4586 *ppos += PAGE_SIZE; 4605 *ppos += PAGE_SIZE;
4587 4606
4588 entries = ring_buffer_entries_cpu(info->tr->buffer, info->cpu); 4607 entries = ring_buffer_entries_cpu(iter->tr->buffer, iter->cpu_file);
4589 } 4608 }
4590 4609
4591 trace_access_unlock(info->cpu); 4610 trace_access_unlock(iter->cpu_file);
4592 spd.nr_pages = i; 4611 spd.nr_pages = i;
4593 4612
4594 /* did we read anything? */ 4613 /* did we read anything? */
4595 if (!spd.nr_pages) { 4614 if (!spd.nr_pages) {
4596 if ((file->f_flags & O_NONBLOCK) || (flags & SPLICE_F_NONBLOCK)) 4615 if ((file->f_flags & O_NONBLOCK) || (flags & SPLICE_F_NONBLOCK)) {
4597 ret = -EAGAIN; 4616 ret = -EAGAIN;
4598 else 4617 goto out;
4599 ret = 0; 4618 }
4600 /* TODO: block */ 4619 default_wait_pipe(iter);
4601 goto out; 4620 if (signal_pending(current)) {
4621 ret = -EINTR;
4622 goto out;
4623 }
4624 goto again;
4602 } 4625 }
4603 4626
4604 ret = splice_to_pipe(pipe, &spd); 4627 ret = splice_to_pipe(pipe, &spd);
@@ -4610,6 +4633,7 @@ out:
4610static const struct file_operations tracing_buffers_fops = { 4633static const struct file_operations tracing_buffers_fops = {
4611 .open = tracing_buffers_open, 4634 .open = tracing_buffers_open,
4612 .read = tracing_buffers_read, 4635 .read = tracing_buffers_read,
4636 .poll = tracing_buffers_poll,
4613 .release = tracing_buffers_release, 4637 .release = tracing_buffers_release,
4614 .splice_read = tracing_buffers_splice_read, 4638 .splice_read = tracing_buffers_splice_read,
4615 .llseek = no_llseek, 4639 .llseek = no_llseek,