From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753980AbYKSOxy (ORCPT ); Wed, 19 Nov 2008 09:53:54 -0500 Received: (majordomo@vger.kernel.org) by vger.kernel.org id S1753543AbYKSOxp (ORCPT ); Wed, 19 Nov 2008 09:53:45 -0500 Received: from ozlabs.org ([203.10.76.45]:56318 "EHLO ozlabs.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753541AbYKSOxo (ORCPT ); Wed, 19 Nov 2008 09:53:44 -0500 From: Rusty Russell To: linux-kernel@vger.kernel.org Subject: core_param: call these really, really early. Date: Thu, 20 Nov 2008 01:23:41 +1030 User-Agent: KMail/1.10.1 (Linux/2.6.27-7-generic; KDE/4.1.2; i686; ; ) Cc: Christoph Lameter MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Disposition: inline Message-Id: <200811200123.41353.rusty@rustcorp.com.au> Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Transfer-Encoding: 8bit X-MIME-Autoconverted: from base64 to 8bit by alpha id mAJErxdq008340 As soon as we have command line, so even before early_param. Theyjust set vars, so it makes sense to do them as early as possible. This allows them to replace early_param, and fixes a bug in the newcpu_alloc implementation patches which was a complete PITA to find. Signed-off-by: Rusty Russell --- include/asm-generic/vmlinux.lds.h | 3 +++ include/linux/moduleparam.h | 26 ++++++++++++++++---------- init/main.c | 25 ++++++++++++++++++++++++- kernel/params.c | 20 ++++++++++---------- 4 files changed, 53 insertions(+), 21 deletions(-) diff -r 65aebfe44ef1 include/asm-generic/vmlinux.lds.h--- a/include/asm-generic/vmlinux.lds.h Wed Nov 19 22:47:52 2008 +1030+++ b/include/asm-generic/vmlinux.lds.h Wed Nov 19 23:58:08 2008 +1030@@ -213,6 +213,9 @@ VMLINUX_SYMBOL(__start___param) = .; \ *(__param) \ VMLINUX_SYMBOL(__stop___param) = .; \+ VMLINUX_SYMBOL(__start___core_param) = .; \+ *(__core_param) \+ VMLINUX_SYMBOL(__stop___core_param) = .; \ . = ALIGN((align)); \ VMLINUX_SYMBOL(__end_rodata) = .; \ } \diff -r 65aebfe44ef1 include/linux/moduleparam.h--- a/include/linux/moduleparam.h Wed Nov 19 22:47:52 2008 +1030+++ b/include/linux/moduleparam.h Wed Nov 19 23:58:08 2008 +1030@@ -79,7 +79,7 @@ parameters. perm sets the visibility in sysfs: 000 means it's not there, read bits mean it's readable, write bits mean it's writable. */-#define __module_param_call(prefix, name, set, get, arg, perm) \+#define __module_param_call(prefix, section, name, set, get, arg, perm) \ /* Default value instead of permissions? */ \ static int __param_perm_check_##name __attribute__((unused)) = \ BUILD_BUG_ON_ZERO((perm) < 0 || (perm) > 0777 || ((perm) & 2)) \@@ -87,11 +87,12 @@ static const char __param_str_##name[] = prefix #name; \ static struct kernel_param __moduleparam_const __param_##name \ __used \- __attribute__ ((unused,__section__ ("__param"),aligned(sizeof(void *)))) \+ __attribute__ ((unused, __section__(section), aligned(sizeof(void *)))) \ = { __param_str_##name, perm, set, get, { arg } } #define module_param_call(name, set, get, arg, perm) \- __module_param_call(MODULE_PARAM_PREFIX, name, set, get, arg, perm)+ __module_param_call(MODULE_PARAM_PREFIX, "__param", \+ name, set, get, arg, perm) /* Helper functions: type is byte, short, ushort, int, uint, long, ulong, charp, bool or invbool, or XXX if you define param_get_XXX,@@ -106,21 +107,22 @@ #ifndef MODULE /**- * core_param - define a historical core kernel parameter.+ * core_param - define a core kernel parameter to be set very early * @name: the name of the cmdline and sysfs parameter (often the same as var) * @var: the variable * @type: the type (for param_set_##type and param_get_##type) * @perm: visibility in sysfs *- * core_param is just like module_param(), but cannot be modular and- * doesn't add a prefix (such as "printk."). This is for compatibility- * with __setup(), and it makes sense as truly core parameters aren't- * tied to the particular file they're in.+ * core_param is just like module_param(), but cannot be modular,+ * doesn't add a prefix (such as "printk.") and is called insanely+ * early in boot. This is for compatibility with __setup(), and it+ * makes sense as truly core parameters aren't tied to the particular+ * file they're in. */ #define core_param(name, var, type, perm) \ param_check_##type(name, &(var)); \- __module_param_call("", name, param_set_##type, param_get_##type, \- &var, perm)+ __module_param_call("", "__core_param", name, param_set_##type, \+ param_get_##type, &var, perm) #endif /* !MODULE */ /* Actually copy string: maxlen param is usually sizeof(string). */@@ -224,4 +226,8 @@ { } #endif +/* Created by include/asm-generic/vmlinux.lds.h */+extern struct kernel_param __start___core_param[], __stop___core_param[];+extern struct kernel_param __start___param[], __stop___param[];+ #endif /* _LINUX_MODULE_PARAMS_H */diff -r 65aebfe44ef1 init/main.c--- a/init/main.c Wed Nov 19 22:47:52 2008 +1030+++ b/init/main.c Wed Nov 19 23:58:08 2008 +1030@@ -256,12 +256,32 @@ early_param("loglevel", loglevel); +static bool __init is_core_param(const char *param)+{+ const struct kernel_param *i;++ for (i = __start___core_param; i < __stop___core_param; i++)+ if (strcmp(param, i->name) == 0)+ return true;+ return false;+}++/* We can ignore options not found in core params. */+static int __init unknown_core_ok(char *param, char *val)+{+ return 0;+}+ /* * Unknown boot options get handed to init, unless they look like * failed parameters */ static int __init unknown_bootoption(char *param, char *val) {+ /* Already handled as a core param? */+ if (is_core_param(param))+ return 0;+ /* Change NUL term back to "=", to make "param" the whole string. */ if (val) { /* param=val or param="val"? */@@ -539,7 +559,6 @@ asmlinkage void __init start_kernel(void) { char * command_line;- extern struct kernel_param __start___param[], __stop___param[]; smp_setup_processor_id(); @@ -569,6 +588,10 @@ setup_arch(&command_line); mm_init_owner(&init_mm, &init_task); setup_command_line(command_line);+ parse_args("Core params", command_line, __start___core_param,+ __stop___core_param - __start___core_param,+ unknown_core_ok);+ unwind_setup(); setup_per_cpu_areas(); setup_nr_cpu_ids();diff -r 65aebfe44ef1 kernel/params.c--- a/kernel/params.c Wed Nov 19 22:47:52 2008 +1030+++ b/kernel/params.c Wed Nov 19 23:58:08 2008 +1030@@ -376,8 +376,6 @@ #define to_module_attr(n) container_of(n, struct module_attribute, attr); #define to_module_kobject(n) container_of(n, struct module_kobject, kobj); -extern struct kernel_param __start___param[], __stop___param[];- struct param_attribute { struct module_attribute mattr;@@ -636,15 +634,17 @@ continue; dot = strchr(kp->name, '.');- if (!dot) {- /* This happens for core_param() */- strcpy(modname, "kernel");- name_len = 0;- } else {- name_len = dot - kp->name + 1;- strlcpy(modname, kp->name, name_len);- }+ BUG_ON(!dot);+ name_len = dot - kp->name + 1;+ strlcpy(modname, kp->name, name_len); kernel_add_sysfs_param(modname, kp, name_len);+ }++ for (kp = __start___core_param; kp < __stop___core_param; kp++) {+ if (kp->perm == 0)+ continue;++ kernel_add_sysfs_param("kernel", kp, 0); } } {.n++%ݶw{.n+{G{ayʇڙ,jfhz_(階ݢj"mG?&~iOzv^m ?I