2008-01-30 15:27:23

by Geert Uytterhoeven

[permalink] [raw]
Subject: Re: x86/non-x86: percpu, node ids, apic ids x86.git fixup

On Wed, 30 Jan 2008, Linux Kernel Mailing List wrote:
> Gitweb: http://git.kernel.org/git/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commit;h=dd5af90a7f3d79e04b7eace9a98644dbf2038f4d
> Commit: dd5af90a7f3d79e04b7eace9a98644dbf2038f4d
> Parent: 3212bff370c2f22e4987c6679ba485654cefb178
> Author: Mike Travis <[email protected]>
> AuthorDate: Wed Jan 30 13:33:32 2008 +0100
> Committer: Ingo Molnar <[email protected]>
> CommitDate: Wed Jan 30 13:33:32 2008 +0100
>
> x86/non-x86: percpu, node ids, apic ids x86.git fixup
>
> Signed-off-by: Ingo Molnar <[email protected]>
> Signed-off-by: Thomas Gleixner <[email protected]>
> ---
> arch/x86/Kconfig | 2 +-
> include/asm-generic/percpu.h | 12 ++----------
> init/main.c | 4 ++--
> kernel/module.c | 8 ++++++++

This broke powerpc (and presumably ia64 and sparc64) in current linux-2.6.git:

| init/main.c:376: error: static declaration of 'setup_per_cpu_areas' follows non-static declaration
| include2/asm/percpu.h:33: error: previous declaration of 'setup_per_cpu_areas' was here

as the generic and x86-specific parts were integrated, while the
powerpc/ia64/sparc64-specific parts are still missing.

> 4 files changed, 13 insertions(+), 13 deletions(-)
>
> diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
> index f0887d1..8e1b33c 100644
> --- a/arch/x86/Kconfig
> +++ b/arch/x86/Kconfig
> @@ -97,7 +97,7 @@ config GENERIC_TIME_VSYSCALL
> bool
> default X86_64
>
> -config ARCH_SETS_UP_PER_CPU_AREA
> +config HAVE_SETUP_PER_CPU_AREA
> def_bool X86_64
>
> config ARCH_SUPPORTS_OPROFILE
> diff --git a/include/asm-generic/percpu.h b/include/asm-generic/percpu.h
> index c41b1a7..4b8d31c 100644
> --- a/include/asm-generic/percpu.h
> +++ b/include/asm-generic/percpu.h
> @@ -47,7 +47,7 @@ extern unsigned long __per_cpu_offset[NR_CPUS];
> #endif
>
> /*
> - * A percpu variable may point to a discarded reghions. The following are
> + * A percpu variable may point to a discarded regions. The following are
> * established ways to produce a usable pointer from the percpu variable
> * offset.
> */
> @@ -59,18 +59,10 @@ extern unsigned long __per_cpu_offset[NR_CPUS];
> (*SHIFT_PERCPU_PTR(&per_cpu_var(var), __my_cpu_offset))
>
>
> -#ifdef CONFIG_ARCH_SETS_UP_PER_CPU_AREA
> +#ifdef CONFIG_HAVE_SETUP_PER_CPU_AREA
> extern void setup_per_cpu_areas(void);
> #endif
>
> -/* A macro to avoid #include hell... */
> -#define percpu_modcopy(pcpudst, src, size) \
> -do { \
> - unsigned int __i; \
> - for_each_possible_cpu(__i) \
> - memcpy((pcpudst)+per_cpu_offset(__i), \
> - (src), (size)); \
> -} while (0)
> #else /* ! SMP */
>
> #define per_cpu(var, cpu) (*((void)(cpu), &per_cpu_var(var)))
> diff --git a/init/main.c b/init/main.c
> index 5843fe9..3316dff 100644
> --- a/init/main.c
> +++ b/init/main.c
> @@ -363,7 +363,7 @@ static inline void smp_prepare_cpus(unsigned int maxcpus) { }
>
> #else
>
> -#ifndef CONFIG_ARCH_SETS_UP_PER_CPU_AREA
> +#ifndef CONFIG_HAVE_SETUP_PER_CPU_AREA
> unsigned long __per_cpu_offset[NR_CPUS] __read_mostly;
>
> EXPORT_SYMBOL(__per_cpu_offset);
> @@ -384,7 +384,7 @@ static void __init setup_per_cpu_areas(void)
> ptr += size;
> }
> }
> -#endif /* CONFIG_ARCH_SETS_UP_CPU_AREA */
> +#endif /* CONFIG_HAVE_SETUP_PER_CPU_AREA */
>
> /* Called by boot processor to activate the rest. */
> static void __init smp_init(void)
> diff --git a/kernel/module.c b/kernel/module.c
> index f6a4e72..bd60278 100644
> --- a/kernel/module.c
> +++ b/kernel/module.c
> @@ -430,6 +430,14 @@ static unsigned int find_pcpusec(Elf_Ehdr *hdr,
> return find_sec(hdr, sechdrs, secstrings, ".data.percpu");
> }
>
> +static void percpu_modcopy(void *pcpudest, const void *from, unsigned long size)
> +{
> + int cpu;
> +
> + for_each_possible_cpu(cpu)
> + memcpy(pcpudest + per_cpu_offset(cpu), from, size);
> +}
> +
> static int percpu_modinit(void)
> {
> pcpu_num_used = 2;
> -
> To unsubscribe from this list: send the line "unsubscribe git-commits-head" in
> the body of a message to [email protected]
> More majordomo info at http://vger.kernel.org/majordomo-info.html
>

With kind regards,

Geert Uytterhoeven
Software Architect

Sony Network and Software Technology Center Europe
The Corporate Village · Da Vincilaan 7-D1 · B-1935 Zaventem · Belgium

Phone: +32 (0)2 700 8453
Fax: +32 (0)2 700 8622
E-mail: [email protected]
Internet: http://www.sony-europe.com/

Sony Network and Software Technology Center Europe
A division of Sony Service Centre (Europe) N.V.
Registered office: Technologielaan 7 · B-1840 Londerzeel · Belgium
VAT BE 0413.825.160 · RPR Brussels
Fortis Bank Zaventem · Swift GEBABEBB08A · IBAN BE39001382358619


2008-01-30 16:02:35

by Mike Travis

[permalink] [raw]
Subject: Re: x86/non-x86: percpu, node ids, apic ids x86.git fixup

Geert Uytterhoeven wrote:
> On Wed, 30 Jan 2008, Linux Kernel Mailing List wrote:
>> Gitweb: http://git.kernel.org/git/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commit;h=dd5af90a7f3d79e04b7eace9a98644dbf2038f4d
>> Commit: dd5af90a7f3d79e04b7eace9a98644dbf2038f4d
>> Parent: 3212bff370c2f22e4987c6679ba485654cefb178
>> Author: Mike Travis <[email protected]>
>> AuthorDate: Wed Jan 30 13:33:32 2008 +0100
>> Committer: Ingo Molnar <[email protected]>
>> CommitDate: Wed Jan 30 13:33:32 2008 +0100
>>
>> x86/non-x86: percpu, node ids, apic ids x86.git fixup
>>
>> Signed-off-by: Ingo Molnar <[email protected]>
>> Signed-off-by: Thomas Gleixner <[email protected]>
>> ---
>> arch/x86/Kconfig | 2 +-
>> include/asm-generic/percpu.h | 12 ++----------
>> init/main.c | 4 ++--
>> kernel/module.c | 8 ++++++++
>
> This broke powerpc (and presumably ia64 and sparc64) in current linux-2.6.git:

I'm generating a "fixup patch" right now...

-Mike
>
> | init/main.c:376: error: static declaration of 'setup_per_cpu_areas' follows non-static declaration
> | include2/asm/percpu.h:33: error: previous declaration of 'setup_per_cpu_areas' was here
>
> as the generic and x86-specific parts were integrated, while the
> powerpc/ia64/sparc64-specific parts are still missing.
>
>> 4 files changed, 13 insertions(+), 13 deletions(-)
>>
>> diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
>> index f0887d1..8e1b33c 100644
>> --- a/arch/x86/Kconfig
>> +++ b/arch/x86/Kconfig
>> @@ -97,7 +97,7 @@ config GENERIC_TIME_VSYSCALL
>> bool
>> default X86_64
>>
>> -config ARCH_SETS_UP_PER_CPU_AREA
>> +config HAVE_SETUP_PER_CPU_AREA
>> def_bool X86_64
>>
>> config ARCH_SUPPORTS_OPROFILE
>> diff --git a/include/asm-generic/percpu.h b/include/asm-generic/percpu.h
>> index c41b1a7..4b8d31c 100644
>> --- a/include/asm-generic/percpu.h
>> +++ b/include/asm-generic/percpu.h
>> @@ -47,7 +47,7 @@ extern unsigned long __per_cpu_offset[NR_CPUS];
>> #endif
>>
>> /*
>> - * A percpu variable may point to a discarded reghions. The following are
>> + * A percpu variable may point to a discarded regions. The following are
>> * established ways to produce a usable pointer from the percpu variable
>> * offset.
>> */
>> @@ -59,18 +59,10 @@ extern unsigned long __per_cpu_offset[NR_CPUS];
>> (*SHIFT_PERCPU_PTR(&per_cpu_var(var), __my_cpu_offset))
>>
>>
>> -#ifdef CONFIG_ARCH_SETS_UP_PER_CPU_AREA
>> +#ifdef CONFIG_HAVE_SETUP_PER_CPU_AREA
>> extern void setup_per_cpu_areas(void);
>> #endif
>>
>> -/* A macro to avoid #include hell... */
>> -#define percpu_modcopy(pcpudst, src, size) \
>> -do { \
>> - unsigned int __i; \
>> - for_each_possible_cpu(__i) \
>> - memcpy((pcpudst)+per_cpu_offset(__i), \
>> - (src), (size)); \
>> -} while (0)
>> #else /* ! SMP */
>>
>> #define per_cpu(var, cpu) (*((void)(cpu), &per_cpu_var(var)))
>> diff --git a/init/main.c b/init/main.c
>> index 5843fe9..3316dff 100644
>> --- a/init/main.c
>> +++ b/init/main.c
>> @@ -363,7 +363,7 @@ static inline void smp_prepare_cpus(unsigned int maxcpus) { }
>>
>> #else
>>
>> -#ifndef CONFIG_ARCH_SETS_UP_PER_CPU_AREA
>> +#ifndef CONFIG_HAVE_SETUP_PER_CPU_AREA
>> unsigned long __per_cpu_offset[NR_CPUS] __read_mostly;
>>
>> EXPORT_SYMBOL(__per_cpu_offset);
>> @@ -384,7 +384,7 @@ static void __init setup_per_cpu_areas(void)
>> ptr += size;
>> }
>> }
>> -#endif /* CONFIG_ARCH_SETS_UP_CPU_AREA */
>> +#endif /* CONFIG_HAVE_SETUP_PER_CPU_AREA */
>>
>> /* Called by boot processor to activate the rest. */
>> static void __init smp_init(void)
>> diff --git a/kernel/module.c b/kernel/module.c
>> index f6a4e72..bd60278 100644
>> --- a/kernel/module.c
>> +++ b/kernel/module.c
>> @@ -430,6 +430,14 @@ static unsigned int find_pcpusec(Elf_Ehdr *hdr,
>> return find_sec(hdr, sechdrs, secstrings, ".data.percpu");
>> }
>>
>> +static void percpu_modcopy(void *pcpudest, const void *from, unsigned long size)
>> +{
>> + int cpu;
>> +
>> + for_each_possible_cpu(cpu)
>> + memcpy(pcpudest + per_cpu_offset(cpu), from, size);
>> +}
>> +
>> static int percpu_modinit(void)
>> {
>> pcpu_num_used = 2;
>> -
>> To unsubscribe from this list: send the line "unsubscribe git-commits-head" in
>> the body of a message to [email protected]
>> More majordomo info at http://vger.kernel.org/majordomo-info.html
>>
>
> With kind regards,
>
> Geert Uytterhoeven
> Software Architect
>
> Sony Network and Software Technology Center Europe
> The Corporate Village · Da Vincilaan 7-D1 · B-1935 Zaventem · Belgium
>
> Phone: +32 (0)2 700 8453
> Fax: +32 (0)2 700 8622
> E-mail: [email protected]
> Internet: http://www.sony-europe.com/
>
> Sony Network and Software Technology Center Europe
> A division of Sony Service Centre (Europe) N.V.
> Registered office: Technologielaan 7 · B-1840 Londerzeel · Belgium
> VAT BE 0413.825.160 · RPR Brussels
> Fortis Bank Zaventem · Swift GEBABEBB08A · IBAN BE39001382358619

2008-01-30 16:13:20

by Ingo Molnar

[permalink] [raw]
Subject: Re: x86/non-x86: percpu, node ids, apic ids x86.git fixup


* Mike Travis <[email protected]> wrote:

> > This broke powerpc (and presumably ia64 and sparc64) in current
> > linux-2.6.git:
>
> I'm generating a "fixup patch" right now...

thanks! Sorry about that: we cross-built on ARM but not on SMP non-x86
platforms so this dependency/breakage went unnoticed.

Ingo

2008-01-30 17:16:22

by Luck, Tony

[permalink] [raw]
Subject: RE: x86/non-x86: percpu, node ids, apic ids x86.git fixup

> > > This broke powerpc (and presumably ia64 and sparc64) in current
> > > linux-2.6.git:
> >
> > I'm generating a "fixup patch" right now...
>
> thanks! Sorry about that: we cross-built on ARM but not on SMP non-x86
> platforms so this dependency/breakage went unnoticed.

Yes ... all ia64 builds (UP and SMP) are broken at the moment. Please
Cc: me with the fixup patch.

Thanks

-Tony

2008-01-30 18:07:10

by Ingo Molnar

[permalink] [raw]
Subject: Re: x86/non-x86: percpu, node ids, apic ids x86.git fixup


* Luck, Tony <[email protected]> wrote:

> > thanks! Sorry about that: we cross-built on ARM but not on SMP
> > non-x86 platforms so this dependency/breakage went unnoticed.
>
> Yes ... all ia64 builds (UP and SMP) are broken at the moment. Please
> Cc: me with the fixup patch.

Could you check the patch below? With this applied to latest -git, ia64
buils fine for me in a cross-compiling environment. (but i dont know
whether it boots ...)

Ingo

----------------->
Subject: generic: percpu infrastructure to rebase the per cpu area to zero
From: [email protected]

* Support an option

CONFIG_HAVE_ZERO_BASED_PER_CPU

that makes offsets for per cpu variables to start at zero.

If a percpu area starts at zero then:

- We do not need RELOC_HIDE anymore

- Provides for the future capability of architectures providing
a per cpu allocator that returns offsets instead of pointers.
The offsets would be independent of the processor so that
address calculations can be done in a processor independent way.
Per cpu instructions can then add the processor specific offset
at the last minute possibly in an atomic instruction.

The data the linker provides is 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. The __per_cpu_x are already
pointers. There is no need to take the address.

* Changes generic setup_per_cpu_areas to allocate per_cpu space in
node local memory. This requires a generic early_cpu_to_node function.

Signed-off-by: Mike Travis <[email protected]>
Reviewed-by: Christoph Lameter <[email protected]>
Signed-off-by: Ingo Molnar <[email protected]>
---
arch/ia64/Kconfig | 2 -
arch/ia64/kernel/module.c | 11 --------
arch/powerpc/Kconfig | 2 -
arch/sparc64/mm/init.c | 5 ++++
include/asm-alpha/topology.h | 1
include/asm-generic/percpu.h | 7 ++++-
include/asm-generic/sections.h | 10 ++++++++
include/asm-generic/topology.h | 3 ++
include/asm-generic/vmlinux.lds.h | 15 ++++++++++++
include/asm-ia64/percpu.h | 29 +++++------------------
include/asm-ia64/topology.h | 1
include/asm-mips/mach-ip27/topology.h | 1
include/asm-powerpc/percpu.h | 29 +----------------------
include/asm-powerpc/topology.h | 1
include/asm-s390/percpu.h | 42 +++++++---------------------------
include/asm-sparc64/percpu.h | 22 ++---------------
init/main.c | 18 ++++++++------
kernel/lockdep.c | 4 +--
18 files changed, 78 insertions(+), 125 deletions(-)

Index: linux-x86.q/arch/ia64/Kconfig
===================================================================
--- linux-x86.q.orig/arch/ia64/Kconfig
+++ linux-x86.q/arch/ia64/Kconfig
@@ -80,7 +80,7 @@ config GENERIC_TIME_VSYSCALL
bool
default y

-config ARCH_SETS_UP_PER_CPU_AREA
+config HAVE_SETUP_PER_CPU_AREA
def_bool y

config DMI
Index: linux-x86.q/arch/ia64/kernel/module.c
===================================================================
--- linux-x86.q.orig/arch/ia64/kernel/module.c
+++ linux-x86.q/arch/ia64/kernel/module.c
@@ -940,14 +940,3 @@ module_arch_cleanup (struct module *mod)
if (mod->arch.core_unw_table)
unw_remove_unwind_table(mod->arch.core_unw_table);
}
-
-#ifdef CONFIG_SMP
-void
-percpu_modcopy (void *pcpudst, const void *src, unsigned long size)
-{
- unsigned int i;
- for_each_possible_cpu(i) {
- memcpy(pcpudst + per_cpu_offset(i), src, size);
- }
-}
-#endif /* CONFIG_SMP */
Index: linux-x86.q/arch/powerpc/Kconfig
===================================================================
--- linux-x86.q.orig/arch/powerpc/Kconfig
+++ linux-x86.q/arch/powerpc/Kconfig
@@ -42,7 +42,7 @@ config GENERIC_HARDIRQS
bool
default y

