aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/trace/trace.c
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/trace/trace.c')
-rw-r--r--kernel/trace/trace.c36
1 files changed, 21 insertions, 15 deletions
diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c
index 9d28476a9851..1ce5dc6372b8 100644
--- a/kernel/trace/trace.c
+++ b/kernel/trace/trace.c
@@ -3277,19 +3277,13 @@ static int tracing_buffers_open(struct inode *inode, struct file *filp)
3277 3277
3278 info->tr = &global_trace; 3278 info->tr = &global_trace;
3279 info->cpu = cpu; 3279 info->cpu = cpu;
3280 info->spare = ring_buffer_alloc_read_page(info->tr->buffer); 3280 info->spare = NULL;
3281 /* Force reading ring buffer for first read */ 3281 /* Force reading ring buffer for first read */
3282 info->read = (unsigned int)-1; 3282 info->read = (unsigned int)-1;
3283 if (!info->spare)
3284 goto out;
3285 3283
3286 filp->private_data = info; 3284 filp->private_data = info;
3287 3285
3288 return 0; 3286 return nonseekable_open(inode, filp);
3289
3290 out:
3291 kfree(info);
3292 return -ENOMEM;
3293} 3287}
3294 3288
3295static ssize_t 3289static ssize_t
@@ -3304,6 +3298,11 @@ tracing_buffers_read(struct file *filp, char __user *ubuf,
3304 if (!count) 3298 if (!count)
3305 return 0; 3299 return 0;
3306 3300
3301 if (!info->spare)
3302 info->spare = ring_buffer_alloc_read_page(info->tr->buffer);
3303 if (!info->spare)
3304 return -ENOMEM;
3305
3307 /* Do we have previous read data to read? */ 3306 /* Do we have previous read data to read? */
3308 if (info->read < PAGE_SIZE) 3307 if (info->read < PAGE_SIZE)
3309 goto read; 3308 goto read;
@@ -3342,7 +3341,8 @@ static int tracing_buffers_release(struct inode *inode, struct file *file)
3342{ 3341{
3343 struct ftrace_buffer_info *info = file->private_data; 3342 struct ftrace_buffer_info *info = file->private_data;
3344 3343
3345 ring_buffer_free_read_page(info->tr->buffer, info->spare); 3344 if (info->spare)
3345 ring_buffer_free_read_page(info->tr->buffer, info->spare);
3346 kfree(info); 3346 kfree(info);
3347 3347
3348 return 0; 3348 return 0;
@@ -3428,14 +3428,19 @@ tracing_buffers_splice_read(struct file *file, loff_t *ppos,
3428 int size, i; 3428 int size, i;
3429 size_t ret; 3429 size_t ret;
3430 3430
3431 /* 3431 if (*ppos & (PAGE_SIZE - 1)) {
3432 * We can't seek on a buffer input 3432 WARN_ONCE(1, "Ftrace: previous read must page-align\n");
3433 */ 3433 return -EINVAL;
3434 if (unlikely(*ppos)) 3434 }
3435 return -ESPIPE;
3436 3435
3436 if (len & (PAGE_SIZE - 1)) {
3437 WARN_ONCE(1, "Ftrace: splice_read should page-align\n");
3438 if (len < PAGE_SIZE)
3439 return -EINVAL;
3440 len &= PAGE_MASK;
3441 }
3437 3442
3438 for (i = 0; i < PIPE_BUFFERS && len; i++, len -= size) { 3443 for (i = 0; i < PIPE_BUFFERS && len; i++, len -= PAGE_SIZE) {
3439 struct page *page; 3444 struct page *page;
3440 int r; 3445 int r;
3441 3446
@@ -3474,6 +3479,7 @@ tracing_buffers_splice_read(struct file *file, loff_t *ppos,
3474 spd.partial[i].offset = 0; 3479 spd.partial[i].offset = 0;
3475 spd.partial[i].private = (unsigned long)ref; 3480 spd.partial[i].private = (unsigned long)ref;
3476 spd.nr_pages++; 3481 spd.nr_pages++;
3482 *ppos += PAGE_SIZE;
3477 } 3483 }
3478 3484
3479 spd.nr_pages = i; 3485 spd.nr_pages = i;