tracing: Minor fixes
Steven Rostedt
maintainercover tracing: Minor fixes
git://git.kernel.org/pub/scm/linux/kernel/git/rostedt/linux-trace.git
for-next
Head SHA1: 92fdd98cf8bdec4d6b0c510e2f073ac4fd059be8
Al Viro (1):
tracing: Fix buggered tee(2) on tracing_pipe
Steven Rostedt (Red Hat) (1):
tracing: Have trace buffer point back to trace_array
----
kernel/trace/trace.c | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-)
Steven Rostedt
maintainerPATCH 1/2 tracing: Have trace buffer point back to trace_array
From: "Steven Rostedt (Red Hat)" <[email protected]>
The trace buffer has a descriptor pointer that goes back to the trace array. But it was never assigned. Luckily, nothing uses it (yet), but it will in the future.
Although nothing currently uses this, if any of the new features get backported to older kernels, and because this is such a simple change, I'm marking it for stable too.
--- kernel/trace/trace.c | 2 ++ 1 file changed, 2 insertions(+)
kernel/trace/trace.c +2 -0
@@ -5914,6 +5914,8 @@ allocate_trace_buffer(struct trace_array *tr, struct trace_buffer *buf, int size rb_flags = trace_flags &TRACE_ITER_OVERWRITE ?RB_FL_OVERWRITE :0 ; + buf->tr = tr; + buf->buffer =ring_buffer_alloc (size, rb_flags);if (!buf->buffer)return -ENOMEM ;
Signature · 1 line
1.8.4.3
Steven Rostedt
maintainerPATCH 2/2 tracing: Fix buggered tee(2) on tracing_pipe
In reply to Steven RostedtFrom: Al Viro <[email protected]>
In kernel/trace/trace.c we have this:
static void tracing_pipe_buf_release(struct pipe_inode_info *pipe,
struct pipe_buffer *buf)
{
__free_page(buf->page);
}
static const struct pipe_buf_operations tracing_pipe_buf_ops = {
.can_merge = 0,
.map = generic_pipe_buf_map,
.unmap = generic_pipe_buf_unmap,
.confirm = generic_pipe_buf_confirm,
.release = tracing_pipe_buf_release,
.steal = generic_pipe_buf_steal,
.get = generic_pipe_buf_get,
};
with
void generic_pipe_buf_get(struct pipe_inode_info *pipe, struct pipe_buffer *buf)
{
page_cache_get(buf->page);
}and I don't see anything that would've prevented tee(2) called on the pipe that got stuff spliced into it from that sucker. ->ops->get() will be called, then buf gets copied into target pipe's ->bufs[] and eventually readers get to both copies of the buffer. With
get_page(page) look at that page __free_page(page) look at that page __free_page(page)
which is not a good thing, to put it mildly. AFAICS, that ought to use the normal generic_pipe_buf_release() (aka page_cache_release(buf->page)), shouldn't it?
[
SDR - As trace_pipe just allocates the page with alloc_page(GFP_KERNEL),
and doesn't do anything special with it (no LRU logic). The __free_page() should be fine, as it wont actually free a page with reference count. Maybe there's a chance to leak memory? Anyway, This change is at a minimum good for being symmetric with generic_pipe_buf_get, it is fine to add.
]
--- kernel/trace/trace.c | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-)
kernel/trace/trace.c +1 -7
@@ -4243,12 +4243,6 @@ out:return sret; } -static void tracing_pipe_buf_release (struct pipe_inode_info *pipe, -struct pipe_buffer *buf) -{ -__free_page (buf->page); -} -static void tracing_spd_release_pipe (struct splice_pipe_desc *spd,unsigned int idx) {
@@ -4260,7 +4254,7 @@ static const struct pipe_buf_operations tracing_pipe_buf_ops = { .map = generic_pipe_buf_map, .unmap = generic_pipe_buf_unmap, .confirm = generic_pipe_buf_confirm, - .release = tracing_pipe_buf_release, + .release = generic_pipe_buf_release, .steal = generic_pipe_buf_steal, .get = generic_pipe_buf_get, };
Signature · 1 line
1.8.4.3