-config ARCH_SETS_UP_PER_CPU_AREA
+config HAVE_SETUP_PER_CPU_AREA
def_bool PPC64

config IRQ_PER_CPU
Index: linux-x86.q/arch/sparc64/mm/init.c
===================================================================
--- linux-x86.q.orig/arch/sparc64/mm/init.c
+++ linux-x86.q/arch/sparc64/mm/init.c
@@ -1328,6 +1328,11 @@ pgd_t swapper_pg_dir[2048];
static void sun4u_pgprot_init(void);
static void sun4v_pgprot_init(void);

+/* Dummy function */
+void __init setup_per_cpu_areas(void)
+{
+}
+
void __init paging_init(void)
{
unsigned long end_pfn, pages_avail, shift, phys_base;
Index: linux-x86.q/include/asm-alpha/topology.h
===================================================================
--- linux-x86.q.orig/include/asm-alpha/topology.h
+++ linux-x86.q/include/asm-alpha/topology.h
@@ -6,6 +6,7 @@
#include <asm/machvec.h>

#ifdef CONFIG_NUMA
+#define early_cpu_to_node(cpu) cpu_to_node(cpu)
static inline int cpu_to_node(int cpu)
{
int node;
Index: linux-x86.q/include/asm-generic/percpu.h
===================================================================
--- linux-x86.q.orig/include/asm-generic/percpu.h
+++ linux-x86.q/include/asm-generic/percpu.h
@@ -43,7 +43,12 @@ extern unsigned long __per_cpu_offset[NR
* Only S390 provides its own means of moving the pointer.
*/
#ifndef SHIFT_PERCPU_PTR
-#define SHIFT_PERCPU_PTR(__p, __offset) RELOC_HIDE((__p), (__offset))
+# ifdef CONFIG_HAVE_ZERO_BASED_PER_CPU
+# define SHIFT_PERCPU_PTR(__p, __offset) \
+ ((__typeof(__p))(((void *)(__p)) + (__offset)))
+# else
+# define SHIFT_PERCPU_PTR(__p, __offset) RELOC_HIDE((__p), (__offset))
+# endif /* CONFIG_HAVE_ZERO_BASED_PER_CPU */
#endif

/*
Index: linux-x86.q/include/asm-generic/sections.h
===================================================================
--- linux-x86.q.orig/include/asm-generic/sections.h
+++ linux-x86.q/include/asm-generic/sections.h
@@ -11,7 +11,17 @@ extern char _sinittext[], _einittext[];
extern char _sextratext[] __attribute__((weak));
extern char _eextratext[] __attribute__((weak));
extern char _end[];
+#ifdef CONFIG_HAVE_ZERO_BASED_PER_CPU
+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-x86.q/include/asm-generic/topology.h
===================================================================
--- linux-x86.q.orig/include/asm-generic/topology.h
+++ linux-x86.q/include/asm-generic/topology.h
@@ -32,6 +32,9 @@
#ifndef cpu_to_node
#define cpu_to_node(cpu) (0)
#endif
+#ifndef early_cpu_to_node
+#define early_cpu_to_node(cpu) cpu_to_node(cpu)
+#endif
#ifndef parent_node
#define parent_node(node) (0)
#endif
Index: linux-x86.q/include/asm-generic/vmlinux.lds.h
===================================================================
--- linux-x86.q.orig/include/asm-generic/vmlinux.lds.h
+++ linux-x86.q/include/asm-generic/vmlinux.lds.h
@@ -341,6 +341,20 @@
*(.initcall7.init) \
*(.initcall7s.init)

+#ifdef CONFIG_HAVE_ZERO_BASED_PER_CPU
+#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 = .; \
@@ -349,3 +363,4 @@
*(.data.percpu.shared_aligned) \
} \
__per_cpu_end = .;
+#endif
Index: linux-x86.q/include/asm-ia64/percpu.h
===================================================================
--- linux-x86.q.orig/include/asm-ia64/percpu.h
+++ linux-x86.q/include/asm-ia64/percpu.h
@@ -19,34 +19,14 @@
# define PER_CPU_ATTRIBUTES __attribute__((__model__ (__small__)))
#endif

-#define DECLARE_PER_CPU(type, name) \
- extern PER_CPU_ATTRIBUTES __typeof__(type) per_cpu__##name
-
-/*
- * Pretty much a literal copy of asm-generic/percpu.h, except that percpu_modcopy() is an
- * external routine, to avoid include-hell.
- */
#ifdef CONFIG_SMP

-extern unsigned long __per_cpu_offset[NR_CPUS];
-#define per_cpu_offset(x) (__per_cpu_offset[x])
-
-/* Equal to __per_cpu_offset[smp_processor_id()], but faster to access: */
-DECLARE_PER_CPU(unsigned long, local_per_cpu_offset);
+#define __my_cpu_offset __ia64_per_cpu_var(local_per_cpu_offset)

-#define per_cpu(var, cpu) (*RELOC_HIDE(&per_cpu__##var, __per_cpu_offset[cpu]))
-#define __get_cpu_var(var) (*RELOC_HIDE(&per_cpu__##var, __ia64_per_cpu_var(local_per_cpu_offset)))
-#define __raw_get_cpu_var(var) (*RELOC_HIDE(&per_cpu__##var, __ia64_per_cpu_var(local_per_cpu_offset)))
-
-extern void percpu_modcopy(void *pcpudst, const void *src, unsigned long size);
-extern void setup_per_cpu_areas (void);
extern void *per_cpu_init(void);

#else /* ! SMP */

-#define per_cpu(var, cpu) (*((void)(cpu), &per_cpu__##var))
-#define __get_cpu_var(var) per_cpu__##var
-#define __raw_get_cpu_var(var) per_cpu__##var
#define per_cpu_init() (__phys_per_cpu_start)

#endif /* SMP */
@@ -57,7 +37,12 @@ extern void *per_cpu_init(void);
* On the positive side, using __ia64_per_cpu_var() instead of __get_cpu_var() is slightly
* more efficient.
*/
-#define __ia64_per_cpu_var(var) (per_cpu__##var)
+#define __ia64_per_cpu_var(var) per_cpu__##var
+
+#include <asm-generic/percpu.h>
+
+/* Equal to __per_cpu_offset[smp_processor_id()], but faster to access: */
+DECLARE_PER_CPU(unsigned long, local_per_cpu_offset);

#endif /* !__ASSEMBLY__ */

Index: linux-x86.q/include/asm-ia64/topology.h
===================================================================
--- linux-x86.q.orig/include/asm-ia64/topology.h
+++ linux-x86.q/include/asm-ia64/topology.h
@@ -31,6 +31,7 @@
* Returns the number of the node containing CPU 'cpu'
*/
#define cpu_to_node(cpu) (int)(cpu_to_node_map[cpu])
+#define early_cpu_to_node(cpu) cpu_to_node(cpu)

/*
* Returns a bitmask of CPUs on Node 'node'.
Index: linux-x86.q/include/asm-mips/mach-ip27/topology.h
===================================================================
--- linux-x86.q.orig/include/asm-mips/mach-ip27/topology.h
+++ linux-x86.q/include/asm-mips/mach-ip27/topology.h
@@ -23,6 +23,7 @@ struct cpuinfo_ip27 {
extern struct cpuinfo_ip27 sn_cpu_info[NR_CPUS];

#define cpu_to_node(cpu) (sn_cpu_info[(cpu)].p_nodeid)
+#define early_cpu_to_node(cpu) cpu_to_node(cpu)
#define parent_node(node) (node)
#define node_to_cpumask(node) (hub_data(node)->h_cpus)
#define node_to_first_cpu(node) (first_cpu(node_to_cpumask(node)))
Index: linux-x86.q/include/asm-powerpc/percpu.h
===================================================================
--- linux-x86.q.orig/include/asm-powerpc/percpu.h
+++ linux-x86.q/include/asm-powerpc/percpu.h
@@ -16,34 +16,9 @@
#define __my_cpu_offset() get_paca()->data_offset
#define per_cpu_offset(x) (__per_cpu_offset(x))

-/* var is in discarded region: offset to particular copy we want */
-#define per_cpu(var, cpu) (*RELOC_HIDE(&per_cpu__##var, __per_cpu_offset(cpu)))
-#define __get_cpu_var(var) (*RELOC_HIDE(&per_cpu__##var, __my_cpu_offset()))
-#define __raw_get_cpu_var(var) (*RELOC_HIDE(&per_cpu__##var, local_paca->data_offset))
+#endif /* CONFIG_SMP */
+#endif /* __powerpc64__ */

-/* A macro to avoid #include hell... */
-#define percpu_modcopy(pcpudst, src, size) \
-do { \
- unsigned int __i; \
- for_each_possible_cpu(__i) \
- memcpy((pcpudst)+__per_cpu_offset(__i), \
- (src), (size)); \
-} while (0)
-
-extern void setup_per_cpu_areas(void);
-
-#else /* ! SMP */
-
-#define per_cpu(var, cpu) (*((void)(cpu), &per_cpu__##var))
-#define __get_cpu_var(var) per_cpu__##var
-#define __raw_get_cpu_var(var) per_cpu__##var
-
-#endif /* SMP */
-
-#define DECLARE_PER_CPU(type, name) extern __typeof__(type) per_cpu__##name
-
-#else
#include <asm-generic/percpu.h>
-#endif

#endif /* _ASM_POWERPC_PERCPU_H_ */
Index: linux-x86.q/include/asm-powerpc/topology.h
===================================================================
--- linux-x86.q.orig/include/asm-powerpc/topology.h
+++ linux-x86.q/include/asm-powerpc/topology.h
@@ -15,6 +15,7 @@ static inline int cpu_to_node(int cpu)
return numa_cpu_lookup_table[cpu];
}

+#define early_cpu_to_node(cpu) cpu_to_node(cpu)
#define parent_node(node) (node)

static inline cpumask_t node_to_cpumask(int node)
Index: linux-x86.q/include/asm-s390/percpu.h
===================================================================
--- linux-x86.q.orig/include/asm-s390/percpu.h
+++ linux-x86.q/include/asm-s390/percpu.h
@@ -13,49 +13,25 @@
*/
#if defined(__s390x__) && defined(MODULE)

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

#else

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

#endif

-#ifdef CONFIG_SMP
+#define __my_cpu_offset S390_lowcore.percpu_offset

-extern unsigned long __per_cpu_offset[NR_CPUS];
-
-#define __get_cpu_var(var) __reloc_hide(var,S390_lowcore.percpu_offset)
-#define __raw_get_cpu_var(var) __reloc_hide(var,S390_lowcore.percpu_offset)
-#define per_cpu(var,cpu) __reloc_hide(var,__per_cpu_offset[cpu])
-#define per_cpu_offset(x) (__per_cpu_offset[x])
-
-/* A macro to avoid #include hell... */
-#define percpu_modcopy(pcpudst, src, size) \
-do { \
- unsigned int __i; \
- for_each_possible_cpu(__i) \
- memcpy((pcpudst)+__per_cpu_offset[__i], \
- (src), (size)); \
-} while (0)
-
-#else /* ! SMP */
-
-#define __get_cpu_var(var) __reloc_hide(var,0)
-#define __raw_get_cpu_var(var) __reloc_hide(var,0)
-#define per_cpu(var,cpu) __reloc_hide(var,0)
-
-#endif /* SMP */
-
-#define DECLARE_PER_CPU(type, name) extern __typeof__(type) per_cpu__##name
+#include <asm-generic/percpu.h>

#endif /* __ARCH_S390_PERCPU__ */
Index: linux-x86.q/include/asm-sparc64/percpu.h
===================================================================
--- linux-x86.q.orig/include/asm-sparc64/percpu.h
+++ linux-x86.q/include/asm-sparc64/percpu.h
@@ -7,7 +7,6 @@ register unsigned long __local_per_cpu_o

#ifdef CONFIG_SMP

-#define setup_per_cpu_areas() do { } while (0)
extern void real_setup_per_cpu_areas(void);

extern unsigned long __per_cpu_base;
@@ -16,29 +15,14 @@ extern unsigned long __per_cpu_shift;
(__per_cpu_base + ((unsigned long)(__cpu) << __per_cpu_shift))
#define per_cpu_offset(x) (__per_cpu_offset(x))

-/* var is in discarded region: offset to particular copy we want */
-#define per_cpu(var, cpu) (*RELOC_HIDE(&per_cpu__##var, __per_cpu_offset(cpu)))
-#define __get_cpu_var(var) (*RELOC_HIDE(&per_cpu__##var, __local_per_cpu_offset))
-#define __raw_get_cpu_var(var) (*RELOC_HIDE(&per_cpu__##var, __local_per_cpu_offset))
-
-/* A macro to avoid #include hell... */
-#define percpu_modcopy(pcpudst, src, size) \
-do { \
- unsigned int __i; \
- for_each_possible_cpu(__i) \
- memcpy((pcpudst)+__per_cpu_offset(__i), \
- (src), (size)); \
-} while (0)
+#define __my_cpu_offset __local_per_cpu_offset
+
#else /* ! SMP */

#define real_setup_per_cpu_areas() do { } while (0)

-#define per_cpu(var, cpu) (*((void)cpu, &per_cpu__##var))
-#define __get_cpu_var(var) per_cpu__##var
-#define __raw_get_cpu_var(var) per_cpu__##var
-
#endif /* SMP */

-#define DECLARE_PER_CPU(type, name) extern __typeof__(type) per_cpu__##name
+#include <asm-generic/percpu.h>

#endif /* __ARCH_SPARC64_PERCPU__ */
Index: linux-x86.q/init/main.c
===================================================================
--- linux-x86.q.orig/init/main.c
+++ linux-x86.q/init/main.c
@@ -374,18 +374,20 @@ 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;
+ printk(KERN_INFO "(generic)PERCPU: Allocating %lu bytes of per cpu data\n", size);
+
+ for_each_possible_cpu(cpu) {
+ char *ptr = alloc_bootmem_pages_node(
+ NODE_DATA(early_cpu_to_node(cpu)), size);
+
+ __per_cpu_offset[cpu] = ptr - __per_cpu_start;
+ memcpy(ptr, __per_cpu_load, __per_cpu_size);
}
}
#endif /* CONFIG_HAVE_SETUP_PER_CPU_AREA */
Index: linux-x86.q/kernel/lockdep.c
===================================================================
--- linux-x86.q.orig/kernel/lockdep.c
+++ linux-x86.q/kernel/lockdep.c
@@ -609,8 +609,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))

