Support an option

        CONFIG_PERCPU_ZERO_BASED

that makes offsets for per cpu variables start at zero.

If a percpu area starts at zero then

1. We do not need RELOC_HIDE anymore

2. Indexes off the per cpu area for each processor are small

3. The percpu area "addresses" are offsets and we can then
   have allocpercpu/cpu_alloc in the future also use these
   offsets so that percpu functions can take any type of
   percpu address if it is provided by a percpu variable
   or a pointer obtained via allocpercpu/cpu_alloc.

The linker area boundaries variables are different for zero based
percpu segments:

__per_cpu_load  -> The address at which the percpu area was loaded
__per_cpu_size  -> The length of the per cpu area


Removes the &__per_cpu_x in lockdep. AFAICT The __per_cpu_x are already
pointers.

Signed-off-by: Christoph Lameter <[EMAIL PROTECTED]>

---
 include/asm-generic/percpu.h      |    7 ++++++-
 include/asm-generic/sections.h    |   10 ++++++++++
 include/asm-generic/vmlinux.lds.h |   15 +++++++++++++++
 init/main.c                       |   17 +++++++++--------
 kernel/lockdep.c                  |    4 ++--
 5 files changed, 42 insertions(+), 11 deletions(-)

Index: linux-2.6.24-rc3-mm2/include/asm-generic/percpu.h
===================================================================
--- linux-2.6.24-rc3-mm2.orig/include/asm-generic/percpu.h      2007-11-29 
22:05:58.359576450 -0800
+++ linux-2.6.24-rc3-mm2/include/asm-generic/percpu.h   2007-11-29 
22:06:22.750825804 -0800
@@ -42,8 +42,13 @@ extern unsigned long __per_cpu_offset[NR
  * Only S390 provides its own means of moving the pointer.
  */
 #ifndef SHIFT_PTR
+#ifdef CONFIG_PERCPU_ZERO_BASED
+#define SHIFT_PTR(__p, __offset) \
+       ((__typeof(__p))(((void *)(__p)) + (__offset)))
+#else
 #define SHIFT_PTR(__p, __offset)       RELOC_HIDE((__p), (__offset))
-#endif
+#endif /* CONFIG_PER_CPU_ZERO_BASED */
+#endif /* SHIFT_PTR */
 
 /*
  * A percpu variable may point to a discarded reghions. The following are
Index: linux-2.6.24-rc3-mm2/include/asm-generic/sections.h
===================================================================
--- linux-2.6.24-rc3-mm2.orig/include/asm-generic/sections.h    2007-11-29 
22:05:58.367576240 -0800
+++ linux-2.6.24-rc3-mm2/include/asm-generic/sections.h 2007-11-29 
22:06:22.754826440 -0800
@@ -9,7 +9,17 @@ extern char __bss_start[], __bss_stop[];
 extern char __init_begin[], __init_end[];
 extern char _sinittext[], _einittext[];
 extern char _end[];
+#ifdef CONFIG_PERCPU_ZERO_BASED
+extern char __per_cpu_load[];
+extern char ____per_cpu_size[];
+#define __per_cpu_size ((unsigned long)&____per_cpu_size)
+#define __per_cpu_start ((char *)0)
+#define __per_cpu_end ((char *)__per_cpu_size)
+#else
 extern char __per_cpu_start[], __per_cpu_end[];
+#define __per_cpu_load __per_cpu_start
+#define __per_cpu_size (__per_cpu_end - __per_cpu_start)
+#endif
 extern char __kprobes_text_start[], __kprobes_text_end[];
 extern char __initdata_begin[], __initdata_end[];
 extern char __start_rodata[], __end_rodata[];
Index: linux-2.6.24-rc3-mm2/include/asm-generic/vmlinux.lds.h
===================================================================
--- linux-2.6.24-rc3-mm2.orig/include/asm-generic/vmlinux.lds.h 2007-11-29 
22:06:03.486826118 -0800
+++ linux-2.6.24-rc3-mm2/include/asm-generic/vmlinux.lds.h      2007-11-29 
22:06:22.754826440 -0800
@@ -255,6 +255,20 @@
        *(.initcall7.init)                                              \
        *(.initcall7s.init)
 
+#ifdef CONFIG_PERCPU_ZERO_BASED
+#define PERCPU(align)                                                  \
+       . = ALIGN(align);                                               \
+       percpu : { } :percpu                                            \
+       __per_cpu_load = .;                                             \
+       .data.percpu 0 : AT(__per_cpu_load - LOAD_OFFSET) {             \
+               *(.data.percpu.first)                                   \
+               *(.data.percpu)                                         \
+               *(.data.percpu.shared_aligned)                          \
+               ____per_cpu_size = .;                                   \
+       }                                                               \
+       . = __per_cpu_load + ____per_cpu_size;                          \
+       data : { } :data
+#else
 #define PERCPU(align)                                                  \
        . = ALIGN(align);                                               \
        __per_cpu_start = .;                                            \
@@ -263,3 +277,4 @@
                *(.data.percpu.shared_aligned)                          \
        }                                                               \
        __per_cpu_end = .;
+#endif
Index: linux-2.6.24-rc3-mm2/init/main.c
===================================================================
--- linux-2.6.24-rc3-mm2.orig/init/main.c       2007-11-29 22:06:01.607326159 
-0800
+++ linux-2.6.24-rc3-mm2/init/main.c    2007-11-29 22:06:22.754826440 -0800
@@ -370,18 +370,19 @@ EXPORT_SYMBOL(__per_cpu_offset);
 
 static void __init setup_per_cpu_areas(void)
 {
-       unsigned long size, i;
-       char *ptr;
-       unsigned long nr_possible_cpus = num_possible_cpus();
+       unsigned long size;
+       int cpu;
 
        /* Copy section for each CPU (we discard the original) */
        size = ALIGN(PERCPU_ENOUGH_ROOM, PAGE_SIZE);
-       ptr = alloc_bootmem_pages(size * nr_possible_cpus);
 
-       for_each_possible_cpu(i) {
-               __per_cpu_offset[i] = ptr - __per_cpu_start;
-               memcpy(ptr, __per_cpu_start, __per_cpu_end - __per_cpu_start);
-               ptr += size;
+       for_each_possible_cpu(cpu) {
+               char *ptr;
+
+               ptr = alloc_bootmem_pages_node(NODE_DATA(cpu_to_node(cpu)),
+                                                               size);
+               __per_cpu_offset[cpu] = ptr - __per_cpu_start;
+               memcpy(ptr, __per_cpu_load, __per_cpu_size);
        }
 }
 #endif /* CONFIG_ARCH_SETS_UP_CPU_AREA */
Index: linux-2.6.24-rc3-mm2/kernel/lockdep.c
===================================================================
--- linux-2.6.24-rc3-mm2.orig/kernel/lockdep.c  2007-11-29 22:05:58.391576218 
-0800
+++ linux-2.6.24-rc3-mm2/kernel/lockdep.c       2007-11-29 22:06:22.754826440 
-0800
@@ -613,8 +613,8 @@ static int static_obj(void *obj)
         * percpu var?
         */
        for_each_possible_cpu(i) {
-               start = (unsigned long) &__per_cpu_start + per_cpu_offset(i);
-               end   = (unsigned long) &__per_cpu_start + PERCPU_ENOUGH_ROOM
+               start = (unsigned long) __per_cpu_start + per_cpu_offset(i);
+               end   = (unsigned long) __per_cpu_start + PERCPU_ENOUGH_ROOM
                                        + per_cpu_offset(i);
 
                if ((addr >= start) && (addr < end))

-- 
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

Reply via email to