Commit b3438f8266cb1f5010085ac47d7ad6a36a212164

Authored by Linus Torvalds
1 parent f44ea62344

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>

Showing 3 changed files with 11 additions and 1 deletions Side-by-side Diff

drivers/cpufreq/cpufreq.c
... ... @@ -59,7 +59,7 @@
59 59 srcu_init_notifier_head(&cpufreq_transition_notifier_list);
60 60 return 0;
61 61 }
62   -core_initcall(init_cpufreq_transition_notifier_list);
  62 +pure_initcall(init_cpufreq_transition_notifier_list);
63 63  
64 64 static LIST_HEAD(cpufreq_governor_list);
65 65 static DEFINE_MUTEX (cpufreq_governor_mutex);
include/asm-generic/vmlinux.lds.h
... ... @@ -215,6 +215,8 @@
215 215 .notes : { *(.note.*) } :note
216 216  
217 217 #define INITCALLS \
  218 + *(.initcall0.init) \
  219 + *(.initcall0s.init) \
218 220 *(.initcall1.init) \
219 221 *(.initcall1s.init) \
220 222 *(.initcall2.init) \
include/linux/init.h
... ... @@ -93,6 +93,14 @@
93 93 static initcall_t __initcall_##fn##id __attribute_used__ \
94 94 __attribute__((__section__(".initcall" level ".init"))) = fn
95 95  
  96 +/*
  97 + * A "pure" initcall has no dependencies on anything else, and purely
  98 + * initializes variables that couldn't be statically initialized.
  99 + *
  100 + * This only exists for built-in code, not for modules.
  101 + */
  102 +#define pure_initcall(fn) __define_initcall("0",fn,1)
  103 +
96 104 #define core_initcall(fn) __define_initcall("1",fn,1)
97 105 #define core_initcall_sync(fn) __define_initcall("1s",fn,1s)
98 106 #define postcore_initcall(fn) __define_initcall("2",fn,2)