mirror of
https://github.com/torvalds/linux.git
synced 2024-12-25 20:32:22 +00:00
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,
|
.get = generic_pipe_buf_get,
|
||||||
};
|
};
|
||||||
|
|
||||||
static int generic_pipe_buf_nosteal(struct pipe_inode_info *pipe,
|
int generic_pipe_buf_nosteal(struct pipe_inode_info *pipe,
|
||||||
struct pipe_buffer *buf)
|
struct pipe_buffer *buf)
|
||||||
{
|
{
|
||||||
return 1;
|
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 *);
|
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_confirm(struct pipe_inode_info *, struct pipe_buffer *);
|
||||||
int generic_pipe_buf_steal(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 generic_pipe_buf_release(struct pipe_inode_info *, struct pipe_buffer *);
|
||||||
void pipe_buf_mark_unmergeable(struct pipe_buffer *buf);
|
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();
|
preempt_disable_notrace();
|
||||||
time = rb_time_stamp(buffer);
|
time = rb_time_stamp(buffer);
|
||||||
preempt_enable_no_resched_notrace();
|
preempt_enable_notrace();
|
||||||
|
|
||||||
return time;
|
return time;
|
||||||
}
|
}
|
||||||
|
@ -496,8 +496,10 @@ int trace_pid_write(struct trace_pid_list *filtered_pids,
|
|||||||
* not modified.
|
* not modified.
|
||||||
*/
|
*/
|
||||||
pid_list = kmalloc(sizeof(*pid_list), GFP_KERNEL);
|
pid_list = kmalloc(sizeof(*pid_list), GFP_KERNEL);
|
||||||
if (!pid_list)
|
if (!pid_list) {
|
||||||
|
trace_parser_put(&parser);
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
}
|
||||||
|
|
||||||
pid_list->pid_max = READ_ONCE(pid_max);
|
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);
|
pid_list->pids = vzalloc((pid_list->pid_max + 7) >> 3);
|
||||||
if (!pid_list->pids) {
|
if (!pid_list->pids) {
|
||||||
|
trace_parser_put(&parser);
|
||||||
kfree(pid_list);
|
kfree(pid_list);
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
}
|
}
|
||||||
@ -7025,19 +7028,23 @@ struct buffer_ref {
|
|||||||
struct ring_buffer *buffer;
|
struct ring_buffer *buffer;
|
||||||
void *page;
|
void *page;
|
||||||
int cpu;
|
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,
|
static void buffer_pipe_buf_release(struct pipe_inode_info *pipe,
|
||||||
struct pipe_buffer *buf)
|
struct pipe_buffer *buf)
|
||||||
{
|
{
|
||||||
struct buffer_ref *ref = (struct buffer_ref *)buf->private;
|
struct buffer_ref *ref = (struct buffer_ref *)buf->private;
|
||||||
|
|
||||||
if (--ref->ref)
|
buffer_ref_release(ref);
|
||||||
return;
|
|
||||||
|
|
||||||
ring_buffer_free_read_page(ref->buffer, ref->cpu, ref->page);
|
|
||||||
kfree(ref);
|
|
||||||
buf->private = 0;
|
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;
|
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;
|
return false;
|
||||||
|
|
||||||
ref->ref++;
|
refcount_inc(&ref->refcount);
|
||||||
return true;
|
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 = {
|
static const struct pipe_buf_operations buffer_pipe_buf_ops = {
|
||||||
.confirm = generic_pipe_buf_confirm,
|
.confirm = generic_pipe_buf_confirm,
|
||||||
.release = buffer_pipe_buf_release,
|
.release = buffer_pipe_buf_release,
|
||||||
.steal = generic_pipe_buf_steal,
|
.steal = generic_pipe_buf_nosteal,
|
||||||
.get = buffer_pipe_buf_get,
|
.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 *ref =
|
||||||
(struct buffer_ref *)spd->partial[i].private;
|
(struct buffer_ref *)spd->partial[i].private;
|
||||||
|
|
||||||
if (--ref->ref)
|
buffer_ref_release(ref);
|
||||||
return;
|
|
||||||
|
|
||||||
ring_buffer_free_read_page(ref->buffer, ref->cpu, ref->page);
|
|
||||||
kfree(ref);
|
|
||||||
spd->partial[i].private = 0;
|
spd->partial[i].private = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -7129,7 +7132,7 @@ tracing_buffers_splice_read(struct file *file, loff_t *ppos,
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
ref->ref = 1;
|
refcount_set(&ref->refcount, 1);
|
||||||
ref->buffer = iter->trace_buffer->buffer;
|
ref->buffer = iter->trace_buffer->buffer;
|
||||||
ref->page = ring_buffer_alloc_read_page(ref->buffer, iter->cpu_file);
|
ref->page = ring_buffer_alloc_read_page(ref->buffer, iter->cpu_file);
|
||||||
if (IS_ERR(ref->page)) {
|
if (IS_ERR(ref->page)) {
|
||||||
|
Loading…
Reference in New Issue
Block a user