From b229baa374dbb1bb47dccad2cc8887d9438ca3e7 Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Wed, 19 Jul 2023 00:11:44 +0300 Subject: kernel.h: split out COUNT_ARGS() and CONCATENATE() to args.h Patch series "kernel.h: Split out a couple of macros to args.h", v4. There are macros in kernel.h that can be used outside of that header. Split them to args.h and replace open coded variants. This patch (of 4): kernel.h is being used as a dump for all kinds of stuff for a long time. The COUNT_ARGS() and CONCATENATE() macros may be used in some places without need of the full kernel.h dependency train with it. Here is the attempt on cleaning it up by splitting out these macros(). While at it, include new header where it's being used. Link: https://lkml.kernel.org/r/20230718211147.18647-1-andriy.shevchenko@linux.intel.com Link: https://lkml.kernel.org/r/20230718211147.18647-2-andriy.shevchenko@linux.intel.com Signed-off-by: Andy Shevchenko Acked-by: Steven Rostedt (Google) Cc: Bjorn Helgaas Acked-by: Bjorn Helgaas [PCI] Cc: Brendan Higgins Cc: Daniel Latypov Cc: Dave Hansen Cc: David Gow Cc: "H. Peter Anvin" Cc: Ingo Molnar Cc: Lorenzo Pieralisi Cc: Mark Rutland Cc: Masami Hiramatsu (Google) Cc: Shuah Khan Cc: Sudeep Holla Cc: Thomas Gleixner Signed-off-by: Andrew Morton --- include/kunit/test.h | 1 + include/linux/args.h | 28 ++++++++++++++++++++++++++++ include/linux/kernel.h | 7 ------- include/linux/pci.h | 2 +- include/trace/bpf_probe.h | 2 ++ 5 files changed, 32 insertions(+), 8 deletions(-) create mode 100644 include/linux/args.h (limited to 'include') diff --git a/include/kunit/test.h b/include/kunit/test.h index 23120d50499e..107c81431634 100644 --- a/include/kunit/test.h +++ b/include/kunit/test.h @@ -12,6 +12,7 @@ #include #include +#include #include #include #include diff --git a/include/linux/args.h b/include/linux/args.h new file mode 100644 index 000000000000..8ff60a54eb7d --- /dev/null +++ b/include/linux/args.h @@ -0,0 +1,28 @@ +/* SPDX-License-Identifier: GPL-2.0 */ + +#ifndef _LINUX_ARGS_H +#define _LINUX_ARGS_H + +/* + * How do these macros work? + * + * In __COUNT_ARGS() _0 to _12 are just placeholders from the start + * in order to make sure _n is positioned over the correct number + * from 12 to 0 (depending on X, which is a variadic argument list). + * They serve no purpose other than occupying a position. Since each + * macro parameter must have a distinct identifier, those identifiers + * are as good as any. + * + * In COUNT_ARGS() we use actual integers, so __COUNT_ARGS() returns + * that as _n. + */ + +/* This counts to 12. Any more, it will return 13th argument. */ +#define __COUNT_ARGS(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _n, X...) _n +#define COUNT_ARGS(X...) __COUNT_ARGS(, ##X, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0) + +/* Concatenate two parameters, but allow them to be expanded beforehand. */ +#define __CONCAT(a, b) a ## b +#define CONCATENATE(a, b) __CONCAT(a, b) + +#endif /* _LINUX_ARGS_H */ diff --git a/include/linux/kernel.h b/include/linux/kernel.h index 0d91e0af0125..b9e76f717a7e 100644 --- a/include/linux/kernel.h +++ b/include/linux/kernel.h @@ -457,13 +457,6 @@ ftrace_vprintk(const char *fmt, va_list ap) static inline void ftrace_dump(enum ftrace_dump_mode oops_dump_mode) { } #endif /* CONFIG_TRACING */ -/* This counts to 12. Any more, it will return 13th argument. */ -#define __COUNT_ARGS(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _n, X...) _n -#define COUNT_ARGS(X...) __COUNT_ARGS(, ##X, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0) - -#define __CONCAT(a, b) a ## b -#define CONCATENATE(a, b) __CONCAT(a, b) - /* Rebuild everything on CONFIG_FTRACE_MCOUNT_RECORD */ #ifdef CONFIG_FTRACE_MCOUNT_RECORD # define REBUILD_DUE_TO_FTRACE_MCOUNT_RECORD diff --git a/include/linux/pci.h b/include/linux/pci.h index c69a2cc1f412..9c856e9aada5 100644 --- a/include/linux/pci.h +++ b/include/linux/pci.h @@ -23,7 +23,7 @@ #ifndef LINUX_PCI_H #define LINUX_PCI_H - +#include #include #include diff --git a/include/trace/bpf_probe.h b/include/trace/bpf_probe.h index 1f7fc1fc590c..e609cd7da47e 100644 --- a/include/trace/bpf_probe.h +++ b/include/trace/bpf_probe.h @@ -12,6 +12,8 @@ #undef __perf_task #define __perf_task(t) (t) +#include + /* cast any integer, pointer, or small struct to u64 */ #define UINTTYPE(size) \ __typeof__(__builtin_choose_expr(size == 1, (u8)1, \ -- cgit v1.2.3 From 90e3e18548e6a8e9e66fe2b4f4ad62bd9e8f0cda Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Wed, 19 Jul 2023 00:11:46 +0300 Subject: arm64: smccc: replace custom COUNT_ARGS() & CONCATENATE() implementations Replace custom implementation of the macros from args.h. Link: https://lkml.kernel.org/r/20230718211147.18647-4-andriy.shevchenko@linux.intel.com Signed-off-by: Andy Shevchenko Cc: Bjorn Helgaas Cc: Borislav Petkov (AMD) Cc: Brendan Higgins Cc: Daniel Latypov Cc: Dave Hansen Cc: David Gow Cc: "H. Peter Anvin" Cc: Ingo Molnar Cc: Lorenzo Pieralisi Cc: Mark Rutland Cc: Masami Hiramatsu (Google) Cc: Shuah Khan Cc: Steven Rostedt (Google) Cc: Sudeep Holla Cc: Thomas Gleixner Signed-off-by: Andrew Morton --- include/linux/arm-smccc.h | 69 ++++++++++++++++++++++------------------------- 1 file changed, 32 insertions(+), 37 deletions(-) (limited to 'include') diff --git a/include/linux/arm-smccc.h b/include/linux/arm-smccc.h index f196c19f8e55..7c67c17321d4 100644 --- a/include/linux/arm-smccc.h +++ b/include/linux/arm-smccc.h @@ -5,6 +5,7 @@ #ifndef __LINUX_ARM_SMCCC_H #define __LINUX_ARM_SMCCC_H +#include #include #include @@ -413,31 +414,26 @@ asmlinkage void __arm_smccc_hvc(unsigned long a0, unsigned long a1, #endif -#define ___count_args(_0, _1, _2, _3, _4, _5, _6, _7, _8, x, ...) x +#define __constraint_read_2 "r" (arg0) +#define __constraint_read_3 __constraint_read_2, "r" (arg1) +#define __constraint_read_4 __constraint_read_3, "r" (arg2) +#define __constraint_read_5 __constraint_read_4, "r" (arg3) +#define __constraint_read_6 __constraint_read_5, "r" (arg4) +#define __constraint_read_7 __constraint_read_6, "r" (arg5) +#define __constraint_read_8 __constraint_read_7, "r" (arg6) +#define __constraint_read_9 __constraint_read_8, "r" (arg7) -#define __count_args(...) \ - ___count_args(__VA_ARGS__, 7, 6, 5, 4, 3, 2, 1, 0) - -#define __constraint_read_0 "r" (arg0) -#define __constraint_read_1 __constraint_read_0, "r" (arg1) -#define __constraint_read_2 __constraint_read_1, "r" (arg2) -#define __constraint_read_3 __constraint_read_2, "r" (arg3) -#define __constraint_read_4 __constraint_read_3, "r" (arg4) -#define __constraint_read_5 __constraint_read_4, "r" (arg5) -#define __constraint_read_6 __constraint_read_5, "r" (arg6) -#define __constraint_read_7 __constraint_read_6, "r" (arg7) - -#define __declare_arg_0(a0, res) \ +#define __declare_arg_2(a0, res) \ struct arm_smccc_res *___res = res; \ register unsigned long arg0 asm("r0") = (u32)a0 -#define __declare_arg_1(a0, a1, res) \ +#define __declare_arg_3(a0, a1, res) \ typeof(a1) __a1 = a1; \ struct arm_smccc_res *___res = res; \ register unsigned long arg0 asm("r0") = (u32)a0; \ register typeof(a1) arg1 asm("r1") = __a1 -#define __declare_arg_2(a0, a1, a2, res) \ +#define __declare_arg_4(a0, a1, a2, res) \ typeof(a1) __a1 = a1; \ typeof(a2) __a2 = a2; \ struct arm_smccc_res *___res = res; \ @@ -445,7 +441,7 @@ asmlinkage void __arm_smccc_hvc(unsigned long a0, unsigned long a1, register typeof(a1) arg1 asm("r1") = __a1; \ register typeof(a2) arg2 asm("r2") = __a2 -#define __declare_arg_3(a0, a1, a2, a3, res) \ +#define __declare_arg_5(a0, a1, a2, a3, res) \ typeof(a1) __a1 = a1; \ typeof(a2) __a2 = a2; \ typeof(a3) __a3 = a3; \ @@ -455,34 +451,26 @@ asmlinkage void __arm_smccc_hvc(unsigned long a0, unsigned long a1, register typeof(a2) arg2 asm("r2") = __a2; \ register typeof(a3) arg3 asm("r3") = __a3 -#define __declare_arg_4(a0, a1, a2, a3, a4, res) \ +#define __declare_arg_6(a0, a1, a2, a3, a4, res) \ typeof(a4) __a4 = a4; \ - __declare_arg_3(a0, a1, a2, a3, res); \ + __declare_arg_5(a0, a1, a2, a3, res); \ register typeof(a4) arg4 asm("r4") = __a4 -#define __declare_arg_5(a0, a1, a2, a3, a4, a5, res) \ +#define __declare_arg_7(a0, a1, a2, a3, a4, a5, res) \ typeof(a5) __a5 = a5; \ - __declare_arg_4(a0, a1, a2, a3, a4, res); \ + __declare_arg_6(a0, a1, a2, a3, a4, res); \ register typeof(a5) arg5 asm("r5") = __a5 -#define __declare_arg_6(a0, a1, a2, a3, a4, a5, a6, res) \ +#define __declare_arg_8(a0, a1, a2, a3, a4, a5, a6, res) \ typeof(a6) __a6 = a6; \ - __declare_arg_5(a0, a1, a2, a3, a4, a5, res); \ + __declare_arg_7(a0, a1, a2, a3, a4, a5, res); \ register typeof(a6) arg6 asm("r6") = __a6 -#define __declare_arg_7(a0, a1, a2, a3, a4, a5, a6, a7, res) \ +#define __declare_arg_9(a0, a1, a2, a3, a4, a5, a6, a7, res) \ typeof(a7) __a7 = a7; \ - __declare_arg_6(a0, a1, a2, a3, a4, a5, a6, res); \ + __declare_arg_8(a0, a1, a2, a3, a4, a5, a6, res); \ register typeof(a7) arg7 asm("r7") = __a7 -#define ___declare_args(count, ...) __declare_arg_ ## count(__VA_ARGS__) -#define __declare_args(count, ...) ___declare_args(count, __VA_ARGS__) - -#define ___constraints(count) \ - : __constraint_read_ ## count \ - : smccc_sve_clobbers "memory" -#define __constraints(count) ___constraints(count) - /* * We have an output list that is not necessarily used, and GCC feels * entitled to optimise the whole sequence away. "volatile" is what @@ -494,11 +482,14 @@ asmlinkage void __arm_smccc_hvc(unsigned long a0, unsigned long a1, register unsigned long r1 asm("r1"); \ register unsigned long r2 asm("r2"); \ register unsigned long r3 asm("r3"); \ - __declare_args(__count_args(__VA_ARGS__), __VA_ARGS__); \ + CONCATENATE(__declare_arg_, \ + COUNT_ARGS(__VA_ARGS__))(__VA_ARGS__); \ asm volatile(SMCCC_SVE_CHECK \ inst "\n" : \ "=r" (r0), "=r" (r1), "=r" (r2), "=r" (r3) \ - __constraints(__count_args(__VA_ARGS__))); \ + : CONCATENATE(__constraint_read_, \ + COUNT_ARGS(__VA_ARGS__)) \ + : smccc_sve_clobbers "memory"); \ if (___res) \ *___res = (typeof(*___res)){r0, r1, r2, r3}; \ } while (0) @@ -542,8 +533,12 @@ asmlinkage void __arm_smccc_hvc(unsigned long a0, unsigned long a1, */ #define __fail_smccc_1_1(...) \ do { \ - __declare_args(__count_args(__VA_ARGS__), __VA_ARGS__); \ - asm ("" : __constraints(__count_args(__VA_ARGS__))); \ + CONCATENATE(__declare_arg_, \ + COUNT_ARGS(__VA_ARGS__))(__VA_ARGS__); \ + asm ("" : \ + : CONCATENATE(__constraint_read_, \ + COUNT_ARGS(__VA_ARGS__)) \ + : smccc_sve_clobbers "memory"); \ if (___res) \ ___res->a0 = SMCCC_RET_NOT_SUPPORTED; \ } while (0) -- cgit v1.2.3 From 2e106e564372a28f6dc9c8db411cb9424e78e743 Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Wed, 19 Jul 2023 00:11:47 +0300 Subject: genetlink: replace custom CONCATENATE() implementation Replace custom implementation of the macros from args.h. Link: https://lkml.kernel.org/r/20230718211147.18647-5-andriy.shevchenko@linux.intel.com Signed-off-by: Andy Shevchenko Cc: Bjorn Helgaas Cc: Borislav Petkov (AMD) Cc: Brendan Higgins Cc: "H. Peter Anvin" Cc: Daniel Latypov Cc: Dave Hansen Cc: David Gow Cc: Ingo Molnar Cc: Lorenzo Pieralisi Cc: Mark Rutland Cc: Masami Hiramatsu (Google) Cc: Shuah Khan Cc: Steven Rostedt (Google) Cc: Sudeep Holla Cc: Thomas Gleixner Signed-off-by: Andrew Morton --- include/linux/genl_magic_func.h | 27 ++++++++++++++------------- include/linux/genl_magic_struct.h | 8 +++----- 2 files changed, 17 insertions(+), 18 deletions(-) (limited to 'include') diff --git a/include/linux/genl_magic_func.h b/include/linux/genl_magic_func.h index 2984b0cb24b1..d4da060b7532 100644 --- a/include/linux/genl_magic_func.h +++ b/include/linux/genl_magic_func.h @@ -2,6 +2,7 @@ #ifndef GENL_MAGIC_FUNC_H #define GENL_MAGIC_FUNC_H +#include #include #include @@ -23,7 +24,7 @@ #define GENL_struct(tag_name, tag_number, s_name, s_fields) \ [tag_name] = { .type = NLA_NESTED }, -static struct nla_policy CONCAT_(GENL_MAGIC_FAMILY, _tla_nl_policy)[] = { +static struct nla_policy CONCATENATE(GENL_MAGIC_FAMILY, _tla_nl_policy)[] = { #include GENL_MAGIC_INCLUDE_FILE }; @@ -209,7 +210,7 @@ static int s_name ## _from_attrs_for_change(struct s_name *s, \ * Magic: define op number to op name mapping {{{1 * {{{2 */ -static const char *CONCAT_(GENL_MAGIC_FAMILY, _genl_cmd_to_str)(__u8 cmd) +static const char *CONCATENATE(GENL_MAGIC_FAMILY, _genl_cmd_to_str)(__u8 cmd) { switch (cmd) { #undef GENL_op @@ -235,7 +236,7 @@ static const char *CONCAT_(GENL_MAGIC_FAMILY, _genl_cmd_to_str)(__u8 cmd) .cmd = op_name, \ }, -#define ZZZ_genl_ops CONCAT_(GENL_MAGIC_FAMILY, _genl_ops) +#define ZZZ_genl_ops CONCATENATE(GENL_MAGIC_FAMILY, _genl_ops) static struct genl_ops ZZZ_genl_ops[] __read_mostly = { #include GENL_MAGIC_INCLUDE_FILE }; @@ -248,32 +249,32 @@ static struct genl_ops ZZZ_genl_ops[] __read_mostly = { * and provide register/unregister functions. * {{{2 */ -#define ZZZ_genl_family CONCAT_(GENL_MAGIC_FAMILY, _genl_family) +#define ZZZ_genl_family CONCATENATE(GENL_MAGIC_FAMILY, _genl_family) static struct genl_family ZZZ_genl_family; /* * Magic: define multicast groups * Magic: define multicast group registration helper */ -#define ZZZ_genl_mcgrps CONCAT_(GENL_MAGIC_FAMILY, _genl_mcgrps) +#define ZZZ_genl_mcgrps CONCATENATE(GENL_MAGIC_FAMILY, _genl_mcgrps) static const struct genl_multicast_group ZZZ_genl_mcgrps[] = { #undef GENL_mc_group #define GENL_mc_group(group) { .name = #group, }, #include GENL_MAGIC_INCLUDE_FILE }; -enum CONCAT_(GENL_MAGIC_FAMILY, group_ids) { +enum CONCATENATE(GENL_MAGIC_FAMILY, group_ids) { #undef GENL_mc_group -#define GENL_mc_group(group) CONCAT_(GENL_MAGIC_FAMILY, _group_ ## group), +#define GENL_mc_group(group) CONCATENATE(GENL_MAGIC_FAMILY, _group_ ## group), #include GENL_MAGIC_INCLUDE_FILE }; #undef GENL_mc_group #define GENL_mc_group(group) \ -static int CONCAT_(GENL_MAGIC_FAMILY, _genl_multicast_ ## group)( \ +static int CONCATENATE(GENL_MAGIC_FAMILY, _genl_multicast_ ## group)( \ struct sk_buff *skb, gfp_t flags) \ { \ unsigned int group_id = \ - CONCAT_(GENL_MAGIC_FAMILY, _group_ ## group); \ + CONCATENATE(GENL_MAGIC_FAMILY, _group_ ## group); \ return genlmsg_multicast(&ZZZ_genl_family, skb, 0, \ group_id, flags); \ } @@ -289,8 +290,8 @@ static struct genl_family ZZZ_genl_family __ro_after_init = { #ifdef GENL_MAGIC_FAMILY_HDRSZ .hdrsize = NLA_ALIGN(GENL_MAGIC_FAMILY_HDRSZ), #endif - .maxattr = ARRAY_SIZE(CONCAT_(GENL_MAGIC_FAMILY, _tla_nl_policy))-1, - .policy = CONCAT_(GENL_MAGIC_FAMILY, _tla_nl_policy), + .maxattr = ARRAY_SIZE(CONCATENATE(GENL_MAGIC_FAMILY, _tla_nl_policy))-1, + .policy = CONCATENATE(GENL_MAGIC_FAMILY, _tla_nl_policy), .ops = ZZZ_genl_ops, .n_ops = ARRAY_SIZE(ZZZ_genl_ops), .mcgrps = ZZZ_genl_mcgrps, @@ -299,12 +300,12 @@ static struct genl_family ZZZ_genl_family __ro_after_init = { .module = THIS_MODULE, }; -int CONCAT_(GENL_MAGIC_FAMILY, _genl_register)(void) +int CONCATENATE(GENL_MAGIC_FAMILY, _genl_register)(void) { return genl_register_family(&ZZZ_genl_family); } -void CONCAT_(GENL_MAGIC_FAMILY, _genl_unregister)(void) +void CONCATENATE(GENL_MAGIC_FAMILY, _genl_unregister)(void) { genl_unregister_family(&ZZZ_genl_family); } diff --git a/include/linux/genl_magic_struct.h b/include/linux/genl_magic_struct.h index f81d48987528..a419d93789ff 100644 --- a/include/linux/genl_magic_struct.h +++ b/include/linux/genl_magic_struct.h @@ -14,14 +14,12 @@ # error "you need to define GENL_MAGIC_INCLUDE_FILE before inclusion" #endif +#include #include #include -#define CONCAT__(a,b) a ## b -#define CONCAT_(a,b) CONCAT__(a,b) - -extern int CONCAT_(GENL_MAGIC_FAMILY, _genl_register)(void); -extern void CONCAT_(GENL_MAGIC_FAMILY, _genl_unregister)(void); +extern int CONCATENATE(GENL_MAGIC_FAMILY, _genl_register)(void); +extern void CONCATENATE(GENL_MAGIC_FAMILY, _genl_unregister)(void); /* * Extension of genl attribute validation policies {{{2 -- cgit v1.2.3 From 46f12960aad2d48fc6742470f718e147e5c85d06 Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Thu, 3 Aug 2023 16:19:18 +0300 Subject: drm/i915: Move abs_diff() to math.h abs_diff() belongs to math.h. Move it there. This will allow others to use it. [andriy.shevchenko@linux.intel.com: add abs_diff() documentation] Link: https://lkml.kernel.org/r/20230804050934.83223-1-andriy.shevchenko@linux.intel.com [akpm@linux-foundation.org: fix comment, per Randy] Link: https://lkml.kernel.org/r/20230803131918.53727-1-andriy.shevchenko@linux.intel.com Signed-off-by: Andy Shevchenko Reviewed-by: Jiri Slaby # tty/serial Acked-by: Jani Nikula Acked-by: Greg Kroah-Hartman Reviewed-by: Andi Shyti Reviewed-by: Philipp Zabel # gpu/ipu-v3 Cc: Alexey Dobriyan Cc: Daniel Vetter Cc: David Airlie Cc: Helge Deller Cc: Imre Deak Cc: Jani Nikula Cc: Joonas Lahtinen Cc: Rasmus Villemoes Cc: Rodrigo Vivi Cc: Tvrtko Ursulin Cc: Randy Dunlap Signed-off-by: Andrew Morton --- include/linux/math.h | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) (limited to 'include') diff --git a/include/linux/math.h b/include/linux/math.h index 2d388650c556..dd4152711de7 100644 --- a/include/linux/math.h +++ b/include/linux/math.h @@ -155,6 +155,25 @@ __STRUCT_FRACT(u32) __builtin_types_compatible_p(typeof(x), unsigned type), \ ({ signed type __x = (x); __x < 0 ? -__x : __x; }), other) +/** + * abs_diff - return absolute value of the difference between the arguments + * @a: the first argument + * @b: the second argument + * + * @a and @b have to be of the same type. With this restriction we compare + * signed to signed and unsigned to unsigned. The result is the subtraction + * the smaller of the two from the bigger, hence result is always a positive + * value. + * + * Return: an absolute value of the difference between the @a and @b. + */ +#define abs_diff(a, b) ({ \ + typeof(a) __a = (a); \ + typeof(b) __b = (b); \ + (void)(&__a == &__b); \ + __a > __b ? (__a - __b) : (__b - __a); \ +}) + /** * reciprocal_scale - "scale" a value into range [0, ep_ro) * @val: value -- cgit v1.2.3 From be33db21427c33a4217bd6b805944d2cf84faf25 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Fri, 4 Aug 2023 08:41:51 +0200 Subject: kthread: unexport __kthread_should_park() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit There are no in-kernel users of __kthread_should_park() so mark it as static and do not export it. Link: https://lkml.kernel.org/r/2023080450-handcuff-stump-1d6e@gregkh Signed-off-by: Greg Kroah-Hartman Reviewed-by: Kees Cook Cc: John Stultz Cc: "Peter Zijlstra (Intel)" Cc: "Arve Hjønnevåg" Cc: Valentin Schneider Cc: Andrew Morton Cc: "Christian Brauner (Microsoft)" Cc: Mike Christie Cc: Nicholas Piggin Cc: Zqiang Cc: Prathu Baronia Cc: Sami Tolvanen Signed-off-by: Andrew Morton --- include/linux/kthread.h | 1 - 1 file changed, 1 deletion(-) (limited to 'include') diff --git a/include/linux/kthread.h b/include/linux/kthread.h index f1f95a71a4bc..2c30ade43bc8 100644 --- a/include/linux/kthread.h +++ b/include/linux/kthread.h @@ -88,7 +88,6 @@ void kthread_bind_mask(struct task_struct *k, const struct cpumask *mask); int kthread_stop(struct task_struct *k); bool kthread_should_stop(void); bool kthread_should_park(void); -bool __kthread_should_park(struct task_struct *k); bool kthread_should_stop_or_park(void); bool kthread_freezable_should_stop(bool *was_frozen); void *kthread_func(struct task_struct *k); -- cgit v1.2.3 From 3c9d017cc283df0dabf6b16a6cb4574426cbd53b Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Fri, 4 Aug 2023 09:46:36 +0300 Subject: range.h: Move resource API and constant to respective files range.h works with struct range data type. The resource_size_t is an alien here. (1) Move cap_resource() implementation into its only user, and (2) rename and move RESOURCE_SIZE_MAX to limits.h. Link: https://lkml.kernel.org/r/20230804064636.15368-1-andriy.shevchenko@linux.intel.com Signed-off-by: Andy Shevchenko Acked-by: Bjorn Helgaas Cc: Alexander Sverdlin Cc: Borislav Petkov (AMD) Cc: Dave Hansen Cc: "H. Peter Anvin" Cc: Ingo Molnar Cc: Rasmus Villemoes Cc: Thomas Bogendoerfer Cc: Thomas Gleixner Signed-off-by: Andrew Morton --- include/linux/limits.h | 2 ++ include/linux/range.h | 8 -------- 2 files changed, 2 insertions(+), 8 deletions(-) (limited to 'include') diff --git a/include/linux/limits.h b/include/linux/limits.h index f6bcc9369010..38eb7f6f7e88 100644 --- a/include/linux/limits.h +++ b/include/linux/limits.h @@ -10,6 +10,8 @@ #define SSIZE_MAX ((ssize_t)(SIZE_MAX >> 1)) #define PHYS_ADDR_MAX (~(phys_addr_t)0) +#define RESOURCE_SIZE_MAX ((resource_size_t)~0) + #define U8_MAX ((u8)~0U) #define S8_MAX ((s8)(U8_MAX >> 1)) #define S8_MIN ((s8)(-S8_MAX - 1)) diff --git a/include/linux/range.h b/include/linux/range.h index 7efb6a9b069b..6ad0b73cb7ad 100644 --- a/include/linux/range.h +++ b/include/linux/range.h @@ -31,12 +31,4 @@ int clean_sort_range(struct range *range, int az); void sort_range(struct range *range, int nr_range); -#define MAX_RESOURCE ((resource_size_t)~0) -static inline resource_size_t cap_resource(u64 val) -{ - if (val > MAX_RESOURCE) - return MAX_RESOURCE; - - return val; -} #endif -- cgit v1.2.3 From 8d539b84f1e3478436f978ceaf55a0b6cab497b5 Mon Sep 17 00:00:00 2001 From: Douglas Anderson Date: Fri, 4 Aug 2023 07:00:42 -0700 Subject: nmi_backtrace: allow excluding an arbitrary CPU The APIs that allow backtracing across CPUs have always had a way to exclude the current CPU. This convenience means callers didn't need to find a place to allocate a CPU mask just to handle the common case. Let's extend the API to take a CPU ID to exclude instead of just a boolean. This isn't any more complex for the API to handle and allows the hardlockup detector to exclude a different CPU (the one it already did a trace for) without needing to find space for a CPU mask. Arguably, this new API also encourages safer behavior. Specifically if the caller wants to avoid tracing the current CPU (maybe because they already traced the current CPU) this makes it more obvious to the caller that they need to make sure that the current CPU ID can't change. [akpm@linux-foundation.org: fix trigger_allbutcpu_cpu_backtrace() stub] Link: https://lkml.kernel.org/r/20230804065935.v4.1.Ia35521b91fc781368945161d7b28538f9996c182@changeid Signed-off-by: Douglas Anderson Acked-by: Michal Hocko Cc: kernel test robot Cc: Lecopzer Chen Cc: Petr Mladek Cc: Pingfan Liu Signed-off-by: Andrew Morton --- include/linux/nmi.h | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) (limited to 'include') diff --git a/include/linux/nmi.h b/include/linux/nmi.h index e3e6a64b98e0..e92e378df000 100644 --- a/include/linux/nmi.h +++ b/include/linux/nmi.h @@ -157,31 +157,31 @@ static inline void touch_nmi_watchdog(void) #ifdef arch_trigger_cpumask_backtrace static inline bool trigger_all_cpu_backtrace(void) { - arch_trigger_cpumask_backtrace(cpu_online_mask, false); + arch_trigger_cpumask_backtrace(cpu_online_mask, -1); return true; } -static inline bool trigger_allbutself_cpu_backtrace(void) +static inline bool trigger_allbutcpu_cpu_backtrace(int exclude_cpu) { - arch_trigger_cpumask_backtrace(cpu_online_mask, true); + arch_trigger_cpumask_backtrace(cpu_online_mask, exclude_cpu); return true; } static inline bool trigger_cpumask_backtrace(struct cpumask *mask) { - arch_trigger_cpumask_backtrace(mask, false); + arch_trigger_cpumask_backtrace(mask, -1); return true; } static inline bool trigger_single_cpu_backtrace(int cpu) { - arch_trigger_cpumask_backtrace(cpumask_of(cpu), false); + arch_trigger_cpumask_backtrace(cpumask_of(cpu), -1); return true; } /* generic implementation */ void nmi_trigger_cpumask_backtrace(const cpumask_t *mask, - bool exclude_self, + int exclude_cpu, void (*raise)(cpumask_t *mask)); bool nmi_cpu_backtrace(struct pt_regs *regs); @@ -190,7 +190,7 @@ static inline bool trigger_all_cpu_backtrace(void) { return false; } -static inline bool trigger_allbutself_cpu_backtrace(void) +static inline bool trigger_allbutcpu_cpu_backtrace(int exclude_cpu) { return false; } -- cgit v1.2.3 From 39ced19b9e60f6f5b80db6b72965a8cf1982439d Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Mon, 14 Aug 2023 19:33:43 +0300 Subject: lib/vsprintf: split out sprintf() and friends Patch series "lib/vsprintf: Rework header inclusions", v3. Some patches that reduce the mess with the header inclusions related to vsprintf.c module. Each patch has its own description, and has no dependencies to each other, except the collisions over modifications of the same places. Hence the series. This patch (of 2): kernel.h is being used as a dump for all kinds of stuff for a long time. sprintf() and friends are used in many drivers without need of the full kernel.h dependency train with it. Here is the attempt on cleaning it up by splitting out sprintf() and friends. Link: https://lkml.kernel.org/r/20230814163344.17429-1-andriy.shevchenko@linux.intel.com Link: https://lkml.kernel.org/r/20230814163344.17429-2-andriy.shevchenko@linux.intel.com Signed-off-by: Andy Shevchenko Reviewed-by: Petr Mladek Cc: Alexander Potapenko Cc: Dmitry Vyukov Cc: Marco Elver Cc: Rasmus Villemoes Cc: Sergey Senozhatsky Cc: Steven Rostedt (Google) Signed-off-by: Andrew Morton --- include/linux/kernel.h | 30 +----------------------------- include/linux/sprintf.h | 25 +++++++++++++++++++++++++ 2 files changed, 26 insertions(+), 29 deletions(-) create mode 100644 include/linux/sprintf.h (limited to 'include') diff --git a/include/linux/kernel.h b/include/linux/kernel.h index b9e76f717a7e..cee8fe87e9f4 100644 --- a/include/linux/kernel.h +++ b/include/linux/kernel.h @@ -29,6 +29,7 @@ #include #include #include +#include #include #include #include @@ -203,35 +204,6 @@ static inline void might_fault(void) { } void do_exit(long error_code) __noreturn; -extern int num_to_str(char *buf, int size, - unsigned long long num, unsigned int width); - -/* lib/printf utilities */ - -extern __printf(2, 3) int sprintf(char *buf, const char * fmt, ...); -extern __printf(2, 0) int vsprintf(char *buf, const char *, va_list); -extern __printf(3, 4) -int snprintf(char *buf, size_t size, const char *fmt, ...); -extern __printf(3, 0) -int vsnprintf(char *buf, size_t size, const char *fmt, va_list args); -extern __printf(3, 4) -int scnprintf(char *buf, size_t size, const char *fmt, ...); -extern __printf(3, 0) -int vscnprintf(char *buf, size_t size, const char *fmt, va_list args); -extern __printf(2, 3) __malloc -char *kasprintf(gfp_t gfp, const char *fmt, ...); -extern __printf(2, 0) __malloc -char *kvasprintf(gfp_t gfp, const char *fmt, va_list args); -extern __printf(2, 0) -const char *kvasprintf_const(gfp_t gfp, const char *fmt, va_list args); - -extern __scanf(2, 3) -int sscanf(const char *, const char *, ...); -extern __scanf(2, 0) -int vsscanf(const char *, const char *, va_list); - -extern int no_hash_pointers_enable(char *str); - extern int get_option(char **str, int *pint); extern char *get_options(const char *str, int nints, int *ints); extern unsigned long long memparse(const char *ptr, char **retptr); diff --git a/include/linux/sprintf.h b/include/linux/sprintf.h new file mode 100644 index 000000000000..9ca23bcf9f42 --- /dev/null +++ b/include/linux/sprintf.h @@ -0,0 +1,25 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +#ifndef _LINUX_KERNEL_SPRINTF_H_ +#define _LINUX_KERNEL_SPRINTF_H_ + +#include +#include + +int num_to_str(char *buf, int size, unsigned long long num, unsigned int width); + +__printf(2, 3) int sprintf(char *buf, const char * fmt, ...); +__printf(2, 0) int vsprintf(char *buf, const char *, va_list); +__printf(3, 4) int snprintf(char *buf, size_t size, const char *fmt, ...); +__printf(3, 0) int vsnprintf(char *buf, size_t size, const char *fmt, va_list args); +__printf(3, 4) int scnprintf(char *buf, size_t size, const char *fmt, ...); +__printf(3, 0) int vscnprintf(char *buf, size_t size, const char *fmt, va_list args); +__printf(2, 3) __malloc char *kasprintf(gfp_t gfp, const char *fmt, ...); +__printf(2, 0) __malloc char *kvasprintf(gfp_t gfp, const char *fmt, va_list args); +__printf(2, 0) const char *kvasprintf_const(gfp_t gfp, const char *fmt, va_list args); + +__scanf(2, 3) int sscanf(const char *, const char *, ...); +__scanf(2, 0) int vsscanf(const char *, const char *, va_list); + +int no_hash_pointers_enable(char *str); + +#endif /* _LINUX_KERNEL_SPRINTF_H */ -- cgit v1.2.3 From 665536092355f17f0e2ea291eec70f9787dccd32 Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Mon, 14 Aug 2023 19:33:44 +0300 Subject: lib/vsprintf: declare no_hash_pointers in sprintf.h Sparse is not happy to see non-static variable without declaration: lib/vsprintf.c:61:6: warning: symbol 'no_hash_pointers' was not declared. Should it be static? Declare respective variable in the sprintf.h. With this, add a comment to discourage its use if no real need. Link: https://lkml.kernel.org/r/20230814163344.17429-3-andriy.shevchenko@linux.intel.com Signed-off-by: Andy Shevchenko Acked-by: Marco Elver Reviewed-by: Petr Mladek Cc: Alexander Potapenko Cc: Dmitry Vyukov Cc: Rasmus Villemoes Cc: Sergey Senozhatsky Cc: Steven Rostedt (Google) Signed-off-by: Andrew Morton --- include/linux/sprintf.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'include') diff --git a/include/linux/sprintf.h b/include/linux/sprintf.h index 9ca23bcf9f42..33dcbec71925 100644 --- a/include/linux/sprintf.h +++ b/include/linux/sprintf.h @@ -20,6 +20,8 @@ __printf(2, 0) const char *kvasprintf_const(gfp_t gfp, const char *fmt, va_list __scanf(2, 3) int sscanf(const char *, const char *, ...); __scanf(2, 0) int vsscanf(const char *, const char *, va_list); +/* These are for specific cases, do not use without real need */ +extern bool no_hash_pointers; int no_hash_pointers_enable(char *str); #endif /* _LINUX_KERNEL_SPRINTF_H */ -- cgit v1.2.3 From 5ffd2c37cb7a53d52099e5ed1fd7ccbc9e358791 Mon Sep 17 00:00:00 2001 From: Oleg Nesterov Date: Thu, 17 Aug 2023 18:37:08 +0200 Subject: kill do_each_thread() Eric has pointed out that we still have 3 users of do_each_thread(). Change them to use for_each_process_thread() and kill this helper. There is a subtle change, after do_each_thread/while_each_thread g == t == &init_task, while after for_each_process_thread() they both point to nowhere, but this doesn't matter. > Why is for_each_process_thread() better than do_each_thread()? Say, for_each_process_thread() is rcu safe, do_each_thread() is not. And certainly for_each_process_thread(p, t) { do_something(p, t); } looks better than do_each_thread(p, t) { do_something(p, t); } while_each_thread(p, t); And again, there are only 3 users of this awkward helper left. It should have been killed years ago and in fact I thought it had already been killed. It uses while_each_thread() which needs some changes. Link: https://lkml.kernel.org/r/20230817163708.GA8248@redhat.com Signed-off-by: Oleg Nesterov Reviewed-by: Kees Cook Cc: "Christian Brauner (Microsoft)" Cc: Eric W. Biederman Cc: Jiri Slaby # tty/serial Signed-off-by: Andrew Morton --- include/linux/sched/signal.h | 7 ------- 1 file changed, 7 deletions(-) (limited to 'include') diff --git a/include/linux/sched/signal.h b/include/linux/sched/signal.h index 669e8cff40c7..0deebe2ab07d 100644 --- a/include/linux/sched/signal.h +++ b/include/linux/sched/signal.h @@ -648,13 +648,6 @@ extern void flush_itimer_signals(void); extern bool current_is_single_threaded(void); -/* - * Careful: do_each_thread/while_each_thread is a double loop so - * 'break' will not work as expected - use goto instead. - */ -#define do_each_thread(g, t) \ - for (g = t = &init_task ; (g = t = next_task(g)) != &init_task ; ) do - #define while_each_thread(g, t) \ while ((t = next_thread(t)) != g) -- cgit v1.2.3 From 6f991cc363a3269866476b8ff10a112768d3d45c Mon Sep 17 00:00:00 2001 From: Eric DeVolder Date: Mon, 14 Aug 2023 17:44:39 -0400 Subject: crash: move a few code bits to setup support of crash hotplug MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Patch series "crash: Kernel handling of CPU and memory hot un/plug", v28. Once the kdump service is loaded, if changes to CPUs or memory occur, either by hot un/plug or off/onlining, the crash elfcorehdr must also be updated. The elfcorehdr describes to kdump the CPUs and memory in the system, and any inaccuracies can result in a vmcore with missing CPU context or memory regions. The current solution utilizes udev to initiate an unload-then-reload of the kdump image (eg. kernel, initrd, boot_params, purgatory and elfcorehdr) by the userspace kexec utility. In the original post I outlined the significant performance problems related to offloading this activity to userspace. This patchset introduces a generic crash handler that registers with the CPU and memory notifiers. Upon CPU or memory changes, from either hot un/plug or off/onlining, this generic handler is invoked and performs important housekeeping, for example obtaining the appropriate lock, and then invokes an architecture specific handler to do the appropriate elfcorehdr update. Note the description in patch 'crash: change crash_prepare_elf64_headers() to for_each_possible_cpu()' and 'x86/crash: optimize CPU changes' that enables further optimizations related to CPU plug/unplug/online/offline performance of elfcorehdr updates. In the case of x86_64, the arch specific handler generates a new elfcorehdr, and overwrites the old one in memory; thus no involvement with userspace needed. To realize the benefits/test this patchset, one must make a couple of minor changes to userspace: - Prevent udev from updating kdump crash kernel on hot un/plug changes. Add the following as the first lines to the RHEL udev rule file /usr/lib/udev/rules.d/98-kexec.rules: # The kernel updates the crash elfcorehdr for CPU and memory changes SUBSYSTEM=="cpu", ATTRS{crash_hotplug}=="1", GOTO="kdump_reload_end" SUBSYSTEM=="memory", ATTRS{crash_hotplug}=="1", GOTO="kdump_reload_end" With this changeset applied, the two rules evaluate to false for CPU and memory change events and thus skip the userspace unload-then-reload of kdump. - Change to the kexec_file_load for loading the kdump kernel: Eg. on RHEL: in /usr/bin/kdumpctl, change to: standard_kexec_args="-p -d -s" which adds the -s to select kexec_file_load() syscall. This kernel patchset also supports kexec_load() with a modified kexec userspace utility. A working changeset to the kexec userspace utility is posted to the kexec-tools mailing list here: http://lists.infradead.org/pipermail/kexec/2023-May/027049.html To use the kexec-tools patch, apply, build and install kexec-tools, then change the kdumpctl's standard_kexec_args to replace the -s with --hotplug. The removal of -s reverts to the kexec_load syscall and the addition of --hotplug invokes the changes put forth in the kexec-tools patch. This patch (of 8): The crash hotplug support leans on the work for the kexec_file_load() syscall. To also support the kexec_load() syscall, a few bits of code need to be move outside of CONFIG_KEXEC_FILE. As such, these bits are moved out of kexec_file.c and into a common location crash_core.c. In addition, struct crash_mem and crash_notes were moved to new locales so that PROC_KCORE, which sets CRASH_CORE alone, builds correctly. No functionality change intended. Link: https://lkml.kernel.org/r/20230814214446.6659-1-eric.devolder@oracle.com Link: https://lkml.kernel.org/r/20230814214446.6659-2-eric.devolder@oracle.com Signed-off-by: Eric DeVolder Reviewed-by: Sourabh Jain Acked-by: Hari Bathini Acked-by: Baoquan He Cc: Akhil Raj Cc: Bjorn Helgaas Cc: Borislav Petkov (AMD) Cc: Boris Ostrovsky Cc: Dave Hansen Cc: Dave Young Cc: David Hildenbrand Cc: Eric W. Biederman Cc: Greg Kroah-Hartman Cc: "H. Peter Anvin" Cc: Ingo Molnar Cc: Jonathan Corbet Cc: Konrad Rzeszutek Wilk Cc: Mimi Zohar Cc: Naveen N. Rao Cc: Oscar Salvador Cc: "Rafael J. Wysocki" Cc: Sean Christopherson Cc: Takashi Iwai Cc: Thomas Gleixner Cc: Thomas Weißschuh Cc: Valentin Schneider Cc: Vivek Goyal Cc: Vlastimil Babka Signed-off-by: Andrew Morton --- include/linux/crash_core.h | 20 ++++++++++++++++++++ include/linux/kexec.h | 15 --------------- 2 files changed, 20 insertions(+), 15 deletions(-) (limited to 'include') diff --git a/include/linux/crash_core.h b/include/linux/crash_core.h index de62a722431e..1e48b1d96404 100644 --- a/include/linux/crash_core.h +++ b/include/linux/crash_core.h @@ -28,6 +28,8 @@ VMCOREINFO_BYTES) typedef u32 note_buf_t[CRASH_CORE_NOTE_BYTES/4]; +/* Per cpu memory for storing cpu states in case of system crash. */ +extern note_buf_t __percpu *crash_notes; void crash_update_vmcoreinfo_safecopy(void *ptr); void crash_save_vmcoreinfo(void); @@ -84,4 +86,22 @@ int parse_crashkernel_high(char *cmdline, unsigned long long system_ram, int parse_crashkernel_low(char *cmdline, unsigned long long system_ram, unsigned long long *crash_size, unsigned long long *crash_base); +/* Alignment required for elf header segment */ +#define ELF_CORE_HEADER_ALIGN 4096 + +struct crash_mem { + unsigned int max_nr_ranges; + unsigned int nr_ranges; + struct range ranges[]; +}; + +extern int crash_exclude_mem_range(struct crash_mem *mem, + unsigned long long mstart, + unsigned long long mend); +extern int crash_prepare_elf64_headers(struct crash_mem *mem, int need_kernel_map, + void **addr, unsigned long *sz); + +struct kimage; +struct kexec_segment; + #endif /* LINUX_CRASH_CORE_H */ diff --git a/include/linux/kexec.h b/include/linux/kexec.h index 22b5cd24f581..fb4350db33ff 100644 --- a/include/linux/kexec.h +++ b/include/linux/kexec.h @@ -230,21 +230,6 @@ static inline int arch_kexec_locate_mem_hole(struct kexec_buf *kbuf) } #endif -/* Alignment required for elf header segment */ -#define ELF_CORE_HEADER_ALIGN 4096 - -struct crash_mem { - unsigned int max_nr_ranges; - unsigned int nr_ranges; - struct range ranges[]; -}; - -extern int crash_exclude_mem_range(struct crash_mem *mem, - unsigned long long mstart, - unsigned long long mend); -extern int crash_prepare_elf64_headers(struct crash_mem *mem, int need_kernel_map, - void **addr, unsigned long *sz); - #ifndef arch_kexec_apply_relocations_add /* * arch_kexec_apply_relocations_add - apply relocations of type RELA -- cgit v1.2.3 From 24726275612140af6b1c0afc7c6611ad66233207 Mon Sep 17 00:00:00 2001 From: Eric DeVolder Date: Mon, 14 Aug 2023 17:44:40 -0400 Subject: crash: add generic infrastructure for crash hotplug support MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit To support crash hotplug, a mechanism is needed to update the crash elfcorehdr upon CPU or memory changes (eg. hot un/plug or off/ onlining). The crash elfcorehdr describes the CPUs and memory to be written into the vmcore. To track CPU changes, callbacks are registered with the cpuhp mechanism via cpuhp_setup_state_nocalls(CPUHP_BP_PREPARE_DYN). The crash hotplug elfcorehdr update has no explicit ordering requirement (relative to other cpuhp states), so meets the criteria for utilizing CPUHP_BP_PREPARE_DYN. CPUHP_BP_PREPARE_DYN is a dynamic state and avoids the need to introduce a new state for crash hotplug. Also, CPUHP_BP_PREPARE_DYN is the last state in the PREPARE group, just prior to the STARTING group, which is very close to the CPU starting up in a plug/online situation, or stopping in a unplug/ offline situation. This minimizes the window of time during an actual plug/online or unplug/offline situation in which the elfcorehdr would be inaccurate. Note that for a CPU being unplugged or offlined, the CPU will still be present in the list of CPUs generated by crash_prepare_elf64_headers(). However, there is no need to explicitly omit the CPU, see justification in 'crash: change crash_prepare_elf64_headers() to for_each_possible_cpu()'. To track memory changes, a notifier is registered to capture the memblock MEM_ONLINE and MEM_OFFLINE events via register_memory_notifier(). The CPU callbacks and memory notifiers invoke crash_handle_hotplug_event() which performs needed tasks and then dispatches the event to the architecture specific arch_crash_handle_hotplug_event() to update the elfcorehdr with the current state of CPUs and memory. During the process, the kexec_lock is held. Link: https://lkml.kernel.org/r/20230814214446.6659-3-eric.devolder@oracle.com Signed-off-by: Eric DeVolder Reviewed-by: Sourabh Jain Acked-by: Hari Bathini Acked-by: Baoquan He Cc: Akhil Raj Cc: Bjorn Helgaas Cc: Borislav Petkov (AMD) Cc: Boris Ostrovsky Cc: Dave Hansen Cc: Dave Young Cc: David Hildenbrand Cc: Eric W. Biederman Cc: Greg Kroah-Hartman Cc: "H. Peter Anvin" Cc: Ingo Molnar Cc: Jonathan Corbet Cc: Konrad Rzeszutek Wilk Cc: Mimi Zohar Cc: Naveen N. Rao Cc: Oscar Salvador Cc: "Rafael J. Wysocki" Cc: Sean Christopherson Cc: Takashi Iwai Cc: Thomas Gleixner Cc: Thomas Weißschuh Cc: Valentin Schneider Cc: Vivek Goyal Cc: Vlastimil Babka Signed-off-by: Andrew Morton --- include/linux/crash_core.h | 7 +++++++ include/linux/kexec.h | 11 +++++++++++ 2 files changed, 18 insertions(+) (limited to 'include') diff --git a/include/linux/crash_core.h b/include/linux/crash_core.h index 1e48b1d96404..0c06561bf5ff 100644 --- a/include/linux/crash_core.h +++ b/include/linux/crash_core.h @@ -104,4 +104,11 @@ extern int crash_prepare_elf64_headers(struct crash_mem *mem, int need_kernel_ma struct kimage; struct kexec_segment; +#define KEXEC_CRASH_HP_NONE 0 +#define KEXEC_CRASH_HP_ADD_CPU 1 +#define KEXEC_CRASH_HP_REMOVE_CPU 2 +#define KEXEC_CRASH_HP_ADD_MEMORY 3 +#define KEXEC_CRASH_HP_REMOVE_MEMORY 4 +#define KEXEC_CRASH_HP_INVALID_CPU -1U + #endif /* LINUX_CRASH_CORE_H */ diff --git a/include/linux/kexec.h b/include/linux/kexec.h index fb4350db33ff..df395f888915 100644 --- a/include/linux/kexec.h +++ b/include/linux/kexec.h @@ -33,6 +33,7 @@ extern note_buf_t __percpu *crash_notes; #include #include #include +#include #include /* Verify architecture specific macros are defined */ @@ -345,6 +346,12 @@ struct kimage { struct purgatory_info purgatory_info; #endif +#ifdef CONFIG_CRASH_HOTPLUG + int hp_action; + int elfcorehdr_index; + bool elfcorehdr_updated; +#endif + #ifdef CONFIG_IMA_KEXEC /* Virtual address of IMA measurement buffer for kexec syscall */ void *ima_buffer; @@ -475,6 +482,10 @@ static inline int arch_kexec_post_alloc_pages(void *vaddr, unsigned int pages, g static inline void arch_kexec_pre_free_pages(void *vaddr, unsigned int pages) { } #endif +#ifndef arch_crash_handle_hotplug_event +static inline void arch_crash_handle_hotplug_event(struct kimage *image) { } +#endif + #else /* !CONFIG_KEXEC_CORE */ struct pt_regs; struct task_struct; -- cgit v1.2.3 From 88a6f89944216b028d3872b0cec0f51a2f955460 Mon Sep 17 00:00:00 2001 From: Eric DeVolder Date: Mon, 14 Aug 2023 17:44:42 -0400 Subject: crash: memory and CPU hotplug sysfs attributes MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Introduce the crash_hotplug attribute for memory and CPUs for use by userspace. These attributes directly facilitate the udev rule for managing userspace re-loading of the crash kernel upon hot un/plug changes. For memory, expose the crash_hotplug attribute to the /sys/devices/system/memory directory. For example: # udevadm info --attribute-walk /sys/devices/system/memory/memory81 looking at device '/devices/system/memory/memory81': KERNEL=="memory81" SUBSYSTEM=="memory" DRIVER=="" ATTR{online}=="1" ATTR{phys_device}=="0" ATTR{phys_index}=="00000051" ATTR{removable}=="1" ATTR{state}=="online" ATTR{valid_zones}=="Movable" looking at parent device '/devices/system/memory': KERNELS=="memory" SUBSYSTEMS=="" DRIVERS=="" ATTRS{auto_online_blocks}=="offline" ATTRS{block_size_bytes}=="8000000" ATTRS{crash_hotplug}=="1" For CPUs, expose the crash_hotplug attribute to the /sys/devices/system/cpu directory. For example: # udevadm info --attribute-walk /sys/devices/system/cpu/cpu0 looking at device '/devices/system/cpu/cpu0': KERNEL=="cpu0" SUBSYSTEM=="cpu" DRIVER=="processor" ATTR{crash_notes}=="277c38600" ATTR{crash_notes_size}=="368" ATTR{online}=="1" looking at parent device '/devices/system/cpu': KERNELS=="cpu" SUBSYSTEMS=="" DRIVERS=="" ATTRS{crash_hotplug}=="1" ATTRS{isolated}=="" ATTRS{kernel_max}=="8191" ATTRS{nohz_full}==" (null)" ATTRS{offline}=="4-7" ATTRS{online}=="0-3" ATTRS{possible}=="0-7" ATTRS{present}=="0-3" With these sysfs attributes in place, it is possible to efficiently instruct the udev rule to skip crash kernel reloading for kernels configured with crash hotplug support. For example, the following is the proposed udev rule change for RHEL system 98-kexec.rules (as the first lines of the rule file): # The kernel updates the crash elfcorehdr for CPU and memory changes SUBSYSTEM=="cpu", ATTRS{crash_hotplug}=="1", GOTO="kdump_reload_end" SUBSYSTEM=="memory", ATTRS{crash_hotplug}=="1", GOTO="kdump_reload_end" When examined in the context of 98-kexec.rules, the above rules test if crash_hotplug is set, and if so, the userspace initiated unload-then-reload of the crash kernel is skipped. CPU and memory checks are separated in accordance with CONFIG_HOTPLUG_CPU and CONFIG_MEMORY_HOTPLUG kernel config options. If an architecture supports, for example, memory hotplug but not CPU hotplug, then the /sys/devices/system/memory/crash_hotplug attribute file is present, but the /sys/devices/system/cpu/crash_hotplug attribute file will NOT be present. Thus the udev rule skips userspace processing of memory hot un/plug events, but the udev rule will evaluate false for CPU events, thus allowing userspace to process CPU hot un/plug events (ie the unload-then-reload of the kdump capture kernel). Link: https://lkml.kernel.org/r/20230814214446.6659-5-eric.devolder@oracle.com Signed-off-by: Eric DeVolder Reviewed-by: Sourabh Jain Acked-by: Hari Bathini Acked-by: Baoquan He Cc: Akhil Raj Cc: Bjorn Helgaas Cc: Borislav Petkov (AMD) Cc: Boris Ostrovsky Cc: Dave Hansen Cc: Dave Young Cc: David Hildenbrand Cc: Eric W. Biederman Cc: Greg Kroah-Hartman Cc: "H. Peter Anvin" Cc: Ingo Molnar Cc: Jonathan Corbet Cc: Konrad Rzeszutek Wilk Cc: Mimi Zohar Cc: Naveen N. Rao Cc: Oscar Salvador Cc: "Rafael J. Wysocki" Cc: Sean Christopherson Cc: Takashi Iwai Cc: Thomas Gleixner Cc: Thomas Weißschuh Cc: Valentin Schneider Cc: Vivek Goyal Cc: Vlastimil Babka Signed-off-by: Andrew Morton --- include/linux/kexec.h | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'include') diff --git a/include/linux/kexec.h b/include/linux/kexec.h index df395f888915..172e9a544928 100644 --- a/include/linux/kexec.h +++ b/include/linux/kexec.h @@ -486,6 +486,14 @@ static inline void arch_kexec_pre_free_pages(void *vaddr, unsigned int pages) { static inline void arch_crash_handle_hotplug_event(struct kimage *image) { } #endif +#ifndef crash_hotplug_cpu_support +static inline int crash_hotplug_cpu_support(void) { return 0; } +#endif + +#ifndef crash_hotplug_memory_support +static inline int crash_hotplug_memory_support(void) { return 0; } +#endif + #else /* !CONFIG_KEXEC_CORE */ struct pt_regs; struct task_struct; -- cgit v1.2.3 From a72bbec70da285a7e09e53fb13c2da7da2032da9 Mon Sep 17 00:00:00 2001 From: Eric DeVolder Date: Mon, 14 Aug 2023 17:44:44 -0400 Subject: crash: hotplug support for kexec_load() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The hotplug support for kexec_load() requires changes to the userspace kexec-tools and a little extra help from the kernel. Given a kdump capture kernel loaded via kexec_load(), and a subsequent hotplug event, the crash hotplug handler finds the elfcorehdr and rewrites it to reflect the hotplug change. That is the desired outcome, however, at kernel panic time, the purgatory integrity check fails (because the elfcorehdr changed), and the capture kernel does not boot and no vmcore is generated. Therefore, the userspace kexec-tools/kexec must indicate to the kernel that the elfcorehdr can be modified (because the kexec excluded the elfcorehdr from the digest, and sized the elfcorehdr memory buffer appropriately). To facilitate hotplug support with kexec_load(): - a new kexec flag KEXEC_UPATE_ELFCOREHDR indicates that it is safe for the kernel to modify the kexec_load()'d elfcorehdr - the /sys/kernel/crash_elfcorehdr_size node communicates the preferred size of the elfcorehdr memory buffer - The sysfs crash_hotplug nodes (ie. /sys/devices/system/[cpu|memory]/crash_hotplug) dynamically take into account kexec_file_load() vs kexec_load() and KEXEC_UPDATE_ELFCOREHDR. This is critical so that the udev rule processing of crash_hotplug is all that is needed to determine if the userspace unload-then-load of the kdump image is to be skipped, or not. The proposed udev rule change looks like: # The kernel updates the crash elfcorehdr for CPU and memory changes SUBSYSTEM=="cpu", ATTRS{crash_hotplug}=="1", GOTO="kdump_reload_end" SUBSYSTEM=="memory", ATTRS{crash_hotplug}=="1", GOTO="kdump_reload_end" The table below indicates the behavior of kexec_load()'d kdump image updates (with the new udev crash_hotplug rule in place): Kernel |Kexec -------+-----+---- Old |Old |New | a | a -------+-----+---- New | a | b -------+-----+---- where kexec 'old' and 'new' delineate kexec-tools has the needed modifications for the crash hotplug feature, and kernel 'old' and 'new' delineate the kernel supports this crash hotplug feature. Behavior 'a' indicates the unload-then-reload of the entire kdump image. For the kexec 'old' column, the unload-then-reload occurs due to the missing flag KEXEC_UPDATE_ELFCOREHDR. An 'old' kernel (with 'new' kexec) does not present the crash_hotplug sysfs node, which leads to the unload-then-reload of the kdump image. Behavior 'b' indicates the desired optimized behavior of the kernel directly modifying the elfcorehdr and avoiding the unload-then-reload of the kdump image. If the udev rule is not updated with crash_hotplug node check, then no matter any combination of kernel or kexec is new or old, the kdump image continues to be unload-then-reload on hotplug changes. To fully support crash hotplug feature, there needs to be a rollout of kernel, kexec-tools and udev rule changes. However, the order of the rollout of these pieces does not matter; kexec_load()'d kdump images still function for hotplug as-is. Link: https://lkml.kernel.org/r/20230814214446.6659-7-eric.devolder@oracle.com Signed-off-by: Eric DeVolder Suggested-by: Hari Bathini Acked-by: Hari Bathini Acked-by: Baoquan He Cc: Akhil Raj Cc: Bjorn Helgaas Cc: Borislav Petkov (AMD) Cc: Boris Ostrovsky Cc: Dave Hansen Cc: Dave Young Cc: David Hildenbrand Cc: Eric W. Biederman Cc: Greg Kroah-Hartman Cc: "H. Peter Anvin" Cc: Ingo Molnar Cc: Jonathan Corbet Cc: Konrad Rzeszutek Wilk Cc: Mimi Zohar Cc: Naveen N. Rao Cc: Oscar Salvador Cc: "Rafael J. Wysocki" Cc: Sean Christopherson Cc: Sourabh Jain Cc: Takashi Iwai Cc: Thomas Gleixner Cc: Thomas Weißschuh Cc: Valentin Schneider Cc: Vivek Goyal Cc: Vlastimil Babka Signed-off-by: Andrew Morton --- include/linux/kexec.h | 14 ++++++++++++-- include/uapi/linux/kexec.h | 1 + 2 files changed, 13 insertions(+), 2 deletions(-) (limited to 'include') diff --git a/include/linux/kexec.h b/include/linux/kexec.h index 172e9a544928..32c78078552c 100644 --- a/include/linux/kexec.h +++ b/include/linux/kexec.h @@ -320,6 +320,10 @@ struct kimage { unsigned int preserve_context : 1; /* If set, we are using file mode kexec syscall */ unsigned int file_mode:1; +#ifdef CONFIG_CRASH_HOTPLUG + /* If set, allow changes to elfcorehdr of kexec_load'd image */ + unsigned int update_elfcorehdr:1; +#endif #ifdef ARCH_HAS_KIMAGE_ARCH struct kimage_arch arch; @@ -396,9 +400,9 @@ bool kexec_load_permitted(int kexec_image_type); /* List of defined/legal kexec flags */ #ifndef CONFIG_KEXEC_JUMP -#define KEXEC_FLAGS KEXEC_ON_CRASH +#define KEXEC_FLAGS (KEXEC_ON_CRASH | KEXEC_UPDATE_ELFCOREHDR) #else -#define KEXEC_FLAGS (KEXEC_ON_CRASH | KEXEC_PRESERVE_CONTEXT) +#define KEXEC_FLAGS (KEXEC_ON_CRASH | KEXEC_PRESERVE_CONTEXT | KEXEC_UPDATE_ELFCOREHDR) #endif /* List of defined/legal kexec file flags */ @@ -486,6 +490,8 @@ static inline void arch_kexec_pre_free_pages(void *vaddr, unsigned int pages) { static inline void arch_crash_handle_hotplug_event(struct kimage *image) { } #endif +int crash_check_update_elfcorehdr(void); + #ifndef crash_hotplug_cpu_support static inline int crash_hotplug_cpu_support(void) { return 0; } #endif @@ -494,6 +500,10 @@ static inline int crash_hotplug_cpu_support(void) { return 0; } static inline int crash_hotplug_memory_support(void) { return 0; } #endif +#ifndef crash_get_elfcorehdr_size +static inline unsigned int crash_get_elfcorehdr_size(void) { return 0; } +#endif + #else /* !CONFIG_KEXEC_CORE */ struct pt_regs; struct task_struct; diff --git a/include/uapi/linux/kexec.h b/include/uapi/linux/kexec.h index 981016e05cfa..01766dd839b0 100644 --- a/include/uapi/linux/kexec.h +++ b/include/uapi/linux/kexec.h @@ -12,6 +12,7 @@ /* kexec flags for different usage scenarios */ #define KEXEC_ON_CRASH 0x00000001 #define KEXEC_PRESERVE_CONTEXT 0x00000002 +#define KEXEC_UPDATE_ELFCOREHDR 0x00000004 #define KEXEC_ARCH_MASK 0xffff0000 /* -- cgit v1.2.3 From dce8f8ed1de1d9d6d27c5ccd202ce4ec163b100c Mon Sep 17 00:00:00 2001 From: Oleg Nesterov Date: Wed, 23 Aug 2023 19:08:06 +0200 Subject: document while_each_thread(), change first_tid() to use for_each_thread() Add the comment to explain that while_each_thread(g,t) is not rcu-safe unless g is stable (e.g. current). Even if g is a group leader and thus can't exit before t, t or another sub-thread can exec and remove g from the thread_group list. The only lockless user of while_each_thread() is first_tid() and it is fine in that it can't loop forever, yet for_each_thread() looks better and I am going to change while_each_thread/next_thread. Link: https://lkml.kernel.org/r/20230823170806.GA11724@redhat.com Signed-off-by: Oleg Nesterov Cc: Eric W. Biederman Signed-off-by: Andrew Morton --- include/linux/sched/signal.h | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'include') diff --git a/include/linux/sched/signal.h b/include/linux/sched/signal.h index 0deebe2ab07d..0014d3adaf84 100644 --- a/include/linux/sched/signal.h +++ b/include/linux/sched/signal.h @@ -648,6 +648,10 @@ extern void flush_itimer_signals(void); extern bool current_is_single_threaded(void); +/* + * Without tasklist/siglock it is only rcu-safe if g can't exit/exec, + * otherwise next_thread(t) will never reach g after list_del_rcu(g). + */ #define while_each_thread(g, t) \ while ((t = next_thread(t)) != g) -- cgit v1.2.3