lkml.org 
[lkml]   [2014]   [Feb]   [13]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    Date
    From
    Subject[tip:x86/asmlinkage] lto, workaround: Add workaround for initcall reordering
    Commit-ID:  ef1b893c29d0dba778f67ad97b554b37f9108dcc
    Gitweb: http://git.kernel.org/tip/ef1b893c29d0dba778f67ad97b554b37f9108dcc
    Author: Andi Kleen <ak@linux.intel.com>
    AuthorDate: Sat, 8 Feb 2014 09:01:08 +0100
    Committer: H. Peter Anvin <hpa@linux.intel.com>
    CommitDate: Thu, 13 Feb 2014 20:24:13 -0800

    lto, workaround: Add workaround for initcall reordering

    Work around a LTO gcc problem: when there is no reference to a variable
    in a module it will be moved to the end of the program. This causes
    reordering of initcalls which the kernel does not like.
    Add a dummy reference function to avoid this. The function is
    deleted by the linker.

    This replaces a previous much slower workaround.

    Thanks to Jan "Honza" Hubička for suggesting this technique.

    Suggested-by: Jan Hubička <hubicka@ucw.cz>
    Signed-off-by: Andi Kleen <ak@linux.intel.com>
    Link: http://lkml.kernel.org/r/1391846481-31491-4-git-send-email-ak@linux.intel.com
    Signed-off-by: H. Peter Anvin <hpa@linux.intel.com>
    ---
    include/linux/init.h | 20 +++++++++++++++++++-
    1 file changed, 19 insertions(+), 1 deletion(-)

    diff --git a/include/linux/init.h b/include/linux/init.h
    index e168880..a3ba270 100644
    --- a/include/linux/init.h
    +++ b/include/linux/init.h
    @@ -163,6 +163,23 @@ extern bool initcall_debug;

    #ifndef __ASSEMBLY__

    +#ifdef CONFIG_LTO
    +/* Work around a LTO gcc problem: when there is no reference to a variable
    + * in a module it will be moved to the end of the program. This causes
    + * reordering of initcalls which the kernel does not like.
    + * Add a dummy reference function to avoid this. The function is
    + * deleted by the linker.
    + */
    +#define LTO_REFERENCE_INITCALL(x) \
    + ; /* yes this is needed */ \
    + static __used __exit void *reference_##x(void) \
    + { \
    + return &x; \
    + }
    +#else
    +#define LTO_REFERENCE_INITCALL(x)
    +#endif
    +
    /* initcalls are now grouped by functionality into separate
    * subsections. Ordering inside the subsections is determined
    * by link order.
    @@ -175,7 +192,8 @@ extern bool initcall_debug;

    #define __define_initcall(fn, id) \
    static initcall_t __initcall_##fn##id __used \
    - __attribute__((__section__(".initcall" #id ".init"))) = fn
    + __attribute__((__section__(".initcall" #id ".init"))) = fn; \
    + LTO_REFERENCE_INITCALL(__initcall_##fn##id)

    /*
    * Early initcalls run before initializing SMP.
    --
    To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
    the body of a message to majordomo@vger.kernel.org
    More majordomo info at http://vger.kernel.org/majordomo-info.html
    Please read the FAQ at http://www.tux.org/lkml/
    \
     
     \ /
      Last update: 2014-02-14 06:22    [W:2.367 / U:0.128 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site