There tracing fixes:
- Use "nosteal" for ring buffer splice pages - Memory leak fix in error path of trace_pid_write() - Fix preempt_enable_no_resched() (use preempt_enable()) in ring buffer code -----BEGIN PGP SIGNATURE----- iIoEABYIADIWIQRRSw7ePDh/lE+zeZMp5XQQmuv6qgUCXMMoghQccm9zdGVkdEBn b29kbWlzLm9yZwAKCRAp5XQQmuv6qmB1AQDfpVxYxcmxibBBAM6fZyILYpKqDWmy ut6gHZ+GHhQT4AEAwSRsC6V4yO3d5dJFpkcQXUj1v+Ip9XU+dv//s8O6tAI= =LsG/ -----END PGP SIGNATURE----- Merge tag 'trace-v5.1-rc6' of git://git.kernel.org/pub/scm/linux/kernel/git/rostedt/linux-trace Pull tracing fixes from Steven Rostedt: "Three tracing fixes: - Use "nosteal" for ring buffer splice pages - Memory leak fix in error path of trace_pid_write() - Fix preempt_enable_no_resched() (use preempt_enable()) in ring buffer code" * tag 'trace-v5.1-rc6' of git://git.kernel.org/pub/scm/linux/kernel/git/rostedt/linux-trace: trace: Fix preempt_enable_no_resched() abuse tracing: Fix a memory leak by early error exit in trace_pid_write() tracing: Fix buffer_ref pipe ops
This commit is contained in:
commit
e9e1a2e7b4
|
@ -330,8 +330,8 @@ const struct pipe_buf_operations default_pipe_buf_ops = {
|
|||
.get = generic_pipe_buf_get,
|
||||
};
|
||||
|
||||
static int generic_pipe_buf_nosteal(struct pipe_inode_info *pipe,
|
||||
struct pipe_buffer *buf)
|
||||
int generic_pipe_buf_nosteal(struct pipe_inode_info *pipe,
|
||||
struct pipe_buffer *buf)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
|
|
@ -176,6 +176,7 @@ void free_pipe_info(struct pipe_inode_info *);
|
|||
bool generic_pipe_buf_get(struct pipe_inode_info *, struct pipe_buffer *);
|
||||
int generic_pipe_buf_confirm(struct pipe_inode_info *, struct pipe_buffer *);
|
||||
int generic_pipe_buf_steal(struct pipe_inode_info *, struct pipe_buffer *);
|
||||
int generic_pipe_buf_nosteal(struct pipe_inode_info *, struct pipe_buffer *);
|
||||
void generic_pipe_buf_release(struct pipe_inode_info *, struct pipe_buffer *);
|
||||
void pipe_buf_mark_unmergeable(struct pipe_buffer *buf);
|
||||
|
||||
|
|
|
@ -762,7 +762,7 @@ u64 ring_buffer_time_stamp(struct ring_buffer *buffer, int cpu)
|
|||
|
||||
preempt_disable_notrace();
|
||||
time = rb_time_stamp(buffer);
|
||||
preempt_enable_no_resched_notrace();
|
||||
preempt_enable_notrace();
|
||||
|
||||
return time;
|
||||
}
|
||||
|
|
|
@ -496,8 +496,10 @@ int trace_pid_write(struct trace_pid_list *filtered_pids,
|
|||
* not modified.
|
||||
*/
|
||||
pid_list = kmalloc(sizeof(*pid_list), GFP_KERNEL);
|
||||
if (!pid_list)
|
||||
if (!pid_list) {
|
||||
trace_parser_put(&parser);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
pid_list->pid_max = READ_ONCE(pid_max);
|
||||
|
||||
|
@ -507,6 +509,7 @@ int trace_pid_write(struct trace_pid_list *filtered_pids,
|
|||
|
||||
pid_list->pids = vzalloc((pid_list->pid_max + 7) >> 3);
|
||||
if (!pid_list->pids) {
|
||||
trace_parser_put(&parser);
|
||||
kfree(pid_list);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
@ -7025,19 +7028,23 @@ struct buffer_ref {
|
|||
struct ring_buffer *buffer;
|
||||
void *page;
|
||||
int cpu;
|
||||
int ref;
|
||||
refcount_t refcount;
|
||||
};
|
||||
|
||||
static void buffer_ref_release(struct buffer_ref *ref)
|
||||
{
|
||||
if (!refcount_dec_and_test(&ref->refcount))
|
||||
return;
|
||||
ring_buffer_free_read_page(ref->buffer, ref->cpu, ref->page);
|
||||
kfree(ref);
|
||||
}
|
||||
|
||||
static void buffer_pipe_buf_release(struct pipe_inode_info *pipe,
|
||||
struct pipe_buffer *buf)
|
||||
{
|
||||
struct buffer_ref *ref = (struct buffer_ref *)buf->private;
|
||||
|
||||
if (--ref->ref)
|
||||
return;
|
||||
|
||||
ring_buffer_free_read_page(ref->buffer, ref->cpu, ref->page);
|
||||
kfree(ref);
|
||||
buffer_ref_release(ref);
|
||||
buf->private = 0;
|
||||
}
|
||||
|
||||
|
@ -7046,10 +7053,10 @@ static bool buffer_pipe_buf_get(struct pipe_inode_info *pipe,
|
|||
{
|
||||
struct buffer_ref *ref = (struct buffer_ref *)buf->private;
|
||||
|
||||
if (ref->ref > INT_MAX/2)
|
||||
if (refcount_read(&ref->refcount) > INT_MAX/2)
|
||||
return false;
|
||||
|
||||
ref->ref++;
|
||||
refcount_inc(&ref->refcount);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -7057,7 +7064,7 @@ static bool buffer_pipe_buf_get(struct pipe_inode_info *pipe,
|
|||
static const struct pipe_buf_operations buffer_pipe_buf_ops = {
|
||||
.confirm = generic_pipe_buf_confirm,
|
||||
.release = buffer_pipe_buf_release,
|
||||
.steal = generic_pipe_buf_steal,
|
||||
.steal = generic_pipe_buf_nosteal,
|
||||
.get = buffer_pipe_buf_get,
|
||||
};
|
||||
|
||||
|
@ -7070,11 +7077,7 @@ static void buffer_spd_release(struct splice_pipe_desc *spd, unsigned int i)
|
|||
struct buffer_ref *ref =
|
||||
(struct buffer_ref *)spd->partial[i].private;
|
||||
|
||||
if (--ref->ref)
|
||||
return;
|
||||
|
||||
ring_buffer_free_read_page(ref->buffer, ref->cpu, ref->page);
|
||||
kfree(ref);
|
||||
buffer_ref_release(ref);
|
||||
spd->partial[i].private = 0;
|
||||
}
|
||||
|
||||
|
@ -7129,7 +7132,7 @@ tracing_buffers_splice_read(struct file *file, loff_t *ppos,
|
|||
break;
|
||||
}
|
||||
|
||||
ref->ref = 1;
|
||||
refcount_set(&ref->refcount, 1);
|
||||
ref->buffer = iter->trace_buffer->buffer;
|
||||
ref->page = ring_buffer_alloc_read_page(ref->buffer, iter->cpu_file);
|
||||
if (IS_ERR(ref->page)) {
|
||||
|
|
Loading…
Reference in New Issue