lkml.org 
[lkml]   [2009]   [Mar]   [31]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    Date
    From
    SubjectRe: [GIT RFC] percpu: use dynamic percpu allocator as the default percpu allocator
    On Wed, 25 Mar 2009 22:34:46 +0900
    Tejun Heo <tj@kernel.org> wrote:

    > Martin Schwidefsky wrote:
    > > On Wed, 25 Mar 2009 22:21:03 +0900
    > > Tejun Heo <tj@kernel.org> wrote:
    > >
    > >> Martin Schwidefsky wrote:
    > >>>> Martin's original patch should do the trick although it would be
    > >>>> slower for static symbols. I'll merge it and post the tree.
    > >>> No, my original patch doesn't work. It will break modules that use
    > >>> static per-cpu variables.
    > >> Oops. Even with the default offset adding macros? Heh... I think it
    > >> would be best to wait for your fix then.
    > >
    > > We could use HAVE_LEGACY_PER_CPU_AREA for the time being.
    >
    > Eh... The thing is that the patch kills the legacy default allocator.
    > We can move it into arch/s390 for the time being but it would be
    > simpler if the constant_p thing or something else could work. :-) Do
    > you think figuring out how to fix it will take long?

    I got the dynamic cpu allocator to work with the patch below. Anybody
    with an objection against the SHIFT_PERCPU_VAR macro ?

    --
    blue skies,
    Martin.

    "Reality continues to ruin my life." - Calvin.

    ---
    Subject: [PATCH] introduce SHIFT_PERCPU_VAR

    From: Martin Schwidefsky <schwidefsky@de.ibm.com>

    Introduce SHIFT_PERCPU_VAR to make it possible to use the dynamic
    percpu allocator on s390. The background for the new macro is the
    addressing limitation on s390 for local variables in an elf object.

    Every variable that the compiler considers to be local to an elf object
    has to be addressable with an load-address-relative-long (LARL)
    instruction, which has a range of +-4GB. A static per-cpu variable is
    allocated in the .data.percpu section. If such a variable is defined in
    a module the module loader will relocate this section to some place
    which will be outside the +-4GB range. So far we used SHIFT_PERCPU_PTR
    to add an indirection over the global offset table via a GOTENT
    reloction. The GOT for the module is created by the module loader
    and is located right next to the module code. That corrects the problem
    with the LARL addressability but GOTENT works only for symbols, not for
    dynamically allocated per-cpu memory. If the dynamic percpu allocator
    is used on s390 the build breaks.

    In order to fix this we need to distinguish the dynamically allocated
    per-cpu objects from the per-cpu variables. For the former we can
    use a simple RELOC_HIDE, for the later we have to use our GOTENT
    indirection.

    Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
    ---

    arch/alpha/include/asm/percpu.h | 2 ++
    arch/s390/Kconfig | 3 ---
    arch/s390/include/asm/percpu.h | 12 ++++++------
    include/asm-generic/percpu.h | 10 +++++++---
    4 files changed, 15 insertions(+), 12 deletions(-)

    diff -urpN linux-next/arch/alpha/include/asm/percpu.h linux-s390/arch/alpha/include/asm/percpu.h
    --- linux-next/arch/alpha/include/asm/percpu.h 2009-03-31 15:55:03.000000000 +0200
    +++ linux-s390/arch/alpha/include/asm/percpu.h 2009-03-31 15:55:46.000000000 +0200
    @@ -47,6 +47,8 @@ extern unsigned long __per_cpu_offset[NR
    : "=&r"(__ptr), "=&r"(tmp_gp)); \
    (typeof(&per_cpu_var(var)))(__ptr + (offset)); })

    +#define SHIFT_PERCPU_VAR(var, offset) SHIFT_PERCPU_PTR(var, offset)
    +
    #define PER_CPU_ATTRIBUTES __used

    #endif /* MODULE */
    diff -urpN linux-next/arch/s390/include/asm/percpu.h linux-s390/arch/s390/include/asm/percpu.h
    --- linux-next/arch/s390/include/asm/percpu.h 2009-03-31 15:55:03.000000000 +0200
    +++ linux-s390/arch/s390/include/asm/percpu.h 2009-03-31 15:55:46.000000000 +0200
    @@ -13,19 +13,19 @@
    */
    #if defined(__s390x__) && defined(MODULE)

    -#define SHIFT_PERCPU_PTR(ptr,offset) (({ \
    +#define SHIFT_PERCPU_VAR(ptr,offset) (({ \
    extern int simple_identifier_##var(void); \
    unsigned long *__ptr; \
    - asm ( "larl %0, %1@GOTENT" \
    + asm ( "larl %0, %1@GOTENT" \
    : "=a" (__ptr) : "X" (ptr) ); \
    (typeof(ptr))((*__ptr) + (offset)); }))

    #else

    -#define SHIFT_PERCPU_PTR(ptr, offset) (({ \
    - extern int simple_identifier_##var(void); \
    - unsigned long __ptr; \
    - asm ( "" : "=a" (__ptr) : "0" (ptr) ); \
    +#define SHIFT_PERCPU_VAR(ptr, offset) (({ \
    + extern int simple_identifier_##var(void); \
    + unsigned long __ptr; \
    + asm ( "" : "=a" (__ptr) : "0" (ptr) ); \
    (typeof(ptr)) (__ptr + (offset)); }))

    #endif
    diff -urpN linux-next/arch/s390/Kconfig linux-s390/arch/s390/Kconfig
    --- linux-next/arch/s390/Kconfig 2009-03-31 15:55:10.000000000 +0200
    +++ linux-s390/arch/s390/Kconfig 2009-03-31 15:55:36.000000000 +0200
    @@ -72,9 +72,6 @@ config PGSTE
    config VIRT_CPU_ACCOUNTING
    def_bool y

    -config HAVE_LEGACY_PER_CPU_AREA
    - def_bool y
    -
    mainmenu "Linux Kernel Configuration"

    config S390
    diff -urpN linux-next/include/asm-generic/percpu.h linux-s390/include/asm-generic/percpu.h
    --- linux-next/include/asm-generic/percpu.h 2009-03-31 15:55:03.000000000 +0200
    +++ linux-s390/include/asm-generic/percpu.h 2009-03-31 15:55:46.000000000 +0200
    @@ -48,17 +48,21 @@ extern unsigned long __per_cpu_offset[NR
    #define SHIFT_PERCPU_PTR(__p, __offset) RELOC_HIDE((__p), (__offset))
    #endif

    +#ifndef SHIFT_PERCPU_VAR
    +#define SHIFT_PERCPU_VAR(__p, __offset) RELOC_HIDE((__p), (__offset))
    +#endif
    +
    /*
    * A percpu variable may point to a discarded regions. The following are
    * established ways to produce a usable pointer from the percpu variable
    * offset.
    */
    #define per_cpu(var, cpu) \
    - (*SHIFT_PERCPU_PTR(&per_cpu_var(var), per_cpu_offset(cpu)))
    + (*SHIFT_PERCPU_VAR(&per_cpu_var(var), per_cpu_offset(cpu)))
    #define __get_cpu_var(var) \
    - (*SHIFT_PERCPU_PTR(&per_cpu_var(var), my_cpu_offset))
    + (*SHIFT_PERCPU_VAR(&per_cpu_var(var), my_cpu_offset))
    #define __raw_get_cpu_var(var) \
    - (*SHIFT_PERCPU_PTR(&per_cpu_var(var), __my_cpu_offset))
    + (*SHIFT_PERCPU_VAR(&per_cpu_var(var), __my_cpu_offset))


    #ifdef CONFIG_HAVE_SETUP_PER_CPU_AREA

    \
     
     \ /
      Last update: 2009-03-31 18:57    [W:4.095 / U:0.032 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site