Add "pure_initcall" for static variable initialization
authorLinus Torvalds <torvalds@woody.osdl.org>
Mon, 20 Nov 2006 19:47:18 +0000 (11:47 -0800)
committerLinus Torvalds <torvalds@woody.osdl.org>
Mon, 20 Nov 2006 19:47:18 +0000 (11:47 -0800)
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>
drivers/cpufreq/cpufreq.c
include/asm-generic/vmlinux.lds.h
include/linux/init.h

index 86e69b7f9122d3639e834307c5a1662e33ee8986..dd0c2623e27be0312eba1220c8d1eb38fe09bef3 100644 (file)
@@ -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);
index 9d873163a7ab09dfe605e2a2a49c5176f1b347e9..e60d6f21fa62f25bee576f58b36fea2ead229a7b 100644 (file)
                .notes : { *(.note.*) } :note
 
 #define INITCALLS                                                      \
+       *(.initcall0.init)                                              \
+       *(.initcall0s.init)                                             \
        *(.initcall1.init)                                              \
        *(.initcall1s.init)                                             \
        *(.initcall2.init)                                              \
index ff40ea118e3a7798f2a3a092be3cc238788cbd2c..5eb5d24b7680fea25a97b44df24424e60342658b 100644 (file)
@@ -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)