2008-01-30 18:20:40

by Mike Travis

[permalink] [raw]
Subject: Re: x86/non-x86: percpu, node ids, apic ids x86.git fixup

Ingo Molnar wrote:
> * Luck, Tony <[email protected]> wrote:
>
>>> thanks! Sorry about that: we cross-built on ARM but not on SMP
>>> non-x86 platforms so this dependency/breakage went unnoticed.
>> Yes ... all ia64 builds (UP and SMP) are broken at the moment. Please
>> Cc: me with the fixup patch.
>
> Could you check the patch below? With this applied to latest -git, ia64
> buils fine for me in a cross-compiling environment. (but i dont know
> whether it boots ...)
>
> Ingo

This patch is from a different patch set (aka "zero-based" patch). That
one will be updated and resubmitted soon...

Thanks,
Mike

>
> ----------------->
> Subject: generic: percpu infrastructure to rebase the per cpu area to zero
> From: [email protected]
>
> * Support an option
>
> CONFIG_HAVE_ZERO_BASED_PER_CPU
>
> that makes offsets for per cpu variables to start at zero.
>
> If a percpu area starts at zero then:
>
> - We do not need RELOC_HIDE anymore
>
> - Provides for the future capability of architectures providing
> a per cpu allocator that returns offsets instead of pointers.
> The offsets would be independent of the processor so that
> address calculations can be done in a processor independent way.
> Per cpu instructions can then add the processor specific offset
> at the last minute possibly in an atomic instruction.
>
> The data the linker provides is 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. The __per_cpu_x are already
> pointers. There is no need to take the address.
>
> * Changes generic setup_per_cpu_areas to allocate per_cpu space in
> node local memory. This requires a generic early_cpu_to_node function.
>
> Signed-off-by: Mike Travis <[email protected]>
> Reviewed-by: Christoph Lameter <[email protected]>
> Signed-off-by: Ingo Molnar <[email protected]>
> ---
> arch/ia64/Kconfig | 2 -
> arch/ia64/kernel/module.c | 11 --------
> arch/powerpc/Kconfig | 2 -
> arch/sparc64/mm/init.c | 5 ++++
> include/asm-alpha/topology.h | 1
> include/asm-generic/percpu.h | 7 ++++-
> include/asm-generic/sections.h | 10 ++++++++
> include/asm-generic/topology.h | 3 ++
> include/asm-generic/vmlinux.lds.h | 15 ++++++++++++
> include/asm-ia64/percpu.h | 29 +++++------------------
> include/asm-ia64/topology.h | 1
> include/asm-mips/mach-ip27/topology.h | 1
> include/asm-powerpc/percpu.h | 29 +----------------------
> include/asm-powerpc/topology.h | 1
> include/asm-s390/percpu.h | 42 +++++++---------------------------
> include/asm-sparc64/percpu.h | 22 ++---------------
> init/main.c | 18 ++++++++------
> kernel/lockdep.c | 4 +--
> 18 files changed, 78 insertions(+), 125 deletions(-)
>
> Index: linux-x86.q/arch/ia64/Kconfig
> ===================================================================
> --- linux-x86.q.orig/arch/ia64/Kconfig
> +++ linux-x86.q/arch/ia64/Kconfig
> @@ -80,7 +80,7 @@ config GENERIC_TIME_VSYSCALL
> bool
> default y
>
> -config ARCH_SETS_UP_PER_CPU_AREA
> +config HAVE_SETUP_PER_CPU_AREA
> def_bool y
>
> config DMI
> Index: linux-x86.q/arch/ia64/kernel/module.c
> ===================================================================
> --- linux-x86.q.orig/arch/ia64/kernel/module.c
> +++ linux-x86.q/arch/ia64/kernel/module.c
> @@ -940,14 +940,3 @@ module_arch_cleanup (struct module *mod)
> if (mod->arch.core_unw_table)
> unw_remove_unwind_table(mod->arch.core_unw_table);
> }
> -
> -#ifdef CONFIG_SMP
> -void
> -percpu_modcopy (void *pcpudst, const void *src, unsigned long size)
> -{
> - unsigned int i;
> - for_each_possible_cpu(i) {
> - memcpy(pcpudst + per_cpu_offset(i), src, size);
> - }
> -}
> -#endif /* CONFIG_SMP */
> Index: linux-x86.q/arch/powerpc/Kconfig
> ===================================================================
> --- linux-x86.q.orig/arch/powerpc/Kconfig
> +++ linux-x86.q/arch/powerpc/Kconfig
> @@ -42,7 +42,7 @@ config GENERIC_HARDIRQS
> bool
> default y
>
> -config ARCH_SETS_UP_PER_CPU_AREA
> +config HAVE_SETUP_PER_CPU_AREA
> def_bool PPC64
>
> config IRQ_PER_CPU
> Index: linux-x86.q/arch/sparc64/mm/init.c
> ===================================================================
> --- linux-x86.q.orig/arch/sparc64/mm/init.c
> +++ linux-x86.q/arch/sparc64/mm/init.c
> @@ -1328,6 +1328,11 @@ pgd_t swapper_pg_dir[2048];
> static void sun4u_pgprot_init(void);
> static void sun4v_pgprot_init(void);
>
> +/* Dummy function */
> +void __init setup_per_cpu_areas(void)
> +{
> +}
> +
> void __init paging_init(void)
> {
> unsigned long end_pfn, pages_avail, shift, phys_base;
> Index: linux-x86.q/include/asm-alpha/topology.h
> ===================================================================
> --- linux-x86.q.orig/include/asm-alpha/topology.h
> +++ linux-x86.q/include/asm-alpha/topology.h
> @@ -6,6 +6,7 @@
> #include <asm/machvec.h>
>
> #ifdef CONFIG_NUMA
> +#define early_cpu_to_node(cpu) cpu_to_node(cpu)
> static inline int cpu_to_node(int cpu)
> {
> int node;
> Index: linux-x86.q/include/asm-generic/percpu.h
> ===================================================================
> --- linux-x86.q.orig/include/asm-generic/percpu.h
> +++ linux-x86.q/include/asm-generic/percpu.h
> @@ -43,7 +43,12 @@ extern unsigned long __per_cpu_offset[NR
> * Only S390 provides its own means of moving the pointer.
> */
> #ifndef SHIFT_PERCPU_PTR
> -#define SHIFT_PERCPU_PTR(__p, __offset) RELOC_HIDE((__p), (__offset))
> +# ifdef CONFIG_HAVE_ZERO_BASED_PER_CPU
> +# define SHIFT_PERCPU_PTR(__p, __offset) \
> + ((__typeof(__p))(((void *)(__p)) + (__offset)))
> +# else
> +# define SHIFT_PERCPU_PTR(__p, __offset) RELOC_HIDE((__p), (__offset))
> +# endif /* CONFIG_HAVE_ZERO_BASED_PER_CPU */
> #endif
>
> /*
> Index: linux-x86.q/include/asm-generic/sections.h
> ===================================================================
> --- linux-x86.q.orig/include/asm-generic/sections.h
> +++ linux-x86.q/include/asm-generic/sections.h
> @@ -11,7 +11,17 @@ extern char _sinittext[], _einittext[];
> extern char _sextratext[] __attribute__((weak));
> extern char _eextratext[] __attribute__((weak));
> extern char _end[];
> +#ifdef CONFIG_HAVE_ZERO_BASED_PER_CPU
> +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-x86.q/include/asm-generic/topology.h
> ===================================================================
> --- linux-x86.q.orig/include/asm-generic/topology.h
> +++ linux-x86.q/include/asm-generic/topology.h
> @@ -32,6 +32,9 @@
> #ifndef cpu_to_node
> #define cpu_to_node(cpu) (0)
> #endif
> +#ifndef early_cpu_to_node
> +#define early_cpu_to_node(cpu) cpu_to_node(cpu)
> +#endif
> #ifndef parent_node
> #define parent_node(node) (0)
> #endif
> Index: linux-x86.q/include/asm-generic/vmlinux.lds.h
> ===================================================================
> --- linux-x86.q.orig/include/asm-generic/vmlinux.lds.h
> +++ linux-x86.q/include/asm-generic/vmlinux.lds.h
> @@ -341,6 +341,20 @@
> *(.initcall7.init) \
> *(.initcall7s.init)
>
> +#ifdef CONFIG_HAVE_ZERO_BASED_PER_CPU
> +#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 = .; \
> @@ -349,3 +363,4 @@
> *(.data.percpu.shared_aligned) \
> } \
> __per_cpu_end = .;
> +#endif
> Index: linux-x86.q/include/asm-ia64/percpu.h
> ===================================================================
> --- linux-x86.q.orig/include/asm-ia64/percpu.h
> +++ linux-x86.q/include/asm-ia64/percpu.h
> @@ -19,34 +19,14 @@
> # define PER_CPU_ATTRIBUTES __attribute__((__model__ (__small__)))
> #endif
>
> -#define DECLARE_PER_CPU(type, name) \
> - extern PER_CPU_ATTRIBUTES __typeof__(type) per_cpu__##name
> -
> -/*
> - * Pretty much a literal copy of asm-generic/percpu.h, except that percpu_modcopy() is an
> - * external routine, to avoid include-hell.
> - */
> #ifdef CONFIG_SMP
>
> -extern unsigned long __per_cpu_offset[NR_CPUS];
> -#define per_cpu_offset(x) (__per_cpu_offset[x])
> -
> -/* Equal to __per_cpu_offset[smp_processor_id()], but faster to access: */
> -DECLARE_PER_CPU(unsigned long, local_per_cpu_offset);
> +#define __my_cpu_offset __ia64_per_cpu_var(local_per_cpu_offset)
>
> -#define per_cpu(var, cpu) (*RELOC_HIDE(&per_cpu__##var, __per_cpu_offset[cpu]))
> -#define __get_cpu_var(var) (*RELOC_HIDE(&per_cpu__##var, __ia64_per_cpu_var(local_per_cpu_offset)))
> -#define __raw_get_cpu_var(var) (*RELOC_HIDE(&per_cpu__##var, __ia64_per_cpu_var(local_per_cpu_offset)))
> -
> -extern void percpu_modcopy(void *pcpudst, const void *src, unsigned long size);
> -extern void setup_per_cpu_areas (void);
> extern void *per_cpu_init(void);
>
> #else /* ! SMP */
>
> -#define per_cpu(var, cpu) (*((void)(cpu), &per_cpu__##var))
> -#define __get_cpu_var(var) per_cpu__##var
> -#define __raw_get_cpu_var(var) per_cpu__##var
> #define per_cpu_init() (__phys_per_cpu_start)
>
> #endif /* SMP */
> @@ -57,7 +37,12 @@ extern void *per_cpu_init(void);
> * On the positive side, using __ia64_per_cpu_var() instead of __get_cpu_var() is slightly
> * more efficient.
> */
> -#define __ia64_per_cpu_var(var) (per_cpu__##var)
> +#define __ia64_per_cpu_var(var) per_cpu__##var
> +
> +#include <asm-generic/percpu.h>
> +
> +/* Equal to __per_cpu_offset[smp_processor_id()], but faster to access: */
> +DECLARE_PER_CPU(unsigned long, local_per_cpu_offset);
>
> #endif /* !__ASSEMBLY__ */
>
> Index: linux-x86.q/include/asm-ia64/topology.h
> ===================================================================
> --- linux-x86.q.orig/include/asm-ia64/topology.h
> +++ linux-x86.q/include/asm-ia64/topology.h
> @@ -31,6 +31,7 @@
> * Returns the number of the node containing CPU 'cpu'
> */
> #define cpu_to_node(cpu) (int)(cpu_to_node_map[cpu])
> +#define early_cpu_to_node(cpu) cpu_to_node(cpu)
>
> /*
> * Returns a bitmask of CPUs on Node 'node'.
> Index: linux-x86.q/include/asm-mips/mach-ip27/topology.h
> ===================================================================
> --- linux-x86.q.orig/include/asm-mips/mach-ip27/topology.h
> +++ linux-x86.q/include/asm-mips/mach-ip27/topology.h
> @@ -23,6 +23,7 @@ struct cpuinfo_ip27 {
> extern struct cpuinfo_ip27 sn_cpu_info[NR_CPUS];
>
> #define cpu_to_node(cpu) (sn_cpu_info[(cpu)].p_nodeid)
> +#define early_cpu_to_node(cpu) cpu_to_node(cpu)
> #define parent_node(node) (node)
> #define node_to_cpumask(node) (hub_data(node)->h_cpus)
> #define node_to_first_cpu(node) (first_cpu(node_to_cpumask(node)))
> Index: linux-x86.q/include/asm-powerpc/percpu.h
> ===================================================================
> --- linux-x86.q.orig/include/asm-powerpc/percpu.h
> +++ linux-x86.q/include/asm-powerpc/percpu.h
> @@ -16,34 +16,9 @@
> #define __my_cpu_offset() get_paca()->data_offset
> #define per_cpu_offset(x) (__per_cpu_offset(x))
>
> -/* var is in discarded region: offset to particular copy we want */
> -#define per_cpu(var, cpu) (*RELOC_HIDE(&per_cpu__##var, __per_cpu_offset(cpu)))
> -#define __get_cpu_var(var) (*RELOC_HIDE(&per_cpu__##var, __my_cpu_offset()))
> -#define __raw_get_cpu_var(var) (*RELOC_HIDE(&per_cpu__##var, local_paca->data_offset))
> +#endif /* CONFIG_SMP */
> +#endif /* __powerpc64__ */
>
> -/* A macro to avoid #include hell... */
> -#define percpu_modcopy(pcpudst, src, size) \
> -do { \
> - unsigned int __i; \
> - for_each_possible_cpu(__i) \
> - memcpy((pcpudst)+__per_cpu_offset(__i), \
> - (src), (size)); \
> -} while (0)
> -
> -extern void setup_per_cpu_areas(void);
> -
> -#else /* ! SMP */
> -
> -#define per_cpu(var, cpu) (*((void)(cpu), &per_cpu__##var))
> -#define __get_cpu_var(var) per_cpu__##var
> -#define __raw_get_cpu_var(var) per_cpu__##var
> -
> -#endif /* SMP */
> -
> -#define DECLARE_PER_CPU(type, name) extern __typeof__(type) per_cpu__##name
> -
> -#else
> #include <asm-generic/percpu.h>
> -#endif
>
> #endif /* _ASM_POWERPC_PERCPU_H_ */
> Index: linux-x86.q/include/asm-powerpc/topology.h
> ===================================================================
> --- linux-x86.q.orig/include/asm-powerpc/topology.h
> +++ linux-x86.q/include/asm-powerpc/topology.h
> @@ -15,6 +15,7 @@ static inline int cpu_to_node(int cpu)
> return numa_cpu_lookup_table[cpu];
> }
>
> +#define early_cpu_to_node(cpu) cpu_to_node(cpu)
> #define parent_node(node) (node)
>
> static inline cpumask_t node_to_cpumask(int node)
> Index: linux-x86.q/include/asm-s390/percpu.h
> ===================================================================
> --- linux-x86.q.orig/include/asm-s390/percpu.h
> +++ linux-x86.q/include/asm-s390/percpu.h
> @@ -13,49 +13,25 @@
> */
> #if defined(__s390x__) && defined(MODULE)
>
> -#define __reloc_hide(var,offset) (*({ \
> +#define SHIFT_PERCPU_PTR(ptr,offset) (({ \
> extern int simple_identifier_##var(void); \
> unsigned long *__ptr; \
> - asm ( "larl %0,per_cpu__"#var"@GOTENT" \
> - : "=a" (__ptr) : "X" (per_cpu__##var) ); \
> - (typeof(&per_cpu__##var))((*__ptr) + (offset)); }))
> + asm ( "larl %0, %1@GOTENT" \
> + : "=a" (__ptr) : "X" (ptr) ); \
> + (typeof(ptr))((*__ptr) + (offset)); }))
>
> #else
>
> -#define __reloc_hide(var, offset) (*({ \
> +#define SHIFT_PERCPU_PTR(ptr, offset) (({ \
> extern int simple_identifier_##var(void); \
> unsigned long __ptr; \
> - asm ( "" : "=a" (__ptr) : "0" (&per_cpu__##var) ); \
> - (typeof(&per_cpu__##var)) (__ptr + (offset)); }))
> + asm ( "" : "=a" (__ptr) : "0" (ptr) ); \
> + (typeof(ptr)) (__ptr + (offset)); }))
>
> #endif
>
> -#ifdef CONFIG_SMP
> +#define __my_cpu_offset S390_lowcore.percpu_offset
>
> -extern unsigned long __per_cpu_offset[NR_CPUS];
> -
> -#define __get_cpu_var(var) __reloc_hide(var,S390_lowcore.percpu_offset)
> -#define __raw_get_cpu_var(var) __reloc_hide(var,S390_lowcore.percpu_offset)
> -#define per_cpu(var,cpu) __reloc_hide(var,__per_cpu_offset[cpu])
> -#define per_cpu_offset(x) (__per_cpu_offset[x])
> -
> -/* A macro to avoid #include hell... */
> -#define percpu_modcopy(pcpudst, src, size) \
> -do { \
> - unsigned int __i; \
> - for_each_possible_cpu(__i) \
> - memcpy((pcpudst)+__per_cpu_offset[__i], \
> - (src), (size)); \
> -} while (0)
> -
> -#else /* ! SMP */
> -
> -#define __get_cpu_var(var) __reloc_hide(var,0)
> -#define __raw_get_cpu_var(var) __reloc_hide(var,0)
> -#define per_cpu(var,cpu) __reloc_hide(var,0)
> -
> -#endif /* SMP */
> -
> -#define DECLARE_PER_CPU(type, name) extern __typeof__(type) per_cpu__##name
> +#include <asm-generic/percpu.h>
>
> #endif /* __ARCH_S390_PERCPU__ */
> Index: linux-x86.q/include/asm-sparc64/percpu.h
> ===================================================================
> --- linux-x86.q.orig/include/asm-sparc64/percpu.h
> +++ linux-x86.q/include/asm-sparc64/percpu.h
> @@ -7,7 +7,6 @@ register unsigned long __local_per_cpu_o
>
> #ifdef CONFIG_SMP
>
> -#define setup_per_cpu_areas() do { } while (0)
> extern void real_setup_per_cpu_areas(void);
>
> extern unsigned long __per_cpu_base;
> @@ -16,29 +15,14 @@ extern unsigned long __per_cpu_shift;
> (__per_cpu_base + ((unsigned long)(__cpu) << __per_cpu_shift))
> #define per_cpu_offset(x) (__per_cpu_offset(x))
>
> -/* var is in discarded region: offset to particular copy we want */
> -#define per_cpu(var, cpu) (*RELOC_HIDE(&per_cpu__##var, __per_cpu_offset(cpu)))
> -#define __get_cpu_var(var) (*RELOC_HIDE(&per_cpu__##var, __local_per_cpu_offset))
> -#define __raw_get_cpu_var(var) (*RELOC_HIDE(&per_cpu__##var, __local_per_cpu_offset))
> -
> -/* A macro to avoid #include hell... */
> -#define percpu_modcopy(pcpudst, src, size) \
> -do { \
> - unsigned int __i; \
> - for_each_possible_cpu(__i) \
> - memcpy((pcpudst)+__per_cpu_offset(__i), \
> - (src), (size)); \
> -} while (0)
> +#define __my_cpu_offset __local_per_cpu_offset
> +
> #else /* ! SMP */
>
> #define real_setup_per_cpu_areas() do { } while (0)
>
> -#define per_cpu(var, cpu) (*((void)cpu, &per_cpu__##var))
> -#define __get_cpu_var(var) per_cpu__##var
> -#define __raw_get_cpu_var(var) per_cpu__##var
> -
> #endif /* SMP */
>
> -#define DECLARE_PER_CPU(type, name) extern __typeof__(type) per_cpu__##name
> +#include <asm-generic/percpu.h>
>
> #endif /* __ARCH_SPARC64_PERCPU__ */
> Index: linux-x86.q/init/main.c
> ===================================================================
> --- linux-x86.q.orig/init/main.c
> +++ linux-x86.q/init/main.c
> @@ -374,18 +374,20 @@ 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;
> + printk(KERN_INFO "(generic)PERCPU: Allocating %lu bytes of per cpu data\n", size);
> +
> + for_each_possible_cpu(cpu) {
> + char *ptr = alloc_bootmem_pages_node(
> + NODE_DATA(early_cpu_to_node(cpu)), size);
> +
> + __per_cpu_offset[cpu] = ptr - __per_cpu_start;
> + memcpy(ptr, __per_cpu_load, __per_cpu_size);
> }
> }
> #endif /* CONFIG_HAVE_SETUP_PER_CPU_AREA */
> Index: linux-x86.q/kernel/lockdep.c
> ===================================================================
> --- linux-x86.q.orig/kernel/lockdep.c
> +++ linux-x86.q/kernel/lockdep.c
> @@ -609,8 +609,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))

2008-01-30 18:31:38

by Luck, Tony

[permalink] [raw]
Subject: RE: x86/non-x86: percpu, node ids, apic ids x86.git fixup

> Could you check the patch below? With this applied to latest -git, ia64
> buils fine for me in a cross-compiling environment. (but i dont know
> whether it boots ...)

Uni-processor build still fails with this patch (config is arch/ia64/configs/tiger_defconfig
with CONFIG_SMP switched from =y to =n).

arch/ia64/kernel/built-in.o(.text+0x5012): In function `show_interrupts':
: relocation truncated to fit: IMM22 per_cpu__kstat
arch/ia64/kernel/built-in.o(.text+0x53e1): In function `__bind_irq_vector':
: relocation truncated to fit: IMM22 per_cpu__vector_irq
arch/ia64/kernel/built-in.o(.text+0x5612): In function `__clear_irq_vector':
: relocation truncated to fit: IMM22 per_cpu__vector_irq
arch/ia64/kernel/built-in.o(.text+0x5a81): In function `__setup_vector_irq':
: relocation truncated to fit: IMM22 per_cpu__vector_irq
arch/ia64/kernel/built-in.o(.text+0x6231): In function `ia64_handle_irq':
: relocation truncated to fit: IMM22 per_cpu____irq_regs
arch/ia64/kernel/built-in.o(.text+0x6272): In function `ia64_handle_irq':
: relocation truncated to fit: IMM22 per_cpu__vector_irq
arch/ia64/kernel/built-in.o(.text+0x7b81): In function `cpu_idle_wait':
: relocation truncated to fit: IMM22 .text
arch/ia64/kernel/built-in.o(.text+0x7e21): In function `cpu_idle':
: relocation truncated to fit: IMM22 .text
arch/ia64/kernel/built-in.o(.text+0x7fd1): In function `ia64_save_extra':
: relocation truncated to fit: IMM22 per_cpu__pfm_syst_info
arch/ia64/kernel/built-in.o(.text+0x8071): In function `ia64_load_extra':
: relocation truncated to fit: IMM22 per_cpu__pfm_syst_info
arch/ia64/kernel/built-in.o(.text+0x95c0): In function `pfm_write_ibr_dbr':
: additional relocation overflows omitted from the output
ld: final link failed: Nonrepresentable section on output
make: *** [.tmp_vmlinux1] Error 1

SMP build (config zx1_defconfig) builds ok and boots ok too.

-Tony

2008-01-30 18:35:53

by Olof Johansson

[permalink] [raw]
Subject: Re: x86/non-x86: percpu, node ids, apic ids x86.git fixup

On Wed, Jan 30, 2008 at 07:06:23PM +0100, Ingo Molnar wrote:
>
> * Luck, Tony <[email protected]> wrote:
>
> > > thanks! Sorry about that: we cross-built on ARM but not on SMP
> > > non-x86 platforms so this dependency/breakage went unnoticed.
> >
> > Yes ... all ia64 builds (UP and SMP) are broken at the moment. Please
> > Cc: me with the fixup patch.
>
> Could you check the patch below? With this applied to latest -git, ia64
> buils fine for me in a cross-compiling environment. (but i dont know
> whether it boots ...)

powerpc (pasemi_defconfig) is broken in new ways from the original
breakage by this patch:

CHK include/linux/utsrelease.h
In file included from include/asm/pgtable-ppc64.h:10,
from include/asm/pgtable.h:13,
from include/linux/mm.h:39,
from include/linux/mman.h:14,
from arch/powerpc/kernel/asm-offsets.c:22:
include/asm/tlbflush.h: In function 'arch_enter_lazy_mmu_mode':
include/asm/tlbflush.h:112: error: '__my_cpu_offset' undeclared (first
use in this function)
include/asm/tlbflush.h:112: error: (Each undeclared identifier is
reported only once
include/asm/tlbflush.h:112: error: for each function it appears in.)
include/asm/tlbflush.h: In function 'arch_leave_lazy_mmu_mode':
include/asm/tlbflush.h:119: error: '__my_cpu_offset' undeclared (first
use in this function)
In file included from include/linux/mm.h:535,
from include/linux/mman.h:14,
from arch/powerpc/kernel/asm-offsets.c:22:
include/linux/vmstat.h: In function '__count_vm_event':
include/linux/vmstat.h:62: error: '__my_cpu_offset' undeclared (first
use in this function)
include/linux/vmstat.h: In function 'count_vm_event':
include/linux/vmstat.h:67: error: '__my_cpu_offset' undeclared (first
use in this function)
include/linux/vmstat.h: In function '__count_vm_events':
include/linux/vmstat.h:73: error: '__my_cpu_offset' undeclared (first
use in this function)
include/linux/vmstat.h: In function 'count_vm_events':
include/linux/vmstat.h:78: error: '__my_cpu_offset' undeclared (first
use in this function)
make[1]: *** [arch/powerpc/kernel/asm-offsets.s] Error 1



-Olof

2008-01-30 18:41:40

by Mike Travis

[permalink] [raw]
Subject: Re: x86/non-x86: percpu, node ids, apic ids x86.git fixup

Luck, Tony wrote:
>> Could you check the patch below? With this applied to latest -git, ia64
>> buils fine for me in a cross-compiling environment. (but i dont know
>> whether it boots ...)
>
> Uni-processor build still fails with this patch (config is arch/ia64/configs/tiger_defconfig
> with CONFIG_SMP switched from =y to =n).

I'll add an ia64-nosmp config to our cross build test environment and fix this up...

Thanks,
Mike

>
> arch/ia64/kernel/built-in.o(.text+0x5012): In function `show_interrupts':
> : relocation truncated to fit: IMM22 per_cpu__kstat
> arch/ia64/kernel/built-in.o(.text+0x53e1): In function `__bind_irq_vector':
> : relocation truncated to fit: IMM22 per_cpu__vector_irq
> arch/ia64/kernel/built-in.o(.text+0x5612): In function `__clear_irq_vector':
> : relocation truncated to fit: IMM22 per_cpu__vector_irq
> arch/ia64/kernel/built-in.o(.text+0x5a81): In function `__setup_vector_irq':
> : relocation truncated to fit: IMM22 per_cpu__vector_irq
> arch/ia64/kernel/built-in.o(.text+0x6231): In function `ia64_handle_irq':
> : relocation truncated to fit: IMM22 per_cpu____irq_regs
> arch/ia64/kernel/built-in.o(.text+0x6272): In function `ia64_handle_irq':
> : relocation truncated to fit: IMM22 per_cpu__vector_irq
> arch/ia64/kernel/built-in.o(.text+0x7b81): In function `cpu_idle_wait':
> : relocation truncated to fit: IMM22 .text
> arch/ia64/kernel/built-in.o(.text+0x7e21): In function `cpu_idle':
> : relocation truncated to fit: IMM22 .text
> arch/ia64/kernel/built-in.o(.text+0x7fd1): In function `ia64_save_extra':
> : relocation truncated to fit: IMM22 per_cpu__pfm_syst_info
> arch/ia64/kernel/built-in.o(.text+0x8071): In function `ia64_load_extra':
> : relocation truncated to fit: IMM22 per_cpu__pfm_syst_info
> arch/ia64/kernel/built-in.o(.text+0x95c0): In function `pfm_write_ibr_dbr':
> : additional relocation overflows omitted from the output
> ld: final link failed: Nonrepresentable section on output
> make: *** [.tmp_vmlinux1] Error 1
>
> SMP build (config zx1_defconfig) builds ok and boots ok too.
>
> -Tony

2008-01-30 18:49:59

by Ingo Molnar

[permalink] [raw]
Subject: Re: x86/non-x86: percpu, node ids, apic ids x86.git fixup


* Luck, Tony <[email protected]> wrote:

> > Could you check the patch below? With this applied to latest -git,
> > ia64 buils fine for me in a cross-compiling environment. (but i dont
> > know whether it boots ...)
>
> Uni-processor build still fails with this patch (config is
> arch/ia64/configs/tiger_defconfig with CONFIG_SMP switched from =y to
> =n).

could you try the full patchset that Travis has just sent and which i've
put into x86.git, you can pull it from:

git://git.kernel.org/pub/scm/linux/kernel/git/x86/linux-2.6-x86.git

it's a fixes only tree, ontop of Linus-very-latest. Head 4b9e425c25f84.
[pull from ssh://master.kernel.org if it's not on git.kernel.org yet,
uploaded it this very minute.]

Ingo

2008-01-30 19:06:00

by Ingo Molnar

[permalink] [raw]
Subject: Re: x86/non-x86: percpu, node ids, apic ids x86.git fixup


* Ingo Molnar <[email protected]> wrote:

> > Uni-processor build still fails with this patch (config is
> > arch/ia64/configs/tiger_defconfig with CONFIG_SMP switched from =y
> > to =n).
>
> could you try the full patchset that Travis has just sent and which
> i've put into x86.git, you can pull it from:

btw., i needed the fix below to get DISCONTIGMEM + !NUMA to build. (this
is an ia64 build breakage independent of the x86.git merge)

Ingo

-------------->
Subject: ia64: build fix
From: Ingo Molnar <[email protected]>

DISCONTIGMEM does not build with NUMA disabled:

include/linux/gfp.h: In function `alloc_pages_node':
include/linux/gfp.h:189: error: implicit declaration of function `NODE_DATA'
include/linux/gfp.h:189: error: invalid type argument of `->'
In file included from include/asm/uaccess.h:39,

Signed-off-by: Ingo Molnar <[email protected]>
---
arch/ia64/Kconfig | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)

Index: linux-x86.q/arch/ia64/Kconfig
===================================================================
--- linux-x86.q.orig/arch/ia64/Kconfig
+++ linux-x86.q/arch/ia64/Kconfig
@@ -351,7 +351,8 @@ config ARCH_SELECT_MEMORY_MODEL
def_bool y

config ARCH_DISCONTIGMEM_ENABLE
- def_bool y
+ def_bool n
+ depends on NUMA
help
Say Y to support efficient handling of discontiguous physical memory,
for architectures which are either NUMA (Non-Uniform Memory Access)
@@ -372,7 +373,7 @@ config ARCH_DISCONTIGMEM_DEFAULT

config NUMA
bool "NUMA support"
- depends on !IA64_HP_SIM && !FLATMEM
+ depends on !IA64_HP_SIM
default y if IA64_SGI_SN2
select ACPI_NUMA if ACPI
help

2008-01-30 19:12:29

by Luck, Tony

[permalink] [raw]
Subject: RE: x86/non-x86: percpu, node ids, apic ids x86.git fixup

> could you try the full patchset that Travis has just sent and which i've
> put into x86.git, you can pull it from:
>
> git://git.kernel.org/pub/scm/linux/kernel/git/x86/linux-2.6-x86.git
>
> it's a fixes only tree, ontop of Linus-very-latest. Head 4b9e425c25f84.
> [pull from ssh://master.kernel.org if it's not on git.kernel.org yet,
> uploaded it this very minute.]

Same build fail for CONFIG_SMP=n. The SMP=y build is good (for tiger_defconfig)
and boots ok too.

-Tony

2008-01-30 19:13:14

by Olof Johansson

[permalink] [raw]
Subject: Re: x86/non-x86: percpu, node ids, apic ids x86.git fixup

On Wed, Jan 30, 2008 at 07:49:20PM +0100, Ingo Molnar wrote:
>
> * Luck, Tony <[email protected]> wrote:
>
> > > Could you check the patch below? With this applied to latest -git,
> > > ia64 buils fine for me in a cross-compiling environment. (but i dont
> > > know whether it boots ...)
> >
> > Uni-processor build still fails with this patch (config is
> > arch/ia64/configs/tiger_defconfig with CONFIG_SMP switched from =y to
> > =n).
>
> could you try the full patchset that Travis has just sent and which i've
> put into x86.git, you can pull it from:

Looks ok for powerpc so far, I haven't gotten through all defconfigs yet
but the first ones that failed before build now. pasemi_defconfig boots
as well.


-Olof

2008-01-30 19:17:49

by Mike Travis

[permalink] [raw]
Subject: Re: x86/non-x86: percpu, node ids, apic ids x86.git fixup

Luck, Tony wrote:
>> Could you check the patch below? With this applied to latest -git, ia64
>> buils fine for me in a cross-compiling environment. (but i dont know
>> whether it boots ...)
>
> Uni-processor build still fails with this patch (config is arch/ia64/configs/tiger_defconfig
> with CONFIG_SMP switched from =y to =n).

Hi Tony,

I'm having trouble replicating this error. With the latest linux-2.6.git
plus the patch I just sent, I get the following errors:

drivers/input/mouse/psmouse-base.c:45: error: __param_proto causes a section type conflict
drivers/md/md.c:5881: error: __param_start_ro causes a section type conflict

(plenty of warnings too, but no vmlinux)

I copied arch/ia64/configs/tiger_defconfig to .config, ran menuconfig to
turn off SMP and built with this line:

make ARCH=ia64 CROSS_COMPILE=ia64-linux-gnu- -i -j10

Could this be a problem with:

#ifdef HAVE_MODEL_SMALL_ATTRIBUTE
# define PER_CPU_ATTRIBUTES __attribute__((__model__ (__small__)))
#endif

This is only defined for !__ASSEMBLY__

Thanks,
Mike

>
> arch/ia64/kernel/built-in.o(.text+0x5012): In function `show_interrupts':
> : relocation truncated to fit: IMM22 per_cpu__kstat
> arch/ia64/kernel/built-in.o(.text+0x53e1): In function `__bind_irq_vector':
> : relocation truncated to fit: IMM22 per_cpu__vector_irq
> arch/ia64/kernel/built-in.o(.text+0x5612): In function `__clear_irq_vector':
> : relocation truncated to fit: IMM22 per_cpu__vector_irq
> arch/ia64/kernel/built-in.o(.text+0x5a81): In function `__setup_vector_irq':
> : relocation truncated to fit: IMM22 per_cpu__vector_irq
> arch/ia64/kernel/built-in.o(.text+0x6231): In function `ia64_handle_irq':
> : relocation truncated to fit: IMM22 per_cpu____irq_regs
> arch/ia64/kernel/built-in.o(.text+0x6272): In function `ia64_handle_irq':
> : relocation truncated to fit: IMM22 per_cpu__vector_irq
> arch/ia64/kernel/built-in.o(.text+0x7b81): In function `cpu_idle_wait':
> : relocation truncated to fit: IMM22 .text
> arch/ia64/kernel/built-in.o(.text+0x7e21): In function `cpu_idle':
> : relocation truncated to fit: IMM22 .text
> arch/ia64/kernel/built-in.o(.text+0x7fd1): In function `ia64_save_extra':
> : relocation truncated to fit: IMM22 per_cpu__pfm_syst_info
> arch/ia64/kernel/built-in.o(.text+0x8071): In function `ia64_load_extra':
> : relocation truncated to fit: IMM22 per_cpu__pfm_syst_info
> arch/ia64/kernel/built-in.o(.text+0x95c0): In function `pfm_write_ibr_dbr':
> : additional relocation overflows omitted from the output
> ld: final link failed: Nonrepresentable section on output
> make: *** [.tmp_vmlinux1] Error 1
>
> SMP build (config zx1_defconfig) builds ok and boots ok too.
>
> -Tony

2008-01-30 19:19:18

by Ingo Molnar

[permalink] [raw]
Subject: Re: x86/non-x86: percpu, node ids, apic ids x86.git fixup


* Olof Johansson <[email protected]> wrote:

> > could you try the full patchset that Travis has just sent and which
> > i've put into x86.git, you can pull it from:
>
> Looks ok for powerpc so far, I haven't gotten through all defconfigs
> yet but the first ones that failed before build now. pasemi_defconfig
> boots as well.

great, thanks!

Ingo

2008-01-30 19:31:32

by Ingo Molnar

[permalink] [raw]
Subject: Re: x86/non-x86: percpu, node ids, apic ids x86.git fixup


* Mike Travis <[email protected]> wrote:

> Could this be a problem with:
>
> #ifdef HAVE_MODEL_SMALL_ATTRIBUTE
> # define PER_CPU_ATTRIBUTES __attribute__((__model__ (__small__)))
> #endif
>
> This is only defined for !__ASSEMBLY__

nope, moving that per the patch below did not resolve the link problems.

Ingo

-------------->
Subject: ia64: build fix #3
From: Ingo Molnar <[email protected]>

Signed-off-by: Ingo Molnar <[email protected]>
---
include/asm-ia64/percpu.h | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)

