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 for Android: free password hash cracker in your pocket
[<prev] [next>] [day] [month] [year] [list]
Date: Thu, 20 Jun 2024 17:00:28 +0800
From: Jinjie Ruan <ruanjinjie@...wei.com>
To: <linux@...linux.org.uk>, <arnd@...db.de>, <afd@...com>,
	<akpm@...ux-foundation.org>, <rmk+kernel@...linux.org.uk>,
	<linus.walleij@...aro.org>, <eric.devolder@...cle.com>, <robh@...nel.org>,
	<vincent.whitchurch@...s.com>, <bhe@...hat.com>, <nico@...xnic.net>,
	<ardb@...nel.org>, <linux-arm-kernel@...ts.infradead.org>,
	<linux-kernel@...r.kernel.org>, <linux-arch@...r.kernel.org>
CC: <ruanjinjie@...wei.com>
Subject: [PATCH] ARM: support PREEMPT_DYNAMIC

Enable support for PREEMPT_DYNAMIC on arm32, allowing the preemption model
to be chosen at boot time.

Similar to arm64, arm32 does not yet use the generic entry code, we must
define our own `sk_dynamic_irqentry_exit_cond_resched`, which will be
enabled/disabled by the common code in kernel/sched/core.c.

And arm32 use generic preempt.h, so declare
`sk_dynamic_irqentry_exit_cond_resched` if the arch do not use generic
entry. Other architectures which use generic preempt.h but not use generic
entry can benefit from it.

Test ok with the below cmdline parameters on Qemu versatilepb board:
	`preempt=none`
	`preempt=voluntary`
	`preempt=full`

Update preempt mode with debugfs interface on above Qemu board is also
tested ok:
	# cd /sys/kernel/debug/sched
	# echo none > preempt
	# echo voluntary > preempt
	# echo full > preempt

Signed-off-by: Jinjie Ruan <ruanjinjie@...wei.com>
---
 arch/arm/Kconfig                 |  1 +
 arch/arm/include/asm/exception.h |  2 ++
 arch/arm/kernel/Makefile         |  2 +-
 arch/arm/kernel/common.c         | 13 +++++++++++++
 arch/arm/kernel/entry-armv.S     |  7 ++++++-
 include/asm-generic/preempt.h    |  5 +++++
 6 files changed, 28 insertions(+), 2 deletions(-)
 create mode 100644 arch/arm/kernel/common.c

diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 036381c5d42f..843f320dde7f 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -124,6 +124,7 @@ config ARM
 	select HAVE_PERF_EVENTS
 	select HAVE_PERF_REGS
 	select HAVE_PERF_USER_STACK_DUMP
+	select HAVE_PREEMPT_DYNAMIC_KEY
 	select MMU_GATHER_RCU_TABLE_FREE if SMP && ARM_LPAE
 	select HAVE_REGS_AND_STACK_ACCESS_API
 	select HAVE_RSEQ
diff --git a/arch/arm/include/asm/exception.h b/arch/arm/include/asm/exception.h
index 3c82975d46db..ac96b76b394e 100644
--- a/arch/arm/include/asm/exception.h
+++ b/arch/arm/include/asm/exception.h
@@ -12,4 +12,6 @@
 
 #define __exception_irq_entry	__irq_entry
 
+bool need_irq_preemption(void);
+
 #endif /* __ASM_ARM_EXCEPTION_H */
diff --git a/arch/arm/kernel/Makefile b/arch/arm/kernel/Makefile
index 89a77e3f51d2..58acd62dc5e9 100644
--- a/arch/arm/kernel/Makefile
+++ b/arch/arm/kernel/Makefile
@@ -17,7 +17,7 @@ CFLAGS_REMOVE_return_address.o = -pg
 
 # Object file lists.
 
-obj-y		:= elf.o entry-common.o irq.o opcodes.o \
+obj-y		:= common.o elf.o entry-common.o irq.o opcodes.o \
 		   process.o ptrace.o reboot.o io.o \
 		   setup.o signal.o sigreturn_codes.o \
 		   stacktrace.o sys_arm.o time.o traps.o
diff --git a/arch/arm/kernel/common.c b/arch/arm/kernel/common.c
new file mode 100644
index 000000000000..52b0abcae07e
--- /dev/null
+++ b/arch/arm/kernel/common.c
@@ -0,0 +1,13 @@
+// SPDX-License-Identifier: GPL-2.0
+
+#include <linux/jump_label.h>
+#include <asm/exception.h>
+
+#ifdef CONFIG_PREEMPT_DYNAMIC
+DEFINE_STATIC_KEY_TRUE(sk_dynamic_irqentry_exit_cond_resched);
+
+bool need_irq_preemption(void)
+{
+	return static_branch_unlikely(&sk_dynamic_irqentry_exit_cond_resched);
+}
+#endif
diff --git a/arch/arm/kernel/entry-armv.S b/arch/arm/kernel/entry-armv.S
index 6150a716828c..571e86433833 100644
--- a/arch/arm/kernel/entry-armv.S
+++ b/arch/arm/kernel/entry-armv.S
@@ -221,6 +221,11 @@ __irq_svc:
 	irq_handler from_user=0
 
 #ifdef CONFIG_PREEMPTION
+#ifdef CONFIG_PREEMPT_DYNAMIC
+	bl	need_irq_preemption
+	cmp	r0, #0
+	beq	2f
+#endif
 	ldr	r8, [tsk, #TI_PREEMPT]		@ get preempt count
 	ldr	r0, [tsk, #TI_FLAGS]		@ get flags
 	teq	r8, #0				@ if preempt count != 0
@@ -228,7 +233,7 @@ __irq_svc:
 	tst	r0, #_TIF_NEED_RESCHED
 	blne	svc_preempt
 #endif
-
+2:
 	svc_exit r5, irq = 1			@ return from exception
  UNWIND(.fnend		)
 ENDPROC(__irq_svc)
diff --git a/include/asm-generic/preempt.h b/include/asm-generic/preempt.h
index 51f8f3881523..2db7a3e86303 100644
--- a/include/asm-generic/preempt.h
+++ b/include/asm-generic/preempt.h
@@ -2,6 +2,7 @@
 #ifndef __ASM_PREEMPT_H
 #define __ASM_PREEMPT_H
 
+#include <linux/jump_label.h>
 #include <linux/thread_info.h>
 
 #define PREEMPT_ENABLED	(0)
@@ -89,6 +90,10 @@ void dynamic_preempt_schedule_notrace(void);
 #define __preempt_schedule()		dynamic_preempt_schedule()
 #define __preempt_schedule_notrace()	dynamic_preempt_schedule_notrace()
 
+#ifndef CONFIG_GENERIC_ENTRY
+DECLARE_STATIC_KEY_TRUE(sk_dynamic_irqentry_exit_cond_resched);
+#endif
+
 #else /* !CONFIG_PREEMPT_DYNAMIC || !CONFIG_HAVE_PREEMPT_DYNAMIC_KEY*/
 
 #define __preempt_schedule() preempt_schedule()
-- 
2.34.1


Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