Skip to content

Commit cc60cdc

Browse files
Steven Rostedtrostedt
authored andcommitted
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>
1 parent 189e578 commit cc60cdc

File tree

1 file changed

+51
-27
lines changed

1 file changed

+51
-27
lines changed

kernel/trace/trace.c

Lines changed: 51 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -3555,10 +3555,8 @@ static int tracing_release_pipe(struct inode *inode, struct file *file)
35553555
}
35563556

35573557
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)
35593559
{
3560-
struct trace_iterator *iter = filp->private_data;
3561-
35623560
if (trace_flags & TRACE_ITER_BLOCK) {
35633561
/*
35643562
* Always select as readable when in blocking mode
@@ -3567,6 +3565,7 @@ tracing_poll_pipe(struct file *filp, poll_table *poll_table)
35673565
} else {
35683566
if (!trace_empty(iter))
35693567
return POLLIN | POLLRDNORM;
3568+
trace_wakeup_needed = true;
35703569
poll_wait(filp, &trace_wait, poll_table);
35713570
if (!trace_empty(iter))
35723571
return POLLIN | POLLRDNORM;
@@ -3575,6 +3574,14 @@ tracing_poll_pipe(struct file *filp, poll_table *poll_table)
35753574
}
35763575
}
35773576

3577+
static unsigned int
3578+
tracing_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+
35783585
/*
35793586
* This is a make-shift waitqueue.
35803587
* A tracer might use this callback on some rare cases:
@@ -4362,9 +4369,8 @@ static const struct file_operations snapshot_fops = {
43624369
#endif /* CONFIG_TRACER_SNAPSHOT */
43634370

43644371
struct ftrace_buffer_info {
4365-
struct trace_array *tr;
4372+
struct trace_iterator iter;
43664373
void *spare;
4367-
int cpu;
43684374
unsigned int read;
43694375
};
43704376

@@ -4381,43 +4387,53 @@ static int tracing_buffers_open(struct inode *inode, struct file *filp)
43814387
if (!info)
43824388
return -ENOMEM;
43834389

4384-
info->tr = tr;
4385-
info->cpu = tc->cpu;
4386-
info->spare = NULL;
4390+
info->iter.tr = tr;
4391+
info->iter.cpu_file = tc->cpu;
4392+
info->spare = NULL;
43874393
/* Force reading ring buffer for first read */
4388-
info->read = (unsigned int)-1;
4394+
info->read = (unsigned int)-1;
43894395

43904396
filp->private_data = info;
43914397

43924398
return nonseekable_open(inode, filp);
43934399
}
43944400

4401+
static unsigned int
4402+
tracing_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+
43954410
static ssize_t
43964411
tracing_buffers_read(struct file *filp, char __user *ubuf,
43974412
size_t count, loff_t *ppos)
43984413
{
43994414
struct ftrace_buffer_info *info = filp->private_data;
4415+
struct trace_iterator *iter = &info->iter;
44004416
ssize_t ret;
44014417
size_t size;
44024418

44034419
if (!count)
44044420
return 0;
44054421

44064422
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);
44084424
if (!info->spare)
44094425
return -ENOMEM;
44104426

44114427
/* Do we have previous read data to read? */
44124428
if (info->read < PAGE_SIZE)
44134429
goto read;
44144430

4415-
trace_access_lock(info->cpu);
4416-
ret = ring_buffer_read_page(info->tr->buffer,
4431+
trace_access_lock(iter->cpu_file);
4432+
ret = ring_buffer_read_page(iter->tr->buffer,
44174433
&info->spare,
44184434
count,
4419-
info->cpu, 0);
4420-
trace_access_unlock(info->cpu);
4435+
iter->cpu_file, 0);
4436+
trace_access_unlock(iter->cpu_file);
44214437
if (ret < 0)
44224438
return 0;
44234439

@@ -4442,9 +4458,10 @@ tracing_buffers_read(struct file *filp, char __user *ubuf,
44424458
static int tracing_buffers_release(struct inode *inode, struct file *file)
44434459
{
44444460
struct ftrace_buffer_info *info = file->private_data;
4461+
struct trace_iterator *iter = &info->iter;
44454462

44464463
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);
44484465
kfree(info);
44494466

44504467
return 0;
@@ -4511,6 +4528,7 @@ tracing_buffers_splice_read(struct file *file, loff_t *ppos,
45114528
unsigned int flags)
45124529
{
45134530
struct ftrace_buffer_info *info = file->private_data;
4531+
struct trace_iterator *iter = &info->iter;
45144532
struct partial_page partial_def[PIPE_DEF_BUFFERS];
45154533
struct page *pages_def[PIPE_DEF_BUFFERS];
45164534
struct splice_pipe_desc spd = {
@@ -4541,8 +4559,9 @@ tracing_buffers_splice_read(struct file *file, loff_t *ppos,
45414559
len &= PAGE_MASK;
45424560
}
45434561

4544-
trace_access_lock(info->cpu);
4545-
entries = ring_buffer_entries_cpu(info->tr->buffer, info->cpu);
4562+
again:
4563+
trace_access_lock(iter->cpu_file);
4564+
entries = ring_buffer_entries_cpu(iter->tr->buffer, iter->cpu_file);
45464565

45474566
for (i = 0; i < pipe->buffers && len && entries; i++, len -= PAGE_SIZE) {
45484567
struct page *page;
@@ -4553,15 +4572,15 @@ tracing_buffers_splice_read(struct file *file, loff_t *ppos,
45534572
break;
45544573

45554574
ref->ref = 1;
4556-
ref->buffer = info->tr->buffer;
4557-
ref->page = ring_buffer_alloc_read_page(ref->buffer, info->cpu);
4575+
ref->buffer = iter->tr->buffer;
4576+
ref->page = ring_buffer_alloc_read_page(ref->buffer, iter->cpu_file);
45584577
if (!ref->page) {
45594578
kfree(ref);
45604579
break;
45614580
}
45624581

45634582
r = ring_buffer_read_page(ref->buffer, &ref->page,
4564-
len, info->cpu, 1);
4583+
len, iter->cpu_file, 1);
45654584
if (r < 0) {
45664585
ring_buffer_free_read_page(ref->buffer, ref->page);
45674586
kfree(ref);
@@ -4585,20 +4604,24 @@ tracing_buffers_splice_read(struct file *file, loff_t *ppos,
45854604
spd.nr_pages++;
45864605
*ppos += PAGE_SIZE;
45874606

4588-
entries = ring_buffer_entries_cpu(info->tr->buffer, info->cpu);
4607+
entries = ring_buffer_entries_cpu(iter->tr->buffer, iter->cpu_file);
45894608
}
45904609

4591-
trace_access_unlock(info->cpu);
4610+
trace_access_unlock(iter->cpu_file);
45924611
spd.nr_pages = i;
45934612

45944613
/* did we read anything? */
45954614
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)) {
45974616
ret = -EAGAIN;
4598-
else
4599-
ret = 0;
4600-
/* TODO: block */
4601-
goto out;
4617+
goto out;
4618+
}
4619+
default_wait_pipe(iter);
4620+
if (signal_pending(current)) {
4621+
ret = -EINTR;
4622+
goto out;
4623+
}
4624+
goto again;
46024625
}
46034626

46044627
ret = splice_to_pipe(pipe, &spd);
@@ -4610,6 +4633,7 @@ tracing_buffers_splice_read(struct file *file, loff_t *ppos,
46104633
static const struct file_operations tracing_buffers_fops = {
46114634
.open = tracing_buffers_open,
46124635
.read = tracing_buffers_read,
4636+
.poll = tracing_buffers_poll,
46134637
.release = tracing_buffers_release,
46144638
.splice_read = tracing_buffers_splice_read,
46154639
.llseek = no_llseek,

0 commit comments

Comments
 (0)