Index: linux-x86.q/include/asm-ia64/percpu.h
===================================================================
--- linux-x86.q.orig/include/asm-ia64/percpu.h
+++ linux-x86.q/include/asm-ia64/percpu.h
@@ -8,6 +8,10 @@

#define PERCPU_ENOUGH_ROOM PERCPU_PAGE_SIZE

+#ifdef HAVE_MODEL_SMALL_ATTRIBUTE
+# define PER_CPU_ATTRIBUTES __attribute__((__model__ (__small__)))
+#endif
+
#ifdef __ASSEMBLY__
# define THIS_CPU(var) (per_cpu__##var) /* use this to mark accesses to per-CPU variables... */
#else /* !__ASSEMBLY__ */
@@ -15,10 +19,6 @@

#include <linux/threads.h>

-#ifdef HAVE_MODEL_SMALL_ATTRIBUTE
-# define PER_CPU_ATTRIBUTES __attribute__((__model__ (__small__)))
-#endif
-
#ifdef CONFIG_SMP

#define __my_cpu_offset __ia64_per_cpu_var(local_per_cpu_offset)

2008-01-30 19:33:53

by Luck, Tony

[permalink] [raw]
Subject: RE: x86/non-x86: percpu, node ids, apic ids x86.git fixup

> I'm having trouble replicating this error. With the latest linux-2.6.git
> plus the patch I just sent, I get the following errors:
>
> drivers/input/mouse/psmouse-base.c:45: error: __param_proto causes a section type conflict
> drivers/md/md.c:5881: error: __param_start_ro causes a section type conflict

