diff options
Diffstat (limited to 'kernel/trace/trace.c')
-rw-r--r-- | kernel/trace/trace.c | 35 |
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 | ||
7034 | static 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 | |||
7031 | static void buffer_pipe_buf_release(struct pipe_inode_info *pipe, | 7042 | static 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, | |||
7057 | static const struct pipe_buf_operations buffer_pipe_buf_ops = { | 7064 | static 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)) { |