diff options
| -rw-r--r-- | fs/splice.c | 4 | ||||
| -rw-r--r-- | include/linux/pipe_fs_i.h | 1 | ||||
| -rw-r--r-- | kernel/trace/trace.c | 28 |
3 files changed, 17 insertions, 16 deletions
diff --git a/fs/splice.c b/fs/splice.c index 3ee7e82df48f..e75807380caa 100644 --- a/fs/splice.c +++ b/fs/splice.c | |||
| @@ -330,8 +330,8 @@ const struct pipe_buf_operations default_pipe_buf_ops = { | |||
| 330 | .get = generic_pipe_buf_get, | 330 | .get = generic_pipe_buf_get, |
| 331 | }; | 331 | }; |
| 332 | 332 | ||
| 333 | static int generic_pipe_buf_nosteal(struct pipe_inode_info *pipe, | 333 | int generic_pipe_buf_nosteal(struct pipe_inode_info *pipe, |
| 334 | struct pipe_buffer *buf) | 334 | struct pipe_buffer *buf) |
| 335 | { | 335 | { |
| 336 | return 1; | 336 | return 1; |
| 337 | } | 337 | } |
diff --git a/include/linux/pipe_fs_i.h b/include/linux/pipe_fs_i.h index 787d224ff43e..a830e9a00eb9 100644 --- a/include/linux/pipe_fs_i.h +++ b/include/linux/pipe_fs_i.h | |||
| @@ -174,6 +174,7 @@ void free_pipe_info(struct pipe_inode_info *); | |||
| 174 | void generic_pipe_buf_get(struct pipe_inode_info *, struct pipe_buffer *); | 174 | void generic_pipe_buf_get(struct pipe_inode_info *, struct pipe_buffer *); |
| 175 | int generic_pipe_buf_confirm(struct pipe_inode_info *, struct pipe_buffer *); | 175 | int generic_pipe_buf_confirm(struct pipe_inode_info *, struct pipe_buffer *); |
| 176 | int generic_pipe_buf_steal(struct pipe_inode_info *, struct pipe_buffer *); | 176 | int generic_pipe_buf_steal(struct pipe_inode_info *, struct pipe_buffer *); |
| 177 | int generic_pipe_buf_nosteal(struct pipe_inode_info *, struct pipe_buffer *); | ||
| 177 | void generic_pipe_buf_release(struct pipe_inode_info *, struct pipe_buffer *); | 178 | void generic_pipe_buf_release(struct pipe_inode_info *, struct pipe_buffer *); |
| 178 | void pipe_buf_mark_unmergeable(struct pipe_buffer *buf); | 179 | void pipe_buf_mark_unmergeable(struct pipe_buffer *buf); |
| 179 | 180 | ||
diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c index 21153e64bf1c..0cfa13a60086 100644 --- a/kernel/trace/trace.c +++ b/kernel/trace/trace.c | |||
| @@ -7025,19 +7025,23 @@ struct buffer_ref { | |||
| 7025 | struct ring_buffer *buffer; | 7025 | struct ring_buffer *buffer; |
| 7026 | void *page; | 7026 | void *page; |
| 7027 | int cpu; | 7027 | int cpu; |
| 7028 | int ref; | 7028 | refcount_t refcount; |
| 7029 | }; | 7029 | }; |
| 7030 | 7030 | ||
| 7031 | static void buffer_ref_release(struct buffer_ref *ref) | ||
| 7032 | { | ||
| 7033 | if (!refcount_dec_and_test(&ref->refcount)) | ||
| 7034 | return; | ||
| 7035 | ring_buffer_free_read_page(ref->buffer, ref->cpu, ref->page); | ||
| 7036 | kfree(ref); | ||
| 7037 | } | ||
| 7038 | |||
| 7031 | static void buffer_pipe_buf_release(struct pipe_inode_info *pipe, | 7039 | static void buffer_pipe_buf_release(struct pipe_inode_info *pipe, |
| 7032 | struct pipe_buffer *buf) | 7040 | struct pipe_buffer *buf) |
| 7033 | { | 7041 | { |
| 7034 | struct buffer_ref *ref = (struct buffer_ref *)buf->private; | 7042 | struct buffer_ref *ref = (struct buffer_ref *)buf->private; |
| 7035 | 7043 | ||
| 7036 | if (--ref->ref) | 7044 | 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; | 7045 | buf->private = 0; |
| 7042 | } | 7046 | } |
| 7043 | 7047 | ||
| @@ -7046,14 +7050,14 @@ static void buffer_pipe_buf_get(struct pipe_inode_info *pipe, | |||
| 7046 | { | 7050 | { |
| 7047 | struct buffer_ref *ref = (struct buffer_ref *)buf->private; | 7051 | struct buffer_ref *ref = (struct buffer_ref *)buf->private; |
| 7048 | 7052 | ||
| 7049 | ref->ref++; | 7053 | refcount_inc(&ref->refcount); |
| 7050 | } | 7054 | } |
| 7051 | 7055 | ||
| 7052 | /* Pipe buffer operations for a buffer. */ | 7056 | /* Pipe buffer operations for a buffer. */ |
| 7053 | static const struct pipe_buf_operations buffer_pipe_buf_ops = { | 7057 | static const struct pipe_buf_operations buffer_pipe_buf_ops = { |
| 7054 | .confirm = generic_pipe_buf_confirm, | 7058 | .confirm = generic_pipe_buf_confirm, |
| 7055 | .release = buffer_pipe_buf_release, | 7059 | .release = buffer_pipe_buf_release, |
| 7056 | .steal = generic_pipe_buf_steal, | 7060 | .steal = generic_pipe_buf_nosteal, |
| 7057 | .get = buffer_pipe_buf_get, | 7061 | .get = buffer_pipe_buf_get, |
| 7058 | }; | 7062 | }; |
| 7059 | 7063 | ||
| @@ -7066,11 +7070,7 @@ static void buffer_spd_release(struct splice_pipe_desc *spd, unsigned int i) | |||
| 7066 | struct buffer_ref *ref = | 7070 | struct buffer_ref *ref = |
| 7067 | (struct buffer_ref *)spd->partial[i].private; | 7071 | (struct buffer_ref *)spd->partial[i].private; |
| 7068 | 7072 | ||
| 7069 | if (--ref->ref) | 7073 | buffer_ref_release(ref); |
| 7070 | return; | ||
| 7071 | |||
| 7072 | ring_buffer_free_read_page(ref->buffer, ref->cpu, ref->page); | ||
| 7073 | kfree(ref); | ||
| 7074 | spd->partial[i].private = 0; | 7074 | spd->partial[i].private = 0; |
| 7075 | } | 7075 | } |
| 7076 | 7076 | ||
| @@ -7125,7 +7125,7 @@ tracing_buffers_splice_read(struct file *file, loff_t *ppos, | |||
| 7125 | break; | 7125 | break; |
| 7126 | } | 7126 | } |
| 7127 | 7127 | ||
| 7128 | ref->ref = 1; | 7128 | refcount_set(&ref->refcount, 1); |
| 7129 | ref->buffer = iter->trace_buffer->buffer; | 7129 | ref->buffer = iter->trace_buffer->buffer; |
| 7130 | ref->page = ring_buffer_alloc_read_page(ref->buffer, iter->cpu_file); | 7130 | ref->page = ring_buffer_alloc_read_page(ref->buffer, iter->cpu_file); |
| 7131 | if (IS_ERR(ref->page)) { | 7131 | if (IS_ERR(ref->page)) { |
