summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@woody.osdl.org>2006-11-20 11:47:18 -0800
committerLinus Torvalds <torvalds@woody.osdl.org>2006-11-20 11:47:18 -0800
commitb3438f8266cb1f5010085ac47d7ad6a36a212164 (patch)
treebb74bd7a3ea7a629e380aa7761ba63a5e44992c7
parentf44ea623443ee0bec266d62f1cd346881224d47d (diff)
Add "pure_initcall" for static variable initialization
This is a quick hack to overcome the fact that SRCU currently does not allow static initializers, and we need to sometimes initialize those things before any other initializers (even "core" ones) can do so. Currently we don't allow this at all for modules, and the only user that needs is right now is cpufreq. As reported by Thomas Gleixner: "Commit b4dfdbb3c707474a2254c5b4d7e62be31a4b7da9 ("[PATCH] cpufreq: make the transition_notifier chain use SRCU breaks cpu frequency notification users, which register the callback > on core_init level." Cc: Thomas Gleixner <tglx@timesys.com> Cc: Ingo Molnar <mingo@elte.hu> Cc: Arjan van de Ven <arjan@infradead.org> Cc: Andrew Morton <akpm@osdl.org>, Signed-off-by: Linus Torvalds <torvalds@osdl.org>
-rw-r--r--drivers/cpufreq/cpufreq.c2
-rw-r--r--include/asm-generic/vmlinux.lds.h2
-rw-r--r--include/linux/init.h8
3 files changed, 11 insertions, 1 deletions
diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c
index 86e69b7f912..dd0c2623e27 100644
--- a/drivers/cpufreq/cpufreq.c
+++ b/drivers/cpufreq/cpufreq.c
@@ -59,7 +59,7 @@ static int __init init_cpufreq_transition_notifier_list(void)
srcu_init_notifier_head(&cpufreq_transition_notifier_list);
return 0;
}
-core_initcall(init_cpufreq_transition_notifier_list);
+pure_initcall(init_cpufreq_transition_notifier_list);
static LIST_HEAD(cpufreq_governor_list);
static DEFINE_MUTEX (cpufreq_governor_mutex);
diff --git a/include/asm-generic/vmlinux.lds.h b/include/asm-generic/vmlinux.lds.h
index 9d873163a7a..e60d6f21fa6 100644
--- a/include/asm-generic/vmlinux.lds.h
+++ b/include/asm-generic/vmlinux.lds.h
@@ -215,6 +215,8 @@
.notes : { *(.note.*) } :note
#define INITCALLS \
+ *(.initcall0.init) \
+ *(.initcall0s.init) \
*(.initcall1.init) \
*(.initcall1s.init) \
*(.initcall2.init) \
diff --git a/include/linux/init.h b/include/linux/init.h
index ff40ea118e3..5eb5d24b768 100644
--- a/include/linux/init.h
+++ b/include/linux/init.h
@@ -93,6 +93,14 @@ extern void setup_arch(char **);
static initcall_t __initcall_##fn##id __attribute_used__ \
__attribute__((__section__(".initcall" level ".init"))) = fn
+/*
+ * A "pure" initcall has no dependencies on anything else, and purely
+ * initializes variables that couldn't be statically initialized.
+ *
+ * This only exists for built-in code, not for modules.
+ */
+#define pure_initcall(fn) __define_initcall("0",fn,1)
+
#define core_initcall(fn) __define_initcall("1",fn,1)
#define core_initcall_sync(fn) __define_initcall("1s",fn,1s)
#define postcore_initcall(fn) __define_initcall("2",fn,2)