Weird. psmouse-base.c builds ok for me. Perhaps there is a compiler
version difference? I'm running a rather old 3.4.6 that came with
my RHEL 4.5 release.

> (plenty of warnings too, but no vmlinux)
New section mismatch checks are complaining about lots of stuff in this
post 2.6.24 world. There are a couple of dozen other warnings in a
"normal" build.

> I copied arch/ia64/configs/tiger_defconfig to .config, ran menuconfig to
> turn off SMP and built with this line

Yup ... my script is a little different. It uses
$ sed -e '/CONFIG_SMP/d' arch/ia64/configs/tiger_defconfig > .config
$ make oldconfig

But the net effect should be equivalent.

> #ifdef HAVE_MODEL_SMALL_ATTRIBUTE
> # define PER_CPU_ATTRIBUTES __attribute__((__model__ (__small__)))
> #endif
>
> This is only defined for !__ASSEMBLY__

Some place in there. The CONFIG_SMP=n path in ia64 makes quite radical
changes ... rather than putting all the per-cpu stuff into the top 64K
of address space and providing a per-cpu TLB mapping for that range to a
different physical address ... it just makes all the per-cpu stuff link
as ordinary variables in .data. The error messages indicate that some of
the new code is unaware of this.

-Tony

2008-01-30 19:46:46

