Skip to contentSkip to conversation

Patch "ring-buffer: Do no reuse reader page if still in use" has been added to the 4.14-stable tree

PATCH [email protected] 1 participant 1 message Dec 30, 2017

Subsystems (3)
lore
Share & tools
lore

[email protected]

author maintainer Applied
#0 lore raw

This is a note to let you know that I've just added the patch titled

ring-buffer: Do no reuse reader page if still in use

to the 4.14-stable tree which can be found at:
http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary

The filename of the patch is:
ring-buffer-do-no-reuse-reader-page-if-still-in-use.patch
and it can be found in the queue-4.14 subdirectory.

If you, or anyone else, feels it should not be added to the stable tree, please let <[email protected]> know about it.

Quoted 1 line

From ae415fa4c5248a8cf4faabd5a3c20576cb1ad607 Mon Sep 17 00:00:00 2001

From: "Steven Rostedt (VMware)" <[email protected]>
Date: Fri, 22 Dec 2017 21:19:29 -0500
Subject: ring-buffer: Do no reuse reader page if still in use

From: Steven Rostedt (VMware) <[email protected]>

commit ae415fa4c5248a8cf4faabd5a3c20576cb1ad607 upstream.

To free the reader page that is allocated with ring_buffer_alloc_read_page(), ring_buffer_free_read_page() must be called. For faster performance, this page can be reused by the ring buffer to avoid having to free and allocate new pages.

The issue arises when the page is used with a splice pipe into the networking code. The networking code may up the page counter for the page, and keep it active while sending it is queued to go to the network. The incrementing of the page ref does not prevent it from being reused in the ring buffer, and this can cause the page that is being sent out to the network to be modified before it is sent by reading new data.

Add a check to the page ref counter, and only reuse the page if it is not being used anywhere else.

Fixes 73a757e63114d ("ring-buffer: Return reader page back into existing ring buffer")
---
 kernel/trace/ring_buffer.c |    6 ++++++
 1 file changed, 6 insertions(+)
kernel/trace/ring_buffer.c +6 -0
@@ -4443,8 +4443,13 @@ void ring_buffer_free_read_page(struct r
 {
 	struct ring_buffer_per_cpu *cpu_buffer = buffer->buffers[cpu];
 	struct buffer_data_page *bpage = data;
+	struct page *page = virt_to_page(bpage);
 	unsigned long flags;
 
+	/* If the page is still in use someplace else, we can't reuse it */
+	if (page_ref_count(page) > 1)
+		goto out;
+
 	local_irq_save(flags);
 	arch_spin_lock(&cpu_buffer->lock);
 
@@ -4456,6 +4461,7 @@ void ring_buffer_free_read_page(struct r
 	arch_spin_unlock(&cpu_buffer->lock);
 	local_irq_restore(flags);
 
+ out:
 	free_page((unsigned long)bpage);
 }
 EXPORT_SYMBOL_GPL(ring_buffer_free_read_page);

Patches currently in stable-queue which might be from [email protected] are

queue-4.14/ring-buffer-do-no-reuse-reader-page-if-still-in-use.patch queue-4.14/tracing-fix-crash-when-it-fails-to-alloc-ring-buffer.patch queue-4.14/tracing-remove-extra-zeroing-out-of-the-ring-buffer-page.patch queue-4.14/ring-buffer-mask-out-the-info-bits-when-returning-buffer-page-length.patch queue-4.14/tracing-fix-possible-double-free-on-failure-of-allocating-trace-buffer.patch