lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [thread-next>] [day] [month] [year] [list]
Message-Id: <1399579402-27034-1-git-send-email-minyard@acm.org>
Date:	Thu,  8 May 2014 15:03:22 -0500
From:	minyard@....org
To:	linux-rt-users@...r.kernel.org, linux-kernel@...r.kernel.org
Cc:	Corey Minyard <cminyard@...sta.com>
Subject: [PATCH] ftrace: Simplify ring buffer resizing, make work with RT

From: Corey Minyard <cminyard@...sta.com>

ring_buffer_resize() would call rb_update_pages() with preempt
disabled.  It did this with preempt disabled, bu rb_update_pages
would eventually claim the zone semaphore, which is a mutex in PREEMPT_RT,
thus resulting in a "scheduling while atomic" BUG.

When doing this, all other CPUs except the running one did the operation
in a work queue.  So just do the current CPU operation in a work queue,
too.  This simplifies the code, gets rid of the need for preempt_disable(),
and solves the RT issue.

Signed-off-by: Corey Minyard <cminyard@...sta.com>
---
 kernel/trace/ring_buffer.c | 10 +---------
 1 file changed, 1 insertion(+), 9 deletions(-)

This isn't well tested, but fixes an obvious PREEMPT_RT problem and seems
like a good simplification.  You can see the PREEMPT_RT bug if you enable
ftrace and all the self tests; it will fail running selftests when it tries
to resize the buffers.

diff --git a/kernel/trace/ring_buffer.c b/kernel/trace/ring_buffer.c
index fc4da2d..972125e 100644
--- a/kernel/trace/ring_buffer.c
+++ b/kernel/trace/ring_buffer.c
@@ -1688,21 +1688,13 @@ int ring_buffer_resize(struct ring_buffer *buffer, unsigned long size,
 				continue;
 
 			/* The update must run on the CPU that is being updated. */
-			preempt_disable();
-			if (cpu == smp_processor_id() || !cpu_online(cpu)) {
+			if (!cpu_online(cpu)) {
 				rb_update_pages(cpu_buffer);
 				cpu_buffer->nr_pages_to_update = 0;
 			} else {
-				/*
-				 * Can not disable preemption for schedule_work_on()
-				 * on PREEMPT_RT.
-				 */
-				preempt_enable();
 				schedule_work_on(cpu,
 						&cpu_buffer->update_pages_work);
-				preempt_disable();
 			}
-			preempt_enable();
 		}
 
 		/* wait for all the updates to complete */
-- 
1.8.3.1

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@...r.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