by Ingo Molnar

[permalink] [raw]
Subject: Re: x86/non-x86: percpu, node ids, apic ids x86.git fixup


* Luck, Tony <[email protected]> wrote:

> > This is only defined for !__ASSEMBLY__
>
> Some place in there. The CONFIG_SMP=n path in ia64 makes quite
> radical changes ... rather than putting all the per-cpu stuff into the
> top 64K of address space and providing a per-cpu TLB mapping for that
> range to a different physical address ... it just makes all the
> per-cpu stuff link as ordinary variables in .data. The error messages
> indicate that some of the new code is unaware of this.

ah, that was the vital clue. The patch below makes the small memory
model only defined on SMP, and makes the config build/link fine here.
Does this build and boot on your box?

Ingo

------------>
Subject: ia64: build fix #3
From: Ingo Molnar <[email protected]>

Signed-off-by: Ingo Molnar <[email protected]>
---
include/asm-ia64/percpu.h | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)

Index: linux-x86.q/include/asm-ia64/percpu.h
===================================================================
--- linux-x86.q.orig/include/asm-ia64/percpu.h
+++ linux-x86.q/include/asm-ia64/percpu.h
@@ -15,12 +15,12 @@

#include <linux/threads.h>

+#ifdef CONFIG_SMP
+
#ifdef HAVE_MODEL_SMALL_ATTRIBUTE
# define PER_CPU_ATTRIBUTES __attribute__((__model__ (__small__)))
#endif

