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.c35
1 files changed, 19 insertions, 16 deletions
diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c
index 6c24755655c7..ca1ee656d6d8 100644
--- a/kernel/trace/trace.c
+++ b/kernel/trace/trace.c
@@ -496,8 +496,10 @@ int trace_pid_write(struct trace_pid_list *filtered_pids,
496 * not modified. 496 * not modified.
497 */ 497 */
498 pid_list = kmalloc(sizeof(*pid_list), GFP_KERNEL); 498 pid_list = kmalloc(sizeof(*pid_list), GFP_KERNEL);
499 if (!pid_list) 499 if (!pid_list) {
500 trace_parser_put(&parser);
500 return -ENOMEM; 501 return -ENOMEM;
502 }
501 503
502 pid_list->pid_max = READ_ONCE(pid_max); 504 pid_list->pid_max = READ_ONCE(pid_max);
503 505
@@ -507,6 +509,7 @@ int trace_pid_write(struct trace_pid_list *filtered_pids,
507 509
508 pid_list->pids = vzalloc((pid_list->pid_max + 7) >> 3); 510 pid_list->pids = vzalloc((pid_list->pid_max + 7) >> 3);
509 if (!pid_list->pids) { 511 if (!pid_list->pids) {
512 trace_parser_put(&parser);
510 kfree(pid_list); 513 kfree(pid_list);
511 return -ENOMEM; 514 return -ENOMEM;
512 } 515 }
@@ -7025,19 +7028,23 @@ struct buffer_ref {
7025 struct ring_buffer *buffer; 7028 struct ring_buffer *buffer;
7026 void *page; 7029 void *page;
7027 int cpu; 7030 int cpu;
7028 int ref; 7031 refcount_t refcount;
7029}; 7032};
7030 7033
7034static void buffer_ref_release(struct buffer_ref *ref)
7035{
7036 if (!refcount_dec_and_test(&ref->refcount))
7037 return;
7038 ring_buffer_free_read_page(ref->buffer, ref->cpu, ref->page);
7039 kfree(ref);
7040}
7041
7031static void buffer_pipe_buf_release(struct pipe_inode_info *pipe, 7042static void buffer_pipe_buf_release(struct pipe_inode_info *pipe,
7032 struct pipe_buffer *buf) 7043 struct pipe_buffer *buf)
7033{ 7044{
7034 struct buffer_ref *ref = (struct buffer_ref *)buf->private; 7045 struct buffer_ref *ref = (struct buffer_ref *)buf->private;
7035 7046
7036 if (--ref->ref) 7047 buffer_ref_release(ref);
7037 return;
7038
7039 ring_buffer_free_read_page(ref->buffer, ref->cpu, ref->page);
7040 kfree(ref);
7041 buf->private = 0; 7048 buf->private = 0;
7042} 7049}
7043 7050
@@ -7046,10 +7053,10 @@ static bool buffer_pipe_buf_get(struct pipe_inode_info *pipe,
7046{ 7053{
7047 struct buffer_ref *ref = (struct buffer_ref *)buf->private; 7054 struct buffer_ref *ref = (struct buffer_ref *)buf->private;
7048 7055
7049 if (ref->ref > INT_MAX/2) 7056 if (refcount_read(&ref->refcount) > INT_MAX/2)
7050 return false; 7057 return false;
7051 7058
7052 ref->ref++; 7059 refcount_inc(&ref->refcount);
7053 return true; 7060 return true;
7054} 7061}
7055 7062
@@ -7057,7 +7064,7 @@ static bool buffer_pipe_buf_get(struct pipe_inode_info *pipe,
7057static const struct pipe_buf_operations buffer_pipe_buf_ops = { 7064static const struct pipe_buf_operations buffer_pipe_buf_ops = {
7058 .confirm = generic_pipe_buf_confirm, 7065 .confirm = generic_pipe_buf_confirm,
7059 .release = buffer_pipe_buf_release, 7066 .release = buffer_pipe_buf_release,
7060 .steal = generic_pipe_buf_steal, 7067 .steal = generic_pipe_buf_nosteal,
7061 .get = buffer_pipe_buf_get, 7068 .get = buffer_pipe_buf_get,
7062}; 7069};
7063 7070
@@ -7070,11 +7077,7 @@ static void buffer_spd_release(struct splice_pipe_desc *spd, unsigned int i)
7070 struct buffer_ref *ref = 7077 struct buffer_ref *ref =
7071 (struct buffer_ref *)spd->partial[i].private; 7078 (struct buffer_ref *)spd->partial[i].private;
7072 7079
7073 if (--ref->ref) 7080 buffer_ref_release(ref);
7074 return;
7075
7076 ring_buffer_free_read_page(ref->buffer, ref->cpu, ref->page);
7077 kfree(ref);
7078 spd->partial[i].private = 0; 7081 spd->partial[i].private = 0;
7079} 7082}
7080 7083
@@ -7129,7 +7132,7 @@ tracing_buffers_splice_read(struct file *file, loff_t *ppos,
7129 break; 7132 break;
7130 } 7133 }
7131 7134
7132 ref->ref = 1; 7135 refcount_set(&ref->refcount, 1);
7133 ref->buffer = iter->trace_buffer->buffer; 7136 ref->buffer = iter->trace_buffer->buffer;
7134 ref->page = ring_buffer_alloc_read_page(ref->buffer, iter->cpu_file); 7137 ref->page = ring_buffer_alloc_read_page(ref->buffer, iter->cpu_file);
7135 if (IS_ERR(ref->page)) { 7138 if (IS_ERR(ref->page)) {