Loading kernel/trace/trace.c +95 −18 Original line number Diff line number Diff line Loading @@ -4206,6 +4206,12 @@ static int tracing_clock_open(struct inode *inode, struct file *file) return single_open(file, tracing_clock_show, inode->i_private); } struct ftrace_buffer_info { struct trace_iterator iter; void *spare; unsigned int read; }; #ifdef CONFIG_TRACER_SNAPSHOT static int tracing_snapshot_open(struct inode *inode, struct file *file) { Loading Loading @@ -4336,6 +4342,35 @@ static int tracing_snapshot_release(struct inode *inode, struct file *file) return 0; } static int tracing_buffers_open(struct inode *inode, struct file *filp); static ssize_t tracing_buffers_read(struct file *filp, char __user *ubuf, size_t count, loff_t *ppos); static int tracing_buffers_release(struct inode *inode, struct file *file); static ssize_t tracing_buffers_splice_read(struct file *file, loff_t *ppos, struct pipe_inode_info *pipe, size_t len, unsigned int flags); static int snapshot_raw_open(struct inode *inode, struct file *filp) { struct ftrace_buffer_info *info; int ret; ret = tracing_buffers_open(inode, filp); if (ret < 0) return ret; info = filp->private_data; if (info->iter.trace->use_max_tr) { tracing_buffers_release(inode, filp); return -EBUSY; } info->iter.snapshot = true; info->iter.trace_buffer = &info->iter.tr->max_buffer; return ret; } #endif /* CONFIG_TRACER_SNAPSHOT */ Loading Loading @@ -4402,14 +4437,17 @@ static const struct file_operations snapshot_fops = { .llseek = tracing_seek, .release = tracing_snapshot_release, }; #endif /* CONFIG_TRACER_SNAPSHOT */ struct ftrace_buffer_info { struct trace_iterator iter; void *spare; unsigned int read; static const struct file_operations snapshot_raw_fops = { .open = snapshot_raw_open, .read = tracing_buffers_read, .release = tracing_buffers_release, .splice_read = tracing_buffers_splice_read, .llseek = no_llseek, }; #endif /* CONFIG_TRACER_SNAPSHOT */ static int tracing_buffers_open(struct inode *inode, struct file *filp) { struct trace_cpu *tc = inode->i_private; Loading Loading @@ -4452,16 +4490,26 @@ tracing_buffers_read(struct file *filp, char __user *ubuf, struct ftrace_buffer_info *info = filp->private_data; struct trace_iterator *iter = &info->iter; ssize_t ret; size_t size; ssize_t size; if (!count) return 0; mutex_lock(&trace_types_lock); #ifdef CONFIG_TRACER_MAX_TRACE if (iter->snapshot && iter->tr->current_trace->use_max_tr) { size = -EBUSY; goto out_unlock; } #endif if (!info->spare) info->spare = ring_buffer_alloc_read_page(iter->trace_buffer->buffer, iter->cpu_file); size = -ENOMEM; if (!info->spare) return -ENOMEM; goto out_unlock; /* Do we have previous read data to read? */ if (info->read < PAGE_SIZE) Loading @@ -4477,31 +4525,42 @@ tracing_buffers_read(struct file *filp, char __user *ubuf, if (ret < 0) { if (trace_empty(iter)) { if ((filp->f_flags & O_NONBLOCK)) return -EAGAIN; if ((filp->f_flags & O_NONBLOCK)) { size = -EAGAIN; goto out_unlock; } mutex_unlock(&trace_types_lock); iter->trace->wait_pipe(iter); if (signal_pending(current)) return -EINTR; mutex_lock(&trace_types_lock); if (signal_pending(current)) { size = -EINTR; goto out_unlock; } goto again; } return 0; size = 0; goto out_unlock; } info->read = 0; read: size = PAGE_SIZE - info->read; if (size > count) size = count; ret = copy_to_user(ubuf, info->spare + info->read, size); if (ret == size) return -EFAULT; if (ret == size) { size = -EFAULT; goto out_unlock; } size -= ret; *ppos += size; info->read += size; out_unlock: mutex_unlock(&trace_types_lock); return size; } Loading Loading @@ -4591,10 +4650,21 @@ tracing_buffers_splice_read(struct file *file, loff_t *ppos, }; struct buffer_ref *ref; int entries, size, i; size_t ret; ssize_t ret; if (splice_grow_spd(pipe, &spd)) return -ENOMEM; mutex_lock(&trace_types_lock); #ifdef CONFIG_TRACER_MAX_TRACE if (iter->snapshot && iter->tr->current_trace->use_max_tr) { ret = -EBUSY; goto out; } #endif if (splice_grow_spd(pipe, &spd)) { ret = -ENOMEM; goto out; } if (*ppos & (PAGE_SIZE - 1)) { ret = -EINVAL; Loading Loading @@ -4666,7 +4736,9 @@ tracing_buffers_splice_read(struct file *file, loff_t *ppos, ret = -EAGAIN; goto out; } mutex_unlock(&trace_types_lock); iter->trace->wait_pipe(iter); mutex_lock(&trace_types_lock); if (signal_pending(current)) { ret = -EINTR; goto out; Loading @@ -4677,6 +4749,8 @@ tracing_buffers_splice_read(struct file *file, loff_t *ppos, ret = splice_to_pipe(pipe, &spd); splice_shrink_spd(&spd); out: mutex_unlock(&trace_types_lock); return ret; } Loading Loading @@ -4880,6 +4954,9 @@ tracing_init_debugfs_percpu(struct trace_array *tr, long cpu) #ifdef CONFIG_TRACER_SNAPSHOT trace_create_file("snapshot", 0644, d_cpu, (void *)&data->trace_cpu, &snapshot_fops); trace_create_file("snapshot_raw", 0444, d_cpu, (void *)&data->trace_cpu, &snapshot_raw_fops); #endif } Loading Loading
kernel/trace/trace.c +95 −18 Original line number Diff line number Diff line Loading @@ -4206,6 +4206,12 @@ static int tracing_clock_open(struct inode *inode, struct file *file) return single_open(file, tracing_clock_show, inode->i_private); } struct ftrace_buffer_info { struct trace_iterator iter; void *spare; unsigned int read; }; #ifdef CONFIG_TRACER_SNAPSHOT static int tracing_snapshot_open(struct inode *inode, struct file *file) { Loading Loading @@ -4336,6 +4342,35 @@ static int tracing_snapshot_release(struct inode *inode, struct file *file) return 0; } static int tracing_buffers_open(struct inode *inode, struct file *filp); static ssize_t tracing_buffers_read(struct file *filp, char __user *ubuf, size_t count, loff_t *ppos); static int tracing_buffers_release(struct inode *inode, struct file *file); static ssize_t tracing_buffers_splice_read(struct file *file, loff_t *ppos, struct pipe_inode_info *pipe, size_t len, unsigned int flags); static int snapshot_raw_open(struct inode *inode, struct file *filp) { struct ftrace_buffer_info *info; int ret; ret = tracing_buffers_open(inode, filp); if (ret < 0) return ret; info = filp->private_data; if (info->iter.trace->use_max_tr) { tracing_buffers_release(inode, filp); return -EBUSY; } info->iter.snapshot = true; info->iter.trace_buffer = &info->iter.tr->max_buffer; return ret; } #endif /* CONFIG_TRACER_SNAPSHOT */ Loading Loading @@ -4402,14 +4437,17 @@ static const struct file_operations snapshot_fops = { .llseek = tracing_seek, .release = tracing_snapshot_release, }; #endif /* CONFIG_TRACER_SNAPSHOT */ struct ftrace_buffer_info { struct trace_iterator iter; void *spare; unsigned int read; static const struct file_operations snapshot_raw_fops = { .open = snapshot_raw_open, .read = tracing_buffers_read, .release = tracing_buffers_release, .splice_read = tracing_buffers_splice_read, .llseek = no_llseek, }; #endif /* CONFIG_TRACER_SNAPSHOT */ static int tracing_buffers_open(struct inode *inode, struct file *filp) { struct trace_cpu *tc = inode->i_private; Loading Loading @@ -4452,16 +4490,26 @@ tracing_buffers_read(struct file *filp, char __user *ubuf, struct ftrace_buffer_info *info = filp->private_data; struct trace_iterator *iter = &info->iter; ssize_t ret; size_t size; ssize_t size; if (!count) return 0; mutex_lock(&trace_types_lock); #ifdef CONFIG_TRACER_MAX_TRACE if (iter->snapshot && iter->tr->current_trace->use_max_tr) { size = -EBUSY; goto out_unlock; } #endif if (!info->spare) info->spare = ring_buffer_alloc_read_page(iter->trace_buffer->buffer, iter->cpu_file); size = -ENOMEM; if (!info->spare) return -ENOMEM; goto out_unlock; /* Do we have previous read data to read? */ if (info->read < PAGE_SIZE) Loading @@ -4477,31 +4525,42 @@ tracing_buffers_read(struct file *filp, char __user *ubuf, if (ret < 0) { if (trace_empty(iter)) { if ((filp->f_flags & O_NONBLOCK)) return -EAGAIN; if ((filp->f_flags & O_NONBLOCK)) { size = -EAGAIN; goto out_unlock; } mutex_unlock(&trace_types_lock); iter->trace->wait_pipe(iter); if (signal_pending(current)) return -EINTR; mutex_lock(&trace_types_lock); if (signal_pending(current)) { size = -EINTR; goto out_unlock; } goto again; } return 0; size = 0; goto out_unlock; } info->read = 0; read: size = PAGE_SIZE - info->read; if (size > count) size = count; ret = copy_to_user(ubuf, info->spare + info->read, size); if (ret == size) return -EFAULT; if (ret == size) { size = -EFAULT; goto out_unlock; } size -= ret; *ppos += size; info->read += size; out_unlock: mutex_unlock(&trace_types_lock); return size; } Loading Loading @@ -4591,10 +4650,21 @@ tracing_buffers_splice_read(struct file *file, loff_t *ppos, }; struct buffer_ref *ref; int entries, size, i; size_t ret; ssize_t ret; if (splice_grow_spd(pipe, &spd)) return -ENOMEM; mutex_lock(&trace_types_lock); #ifdef CONFIG_TRACER_MAX_TRACE if (iter->snapshot && iter->tr->current_trace->use_max_tr) { ret = -EBUSY; goto out; } #endif if (splice_grow_spd(pipe, &spd)) { ret = -ENOMEM; goto out; } if (*ppos & (PAGE_SIZE - 1)) { ret = -EINVAL; Loading Loading @@ -4666,7 +4736,9 @@ tracing_buffers_splice_read(struct file *file, loff_t *ppos, ret = -EAGAIN; goto out; } mutex_unlock(&trace_types_lock); iter->trace->wait_pipe(iter); mutex_lock(&trace_types_lock); if (signal_pending(current)) { ret = -EINTR; goto out; Loading @@ -4677,6 +4749,8 @@ tracing_buffers_splice_read(struct file *file, loff_t *ppos, ret = splice_to_pipe(pipe, &spd); splice_shrink_spd(&spd); out: mutex_unlock(&trace_types_lock); return ret; } Loading Loading @@ -4880,6 +4954,9 @@ tracing_init_debugfs_percpu(struct trace_array *tr, long cpu) #ifdef CONFIG_TRACER_SNAPSHOT trace_create_file("snapshot", 0644, d_cpu, (void *)&data->trace_cpu, &snapshot_fops); trace_create_file("snapshot_raw", 0444, d_cpu, (void *)&data->trace_cpu, &snapshot_raw_fops); #endif } Loading