-#ifdef CONFIG_SMP
-
#define __my_cpu_offset __ia64_per_cpu_var(local_per_cpu_offset)

extern void *per_cpu_init(void);

2008-01-30 19:49:57

by Ingo Molnar

[permalink] [raw]
Subject: Re: x86/non-x86: percpu, node ids, apic ids x86.git fixup


* Ingo Molnar <[email protected]> wrote:

> > Some place in there. The CONFIG_SMP=n path in ia64 makes quite
> > radical changes ... rather than putting all the per-cpu stuff into
> > the top 64K of address space and providing a per-cpu TLB mapping for
> > that range to a different physical address ... it just makes all the
> > per-cpu stuff link as ordinary variables in .data. The error
> > messages indicate that some of the new code is unaware of this.
>
> ah, that was the vital clue. The patch below makes the small memory
> model only defined on SMP, and makes the config build/link fine here.
> Does this build and boot on your box?

if this works for you then could you please send me your Acked-by as
well, for this and the other ia64 changes, so that we can send these to
Linus ASAP?

Ingo

2008-01-30 20:00:49

by Luck, Tony

[permalink] [raw]
Subject: RE: x86/non-x86: percpu, node ids, apic ids x86.git fixup

> ah, that was the vital clue. The patch below makes the small memory
> model only defined on SMP, and makes the config build/link fine here.
> Does this build and boot on your box?

I applied this on top of the git pull from
git://git.kernel.org/pub/scm/linux/kernel/git/x86/linux-2.6-x86.git

and I see see a build problem for SMP=n :-(

-Tony

2008-01-30 20:11:32

by Ingo Molnar

[permalink] [raw]
Subject: Re: x86/non-x86: percpu, node ids, apic ids x86.git fixup


* Luck, Tony <[email protected]> wrote:

> > ah, that was the vital clue. The patch below makes the small memory
> > model only defined on SMP, and makes the config build/link fine here.
> > Does this build and boot on your box?
>
> I applied this on top of the git pull from
> git://git.kernel.org/pub/scm/linux/kernel/git/x86/linux-2.6-x86.git
>
> and I see see a build problem for SMP=n :-(

could you send the .config you are using?

Ingo

2008-01-30 20:21:16

by Luck, Tony

[permalink] [raw]
Subject: RE: x86/non-x86: percpu, node ids, apic ids x86.git fixup

> could you send the .config you are using?

Ok. Attached.

-Tony


Attachments:
upconfig (30.17 kB)
upconfig

2008-01-30 20:59:50

by Ingo Molnar

[permalink] [raw]
Subject: Re: x86/non-x86: percpu, node ids, apic ids x86.git fixup


* Luck, Tony <[email protected]> wrote:

> > could you send the .config you are using?
>
> Ok. Attached.

thanks a ton - this produced a link error here too.

after half an hour of head scratching, the updated patch below solves
the build problem.

The problem i believe is this code in arch/ia64/kernel/mca_asm.S:

#define GET_IA64_MCA_DATA(reg) \
GET_THIS_PADDR(reg, ia64_mca_data) \
;; \
ld8 reg=[reg]

this i believe builds an implicit dependency between the mca_asm.o
position within the image and the ia64_mca_data percpu variable it
accesses - it relies on the immediate 22 addressing mode that has 4MB of
scope. Per chance, the .config you sent creates a 14MB image, and the
percpu variables moved too far away for the linker to be able to fulfill
this constraint.

The workaround is to define PER_CPU_ATTRIBUTES to link percpu variables
back into the .percpu section on UP too - which ia64 links specially
into its vmlinux.lds. But ultimately i think the better solution would
be to remove this dependency between arch/ia64/kernel/mca_asm.S and the
position of the percpu data.

Is my analysis correct? Do you like my fix and does the patch build and
boot on your system? Thanks,

Ingo

--------------->
Subject: ia64: on UP percpu variables are not small memory model
From: Ingo Molnar <[email protected]>

Tony says:

| The CONFIG_SMP=n path in ia64 makes quite radical changes ... rather
| than putting all the per-cpu stuff into the top 64K of address space
| and providing a per-cpu TLB mapping for that range to a different
| physical address ... it just makes all the per-cpu stuff link as ordinary
| variables in .data.

the new generic percpu code got confused about this as PER_CPU_ATTRIBUTES
was defined even on UP, so it picked up that small memory model - which
was not possible to get linked. The right fix is to only define that
on SMP. This resolved the build failures in my cross-compiling environment.

also link these variables into the .percpu section - some assembly code
has offset dependencies.

Signed-off-by: Ingo Molnar <[email protected]>
---
include/asm-ia64/percpu.h | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)

Index: linux-x86.q/include/asm-ia64/percpu.h
===================================================================
--- linux-x86.q.orig/include/asm-ia64/percpu.h
+++ linux-x86.q/include/asm-ia64/percpu.h
@@ -15,18 +15,20 @@

#include <linux/threads.h>

+#ifdef CONFIG_SMP
+
#ifdef HAVE_MODEL_SMALL_ATTRIBUTE
# define PER_CPU_ATTRIBUTES __attribute__((__model__ (__small__)))
#endif

-#ifdef CONFIG_SMP
-
#define __my_cpu_offset __ia64_per_cpu_var(local_per_cpu_offset)

extern void *per_cpu_init(void);

#else /* ! SMP */

+#define PER_CPU_ATTRIBUTES __attribute__((__section__(".data.percpu")))
+
#define per_cpu_init() (__phys_per_cpu_start)

#endif /* SMP */

2008-01-30 21:22:29

by Luck, Tony

[permalink] [raw]
Subject: RE: x86/non-x86: percpu, node ids, apic ids x86.git fixup

> this i believe builds an implicit dependency between the mca_asm.o
> position within the image and the ia64_mca_data percpu variable it
> accesses - it relies on the immediate 22 addressing mode that has 4MB of
> scope. Per chance, the .config you sent creates a 14MB image, and the
> percpu variables moved too far away for the linker to be able to fulfill
> this constraint.

Sounds very plausible.

> The workaround is to define PER_CPU_ATTRIBUTES to link percpu variables
> back into the .percpu section on UP too - which ia64 links specially
> into its vmlinux.lds. But ultimately i think the better solution would
> be to remove this dependency between arch/ia64/kernel/mca_asm.S and the
> position of the percpu data.

Yup. That fixes the build ... the resulting binary doesn't boot though :-(
I just realized that it has been a while since I tried booting a UP
kernel ... so the problem may be unrelated bitrot elsewhere.

Overall you are right that the mca_asm.S code should not be dependent on
the relative location of the data objects.

I'll start digging on why this doesn't boot ... but you might as well
send the fixes so far upstream to Linus so that the SMP fix is available
(which is all anyone really cares about ... there are very, very few
UP ia64 systems in existence).

Acked-by: Tony Luck <[email protected]>


-Tony

2008-01-30 21:23:00

by Geoff Levand

[permalink] [raw]
Subject: Re: x86/non-x86: percpu, node ids, apic ids x86.git fixup

Ingo Molnar wrote:
> * Luck, Tony <[email protected]> wrote:
>
>> > Could you check the patch below? With this applied to latest -git,
>> > ia64 buils fine for me in a cross-compiling environment. (but i dont
>> > know whether it boots ...)
>>
>> Uni-processor build still fails with this patch (config is
>> arch/ia64/configs/tiger_defconfig with CONFIG_SMP switched from =y to
>> =n).
>
> could you try the full patchset that Travis has just sent and which i've
> put into x86.git, you can pull it from:
>
> git://git.kernel.org/pub/scm/linux/kernel/git/x86/linux-2.6-x86.git
>
> it's a fixes only tree, ontop of Linus-very-latest. Head 4b9e425c25f84.
> [pull from ssh://master.kernel.org if it's not on git.kernel.org yet,
> uploaded it this very minute.]

Just FYI, the following diff from the above tree applied to linux-2.6.git
works with ps3_defconfig on the PS3 (powerpc):

git diff dd430ca20c40ecccd6954a7efd13d4398f507728..3823daf866c272c670dda7dc6179a647da64467f

-Geoff

2008-01-30 21:24:12

by Ingo Molnar

[permalink] [raw]
Subject: Re: x86/non-x86: percpu, node ids, apic ids x86.git fixup


* Luck, Tony <[email protected]> wrote:

> I'll start digging on why this doesn't boot ... but you might as well
> send the fixes so far upstream to Linus so that the SMP fix is
> available (which is all anyone really cares about ... there are very,
> very few UP ia64 systems in existence).
>
> Acked-by: Tony Luck <[email protected]>

thanks alot! Can i also add your Acked-by to this patch:

Subject: ia64: use generic percpu
From: [email protected]

it seems like a sensible cleanup to me.

Ingo

2008-01-30 21:27:15

by Ingo Molnar

[permalink] [raw]
Subject: [powerpc changes] Re: x86/non-x86: percpu, node ids, apic ids x86.git fixup


* Olof Johansson <[email protected]> wrote:

> > could you try the full patchset that Travis has just sent and which
> > i've put into x86.git, you can pull it from:
>
> Looks ok for powerpc so far, I haven't gotten through all defconfigs
> yet but the first ones that failed before build now. pasemi_defconfig
> boots as well.

could the PowerPC maintainers please Ack the following patch (attached
below):

Subject: POWERPC: use generic per cpu
From: [email protected]

so that we can push this fix upstream ASAP?

Ingo

--------------->
Subject: POWERPC: use generic per cpu
From: [email protected]

Powerpc has a way to determine the address of the per cpu area of the
currently executing processor via the paca and the array of per cpu
offsets is avoided by looking up the per cpu area from the remote
paca's (copying x86_64).

Cc: Paul Mackerras <[email protected]>
Cc: Geert Uytterhoeven <[email protected]>
Signed-off-by: Mike Travis <[email protected]>
Signed-off-by: Ingo Molnar <[email protected]>
---
include/asm-powerpc/percpu.h | 22 +++-------------------
1 file changed, 3 insertions(+), 19 deletions(-)

Index: linux-x86.q/include/asm-powerpc/percpu.h
===================================================================
--- linux-x86.q.orig/include/asm-powerpc/percpu.h
+++ linux-x86.q/include/asm-powerpc/percpu.h
@@ -13,28 +13,12 @@
#include <asm/paca.h>

#define __per_cpu_offset(cpu) (paca[cpu].data_offset)
-#define __my_cpu_offset() get_paca()->data_offset
+#define __my_cpu_offset get_paca()->data_offset
#define per_cpu_offset(x) (__per_cpu_offset(x))

-/* var is in discarded region: offset to particular copy we want */
-#define per_cpu(var, cpu) (*RELOC_HIDE(&per_cpu__##var, __per_cpu_offset(cpu)))
-#define __get_cpu_var(var) (*RELOC_HIDE(&per_cpu__##var, __my_cpu_offset()))
-#define __raw_get_cpu_var(var) (*RELOC_HIDE(&per_cpu__##var, local_paca->data_offset))
+#endif /* CONFIG_SMP */
+#endif /* __powerpc64__ */

-extern void setup_per_cpu_areas(void);
-
-#else /* ! SMP */
-
-#define per_cpu(var, cpu) (*((void)(cpu), &per_cpu__##var))
-#define __get_cpu_var(var) per_cpu__##var
-#define __raw_get_cpu_var(var) per_cpu__##var
-
-#endif /* SMP */
-
-#define DECLARE_PER_CPU(type, name) extern __typeof__(type) per_cpu__##name
-
-#else
#include <asm-generic/percpu.h>
-#endif

#endif /* _ASM_POWERPC_PERCPU_H_ */

2008-01-30 21:39:31

by Olof Johansson

[permalink] [raw]
Subject: Re: [powerpc changes] Re: x86/non-x86: percpu, node ids, apic ids x86.git fixup

On Wed, Jan 30, 2008 at 10:25:58PM +0100, Ingo Molnar wrote:
>
> * Olof Johansson <[email protected]> wrote:
>
> > > could you try the full patchset that Travis has just sent and which
> > > i've put into x86.git, you can pull it from:
> >
> > Looks ok for powerpc so far, I haven't gotten through all defconfigs
> > yet but the first ones that failed before build now. pasemi_defconfig
> > boots as well.
>
> could the PowerPC maintainers please Ack the following patch (attached
> below):
>
> Subject: POWERPC: use generic per cpu
> From: [email protected]
>
> so that we can push this fix upstream ASAP?

> Subject: POWERPC: use generic per cpu
> From: [email protected]
>
> Powerpc has a way to determine the address of the per cpu area of the
> currently executing processor via the paca and the array of per cpu
> offsets is avoided by looking up the per cpu area from the remote
> paca's (copying x86_64).
>
> Cc: Paul Mackerras <[email protected]>
> Cc: Geert Uytterhoeven <[email protected]>
> Signed-off-by: Mike Travis <[email protected]>
> Signed-off-by: Ingo Molnar <[email protected]>

Paul is at LCA, I'm not sure if he's reading email. Looks good to me so:

Acked-by: Olof Johansson <[email protected]>


-Olof

2008-01-30 21:58:16

by Geoff Levand

[permalink] [raw]
Subject: Re: [powerpc changes] Re: x86/non-x86: percpu, node ids, apic ids x86.git fixup

Ingo Molnar wrote:
> * Olof Johansson <[email protected]> wrote:
>
>> > could you try the full patchset that Travis has just sent and which
>> > i've put into x86.git, you can pull it from:
>>
>> Looks ok for powerpc so far, I haven't gotten through all defconfigs
>> yet but the first ones that failed before build now. pasemi_defconfig
>> boots as well.
>
> could the PowerPC maintainers please Ack the following patch (attached
> below):
>
> Subject: POWERPC: use generic per cpu
> From: [email protected]
>
> so that we can push this fix upstream ASAP?
>
> Ingo
>
> --------------->
> Subject: POWERPC: use generic per cpu
> From: [email protected]
>
> Powerpc has a way to determine the address of the per cpu area of the
> currently executing processor via the paca and the array of per cpu
> offsets is avoided by looking up the per cpu area from the remote
> paca's (copying x86_64).
>
> Cc: Paul Mackerras <[email protected]>
> Cc: Geert Uytterhoeven <[email protected]>
> Signed-off-by: Mike Travis <[email protected]>
> Signed-off-by: Ingo Molnar <[email protected]>
> ---
> include/asm-powerpc/percpu.h | 22 +++-------------------
> 1 file changed, 3 insertions(+), 19 deletions(-)

Tested on PS3 with ps3_defconfig and works OK.

Acked-by: Geoff Levand <[email protected]>

2008-01-31 10:47:20

by Adrian Bunk

[permalink] [raw]
Subject: Re: x86/non-x86: percpu, node ids, apic ids x86.git fixup

On Wed, Jan 30, 2008 at 11:33:29AM -0800, Luck, Tony wrote:
> > I'm having trouble replicating this error. With the latest linux-2.6.git
> > plus the patch I just sent, I get the following errors:
> >
> > drivers/input/mouse/psmouse-base.c:45: error: __param_proto causes a section type conflict
> > drivers/md/md.c:5881: error: __param_start_ro causes a section type conflict
>
> Weird. psmouse-base.c builds ok for me. Perhaps there is a compiler
> version difference? I'm running a rather old 3.4.6 that came with
> my RHEL 4.5 release.
>...

It depends on the compiler version.

And you were in the Cc of Ivan's patch that fixes it... [1]

> -Tony

cu
Adrian

[1] http://lkml.org/lkml/2007/12/27/29

--

"Is there not promise of rain?" Ling Tan asked suddenly out
of the darkness. There had been need of rain for many days.
"Only a promise," Lao Er said.
Pearl S. Buck - Dragon Seed