percpu: Optimize percpu accesses
Subsystems (6)
cover percpu: Optimize percpu accesses
This patchset provides the following:
* Generic: Percpu infrastructure to rebase the per cpu area to zero
This provides for the capability of accessing the percpu variables using a local register instead of having to go through a table on node 0 to find the cpu-specific offsets. It also would allow atomic operations on percpu variables to reduce required locking. Uses a new config var HAVE_ZERO_BASED_PER_CPU to indicate to the generic code that the arch has this new basing.
* x86_64: Fold pda into per cpu area
Declare the pda as a per cpu variable. This will move the pda area to an address accessible by the x86_64 per cpu macros. Subtraction of __per_cpu_start will make the offset based from the beginning of the per cpu area. Since %gs is pointing to the pda, it will then also point to the per cpu variables and can be accessed thusly:
%gs:[&per_cpu_xxxx - __per_cpu_start]
* x86_64: Rebase per cpu variables to zero
Take advantage of the zero-based per cpu area provided above. Then we can directly use the x86_32 percpu operations. x86_32 offsets %fs by __per_cpu_start. x86_64 has %gs pointing directly to the pda and the per cpu area thereby allowing access to the pda with the x86_64 pda operations and access to the per cpu variables using x86_32 percpu operations.
Based on linux-2.6.tip
---
PATCH 1/4 Zero based percpu: Infrastructure to rebase the per cpu area to zero
* Support an option
CONFIG_HAVE_ZERO_BASED_PER_CPU
to make 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.
* Updates kernel/module.c to be able to deal with a percpu area that is loaded at __per_cpu_load but is accessed at __per_cpu_start.
Based on linux-2.6.tip
--- include/asm-generic/percpu.h | 9 ++++++++- include/asm-generic/sections.h | 10 ++++++++++ include/asm-generic/vmlinux.lds.h | 16 ++++++++++++++++ include/linux/percpu.h | 17 ++++++++++++++++- kernel/lockdep.c | 4 ++-- kernel/module.c | 7 ++++--- 6 files changed, 56 insertions(+), 7 deletions(-)
include/asm-generic/percpu.h +8 -1
@@ -45,7 +45,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 /*
@@ -70,6 +75,8 @@ extern void setup_per_cpu_areas(void);#define per_cpu (var, cpu) (*((void)(cpu), &per_cpu_var(var)))#define __get_cpu_var (var) per_cpu_var(var)#define __raw_get_cpu_var (var) per_cpu_var(var) +#define SHIFT_PERCPU_PTR (__p, __offset) (__p) +#define per_cpu_offset (x) 0L#endif /* SMP */
include/asm-generic/sections.h +10 -0
@@ -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_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[];
include/asm-generic/vmlinux.lds.h +16 -0
@@ -371,6 +371,21 @@ *(.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.shared_aligned) \ + *(.data.percpu) \ + *(.data.percpu.page_aligned) \ + ____per_cpu_size = .; \ + } \ + . = __per_cpu_load + ____per_cpu_size; \ + data : { } :data +#else #define PERCPU (align) \ . = ALIGN(align); \ __per_cpu_start = .; \
@@ -380,3 +395,4 @@ *(.data.percpu.shared_aligned) \ } \ __per_cpu_end = .; +#endif
include/linux/percpu.h +16 -1
@@ -27,7 +27,18 @@#define DEFINE_PER_CPU_PAGE_ALIGNED (type, name) \ __attribute__((__section__(".data.percpu.page_aligned"))) \ PER_CPU_ATTRIBUTES __typeof__(type) per_cpu__##name + +#ifdef CONFIG_HAVE_ZERO_BASED_PER_CPU +#define DEFINE_PER_CPU_FIRST (type, name) \ + __attribute__((__section__(".data.percpu.first"))) \ + PER_CPU_ATTRIBUTES __typeof__(type) per_cpu__##name#else +#define DEFINE_PER_CPU_FIRST (type, name) \ + DEFINE_PER_CPU(type, name) +#endif + +#else /* !CONFIG_SMP */ +#define DEFINE_PER_CPU (type, name) \ PER_CPU_ATTRIBUTES __typeof__(type) per_cpu__##name
@@ -36,7 +47,11 @@#define DEFINE_PER_CPU_PAGE_ALIGNED (type, name) \ DEFINE_PER_CPU(type, name) -#endif + +#define DEFINE_PER_CPU_FIRST (type, name) \ + DEFINE_PER_CPU(type, name) + +#endif /* !CONFIG_SMP */ #define EXPORT_PER_CPU_SYMBOL (var) EXPORT_SYMBOL(per_cpu__##var)#define EXPORT_PER_CPU_SYMBOL_GPL (var) EXPORT_SYMBOL_GPL(per_cpu__##var)
kernel/lockdep.c +2 -2
@@ -614,8 +614,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))
kernel/module.c +4 -3
@@ -45,6 +45,7 @@#include <linux/unwind.h> #include <asm/uaccess.h> #include <asm/cacheflush.h> +#include <asm/sections.h> #include <linux/license.h> #include <asm/sections.h> #include <linux/marker.h>
@@ -367,7 +368,7 @@ static void *percpu_modalloc(unsigned lo align =PAGE_SIZE ; } - ptr = __per_cpu_start; + ptr = __per_cpu_load;for (i =0 ; i < pcpu_num_used; ptr +=block_size (pcpu_size[i]), i++) {/* Extra for alignment requirement. */ extra =ALIGN ((unsigned long )ptr, align) - (unsigned long )ptr;
@@ -402,7 +403,7 @@ static void *percpu_modalloc(unsigned lostatic void percpu_modfree (void *freeme) {unsigned int i; -void *ptr = __per_cpu_start +block_size (pcpu_size[0 ]); +void *ptr = __per_cpu_load +block_size (pcpu_size[0 ]);/* First entry is core kernel percpu data. */ for (i =1 ; i < pcpu_num_used; ptr +=block_size (pcpu_size[i]), i++) {
@@ -453,7 +454,7 @@ static int percpu_modinit(void) pcpu_size =kmalloc (sizeof (pcpu_size[0 ]) * pcpu_num_allocated,GFP_KERNEL );/* Static in-kernel percpu data (used). */ - pcpu_size[0 ] = -(__per_cpu_end-__per_cpu_start); + pcpu_size[0 ] = -__per_cpu_size;/* Free room. */ pcpu_size[1 ] =PERCPU_ENOUGH_ROOM + pcpu_size[0 ];if (pcpu_size[1 ] <0 ) {
Ingo Molnar
AppliedRe: [PATCH 1/4] Zero based percpu: Infrastructure to rebase the per cpu area to zero
Quoted 22 lines · Mike Travis
* Support an option
CONFIG_HAVE_ZERO_BASED_PER_CPUto make offsets for per cpu variables to start at zero.
If a percpu area starts at zero then:
- We do not need
RELOC_HIDEanymore- 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
Quoted 7 lines
* Removes the
&__per_cpu_xin lockdep. The__per_cpu_xare already pointers. There is no need to take the address.* Updates
kernel/module.cto be able to deal with a percpu area that is loaded at__per_cpu_loadbut is accessed at__per_cpu_start.Based on linux-2.6.tip
applied to tip/core/percpu, thanks.
Ingo
PATCH 2/4 x86: Extend percpu ops to 64 bit
In reply to Mike Travis* x86 percpu ops now will work on 64 bit too, so add the missing 8 byte cases.
* Add a few atomic ops that will be useful in the future:
x86_xchg_percpu()
x86_cmpxchg_percpu().
x86_inc_percpu() - Increment by one can generate more efficient
x86_dec_percpu() instructions and inc/dec will be supported by
cpu ops later.
* Use per_cpu_var() instead of per_cpu__##xxx.
Based on linux-2.6.tip
--- include/asm-x86/percpu.h | 83 ++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 78 insertions(+), 5 deletions(-)
include/asm-x86/percpu.h +78 -5
@@ -108,6 +108,11 @@ do { \ : "+m" (var) \ : "ri" ((T__)val)); \break ; \ +case 8 : \ + asm(op"q %1," __percpu_seg"%0" \ + :"+m" (var) \ + :"ri" ((T__ )val)); \ +break ; \default :__bad_percpu_size (); \ } \ }while (0 )
@@ -131,16 +136,84 @@ do { \ : "=r" (ret__) \ : "m" (var)); \break ; \ +case 8 : \ + asm(op"q " __percpu_seg"%1,%0" \ + :"=r" (ret__) \ + :"m" (var)); \ +break ; \default :__bad_percpu_size (); \ } \ ret__; \ }) -#define x86_read_percpu (var) percpu_from_op("mov", per_cpu__##var) -#define x86_write_percpu (var, val) percpu_to_op("mov", per_cpu__##var, val) -#define x86_add_percpu (var, val) percpu_to_op("add", per_cpu__##var, val) -#define x86_sub_percpu (var, val) percpu_to_op("sub", per_cpu__##var, val) -#define x86_or_percpu (var, val) percpu_to_op("or", per_cpu__##var, val) +#define percpu_addr_op (op, var) \ +({ \ + switch (sizeof(var)) { \ + case 1: \ + asm(op "b "__percpu_seg"%0" \ + : : "m"(var)); \ + break; \ + case 2: \ + asm(op "w "__percpu_seg"%0" \ + : : "m"(var)); \ + break; \ + case 4: \ + asm(op "l "__percpu_seg"%0" \ + : : "m"(var)); \ + break; \ + case 8: \ + asm(op "q "__percpu_seg"%0" \ + : : "m"(var)); \ + break; \ + default: __bad_percpu_size(); \ + } \ +}) + +#define percpu_cmpxchg_op (var, old, new) \ +({ \ + typeof(var) prev; \ + switch (sizeof(var)) { \ + case 1: \ + asm("cmpxchgb %b1, "__percpu_seg"%2" \ + : "=a"(prev) \ + : "q"(new), "m"(var), "0"(old) \ + : "memory"); \ + break; \ + case 2: \ + asm("cmpxchgw %w1, "__percpu_seg"%2" \ + : "=a"(prev) \ + : "r"(new), "m"(var), "0"(old) \ + : "memory"); \ + break; \ + case 4: \ + asm("cmpxchgl %k1, "__percpu_seg"%2" \ + : "=a"(prev) \ + : "r"(new), "m"(var), "0"(old) \ + : "memory"); \ + break; \ + case 8: \ + asm("cmpxchgq %1, "__percpu_seg"%2" \ + : "=a"(prev) \ + : "r"(new), "m"(var), "0"(old) \ + : "memory"); \ + break; \ + default: \ + __bad_percpu_size(); \ + } \ + return prev; \ +}) + +#define x86_read_percpu (var) percpu_from_op("mov", per_cpu_var(var)) +#define x86_write_percpu (var, val) percpu_to_op("mov", per_cpu_var(var), val) +#define x86_add_percpu (var, val) percpu_to_op("add", per_cpu_var(var), val) +#define x86_sub_percpu (var, val) percpu_to_op("sub", per_cpu_var(var), val) +#define x86_inc_percpu (var) percpu_addr_op("inc", per_cpu_var(var)) +#define x86_dec_percpu (var) percpu_addr_op("dec", per_cpu_var(var)) +#define x86_or_percpu (var, val) percpu_to_op("or", per_cpu_var(var), val) +#define x86_xchg_percpu (var, val) percpu_to_op("xchg", per_cpu_var(var), val) +#define x86_cmpxchg_percpu (var, old, new) \ + percpu_cmpxchg_op(per_cpu_var(var), old, new) +#endif /* !__ASSEMBLY__ */ #endif /* !CONFIG_X86_64 */
Ingo Molnar
AppliedRe: [PATCH 2/4] x86: Extend percpu ops to 64 bit
Quoted 7 lines · Mike Travis
* x86 percpu ops now will work on 64 bit too, so add the missing 8 byte cases.
* Add a few atomic ops that will be useful in the future:
x86_xchg_percpu()
x86_cmpxchg_percpu().
Quoted 7 lines
x86_inc_percpu()- Increment by one can generate more efficient
x86_dec_percpu()instructions and inc/dec will be supported by
cpu ops later.* Use
per_cpu_var()instead of per_cpu__##xxx.Based on linux-2.6.tip
applied to tip/cpus4096, thanks Mike.
Ingo
PATCH 3/4 x86_64: Fold pda into per cpu area
In reply to Mike Travis* Declare the pda as a per cpu variable.
* Make the x86_64 per cpu area start at zero.
* Since the pda is now the first element of the per_cpu area, cpu_pda() is no longer needed and per_cpu() can be used instead. This also makes the _cpu_pda[] table obsolete.
* Since %gs is pointing to the pda, it will then also point to the per cpu variables and can be accessed thusly:
%gs:[&per_cpu_xxxx - __per_cpu_start]
Based on linux-2.6.tip
--- arch/x86/Kconfig | 3 + arch/x86/kernel/head64.c | 34 ++++++-------- arch/x86/kernel/irq_64.c | 36 ++++++++------- arch/x86/kernel/setup.c | 90 ++++++++++++--------------------------- arch/x86/kernel/setup64.c | 5 -- arch/x86/kernel/smpboot.c | 51 ---------------------- arch/x86/kernel/traps_64.c | 11 +++- arch/x86/kernel/vmlinux_64.lds.S | 1 include/asm-x86/percpu.h | 48 ++++++-------------- 9 files changed, 89 insertions(+), 190 deletions(-)
arch/x86/Kconfig +3 -0
@@ -129,6 +129,9 @@ config HAVE_SETUP_PER_CPU_AREA config HAVE_CPUMASK_OF_CPU_MAP def_bool X86_64_SMP +config HAVE_ZERO_BASED_PER_CPU + def_bool X86_64_SMP + config ARCH_HIBERNATION_POSSIBLE def_bool y depends on !SMP || !X86_VOYAGER
arch/x86/kernel/head64.c +14 -20
@@ -25,20 +25,6 @@#include <asm/e820.h> #include <asm/bios_ebda.h> -/* boot cpu pda */ -static struct x8664_pda _boot_cpu_pda__read_mostly ; - -#ifdef CONFIG_SMP -/* -* We install an empty cpu_pda pointer table to indicate to early users -* (numa_set_node) that the cpu_pda pointer table for cpus other than -* the boot cpu is not yet setup. -*/ -static struct x8664_pda *__cpu_pda[NR_CPUS ]__initdata ; -#else -static struct x8664_pda *__cpu_pda[NR_CPUS ]__read_mostly ; -#endif -static void __init zap_identity_mappings (void ) {pgd_t *pgd =pgd_offset_k (0UL );
@@ -159,6 +145,20 @@ void __init x86_64_start_kernel(char * r/* Cleanup the over mapped high alias */ cleanup_highmap (); +/* point to boot pda which is the first element in the percpu area */ + { +struct x8664_pda *pda; +#ifdef CONFIG_SMP + pda = (struct x8664_pda *)__per_cpu_load; + pda->data_offset =per_cpu_offset (0 ) = (unsigned long )pda; +#else + pda = &per_cpu (pda,0 ); + pda->data_offset = (unsigned long )pda; +#endif + } +/* initialize boot cpu_pda data */ +pda_init (0 ); +for (i =0 ; i <NUM_EXCEPTION_VECTORS ; i++) {#ifdef CONFIG_EARLY_PRINTK set_intr_gate (i, &early_idt_handlers[i]);
@@ -170,12 +170,6 @@ void __init x86_64_start_kernel(char * rearly_printk ("Kernel alive\n" ); - _cpu_pda = __cpu_pda; -cpu_pda (0 ) = &_boot_cpu_pda; -pda_init (0 ); - -early_printk ("Kernel really alive\n" ); -copy_bootdata (__va (real_mode_data));reserve_early (__pa_symbol (&_text),__pa_symbol (&_end),"TEXT DATA BSS" );
arch/x86/kernel/irq_64.c +20 -16
@@ -115,39 +115,43 @@ skip: }else if (i ==NR_IRQS ) {seq_printf (p,"NMI: " );for_each_online_cpu (j) -seq_printf (p,"%10u " ,cpu_pda (j)->__nmi_count); +seq_printf (p,"%10u " ,per_cpu (pda.__nmi_count, j));seq_printf (p," Non-maskable interrupts\n" );seq_printf (p,"LOC: " );for_each_online_cpu (j) -seq_printf (p,"%10u " ,cpu_pda (j)->apic_timer_irqs); +seq_printf (p,"%10u " ,per_cpu (pda.apic_timer_irqs, j));seq_printf (p," Local timer interrupts\n" );#ifdef CONFIG_SMP seq_printf (p,"RES: " );for_each_online_cpu (j) -seq_printf (p,"%10u " ,cpu_pda (j)->irq_resched_count); +seq_printf (p,"%10u " , +per_cpu (pda.irq_resched_count, j));seq_printf (p," Rescheduling interrupts\n" );seq_printf (p,"CAL: " );for_each_online_cpu (j) -seq_printf (p,"%10u " ,cpu_pda (j)->irq_call_count); +seq_printf (p,"%10u " ,per_cpu (pda.irq_call_count, j));seq_printf (p," function call interrupts\n" );seq_printf (p,"TLB: " );for_each_online_cpu (j) -seq_printf (p,"%10u " ,cpu_pda (j)->irq_tlb_count); +seq_printf (p,"%10u " ,per_cpu (pda.irq_tlb_count, j));seq_printf (p," TLB shootdowns\n" );#endif #ifdef CONFIG_X86_MCE seq_printf (p,"TRM: " );for_each_online_cpu (j) -seq_printf (p,"%10u " ,cpu_pda (j)->irq_thermal_count); +seq_printf (p,"%10u " , +per_cpu (pda.irq_thermal_count, j));seq_printf (p," Thermal event interrupts\n" );seq_printf (p,"THR: " );for_each_online_cpu (j) -seq_printf (p,"%10u " ,cpu_pda (j)->irq_threshold_count); +seq_printf (p,"%10u " , +per_cpu (pda.irq_threshold_count, j));seq_printf (p," Threshold APIC interrupts\n" );#endif seq_printf (p,"SPU: " );for_each_online_cpu (j) -seq_printf (p,"%10u " ,cpu_pda (j)->irq_spurious_count); +seq_printf (p,"%10u " , +per_cpu (pda.irq_spurious_count, j));seq_printf (p," Spurious interrupts\n" );seq_printf (p,"ERR: %10u\n" ,atomic_read (&irq_err_count)); }
@@ -159,19 +163,19 @@ skip:*/ u64 arch_irq_stat_cpu (unsigned int cpu) { -u64 sum =cpu_pda (cpu)->__nmi_count; +u64 sum =per_cpu (pda.__nmi_count, cpu); - sum +=cpu_pda (cpu)->apic_timer_irqs; + sum +=per_cpu (pda.apic_timer_irqs, cpu);#ifdef CONFIG_SMP - sum +=cpu_pda (cpu)->irq_resched_count; - sum +=cpu_pda (cpu)->irq_call_count; - sum +=cpu_pda (cpu)->irq_tlb_count; + sum +=per_cpu (pda.irq_resched_count, cpu); + sum +=per_cpu (pda.irq_call_count, cpu); + sum +=per_cpu (pda.irq_tlb_count, cpu);#endif #ifdef CONFIG_X86_MCE - sum +=cpu_pda (cpu)->irq_thermal_count; - sum +=cpu_pda (cpu)->irq_threshold_count; + sum +=per_cpu (pda.irq_thermal_count, cpu); + sum +=per_cpu (pda.irq_threshold_count, cpu);#endif - sum +=cpu_pda (cpu)->irq_spurious_count; + sum +=per_cpu (pda.irq_spurious_count, cpu);return sum; }
arch/x86/kernel/setup.c +28 -62
131 lines not on this page · raw message
arch/x86/kernel/setup64.c +1 -4
@@ -35,9 +35,6 @@ struct boot_params boot_params;cpumask_t cpu_initialized__cpuinitdata =CPU_MASK_NONE ; -struct x8664_pda **_cpu_pda__read_mostly ; -EXPORT_SYMBOL (_cpu_pda); -struct desc_ptr idt_descr = {256 *16 -1 , (unsigned long ) idt_table }; char boot_cpu_stack[IRQSTACKSIZE] __attribute__((section(".bss.page_aligned")));
@@ -89,7 +86,7 @@ __setup("noexec32=", nonx32_setup);void pda_init (int cpu) { -struct x8664_pda *pda =cpu_pda (cpu); +struct x8664_pda *pda = &per_cpu (pda, cpu);/* Setup up data that may be needed in __get_free_pages early */ asmvolatile ("movl %0,%%fs ; movl %0,%%gs" ::"r" (0 ));
arch/x86/kernel/smpboot.c +1 -50
75 lines not on this page · raw message
arch/x86/kernel/traps_64.c +7 -4
@@ -265,7 +265,8 @@ void dump_trace(struct task_struct *tsk, const struct stacktrace_ops *ops, void *data) { const unsigned cpu = get_cpu(); -unsigned long *irqstack_end = (unsigned long *)cpu_pda (cpu)->irqstackptr; +unsigned long *irqstack_end = + (unsigned long *)per_cpu (pda.irqstackptr, cpu);unsigned used =0 ;struct thread_info *tinfo;
@@ -399,8 +400,10 @@ _show_stack(struct task_struct *tsk, strunsigned long *stack;int i;const int cpu =smp_processor_id (); -unsigned long *irqstack_end = (unsigned long *) (cpu_pda (cpu)->irqstackptr); -unsigned long *irqstack = (unsigned long *) (cpu_pda (cpu)->irqstackptr -IRQSTACKSIZE ); +unsigned long *irqstack_end = + (unsigned long *)per_cpu (pda.irqstackptr, cpu); +unsigned long *irqstack = + (unsigned long *)(per_cpu (pda.irqstackptr, cpu) -IRQSTACKSIZE );// debugging aid: "show_stack(NULL, NULL);" prints the // back trace for this cpu.
@@ -464,7 +467,7 @@ void show_registers(struct pt_regs *regsint i;unsigned long sp;const int cpu =smp_processor_id (); -struct task_struct *cur =cpu_pda (cpu)->pcurrent; +struct task_struct *cur =__get_cpu_var (pda.pcurrent);u8 *ip;unsigned int code_prologue = code_bytes *43 /64 ;unsigned int code_len = code_bytes;
arch/x86/kernel/vmlinux_64.lds.S +1 -0
@@ -16,6 +16,7 @@ jiffies_64 = jiffies; _proxy_pda = 1; PHDRS { text PT_LOAD FLAGS(5); /* R_E */ + percpu PT_LOAD FLAGS(4); /* R__ */ data PT_LOAD FLAGS(7); /* RWE */ user PT_LOAD FLAGS(7); /* RWE */ data.init PT_LOAD FLAGS(7); /* RWE */
include/asm-x86/percpu.h +14 -34
83 lines not on this page · raw message
Re: [PATCH 3/4] x86_64: Fold pda into per cpu area
Quoted 4 lines · Mike Travis
* Declare the pda as a per cpu variable.
* Make the
x86_64per cpu area start at zero.
Quoted 9 lines
* Since the pda is now the first element of the
per_cpuarea,cpu_pda()is no longer needed andper_cpu()can be used instead. This also makes the _cpu_pda[] table obsolete.* Since %gs is pointing to the pda, it will then also point to the per cpu variables and can be accessed thusly:
%gs:[&per_cpu_xxxx -
__per_cpu_start]
Unfortunately that doesn't actually work, because you can't have a reloc with two variables.
In something like:
mov %gs:per_cpu__foo - 12345, %rax mov %gs:per_cpu__foo, %rax mov %gs:per_cpu__foo - 12345(%rip), %rax mov %gs:per_cpu__foo(%rip), %rax mov %gs:per_cpu__foo - __per_cpu_start, %rax mov %gs:per_cpu__foo - __per_cpu_start(%rip), %rax
the last two lines will not assemble:
t.S:5: Error: can't resolve per_cpu__foo' {*UND* section} - __per_cpu_start' {*UND* section} t.S:6: Error: can't resolve per_cpu__foo' {*UND* section} - __per_cpu_start' {*UND* section}
Unfortunately, the only way I can think of fixing this is to compute the offset into a temp register, then use that:
lea per_cpu__foo(%rip), %rax mov %gs:__per_cpu_offset(%rax), %rax
(where __per_cpu_offset is defined in the linker script as -__per_cpu_start).
This seems to be a general problem with zero-offset per-cpu. And its unfortunate, because no-register access to per-cpu variables is nice to have.
The other alternative - and I have no idea whether this is practical or possible - is to define a complete set of pre-offset per_cpu symbols.
J
Re: [PATCH 3/4] x86_64: Fold pda into per cpu area
Quoted 10 lines · Jeremy Fitzhardinge
Quoted 9 lines · Mike Travis
* Declare the pda as a per cpu variable.
* Make the
x86_64per cpu area start at zero.* Since the pda is now the first element of the
per_cpuarea,cpu_pda()is no longer needed andper_cpu()can be used instead. This also
makesthe _cpu_pda[] table obsolete.
Quoted 6 lines
Quoted 6 lines
* Since %gs is pointing to the pda, it will then also point to the
per cpu
variables and can be accessed thusly:%gs:[&per_cpu_xxxx -
__per_cpu_start]
The above is only a partial story (I folded the two patches but didn't update the comments correctly.] The variables are already offset from __per_cpu_start by virtue of the .data.percpu section being based at zero. Therefore only the %gs register needs to be set to the base of each cpu's percpu section to resolve the target address:
%gs:&per_cpu_xxxx
And the .data.percpu.first forces the pda percpu variable to the front.
Quoted 37 lines
Unfortunately that doesn't actually work, because you can't have a reloc with two variables.
In something like:
mov %gs:per_cpu__foo - 12345, %rax mov %gs:per_cpu__foo, %rax mov %gs:per_cpu__foo - 12345(%rip), %rax mov %gs:per_cpu__foo(%rip), %rax mov %gs:per_cpu__foo - __per_cpu_start, %rax mov %gs:per_cpu__foo - __per_cpu_start(%rip), %raxthe last two lines will not assemble:
t.S:5: Error: can't resolve
per_cpu__foo' {*UND* section} -__per_cpu_start' {*UND* section}
t.S:6: Error: can't resolveper_cpu__foo' {*UND* section} -__per_cpu_start' {*UND* section}Unfortunately, the only way I can think of fixing this is to compute the offset into a temp register, then use that:
lea per_cpu__foo(%rip), %rax mov %gs:__per_cpu_offset(%rax), %rax(where
__per_cpu_offsetis defined in the linker script as -__per_cpu_start).This seems to be a general problem with zero-offset per-cpu. And its unfortunate, because no-register access to per-cpu variables is nice to have.
The other alternative - and I have no idea whether this is practical or possible - is to define a complete set of pre-offset
per_cpusymbols.J
Re: [PATCH 3/4] x86_64: Fold pda into per cpu area
Quoted 22 lines · Mike Travis
Quoted 11 lines · Jeremy Fitzhardinge
Quoted 9 lines · Mike Travis
* Declare the pda as a per cpu variable.
* Make the
x86_64per cpu area start at zero.* Since the pda is now the first element of the
per_cpuarea,cpu_pda()is no longer needed andper_cpu()can be used instead. This also
makesthe _cpu_pda[] table obsolete.Quoted 7 lines
Quoted 7 lines
* Since %gs is pointing to the pda, it will then also point to the
per cpu
variables and can be accessed thusly:%gs:[&per_cpu_xxxx -
__per_cpu_start]
Quoted 8 lines
The above is only a partial story (I folded the two patches but didn't update the comments correctly.] The variables are already offset from
__per_cpu_startby virtue of the .data.percpu section being based at zero. Therefore only the %gs register needs to be set to the base of each cpu's percpu section to resolve the target address:%gs:&per_cpu_xxxx
Oh, good. I'd played with trying to make that work at one point, and got lost in linker bugs and/or random version-specific strangeness.
J
Re: [PATCH 3/4] x86_64: Fold pda into per cpu area
Quoted 29 lines · Jeremy Fitzhardinge
Quoted 28 lines · Mike Travis
Quoted 12 lines · Jeremy Fitzhardinge
Quoted 10 lines · Mike Travis
* Declare the pda as a per cpu variable.
* Make the
x86_64per cpu area start at zero.* Since the pda is now the first element of the
per_cpuarea,cpu_pda()
is no longer needed andper_cpu()can be used instead. This also
makesthe _cpu_pda[] table obsolete.Quoted 7 lines
Quoted 7 lines
* Since %gs is pointing to the pda, it will then also point to the
per cpu
variables and can be accessed thusly:%gs:[&per_cpu_xxxx -
__per_cpu_start]The above is only a partial story (I folded the two patches but didn't
update the comments correctly.] The variables are already offset from__per_cpu_startby virtue of the .data.percpu section being based at zero. Therefore only the %gs register needs to be set to the base of each cpu's percpu section to resolve the target address:
Quoted 6 lines
Quoted 2 lines
%gs:&per_cpu_xxxxOh, good. I'd played with trying to make that work at one point, and got lost in linker bugs and/or random version-specific strangeness.
J
Incidentally, this is why the following load is needed in x86_64_start_kernel():
pda = (struct x8664_pda *)__per_cpu_load;
pda->data_offset = per_cpu_offset(0) = (unsigned long)pda;
/* initialize boot cpu_pda data */
pda_init(0);pda_init() loads the %gs reg so early accesses to the static per_cpu section can be executed before the percpu areas are allocated.
Re: [PATCH 3/4] x86_64: Fold pda into per cpu area
In reply to Jeremy FitzhardingeQuoted 5 lines · Jeremy Fitzhardinge
Quoted 2 lines
%gs:[&per_cpu_xxxx - __per_cpu_start]Unfortunately that doesn't actually work, because you can't have a reloc with two variables.
That is just a conceptual discussion. __per_cpu_start is 0 with the zero based patch. And thus this reduces to
%gs[&per_cpu_xxx]
[crash, bisected] Re: [PATCH 3/4] x86_64: Fold pda into per cpu area
In reply to Mike TravisQuoted 8 lines · Mike Travis
* Declare the pda as a per cpu variable.
* Make the
x86_64per cpu area start at zero.* Since the pda is now the first element of the
per_cpuarea,cpu_pda()is no longer needed andper_cpu()can be used instead. This also makes the _cpu_pda[] table obsolete.
Quoted 6 lines
* Since %gs is pointing to the pda, it will then also point to the per cpu variables and can be accessed thusly:
%gs:[&per_cpu_xxxx -
__per_cpu_start]Based on linux-2.6.tip
-tip testing found an instantaneous reboot crash on 64-bit x86, with this config:
http://redhat.com/~mingo/misc/config-Thu_Jun__5_11_43_51_CEST_2008.bad
there is no boot log as the instantaneous reboot happens before anything is printed to the (early-) serial console. I have bisected it down to:
| 7670dc09e89a2b151a1cf49eccebc07c41c2ce9f is first bad commit | commit 7670dc09e89a2b151a1cf49eccebc07c41c2ce9f | Author: Mike Travis <[email protected]> | Date: Tue Jun 3 17:30:21 2008 -0700 | | x86_64: Fold pda into per cpu area
the big problem is not just this crash, but that the patch is _way_ too big:
arch/x86/Kconfig | 3 + arch/x86/kernel/head64.c | 34 ++++++-------- arch/x86/kernel/irq_64.c | 36 ++++++++------- arch/x86/kernel/setup.c | 90 ++++++++++++--------------------------- arch/x86/kernel/setup64.c | 5 -- arch/x86/kernel/smpboot.c | 51 ---------------------- arch/x86/kernel/traps_64.c | 11 +++- arch/x86/kernel/vmlinux_64.lds.S | 1 include/asm-x86/percpu.h | 48 ++++++-------------- 9 files changed, 89 insertions(+), 190 deletions(-)
considering the danger involved, this is just way too large, and there's no reasonable debugging i can do in the bisection to narrow it down any further.
Please resubmit with the bug fixed and with a proper splitup, the more patches you manage to create, the better. For a dangerous code area like this, with a track record of frequent breakages in the past, i would not mind a "one line of code changed per patch" splitup either. (Feel free to send a git tree link for us to try as well.)
Ingo
Re: [crash, bisected] Re: [PATCH 3/4] x86_64: Fold pda into per cpu area
Quoted 50 lines · Ingo Molnar
Quoted 8 lines · Mike Travis
* Declare the pda as a per cpu variable.
* Make the
x86_64per cpu area start at zero.* Since the pda is now the first element of the
per_cpuarea,cpu_pda()is no longer needed andper_cpu()can be used instead. This also makes the _cpu_pda[] table obsolete.Quoted 6 lines
* Since %gs is pointing to the pda, it will then also point to the per cpu variables and can be accessed thusly:
%gs:[&per_cpu_xxxx -
__per_cpu_start]Based on linux-2.6.tip
-tip testing found an instantaneous reboot crash on 64-bit x86, with this config:
http://redhat.com/~mingo/misc/config-Thu_Jun__5_11_43_51_CEST_2008.bad
there is no boot log as the instantaneous reboot happens before anything is printed to the (early-) serial console. I have bisected it down to:
| 7670dc09e89a2b151a1cf49eccebc07c41c2ce9f is first bad commit | commit 7670dc09e89a2b151a1cf49eccebc07c41c2ce9f | Author: Mike Travis <[email protected]> | Date: Tue Jun 3 17:30:21 2008 -0700 | | x86_64: Fold pda into per cpu areathe big problem is not just this crash, but that the patch is _way_ too big:
arch/x86/Kconfig | 3 + arch/x86/kernel/head64.c | 34 ++++++-------- arch/x86/kernel/irq_64.c | 36 ++++++++------- arch/x86/kernel/setup.c | 90 ++++++++++++--------------------------- arch/x86/kernel/setup64.c | 5 -- arch/x86/kernel/smpboot.c | 51 ---------------------- arch/x86/kernel/traps_64.c | 11 +++- arch/x86/kernel/vmlinux_64.lds.S | 1 include/asm-x86/percpu.h | 48 ++++++-------------- 9 files changed, 89 insertions(+), 190 deletions(-)considering the danger involved, this is just way too large, and there's no reasonable debugging i can do in the bisection to narrow it down any further.
Quoted 7 lines
Please resubmit with the bug fixed and with a proper splitup, the more patches you manage to create, the better. For a dangerous code area like this, with a track record of frequent breakages in the past, i would not mind a "one line of code changed per patch" splitup either. (Feel free to send a git tree link for us to try as well.)
Ingo
Thanks for the feedback Ingo. I'll test the above config and look at splitting up the patch. The difficulty is making each patch independently compilable and testable.
Mike
Re: [crash, bisected] Re: [PATCH 3/4] x86_64: Fold pda into per cpu area
Quoted 49 lines · Mike Travis
Quoted 47 lines · Ingo Molnar
Quoted 8 lines · Mike Travis
* Declare the pda as a per cpu variable.
* Make the
x86_64per cpu area start at zero.* Since the pda is now the first element of the
per_cpuarea,cpu_pda()is no longer needed andper_cpu()can be used instead. This also makes the _cpu_pda[] table obsolete.Quoted 7 lines
* Since %gs is pointing to the pda, it will then also point to the per cpu variables and can be accessed thusly:
%gs:[&per_cpu_xxxx -
__per_cpu_start]Based on linux-2.6.tip
-tip testing found an instantaneous reboot crash on 64-bit x86, with this config:
http://redhat.com/~mingo/misc/config-Thu_Jun__5_11_43_51_CEST_2008.bad
there is no boot log as the instantaneous reboot happens before anything is printed to the (early-) serial console. I have bisected it down to:
| 7670dc09e89a2b151a1cf49eccebc07c41c2ce9f is first bad commit | commit 7670dc09e89a2b151a1cf49eccebc07c41c2ce9f | Author: Mike Travis <[email protected]> | Date: Tue Jun 3 17:30:21 2008 -0700 | | x86_64: Fold pda into per cpu areathe big problem is not just this crash, but that the patch is _way_ too big:
arch/x86/Kconfig | 3 + arch/x86/kernel/head64.c | 34 ++++++-------- arch/x86/kernel/irq_64.c | 36 ++++++++------- arch/x86/kernel/setup.c | 90 ++++++++++++--------------------------- arch/x86/kernel/setup64.c | 5 -- arch/x86/kernel/smpboot.c | 51 ---------------------- arch/x86/kernel/traps_64.c | 11 +++- arch/x86/kernel/vmlinux_64.lds.S | 1 include/asm-x86/percpu.h | 48 ++++++-------------- 9 files changed, 89 insertions(+), 190 deletions(-)considering the danger involved, this is just way too large, and there's no reasonable debugging i can do in the bisection to narrow it down any further.
Quoted 8 lines
Quoted 4 lines
Please resubmit with the bug fixed and with a proper splitup, the more patches you manage to create, the better. For a dangerous code area like this, with a track record of frequent breakages in the past, i would not mind a "one line of code changed per patch" splitup either. (Feel free to send a git tree link for us to try as well.)
Ingo
Thanks for the feedback Ingo. I'll test the above config and look at splitting up the patch. The difficulty is making each patch independently compilable and testable.
FWIW, I'm getting past the "crashes very, very early" stage with this series applied when booting under Xen. Then it crashes pretty early, but that's not your fault...
J
Re: [crash, bisected] Re: [PATCH 3/4] x86_64: Fold pda into per cpu area
Quoted 73 lines · Jeremy Fitzhardinge
Quoted 64 lines · Mike Travis
Quoted 62 lines · Ingo Molnar
Quoted 10 lines · Mike Travis
* Declare the pda as a per cpu variable.
* Make the
x86_64per cpu area start at zero.* Since the pda is now the first element of the
per_cpuarea,cpu_pda()
is no longer needed andper_cpu()can be used instead. This
also makesthe _cpu_pda[] table obsolete.Quoted 8 lines
* Since %gs is pointing to the pda, it will then also point to the
per cpu
variables and can be accessed thusly:%gs:[&per_cpu_xxxx -
__per_cpu_start]Based on linux-2.6.tip
-tip testing found an instantaneous reboot crash on 64-bit x86, with this config:
http://redhat.com/~mingo/misc/config-Thu_Jun__5_11_43_51_CEST_2008.bad
there is no boot log as the instantaneous reboot happens before anything is printed to the (early-) serial console. I have bisected it down to:
| 7670dc09e89a2b151a1cf49eccebc07c41c2ce9f is first bad commit | commit 7670dc09e89a2b151a1cf49eccebc07c41c2ce9f | Author: Mike Travis <[email protected]> | Date: Tue Jun 3 17:30:21 2008 -0700 | | x86_64: Fold pda into per cpu areathe big problem is not just this crash, but that the patch is _way_ too big:
arch/x86/Kconfig | 3 + arch/x86/kernel/head64.c | 34 ++++++-------- arch/x86/kernel/irq_64.c | 36 ++++++++------- arch/x86/kernel/setup.c | 90 ++++++++++++--------------------------- arch/x86/kernel/setup64.c | 5 -- arch/x86/kernel/smpboot.c | 51 ---------------------- arch/x86/kernel/traps_64.c | 11 +++- arch/x86/kernel/vmlinux_64.lds.S | 1 include/asm-x86/percpu.h | 48 ++++++-------------- 9 files changed, 89 insertions(+), 190 deletions(-)considering the danger involved, this is just way too large, and there's no reasonable debugging i can do in the bisection to narrow it down any further.
Please resubmit with the bug fixed and with a proper splitup, the more patches you manage to create, the better. For a dangerous code area like this, with a track record of frequent breakages in the past, i would not mind a "one line of code changed per patch" splitup either. (Feel free to send a git tree link for us to try as well.)
Quoted 7 lines
Quoted 2 lines
Ingo
Thanks for the feedback Ingo. I'll test the above config and look at splitting up the patch. The difficulty is making each patch independently
compilable and testable.
Quoted 5 lines
FWIW, I'm getting past the "crashes very, very early" stage with this series applied when booting under Xen. Then it crashes pretty early, but that's not your fault...
J
Hi Jeremy,
Yes we have a simulator for Nahelem that also breezes past the boot up problem (actually makes it to the kernel login prompt.) Weirdly, the problem doesn't exist in an earlier code base so my changes are tickling something else newly introduced. I'm attempting to see if I can use GRUB 2 with the GDB stubs to track it down (which is time consuming in itself to setup.)
It is definitely related to basing percpu variable offsets from %gs and (I think) interrupts.
Thanks,
Mike
Re: [crash, bisected] Re: [PATCH 3/4] x86_64: Fold pda into per cpu area
Quoted 95 lines · Mike Travis
Quoted 77 lines · Jeremy Fitzhardinge
Quoted 67 lines · Mike Travis
Quoted 64 lines · Ingo Molnar
Quoted 10 lines · Mike Travis
* Declare the pda as a per cpu variable.
* Make the
x86_64per cpu area start at zero.* Since the pda is now the first element of the
per_cpuarea,cpu_pda()
is no longer needed andper_cpu()can be used instead. This
also makesthe _cpu_pda[] table obsolete.Quoted 9 lines
* Since %gs is pointing to the pda, it will then also point to the
per cpu
variables and can be accessed thusly:%gs:[&per_cpu_xxxx -
__per_cpu_start]Based on linux-2.6.tip
-tip testing found an instantaneous reboot crash on 64-bit x86, with this config:
http://redhat.com/~mingo/misc/config-Thu_Jun__5_11_43_51_CEST_2008.bad
there is no boot log as the instantaneous reboot happens before anything is printed to the (early-) serial console. I have bisected it down to:
| 7670dc09e89a2b151a1cf49eccebc07c41c2ce9f is first bad commit | commit 7670dc09e89a2b151a1cf49eccebc07c41c2ce9f | Author: Mike Travis <[email protected]> | Date: Tue Jun 3 17:30:21 2008 -0700 | | x86_64: Fold pda into per cpu areathe big problem is not just this crash, but that the patch is _way_ too big:
arch/x86/Kconfig | 3 + arch/x86/kernel/head64.c | 34 ++++++-------- arch/x86/kernel/irq_64.c | 36 ++++++++------- arch/x86/kernel/setup.c | 90 ++++++++++++--------------------------- arch/x86/kernel/setup64.c | 5 -- arch/x86/kernel/smpboot.c | 51 ---------------------- arch/x86/kernel/traps_64.c | 11 +++- arch/x86/kernel/vmlinux_64.lds.S | 1 include/asm-x86/percpu.h | 48 ++++++-------------- 9 files changed, 89 insertions(+), 190 deletions(-)considering the danger involved, this is just way too large, and there's no reasonable debugging i can do in the bisection to narrow it down any further.
Please resubmit with the bug fixed and with a proper splitup, the more patches you manage to create, the better. For a dangerous code area like this, with a track record of frequent breakages in the past, i would not mind a "one line of code changed per patch" splitup either. (Feel free to send a git tree link for us to try as well.)
Quoted 8 lines
Quoted 3 lines
Ingo
Thanks for the feedback Ingo. I'll test the above config and look at splitting up the patch. The difficulty is making each patch independently
compilable and testable.Quoted 6 lines
FWIW, I'm getting past the "crashes very, very early" stage with this series applied when booting under Xen. Then it crashes pretty early, but that's not your fault...
J
Hi Jeremy,
Yes we have a simulator for Nahelem that also breezes past the boot up problem (actually makes it to the kernel login prompt.) Weirdly, the problem doesn't exist in an earlier code base so my changes are tickling something else newly introduced. I'm attempting to see if I can use GRUB 2 with the GDB stubs to track it down (which is time consuming in itself to setup.)
Quoted 3 lines
It is definitely related to basing percpu variable offsets from %gs and (I think) interrupts.
Hi Mike,
Have you made any progress on this? I'm bumping up against it when I run on native hardware (as opposed to under Xen).
J
Re: [crash, bisected] Re: [PATCH 3/4] x86_64: Fold pda into per cpu area
In reply to Ingo MolnarQuoted 13 lines · Ingo Molnar
Quoted 11 lines · Mike Travis
* Declare the pda as a per cpu variable.
* Make the
x86_64per cpu area start at zero.* Since the pda is now the first element of the
per_cpuarea,cpu_pda()is no longer needed andper_cpu()can be used instead. This also makes the _cpu_pda[] table obsolete.* Since %gs is pointing to the pda, it will then also point to the per cpu variables and can be accessed thusly:
Quoted 8 lines
Quoted 3 lines
%gs:[&per_cpu_xxxx - __per_cpu_start]Based on linux-2.6.tip
-tip testing found an instantaneous reboot crash on 64-bit x86, with this config:
http://redhat.com/~mingo/misc/config-Thu_Jun__5_11_43_51_CEST_2008.bad
I'm still stuck on this one. One new development is that the current -tip branch without the patches boots to the kernel prompt then hangs after a few moments and then reboots. It seems you can tickle it using ^C to abort a process.
-Mike
Quoted 36 lines
there is no boot log as the instantaneous reboot happens before anything is printed to the (early-) serial console. I have bisected it down to:
| 7670dc09e89a2b151a1cf49eccebc07c41c2ce9f is first bad commit | commit 7670dc09e89a2b151a1cf49eccebc07c41c2ce9f | Author: Mike Travis <[email protected]> | Date: Tue Jun 3 17:30:21 2008 -0700 | | x86_64: Fold pda into per cpu areathe big problem is not just this crash, but that the patch is _way_ too big:
arch/x86/Kconfig | 3 + arch/x86/kernel/head64.c | 34 ++++++-------- arch/x86/kernel/irq_64.c | 36 ++++++++------- arch/x86/kernel/setup.c | 90 ++++++++++++--------------------------- arch/x86/kernel/setup64.c | 5 -- arch/x86/kernel/smpboot.c | 51 ---------------------- arch/x86/kernel/traps_64.c | 11 +++- arch/x86/kernel/vmlinux_64.lds.S | 1 include/asm-x86/percpu.h | 48 ++++++-------------- 9 files changed, 89 insertions(+), 190 deletions(-)considering the danger involved, this is just way too large, and there's no reasonable debugging i can do in the bisection to narrow it down any further.
Please resubmit with the bug fixed and with a proper splitup, the more patches you manage to create, the better. For a dangerous code area like this, with a track record of frequent breakages in the past, i would not mind a "one line of code changed per patch" splitup either. (Feel free to send a git tree link for us to try as well.)
Ingo
Re: [crash, bisected] Re: [PATCH 3/4] x86_64: Fold pda into per cpu area
Quoted 23 lines · Mike Travis
Quoted 21 lines · Ingo Molnar
Quoted 8 lines · Mike Travis
* Declare the pda as a per cpu variable.
* Make the
x86_64per cpu area start at zero.* Since the pda is now the first element of the
per_cpuarea,cpu_pda()is no longer needed andper_cpu()can be used instead. This also makes the _cpu_pda[] table obsolete.Quoted 7 lines
* Since %gs is pointing to the pda, it will then also point to the per cpu variables and can be accessed thusly:
%gs:[&per_cpu_xxxx -
__per_cpu_start]Based on linux-2.6.tip
-tip testing found an instantaneous reboot crash on 64-bit x86, with this config:
Quoted 7 lines
I'm still stuck on this one. One new development is that the current -tip branch without the patches boots to the kernel prompt then hangs after a few moments and then reboots. It seems you can tickle it using ^C to abort a process.
Hi Mike,
I added some instrumentation to Xen to print the cpu state on triple-fault, which highlights an obvious-looking problem.
(XEN) hvm.c:767:d1 Triple fault on VCPU0 - invoking HVM system reset. (XEN) ----[ Xen-3.3-unstable x86_64 debug=y Not tainted ]----
(XEN) CPU: 1
(XEN) RIP: 0010:[<ffffffff80200160>]
(XEN) RFLAGS: 0000000000010002 CONTEXT: hvm
(XEN) rax: 0000000000000018 rbx: 0000000000000000 rcx: 00000000c0000080 (XEN) rdx: 0000000000000000 rsi: 0000000000092f40 rdi: 0000000020100800 (XEN) rbp: 0000000000000000 rsp: ffffffff807dfff8 r8: 0000000000208000 (XEN) r9: 0000000000000000 r10: 0000000000000000 r11: 00000000000000de (XEN) r12: 0000000000000000 r13: 0000000000000000 r14: 0000000000000000 (XEN) r15: 0000000000000000 cr0: 0000000080050033 cr4: 00000000000000a0 (XEN) cr3: 0000000000201000 cr2: 0000000000000000
(XEN) ds: 0000 es: 0000 fs: 0000 gs: 0000 ss: 0000 cs: 0010
The rip is:
(gdb) x/i 0xffffffff802001600xffffffff80200160 <secondary_startup_64+96>: movl %eax,%ds
which is:
lgdt early_gdt_descr(%rip) /* set up data segments. actually 0 would do too */ movl $__KERNEL_DS,%eax movl %eax,%ds movl %eax,%ss movl %eax,%es
And early_gdt_descr is:
.globl early_gdt_descrearly_gdt_descr:
.word GDT_ENTRIES*8-1 .quad per_cpu__gdt_page
and per_cpu__gdt_page is zero-based, and therefore not a directly addressable symbol.
I tried this patch, but it didn't work. Perhaps I'm missing something.
arch/x86/kernel/head_64.S +0 -0
@@ -94,6 +94,8 @@
addq %rbp, level2_fixmap_pgt + (506*8)(%rip)
+ addq $__per_cpu_load, early_gdt_descr+2(%rip)
+
/* Add an Identity mapping if I am above 1G */ leaq _text(%rip), %rdi andq $PMD_PAGE_MASK, %rdi
J
Re: [crash, bisected] Re: [PATCH 3/4] x86_64: Fold pda into per cpu area
Quoted 97 lines · Jeremy Fitzhardinge
Quoted 29 lines · Mike Travis
Quoted 17 lines · Ingo Molnar
Quoted 14 lines · Mike Travis
* Declare the pda as a per cpu variable.
* Make the
x86_64per cpu area start at zero.* Since the pda is now the first element of the
per_cpuarea,cpu_pda()
is no longer needed andper_cpu()can be used instead. This
also makesthe _cpu_pda[] table obsolete.* Since %gs is pointing to the pda, it will then also point to the
per cpu
variables and can be accessed thusly:Quoted 9 lines
Quoted 4 lines
%gs:[&per_cpu_xxxx - __per_cpu_start]Based on linux-2.6.tip
-tip testing found an instantaneous reboot crash on 64-bit x86, with this config:
http://redhat.com/~mingo/misc/config-Thu_Jun__5_11_43_51_CEST_2008.bad
Quoted 6 lines
I'm still stuck on this one. One new development is that the current -tip
branch without the patches boots to the kernel prompt then hangs after a few
moments and then reboots. It seems you can tickle it using ^C to abort a process.Hi Mike,
I added some instrumentation to Xen to print the cpu state on triple-fault, which highlights an obvious-looking problem.
(XEN) hvm.c:767:d1 Triple fault on VCPU0 - invoking HVM system reset. (XEN) ----[ Xen-3.3-unstable
x86_64debug=y Not tainted ]----
(XEN) CPU: 1
(XEN) RIP: 0010:[<ffffffff80200160>]
(XEN) RFLAGS: 0000000000010002 CONTEXT: hvm(XEN) rax: 0000000000000018 rbx: 0000000000000000 rcx: 00000000c0000080 (XEN) rdx: 0000000000000000 rsi: 0000000000092f40 rdi: 0000000020100800 (XEN) rbp: 0000000000000000 rsp: ffffffff807dfff8 r8: 0000000000208000 (XEN) r9: 0000000000000000 r10: 0000000000000000 r11: 00000000000000de (XEN) r12: 0000000000000000 r13: 0000000000000000 r14: 0000000000000000 (XEN) r15: 0000000000000000 cr0: 0000000080050033 cr4: 00000000000000a0 (XEN) cr3: 0000000000201000 cr2: 0000000000000000(XEN) ds: 0000 es: 0000 fs: 0000 gs: 0000 ss: 0000 cs: 0010
The rip is:
(gdb) x/i
0xffffffff802001600xffffffff80200160<secondary_startup_64+96>: movl %eax,%dswhich is:
lgdt early_gdt_descr(%rip) /* set up data segments. actually 0 would do too */ movl $__KERNEL_DS,%eax movl %eax,%ds movl %eax,%ss movl %eax,%esAnd
early_gdt_descris:.globl
early_gdt_descrearly_gdt_descr:
.word GDT_ENTRIES*8-1
.quadper_cpu__gdt_pageand
per_cpu__gdt_pageis zero-based, and therefore not a directly addressable symbol.I tried this patch, but it didn't work. Perhaps I'm missing something.
diff -r
bf5a46e13f78arch/x86/kernel/head_64.Sarch/x86/kernel/head_64.S Wed Jun 18 10:34:24 2008 -0700 renamed from arch/x86/kernel/head_64.S Tue Jun 17 22:10:51 2008 -0700 +2
-0@@ -94,6 +94,8 @@ addq %rbp, level2_fixmap_pgt + (506*8)(%rip) + addq $__per_cpu_load, early_gdt_descr+2(%rip) + /* Add an Identity mapping if I am above 1G */ leaq _text(%rip), %rdi andq $PMD_PAGE_MASK, %rdi
Quoted 1 line
J
Hi Jeremy,
I'm not finding that code in the tip/latest or linux-next branches... ?
I can send you my latest version of the patch which is better than the previous but still is having problems with the config file that Ingo sent out. (It also has a weird quirk that it will hang and reboot after about 30 seconds with or without my patch.)
Thanks,
Mike
Re: [crash, bisected] Re: [PATCH 3/4] x86_64: Fold pda into per cpu area
Quoted 9 lines · Mike Travis
Hi Jeremy,
I'm not finding that code in the tip/latest or linux-next branches... ?
I can send you my latest version of the patch which is better than the previous but still is having problems with the config file that Ingo sent out. (It also has a weird quirk that it will hang and reboot after about 30 seconds with or without my patch.)
the patch is not in -tip yet because we dont keep known-broken patches applied unless there's some really strong reason to do so.
Ingo
Re: [crash, bisected] Re: [PATCH 3/4] x86_64: Fold pda into per cpu area
In reply to Mike TravisQuoted 103 lines · Mike Travis
Quoted 101 lines · Jeremy Fitzhardinge
Quoted 32 lines · Mike Travis
Quoted 20 lines · Ingo Molnar
Quoted 16 lines · Mike Travis
* Declare the pda as a per cpu variable.
* Make the
x86_64per cpu area start at zero.* Since the pda is now the first element of the
per_cpuarea,cpu_pda()
is no longer needed andper_cpu()can be used instead. This
also makesthe _cpu_pda[] table obsolete.* Since %gs is pointing to the pda, it will then also point to the
per cpu
variables and can be accessed thusly:%gs:[&per_cpu_xxxx -
__per_cpu_start]Quoted 9 lines
Quoted 3 lines
Based on linux-2.6.tip
-tip testing found an instantaneous reboot crash on 64-bit x86, with this config:
http://redhat.com/~mingo/misc/config-Thu_Jun__5_11_43_51_CEST_2008.bad
Quoted 7 lines
I'm still stuck on this one. One new development is that the current -tip
branch without the patches boots to the kernel prompt then hangs after a few
moments and then reboots. It seems you can tickle it using ^C to abort a process.Hi Mike,
I added some instrumentation to Xen to print the cpu state on triple-fault, which highlights an obvious-looking problem.
(XEN) hvm.c:767:d1 Triple fault on VCPU0 - invoking HVM system reset. (XEN) ----[ Xen-3.3-unstable
x86_64debug=y Not tainted ]----
(XEN) CPU: 1
(XEN) RIP: 0010:[<ffffffff80200160>]
(XEN) RFLAGS: 0000000000010002 CONTEXT: hvm(XEN) rax: 0000000000000018 rbx: 0000000000000000 rcx: 00000000c0000080 (XEN) rdx: 0000000000000000 rsi: 0000000000092f40 rdi: 0000000020100800 (XEN) rbp: 0000000000000000 rsp: ffffffff807dfff8 r8: 0000000000208000 (XEN) r9: 0000000000000000 r10: 0000000000000000 r11: 00000000000000de (XEN) r12: 0000000000000000 r13: 0000000000000000 r14: 0000000000000000 (XEN) r15: 0000000000000000 cr0: 0000000080050033 cr4: 00000000000000a0 (XEN) cr3: 0000000000201000 cr2: 0000000000000000(XEN) ds: 0000 es: 0000 fs: 0000 gs: 0000 ss: 0000 cs: 0010
The rip is:
(gdb) x/i
0xffffffff802001600xffffffff80200160<secondary_startup_64+96>: movl %eax,%dswhich is:
lgdt early_gdt_descr(%rip) /* set up data segments. actually 0 would do too */ movl $__KERNEL_DS,%eax movl %eax,%ds movl %eax,%ss movl %eax,%esAnd
early_gdt_descris:.globl
early_gdt_descrearly_gdt_descr:
.word GDT_ENTRIES*8-1
.quadper_cpu__gdt_pageand
per_cpu__gdt_pageis zero-based, and therefore not a directly addressable symbol.I tried this patch, but it didn't work. Perhaps I'm missing something.
diff -r
bf5a46e13f78arch/x86/kernel/head_64.Sarch/x86/kernel/head_64.S Wed Jun 18 10:34:24 2008 -0700 renamed from arch/x86/kernel/head_64.S Tue Jun 17 22:10:51 2008 -0700 +2
-0@@ -94,6 +94,8 @@ addq %rbp, level2_fixmap_pgt + (506*8)(%rip) + addq $__per_cpu_load, early_gdt_descr+2(%rip) + /* Add an Identity mapping if I am above 1G */ leaq _text(%rip), %rdi andq $PMD_PAGE_MASK, %rdi
Quoted 7 lines
Quoted 2 lines
J
Hi Jeremy,
I'm not finding that code in the tip/latest or linux-next branches... ?
You mean your percpu/pda code? No, I'm carrying it locally because I need it as a base for my Xen work. Xen bypasses these early boot stages, so I haven't seen any problems so far. But I'd also like to make sure that my Xen changes don't break native boots, too...
Quoted 5 lines
I can send you my latest version of the patch which is better than the previous but still is having problems with the config file that Ingo sent out. (It also has a weird quirk that it will hang and reboot after about 30 seconds with or without my patch.)
Yes, keep me uptodate with the percpu work.
J
A message that is not in the archive (sent off-list or not yet received): [email protected]
A message that is not in the archive (sent off-list or not yet received): [email protected]
A message that is not in the archive (sent off-list or not yet received): [email protected]
A message that is not in the archive (sent off-list or not yet received): [email protected]
A message that is not in the archive (sent off-list or not yet received): [email protected]
A message that is not in the archive (sent off-list or not yet received): [email protected]
A message that is not in the archive (sent off-list or not yet received): [email protected]
Re: [crash, bisected] Re: [PATCH 3/4] x86_64: Fold pda into per cpu area
Quoted 6 lines · Mike Travis
Oh yeah, is it alright to re-use the pda in the static percpu load area for each startup cpu, or should it be adjusted to use the areas allocated by
setup_per_cpu_areas()?pda_init()is called inx86_64_start_kernelso it would only be for anything that occurs before then. (And I moved the call topda_init()to before theearly_idt_handlersare setup.)
Why not use the real pda for all cpus?
Do you move the boot-cpu's per-cpu data? (Please don't) If not, you can just use percpu__pda from the start without having to do anything else, and then set up %gs pointing to the pda base for each secondary cpu.
64-bit inherits 32-bit's use of per-cpu gdts, though its mostly useless on 64-bit.
More important is to have a:
startup_percpu_base: .quad __per_cpu_load
which you stick the processor's initial %gs into, and then load that from in startup_secondary_64:
mov $X86_MSR_GSBASE, %ecx
mov startup_percpu_base, %eax
mov startup_percpu_base+4, %edx
wrmsr
and put
startup_percpu_base = new_cpus_percpu_base;
in do_cpu_boot().
Quoted 4 lines
I hadn't realized that this code is executed for cpus other than the boot cpu. Is there a way to find out if this is the boot cpu (and/or the initial execution)?
Don't think so. If you want something to happen only at boot time, do it in startup_64.
Quoted 8 lines
If it's the boot cpu, then this would work for the gdt, yes?
leaq early_gdt_descr_base(%rip), %edi movq 0(%edi), %rax addq $__per_cpu_load, %rax movq %rax, 0(%edi) lgdt early_gdt_descr(%rip)
As I mentioned in my other mail, a simple add should be enough.
Quoted 10 lines
But it should only be executed for the boot because
do_boot_cpu()does this:early_gdt_descr.address = (unsigned long)get_cpu_gdt_table(cpu);static inline struct
desc_struct*get_cpu_gdt_table(unsigned int cpu){ return per_cpu(gdt_page, cpu).gdt; }
Right, do it in startup_64.
Quoted 3 lines
Btw, I've only been testing on an
x86_64system. I'm sure I've got things to fix up for i386.
It should be possible to share almost everything, at least in C.
J
Re: [crash, bisected] Re: [PATCH 3/4] x86_64: Fold pda into per cpu area
Quoted 1 line · Jeremy Fitzhardinge
64-bit inherits 32-bit's use of per-cpu gdts, though its mostly useless on 64-bit.
Note to self: Not really true; they're still needed for 32-on-64.
J
Re: [crash, bisected] Re: [PATCH 3/4] x86_64: Fold pda into per cpu area
In reply to Jeremy FitzhardingeQuoted 2 lines · Jeremy Fitzhardinge
Why not use the real pda for all cpus?
Yeah, I figured that out after doing some more thinking... ;-)
Quoted 4 lines
Do you move the boot-cpu's per-cpu data? (Please don't) If not, you can just use
percpu__pdafrom the start without having to do anything else, and then set up %gs pointing to the pda base for each secondary cpu.
The problem is that the static percpu area is removed as it lies in the initdata section, so the pda is removed as well.
But I took your suggestion to move the fixup to before secondary_startup.
Below is a revised version. It builds but I'll have to test it tomorrow. Note the addition of:
+ initial_pda = (unsigned long)get_percpu_pda(cpu);
in do_boot_cpu.
I'm not sure yet what to put into acpi_save_state_mem:
initial_code = (unsigned long)wakeup_long64;
+ /* ZZZ initial_pda = (unsigned long)?; */
Thanks again for your help!
Based on linux-2.6.tip/master
--- arch/x86/Kconfig | 3 + arch/x86/kernel/acpi/sleep.c | 1 arch/x86/kernel/head64.c | 34 ++++++--------- arch/x86/kernel/head_64.S | 13 +++++ arch/x86/kernel/setup.c | 86 +++++++++++---------------------------- arch/x86/kernel/setup64.c | 3 - arch/x86/kernel/smpboot.c | 52 ----------------------- arch/x86/kernel/vmlinux_64.lds.S | 1 include/asm-x86/desc.h | 5 ++ include/asm-x86/pda.h | 3 - include/asm-x86/percpu.h | 46 +++++--------------- include/asm-x86/trampoline.h | 1 12 files changed, 78 insertions(+), 170 deletions(-)
arch/x86/Kconfig +3 -0
@@ -129,6 +129,9 @@ config HAVE_SETUP_PER_CPU_AREA config HAVE_CPUMASK_OF_CPU_MAP def_bool X86_64_SMP +config HAVE_ZERO_BASED_PER_CPU + def_bool X86_64_SMP + config ARCH_HIBERNATION_POSSIBLE def_bool y depends on !SMP || !X86_VOYAGER
arch/x86/kernel/acpi/sleep.c +1 -0
@@ -76,6 +76,7 @@ int acpi_save_state_mem(void) stack_start.sp = temp_stack +4096 ;#endif initial_code = (unsigned long )wakeup_long64; +/* ZZZ initial_pda = (unsigned long)?; */ saved_magic =0x123456789abcdef0 ;#endif /* CONFIG_64BIT */
arch/x86/kernel/head64.c +14 -20
@@ -25,20 +25,6 @@#include <asm/e820.h> #include <asm/bios_ebda.h> -/* boot cpu pda */ -static struct x8664_pda _boot_cpu_pda__read_mostly ; - -#ifdef CONFIG_SMP -/* -* We install an empty cpu_pda pointer table to indicate to early users -* (numa_set_node) that the cpu_pda pointer table for cpus other than -* the boot cpu is not yet setup. -*/ -static struct x8664_pda *__cpu_pda[NR_CPUS ]__initdata ; -#else -static struct x8664_pda *__cpu_pda[NR_CPUS ]__read_mostly ; -#endif -static void __init zap_identity_mappings (void ) {pgd_t *pgd =pgd_offset_k (0UL );
@@ -91,6 +77,20 @@ void __init x86_64_start_kernel(char * r/* Cleanup the over mapped high alias */ cleanup_highmap (); +/* point to boot pda which is the first element in the percpu area */ + { +struct x8664_pda *pda; +#ifdef CONFIG_SMP + pda = (struct x8664_pda *)__per_cpu_load; + pda->data_offset =per_cpu_offset (0 ) = (unsigned long )pda; +#else + pda = &per_cpu (pda,0 ); + pda->data_offset = (unsigned long )pda; +#endif + } +/* initialize boot cpu_pda data */ +pda_init (0 ); +for (i =0 ; i <NUM_EXCEPTION_VECTORS ; i++) {#ifdef CONFIG_EARLY_PRINTK set_intr_gate (i, &early_idt_handlers[i]);
@@ -102,12 +102,6 @@ void __init x86_64_start_kernel(char * rearly_printk ("Kernel alive\n" ); - _cpu_pda = __cpu_pda; -cpu_pda (0 ) = &_boot_cpu_pda; -pda_init (0 ); - -early_printk ("Kernel really alive\n" ); -copy_bootdata (__va (real_mode_data));reserve_early (__pa_symbol (&_text),__pa_symbol (&_end),"TEXT DATA BSS" );
arch/x86/kernel/head_64.S +12 -1
@@ -12,6 +12,7 @@ #include <linux/linkage.h> #include <linux/threads.h> #include <linux/init.h> +#include <asm/asm-offsets.h> #include <asm/desc.h> #include <asm/segment.h> #include <asm/pgtable.h>
@@ -132,6 +133,12 @@ ident_complete: #ifdef CONFIG_SMP addq %rbp, trampoline_level4_pgt + 0(%rip) addq %rbp, trampoline_level4_pgt + (511*8)(%rip) + + /* + * Fix up per_cpu__gdt_page offset when basing percpu + * variables at zero. This is only needed for the boot cpu. + */ + addq $__per_cpu_load, early_gdt_descr_base #endif /* Due to ENTRY(), sometimes the empty space gets filled with
@@ -224,10 +231,11 @@ ENTRY(secondary_startup_64) * that does in_interrupt() */ movl $MSR_GS_BASE,%ecx - movq $empty_zero_page,%rax + movq initial_pda(%rip), %rax movq %rax,%rdx shrq $32,%rdx wrmsr + movq %rax,%gs:pda_data_offset /* esi is pointer to real mode structure with interesting info. pass it to C */
@@ -250,6 +258,8 @@ ENTRY(secondary_startup_64) .align 8 ENTRY(initial_code) .quad x86_64_start_kernel + ENTRY(initial_pda) + .quad __per_cpu_load __FINITDATA ENTRY(stack_start)
@@ -394,6 +404,7 @@ NEXT_PAGE(level2_spare_pgt) .globl early_gdt_descr early_gdt_descr: .word GDT_ENTRIES*8-1 +early_gdt_descr_base: .quad per_cpu__gdt_page ENTRY(phys_base)
arch/x86/kernel/setup.c +26 -60
121 lines not on this page · raw message
arch/x86/kernel/setup64.c +0 -3
@@ -35,9 +35,6 @@ struct boot_params boot_params;cpumask_t cpu_initialized__cpuinitdata =CPU_MASK_NONE ; -struct x8664_pda **_cpu_pda__read_mostly ; -EXPORT_SYMBOL (_cpu_pda); -struct desc_ptr idt_descr = {256 *16 -1 , (unsigned long ) idt_table }; char boot_cpu_stack[IRQSTACKSIZE] __page_aligned_bss;
arch/x86/kernel/smpboot.c +1 -51
76 lines not on this page · raw message
arch/x86/kernel/vmlinux_64.lds.S +1 -0
@@ -16,6 +16,7 @@ jiffies_64 = jiffies; _proxy_pda = 1; PHDRS { text PT_LOAD FLAGS(5); /* R_E */ + percpu PT_LOAD FLAGS(7); /* RWE */ data PT_LOAD FLAGS(7); /* RWE */ user PT_LOAD FLAGS(7); /* RWE */ data.init PT_LOAD FLAGS(7); /* RWE */
include/asm-x86/desc.h +5 -0
@@ -41,6 +41,11 @@ static inline struct desc_struct *get_cp#ifdef CONFIG_X86_64 +static inline struct x8664_pda *get_percpu_pda (unsigned int cpu) +{ +return &per_cpu (pda, cpu); +} +static inline void pack_gate (gate_desc *gate,unsigned type,unsigned long func,unsigned dpl,unsigned ist,unsigned seg) {
include/asm-x86/pda.h +1 -2
@@ -37,10 +37,9 @@ struct x8664_pda {unsigned irq_spurious_count; }____cacheline_aligned_in_smp ; -extern struct x8664_pda **_cpu_pda;extern void pda_init (int ); -#define cpu_pda (i) (_cpu_pda[i]) +#define cpu_pda (i) (&per_cpu(pda, i))/* * There is no fast way to get the base address of the PDA, all the accesses
include/asm-x86/percpu.h +13 -33
82 lines not on this page · raw message
include/asm-x86/trampoline.h +1 -0
@@ -12,6 +12,7 @@ extern unsigned char *trampoline_base;extern unsigned long init_rsp;extern unsigned long initial_code; +extern unsigned long initial_pda;#define TRAMPOLINE_BASE 0x6000extern unsigned long setup_trampoline (void );
Re: [crash, bisected] Re: [PATCH 3/4] x86_64: Fold pda into per cpu area
Quoted 9 lines · Mike Travis
Quoted 2 lines · Jeremy Fitzhardinge
Why not use the real pda for all cpus?
Yeah, I figured that out after doing some more thinking... ;-)
Quoted 8 lines
Quoted 4 lines
Do you move the boot-cpu's per-cpu data? (Please don't) If not, you can just use
percpu__pdafrom the start without having to do anything else, and then set up %gs pointing to the pda base for each secondary cpu.The problem is that the static percpu area is removed as it lies in the initdata section, so the pda is removed as well.
Well, that's easy to fix...
Quoted 3 lines
But I took your suggestion to move the fixup to before
secondary_startup.Below is a revised version.
(Incremental diffs are easier to review and work with.)
Quoted 12 lines
It builds but I'll have to test it tomorrow.
Note the addition of:+
initial_pda= (unsigned long)get_percpu_pda(cpu);in
do_boot_cpu.I'm not sure yet what to put into
acpi_save_state_mem:initial_code = (unsigned long)wakeup_long64;+ /* ZZZ
initial_pda= (unsigned long)?; */
You'll need to change wakeup_long64 to load the right value into the GS_BASE msr anyway.
J
Re: [crash, bisected] Re: [PATCH 3/4] x86_64: Fold pda into per cpu area
Quoted 1 line · Jeremy Fitzhardinge
Mike Travis wrote:
...
Quoted 10 lines
Quoted 5 lines
I'm not sure yet what to put into
acpi_save_state_mem:initial_code = (unsigned long)wakeup_long64;+ /* ZZZ
initial_pda= (unsigned long)?; */You'll need to change
wakeup_long64to load the right value into theGS_BASEmsr anyway.J
I'm afraid I don't quite understand the transitioning of the ACPI states to figure out the correct thing to do. My first inclination would be to: [sorry, cut and pasted]
arch/x86/kernel/acpi/sleep.c +2 -0
@@ -89,6 +89,8 @@ int acpi_save_state_mem(void)#ifdef CONFIG_SMP stack_start.sp = temp_stack +4096 ;#endif + early_gdt_descr.address = (unsigned long )get_cpu_gdt_table (cpu); + initial_pda = (unsigned long )get_cpu_pda (cpu); initial_code = (unsigned long )wakeup_long64; saved_magic =0x123456789abcdef0 ;#endif /* CONFIG_64BIT */
But I'd like some confirmation that this is right thing to do...
[This mimics what smpboot.c:do_boot_cpu() does.]
Len - I'll cc you on the full patch submission shortly.
Thanks,
Mike
Re: [crash, bisected] Re: [PATCH 3/4] x86_64: Fold pda into per cpu area
In reply to Mike Travisarch/x86/kernel/head_64.S ident_complete: · line 142
Quoted 11 lines · Mike Travis
arch/x86/kernel/head_64.S +6
-0@@ -132,6 +133,12 @@ ident_complete: #ifdef CONFIG_SMP addq %rbp, trampoline_level4_pgt + 0(%rip) addq %rbp, trampoline_level4_pgt + (511*8)(%rip) + + /* + * Fix up per_cpu__gdt_page offset when basing percpu + * variables at zero. This is only needed for the boot cpu. + */ + addq $__per_cpu_load, early_gdt_descr_base
This needs to be rip-relative. An absolute reference here will fail because you're still running in physical addresses.
J
A message that is not in the archive (sent off-list or not yet received): [email protected]
Re: [crash, bisected] Re: [PATCH 3/4] x86_64: Fold pda into per cpu area
Quoted 19 lines · Mike Travis
Quoted 17 lines · Jeremy Fitzhardinge
Review ident_complete: · line 143
Quoted 12 lines · Mike Travis
(quoted diff) +6
-0@@ -132,6 +133,12 @@ ident_complete: #ifdef CONFIG_SMP addq %rbp, trampoline_level4_pgt + 0(%rip) addq %rbp, trampoline_level4_pgt + (511*8)(%rip) + + /* + * Fix up per_cpu__gdt_page offset when basing percpu + * variables at zero. This is only needed for the boot cpu. + */ + addq $__per_cpu_load, early_gdt_descr_baseThis needs to be rip-relative. An absolute reference here will fail because you're still running in physical addresses.
Quoted 5 lines
Quoted 2 lines
J
Still bombs right at boot up... ;-(
Yep. I see the triple-fault at the "mov %eax,%ds", which means it's having trouble with the gdt. Either 1) the lgdt pointed to a bad address, or 2) there's something wrong with the descriptor there.
The dump is:
(XEN) hvm.c:767:d14 Triple fault on VCPU0 - invoking HVM system reset. (XEN) ----[ Xen-3.3-unstable x86_64 debug=n Not tainted ]----
(XEN) CPU: 0
(XEN) RIP: 0010:[<ffffffff80200167>]
(XEN) RFLAGS: 0000000000010002 CONTEXT: hvm
(XEN) rax: 0000000000000018 rbx: 0000000000000000 rcx: ffffffff808d6000 (XEN) rdx: 0000000000000000 rsi: 0000000000092f40 rdi: 0000000020100800 (XEN) rbp: 0000000000000000 rsp: ffffffff80827ff8 r8: 0000000000208000 (XEN) r9: 0000000000000000 r10: 0000000000000000 r11: 00000000000000d8 (XEN) r12: 0000000000000000 r13: 0000000000000000 r14: 0000000000000000 (XEN) r15: 0000000000000000 cr0: 0000000080050033 cr4: 00000000000000a0 (XEN) cr3: 0000000000201000 cr2: 0000000000000000
(XEN) ds: 0000 es: 0000 fs: 0000 gs: 0000 ss: 0000 cs: 0010
I loaded early_gdt_descr+2 into %rcx, which looks reasonable. Hm, but loading the __KERNEL_DS descriptor into %rdx, which is all zero.
So it seems the problem is that the pre-initialized gdt_page is being lost and replaced with zero. Linker script bug?
J
arch/x86/kernel/head_64.S +0 -0
@@ -213,6 +213,8 @@
* because in 32bit we couldn't load a 64bit linear address. */ lgdt early_gdt_descr(%rip)
+ movq early_gdt_descr+2(%rip), %rcx
+ movq __KERNEL_DS(%rcx), %rdx
/* set up data segments. actually 0 would do too */ movl $__KERNEL_DS,%eax
Re: [crash, bisected] Re: [PATCH 3/4] x86_64: Fold pda into per cpu area
Quoted 2 lines · Jeremy Fitzhardinge
So it seems the problem is that the pre-initialized
gdt_pageis being lost and replaced with zero. Linker script bug?
Is the pre initialized gdt page in the per cpu area? Does not look like it. The loader setup for the percpu section changes with zero basing. Maybe that has bad side effects?
Re: [crash, bisected] Re: [PATCH 3/4] x86_64: Fold pda into per cpu area
Quoted 8 lines · Christoph Lameter
Quoted 2 lines · Jeremy Fitzhardinge
So it seems the problem is that the pre-initialized
gdt_pageis being lost and replaced with zero. Linker script bug?Is the pre initialized gdt page in the per cpu area? Does not look like it. The loader setup for the percpu section changes with zero basing. Maybe that has bad side effects?
Yes, it is... The fixup logic is this:
0000000000004000 D per_cpu__gdt_pageffffffff81911000 A __per_cpu_load
arch/x86/kernel/cpu/common.c:
DEFINE_PER_CPU_PAGE_ALIGNED(struct gdt_page, gdt_page) = { .gdt = {
[GDT_ENTRY_KERNEL_CS] = { { { 0x0000ffff, 0x00cf9a00 } } },...
arch/x86/kernel/head_64.S:
startup_64:
...
/*
* Fix up per_cpu__gdt_page offset when basing percpu
* variables at zero. This is only needed for the boot cpu. */
addq $__per_cpu_load, early_gdt_descr_base(%rip)
ENTRY(secondary_startup_64)
...
/*
* We must switch to a new descriptor in kernel space for the GDT
* because soon the kernel won't have access anymore to the userspace
* addresses where we're currently running on. We have to do that here
* because in 32bit we couldn't load a 64bit linear address. */
lgdt early_gdt_descr(%rip)
...
.globl early_gdt_descrearly_gdt_descr:
.word GDT_ENTRIES*8-1
early_gdt_descr_base:
.quad per_cpu__gdt_page
Re: [crash, bisected] Re: [PATCH 3/4] x86_64: Fold pda into per cpu area
Quoted 10 lines · Mike Travis
Yes, it is... The fixup logic is this:
0000000000004000 D
per_cpu__gdt_pageffffffff81911000A__per_cpu_load
arch/x86/kernel/cpu/common.c:DEFINE_PER_CPU_PAGE_ALIGNED(struct gdt_page, gdt_page) = { .gdt = { [GDT_ENTRY_KERNEL_CS] = { { { 0x0000ffff, 0x00cf9a00 } } },
Aha, you fell into the trap! "common" in this case means "common to 32-bit x86". Or something. But setup_64.c is what you want to be looking at.
J
Re: [crash, bisected] Re: [PATCH 3/4] x86_64: Fold pda into per cpu area
In reply to Christoph LameterQuoted 8 lines · Christoph Lameter
Quoted 3 lines · Jeremy Fitzhardinge
So it seems the problem is that the pre-initialized
gdt_pageis being lost and replaced with zero. Linker script bug?Is the pre initialized gdt page in the per cpu area? Does not look like it.
Yes, it should be. arch/x86/kernel/setup_64.c:
DEFINE_PER_CPU(struct gdt_page, gdt_page) = { .gdt = {
[GDT_ENTRY_KERNEL32_CS] = { { { 0x0000ffff, 0x00cf9b00 } } },
[GDT_ENTRY_KERNEL_CS] = { { { 0x0000ffff, 0x00af9b00 } } },
[GDT_ENTRY_KERNEL_DS] = { { { 0x0000ffff, 0x00cf9300 } } },
[GDT_ENTRY_DEFAULT_USER32_CS] = { { { 0x0000ffff, 0x00cffb00 } } },
[GDT_ENTRY_DEFAULT_USER_DS] = { { { 0x0000ffff, 0x00cff300 } } },
[GDT_ENTRY_DEFAULT_USER_CS] = { { { 0x0000ffff, 0x00affb00 } } },
} };Quoted 1 line
The loader setup for the percpu section changes with zero basing. Maybe that has bad side effects
How does it work? The symbols in the percpu segment are 0-based, but where does the data for the sections which correspond to that segment go?
The vmlinux looks like it has the gdt_page data in it. per_cpu__gdt_page is 0x5000, and offset 0x5000 in .data.percpu has the right stuff:
5000 00000000 00000000 ffff0000 009bcf00 ................ 5010 ffff0000 009baf00 ffff0000 0093cf00 ................ 5020 ffff0000 00fbcf00 ffff0000 00f3cf00 ................ 5030 ffff0000 00fbaf00 00000000 00000000 ................ 5040 00000000 00000000 00000000 00000000 ................ 5050 00000000 00000000 00000000 00000000 ................ 5060 00000000 00000000 00000000 00000000 ................
So the question is what kernel virtual address is it being loaded to? __per_cpu_load is ffffffff808d1000, so ffffffff808d6000 is what you'd expect...
Hm, but what happens when this gets converted to bzImage? Hm, looks OK, I think.
BTW, I think __per_cpu_load will cause trouble if you make a relocatable kernel, being an absolute symbol. But I have relocation off at the moment.
J
Re: [crash, bisected] Re: [PATCH 3/4] x86_64: Fold pda into per cpu area
Quoted 5 lines · Jeremy Fitzhardinge
Quoted 2 lines
The loader setup for the percpu section changes with zero basing. Maybe that has bad side effects
How does it work? The symbols in the percpu segment are 0-based, but where does the data for the sections which correspond to that segment go?
Its loaded at __per_cpu_load but the symbols have addresses starting at 0.
Quoted 3 lines
So the question is what kernel virtual address is it being loaded to?
__per_cpu_loadisffffffff808d1000, soffffffff808d6000is what you'd expect...
Correct.
Quoted 5 lines
Hm, but what happens when this gets converted to bzImage? Hm, looks OK, I think.
BTW, I think
__per_cpu_loadwill cause trouble if you make a relocatable kernel, being an absolute symbol. But I have relocation off at the moment.
Hmmm.... we could add the relocation offset to __per_cpu_load? __per_cpu_load is used very sparingly. Basically only useful during early boot and when a new per cpu area has to be setup. In that case we want to copy from __per_cpu_load to the newly allocated percpu area.
Re: [crash, bisected] Re: [PATCH 3/4] x86_64: Fold pda into per cpu area
Quoted 12 lines · Christoph Lameter
Quoted 6 lines · Jeremy Fitzhardinge
Quoted 3 lines
The loader setup for the percpu section changes with zero basing. Maybe that has bad side effects
How does it work? The symbols in the percpu segment are 0-based, but where does the data for the sections which correspond to that segment go?
Its loaded at
__per_cpu_loadbut the symbols have addresses starting at 0.
Yes, which leads to an odd-looking ELF file where the Phdrs aren't sorted by virtual address order. I'm wondering what would happen if a bootloader that actually understood ELF files tried to load it as an actual ELF file...
Quoted 7 lines
Quoted 4 lines
So the question is what kernel virtual address is it being loaded to?
__per_cpu_loadisffffffff808d1000, soffffffff808d6000is what you'd expect...Correct.
Well, reading back from that address got zeros, so something is amiss.
Quoted 9 lines
Quoted 6 lines
Hm, but what happens when this gets converted to bzImage? Hm, looks OK, I think.
BTW, I think
__per_cpu_loadwill cause trouble if you make a relocatable kernel, being an absolute symbol. But I have relocation off at the moment.Hmmm.... we could add the relocation offset to
__per_cpu_load?__per_cpu_loadis used very sparingly. Basically only useful during early boot and when a new per cpu area has to be setup. In that case we want to copy from__per_cpu_loadto the newly allocated percpu area.
Yes, it should be fairly easy to manually relocate it by applying the (load - link) offset to it.
J
H. Peter Anvin
reviewerRe: [crash, bisected] Re: [PATCH 3/4] x86_64: Fold pda into per cpu area
Quoted 5 lines · Jeremy Fitzhardinge
Quoted 2 lines
Its loaded at
__per_cpu_loadbut the symbols have addresses starting at 0.Yes, which leads to an odd-looking ELF file where the Phdrs aren't sorted by virtual address order. I'm wondering what would happen if a bootloader that actually understood ELF files tried to load it as an actual ELF file...
If it is implemented correctly, it will work. It might trigger bugs in such loaders, however.
Quoted 3 lines
Quoted 1 line
Hmmm.... we could add the relocation offset to
__per_cpu_load?__per_cpu_loadis used very sparingly. Basically only useful during early boot and when a new per cpu area has to be setup. In that case we want to copy from__per_cpu_loadto the newly allocated percpu area.Yes, it should be fairly easy to manually relocate it by applying the (load - link) offset to it.
Seems easy enough, and as already stated, this is not performance-critical so a few extra instructions is pretty much a non-issue.
-hpa
Re: [crash, bisected] Re: [PATCH 3/4] x86_64: Fold pda into per cpu area
In reply to Jeremy FitzhardingeQuoted 11 lines · Jeremy Fitzhardinge
Quoted 10 lines · Christoph Lameter
Quoted 6 lines · Jeremy Fitzhardinge
Quoted 3 lines
The loader setup for the percpu section changes with zero basing. Maybe that has bad side effects
How does it work? The symbols in the percpu segment are 0-based, but where does the data for the sections which correspond to that segment go?
Quoted 7 lines
Quoted 2 lines
Its loaded at
__per_cpu_loadbut the symbols have addresses starting at 0.Yes, which leads to an odd-looking ELF file where the Phdrs aren't sorted by virtual address order. I'm wondering what would happen if a bootloader that actually understood ELF files tried to load it as an actual ELF file...
Well /sbin/kexec looks at the physical addresses not the virtual ones so that may not be a problem.
Quoted 10 lines
Quoted 7 lines
Quoted 4 lines
So the question is what kernel virtual address is it being loaded to?
__per_cpu_loadisffffffff808d1000, soffffffff808d6000is what you'd expect...Correct.
Well, reading back from that address got zeros, so something is amiss.
Weird.
Quoted 7 lines
Quoted 7 lines
Quoted 6 lines
Hm, but what happens when this gets converted to bzImage? Hm, looks OK, I think.
BTW, I think
__per_cpu_loadwill cause trouble if you make a relocatable kernel, being an absolute symbol. But I have relocation off at the moment.
Quoted 8 lines
Quoted 5 lines
Hmmm.... we could add the relocation offset to
__per_cpu_load?__per_cpu_loadis used very sparingly. Basically only useful during early boot and when a new per cpu area has to be setup. In that case we want to copy from__per_cpu_loadto the newly allocated percpu area.Yes, it should be fairly easy to manually relocate it by applying the (load - link) offset to it.
For x86_64 all kernels are built relocatable as the only cost was changing the physical addresses in the initial page tables. The virtual address always remain the same but the physical addresses change. So that could be part of what is going on.
Is this a change that only got tested on x86_32?
As long as we are not changing the way the kernel virtual address are actually being used we should be ok with a change to make the pda 0 based. Still it is an area you need to be especially careful with.
Eric
Re: [crash, bisected] Re: [PATCH 3/4] x86_64: Fold pda into per cpu area
Quoted 47 lines · Eric W. Biederman
Quoted 10 lines · Jeremy Fitzhardinge
Quoted 9 lines · Christoph Lameter
Quoted 6 lines · Jeremy Fitzhardinge
Quoted 3 lines
The loader setup for the percpu section changes with zero basing. Maybe that has bad side effects
How does it work? The symbols in the percpu segment are 0-based, but where does the data for the sections which correspond to that segment go?
Quoted 6 lines
Quoted 2 lines
Its loaded at
__per_cpu_loadbut the symbols have addresses starting at 0.Yes, which leads to an odd-looking ELF file where the Phdrs aren't sorted by virtual address order. I'm wondering what would happen if a bootloader that actually understood ELF files tried to load it as an actual ELF file...
Well
/sbin/kexeclooks at the physical addresses not the virtual ones so that may not be a problem.Quoted 8 lines
Quoted 6 lines
Quoted 4 lines
So the question is what kernel virtual address is it being loaded to?
__per_cpu_loadisffffffff808d1000, soffffffff808d6000is what you'd expect...Correct.
Well, reading back from that address got zeros, so something is amiss.
Weird.
Quoted 6 lines
Quoted 6 lines
Quoted 6 lines
Hm, but what happens when this gets converted to bzImage? Hm, looks OK, I think.
BTW, I think
__per_cpu_loadwill cause trouble if you make a relocatable kernel, being an absolute symbol. But I have relocation off at the moment.Quoted 7 lines
Quoted 5 lines
Hmmm.... we could add the relocation offset to
__per_cpu_load?__per_cpu_loadis used very sparingly. Basically only useful during early boot and when a new per cpu area has to be setup. In that case we want to copy from__per_cpu_loadto the newly allocated percpu area.Yes, it should be fairly easy to manually relocate it by applying the (load - link) offset to it.
Quoted 6 lines
For
x86_64all kernels are built relocatable as the only cost was changing the physical addresses in the initial page tables. The virtual address always remain the same but the physical addresses change. So that could be part of what is going on.Is this a change that only got tested on
x86_32?
I'm only testing this on x86_64. The zero-based percpu/pda changes worked fine up until just recently. At first it was one of Ingo's "randconfig" config files that was tripping it up, but lately it's not working on any config.
Quoted 4 lines
As long as we are not changing the way the kernel virtual address are actually being used we should be ok with a change to make the pda 0 based. Still it is an area you need to be especially careful with.
The major gotcha's seem to be in referencing the per_cpu symbol directly though I've examined them all and nothing seems amiss.
Quoted 3 lines
Eric
Thanks,
Mike
Re: [crash, bisected] Re: [PATCH 3/4] x86_64: Fold pda into per cpu area
Quoted 5 lines · Mike Travis
Quoted 1 line
Is this a change that only got tested on
x86_32?I'm only testing this on
x86_64. The zero-based percpu/pda changes worked fine up until just recently. At first it was one of Ingo's "randconfig" config files that was tripping it up, but lately it's not working on any config.
x86_32 does not need the zero basing since it does not have a pda.
Re: [crash, bisected] Re: [PATCH 3/4] x86_64: Fold pda into per cpu area
In reply to Jeremy FitzhardingeQuoted 5 lines · Jeremy Fitzhardinge
BTW, I think
__per_cpu_loadwill cause trouble if you make a relocatable kernel, being an absolute symbol. But I have relocation off at the moment.
...
Here's where it's defined (in include/asm-generic/vmlinux.lds.h):
#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.shared_aligned) \
*(.data.percpu) \
*(.data.percpu.page_aligned) \
____per_cpu_size = .; \
} \
. = __per_cpu_load + ____per_cpu_size; \ data : { } :data
#else
Can we generate a new symbol which would account for LOAD_OFFSET?
Re: [crash, bisected] Re: [PATCH 3/4] x86_64: Fold pda into per cpu area
Quoted 22 lines · Mike Travis
Quoted 5 lines · Jeremy Fitzhardinge
BTW, I think
__per_cpu_loadwill cause trouble if you make a relocatable kernel, being an absolute symbol. But I have relocation off at the moment....
Here's where it's defined (ininclude/asm-generic/vmlinux.lds.h):#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.shared_aligned) \ *(.data.percpu) \ *(.data.percpu.page_aligned) \ ____per_cpu_size = .; \ } \ . = __per_cpu_load + ____per_cpu_size; \
Quoted 4 lines
data : { } :data
#elseCan we generate a new symbol which would account for
LOAD_OFFSET?
Ouch. Absolute symbols indeed. On the 32bit kernel that may play havoc with the relocatable kernel, although we have had similar absolute logic for the last year. With __per_cpu_start and __per_cpu_end so it may not be a problem.
To initialize the percpu data you do want to talk to the virtual address at __per_coup_load. But it is absolute Ugh.
It might be worth saying something like.
.data.percpu.start : AT(.data.percpu.dummy - LOAD_OFFSET) {
DATA(0)
. = ALIGN(align);
__per_cpu_load = . ;
}To make __per_cpu_load a relative symbol. ld has a bad habit of taking symbols out of empty sections and making them absolute. Which is why I added the DATA(0).
Still I don't think that would be the 64bit problem.
Eric
Re: [crash, bisected] Re: [PATCH 3/4] x86_64: Fold pda into per cpu area
Quoted 8 lines · Eric W. Biederman
at
__per_coup_load. But it is absolute Ugh.It might be worth saying something like.
.data.percpu.start : AT(.data.percpu.dummy - LOAD_OFFSET) { DATA(0) . = ALIGN(align); __per_cpu_load = . ; }
Quoted 5 lines
To make
__per_cpu_loada relative symbol. ld has a bad habit of taking symbols out of empty sections and making them absolute. Which is why I added the DATA(0).Still I don't think that would be the 64bit problem.
Ahh.. Good idea. I had a long fight with the loader before it did the right thing.
Re: [crash, bisected] Re: [PATCH 3/4] x86_64: Fold pda into per cpu area
In reply to Eric W. BiedermanQuoted 42 lines · Eric W. Biederman
Quoted 21 lines · Mike Travis
Quoted 4 lines · Jeremy Fitzhardinge
BTW, I think
__per_cpu_loadwill cause trouble if you make a relocatable kernel, being an absolute symbol. But I have relocation off at the moment....
Here's where it's defined (ininclude/asm-generic/vmlinux.lds.h):#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.shared_aligned) \ *(.data.percpu) \ *(.data.percpu.page_aligned) \ ____per_cpu_size = .; \ } \ . = __per_cpu_load + ____per_cpu_size; \Quoted 4 lines
data : { } :data
#elseCan we generate a new symbol which would account for
LOAD_OFFSET?Ouch. Absolute symbols indeed. On the 32bit kernel that may play havoc with the relocatable kernel, although we have had similar absolute logic for the last year. With
__per_cpu_startand__per_cpu_endso it may not be a problem.To initialize the percpu data you do want to talk to the virtual address at
__per_coup_load. But it is absolute Ugh.It might be worth saying something like.
.data.percpu.start : AT(.data.percpu.dummy - LOAD_OFFSET) { DATA(0) . = ALIGN(align); __per_cpu_load = . ; }
Quoted 7 lines
To make
__per_cpu_loada relative symbol. ld has a bad habit of taking symbols out of empty sections and making them absolute. Which is why I added the DATA(0).Still I don't think that would be the 64bit problem.
Eric
I'm not sure I understand the linker lingo enough to fill in the rest of the blanks... I've tried various versions around this framework and none have been accepted yet.
#ifdef CONFIG_HAVE_ZERO_BASED_PER_CPU
#define PERCPU(align) \
.data.percpu.start : AT(.data.percpu.dummy - LOAD_OFFSET) { \
DATA(0) \
. = ALIGN(align); \
__per_cpu_load = .; \
*(.data.percpu.first) \
*(.data.percpu.shared_aligned) \
*(.data.percpu) \
*(.data.percpu.page_aligned) \
____per_cpu_size = . - __per_cpu_load \
} \#else
Thanks,
Mike
Re: [crash, bisected] Re: [PATCH 3/4] x86_64: Fold pda into per cpu area
Quoted 71 lines · Mike Travis
Quoted 44 lines · Eric W. Biederman
Quoted 22 lines · Mike Travis
Quoted 4 lines · Jeremy Fitzhardinge
BTW, I think
__per_cpu_loadwill cause trouble if you make a relocatable kernel, being an absolute symbol. But I have relocation off at the moment....
Here's where it's defined (ininclude/asm-generic/vmlinux.lds.h):#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.shared_aligned) \ *(.data.percpu) \ *(.data.percpu.page_aligned) \ ____per_cpu_size = .; \ } \ . = __per_cpu_load + ____per_cpu_size; \Quoted 5 lines
data : { } :data
#elseCan we generate a new symbol which would account for
LOAD_OFFSET?Ouch. Absolute symbols indeed. On the 32bit kernel that may play havoc with the relocatable kernel, although we have had similar absolute logic for the last year. With
__per_cpu_startand__per_cpu_endso it may not be a problem.To initialize the percpu data you do want to talk to the virtual address at
__per_coup_load. But it is absolute Ugh.It might be worth saying something like.
.data.percpu.start : AT(.data.percpu.dummy - LOAD_OFFSET) { DATA(0) . = ALIGN(align); __per_cpu_load = . ; }Quoted 8 lines
To make
__per_cpu_loada relative symbol. ld has a bad habit of taking symbols out of empty sections and making them absolute. Which is why I added the DATA(0).Still I don't think that would be the 64bit problem.
Eric
I'm not sure I understand the linker lingo enough to fill in the rest of the blanks... I've tried various versions around this framework and none have been accepted yet.
#ifdef
CONFIG_HAVE_ZERO_BASED_PER_CPU#define PERCPU(align) \ .data.percpu.start : AT(.data.percpu.dummy - LOAD_OFFSET) { \ DATA(0) \ . = ALIGN(align); \ __per_cpu_load = .; \ *(.data.percpu.first) \ *(.data.percpu.shared_aligned) \ *(.data.percpu) \ *(.data.percpu.page_aligned) \ ____per_cpu_size = . - __per_cpu_load \ } \
Quoted 2 lines
#else
That looks OK to me. Does it work?
J
Re: [crash, bisected] Re: [PATCH 3/4] x86_64: Fold pda into per cpu area
Quoted 86 lines · Jeremy Fitzhardinge
Quoted 82 lines · Mike Travis
Quoted 55 lines · Eric W. Biederman
Quoted 33 lines · Mike Travis
Quoted 6 lines · Jeremy Fitzhardinge
BTW, I think
__per_cpu_loadwill cause trouble if you make a relocatable
kernel, being an absolute symbol. But I have relocation off at the moment....
Here's where it's defined (ininclude/asm-generic/vmlinux.lds.h):#ifdef
CONFIG_HAVE_ZERO_BASED_PER_CPU
#definePERCPU(align) \ . = ALIGN(align); \ percpu : { } :percpu \ __per_cpu_load =.; \
.data.percpu 0 :AT(__per_cpu_load - LOAD_OFFSET)
{ \*(.data.percpu.first) \
*(.data.percpu.shared_aligned) \
*(.data.percpu) \
*(.data.percpu.page_aligned) \ ____per_cpu_size =.; \
Quoted 8 lines
} \ . = __per_cpu_load +
____per_cpu_size; \
data : { } :data
#elseCan we generate a new symbol which would account for
LOAD_OFFSET?Ouch. Absolute symbols indeed. On the 32bit kernel that may play havoc with the relocatable kernel, although we have had similar absolute logic for the last year. With
__per_cpu_startand__per_cpu_endso it may not be a problem.To initialize the percpu data you do want to talk to the virtual address at
__per_coup_load. But it is absolute Ugh.
It might be worth saying something like..data.percpu.start : AT(.data.percpu.dummy - LOAD_OFFSET) { DATA(0) . = ALIGN(align); __per_cpu_load = . ; }Quoted 8 lines
To make
__per_cpu_loada relative symbol. ld has a bad habit of taking symbols out of empty sections and making them absolute. Which is why I added the DATA(0).Still I don't think that would be the 64bit problem.
Eric
I'm not sure I understand the linker lingo enough to fill in the rest of the blanks... I've tried various versions around this framework and none have been accepted yet.
#ifdef
CONFIG_HAVE_ZERO_BASED_PER_CPU#define PERCPU(align) \ .data.percpu.start : AT(.data.percpu.dummy - LOAD_OFFSET) { \ DATA(0) \ . = ALIGN(align); \ __per_cpu_load = .; \ *(.data.percpu.first) \ *(.data.percpu.shared_aligned) \ *(.data.percpu) \ *(.data.percpu.page_aligned) \ ____per_cpu_size = . - __per_cpu_load \ } \Quoted 2 lines
#else
Quoted 3 lines
That looks OK to me. Does it work?
J
Nope, fighting undefines and/or syntax errors in the linker.
Re: [crash, bisected] Re: [PATCH 3/4] x86_64: Fold pda into per cpu area
Quoted 11 lines
Quoted 11 lines
Quoted 11 lines
Quoted 11 lines
To initialize the percpu data you do want to talk to the virtual address at
__per_coup_load. But it is absolute Ugh.
It might be worth saying something like..data.percpu.start : AT(.data.percpu.dummy - LOAD_OFFSET) { DATA(0) . = ALIGN(align); __per_cpu_load = . ; }To make
__per_cpu_loada relative symbol. ld has a bad habit of taking symbols out of empty sections and making them absolute. Which is why I added the DATA(0).
The syntax error is at this "DATA(0)" statement. I don't find this as a linker script command or a macro. What is it we're trying to do with this?
Thanks,
Mike
...
Quoted 17 lines
Quoted 17 lines
Quoted 17 lines
I'm not sure I understand the linker lingo enough to fill in the rest of the blanks... I've tried various versions around this framework and none have been accepted yet.
#ifdef
CONFIG_HAVE_ZERO_BASED_PER_CPU#define PERCPU(align) \ .data.percpu.start : AT(.data.percpu.dummy - LOAD_OFFSET) { \ DATA(0) \ . = ALIGN(align); \ __per_cpu_load = .; \ *(.data.percpu.first) \ *(.data.percpu.shared_aligned) \ *(.data.percpu) \ *(.data.percpu.page_aligned) \ ____per_cpu_size = . - __per_cpu_load \ } \#else
Re: [crash, bisected] Re: [PATCH 3/4] x86_64: Fold pda into per cpu area
Quoted 3 lines · Mike Travis
The syntax error is at this "DATA(0)" statement. I don't find this as a linker script command or a macro. What is it we're trying to do with this?
In Eric's sample, it's intended to prevent there being an empty section, which can cause linker bugs. In your case it probably isn't necessary, since you're also putting the percpu data in that section.
"DATA" is probably a typo. It should be "LONG" or something like that. (See "3.6.5 Output Section Data" in the linker manual.)
J
Re: [crash, bisected] Re: [PATCH 3/4] x86_64: Fold pda into per cpu area
Quoted 6 lines · Jeremy Fitzhardinge
Quoted 4 lines · Mike Travis
The syntax error is at this "DATA(0)" statement. I don't find this as a linker script command or a macro. What is it we're trying to do with this?
Quoted 8 lines
In Eric's sample, it's intended to prevent there being an empty section, which can cause linker bugs. In your case it probably isn't necessary, since you're also putting the percpu data in that section.
"DATA" is probably a typo. It should be "LONG" or something like that. (See "3.6.5 Output Section Data" in the linker manual.)
J
Yes, thanks I did find that.
I now have the version below which seems to have what we need... but it hasn't had an effect on the boot startup panic. I'm back to verifying that the assembler effective addresses are correct in the loaded object.
ffffffff81911000 D __per_cpu_load
0000000000000000 D per_cpu__pda
0000000000000080 D per_cpu__init_tss
.
.000000000000a2d0 d per_cpu__cookie_scratch000000000000a470 d per_cpu__cookie_scratch000000000000a604 D ____per_cpu_size
Btw, the "percpu : { } :percpu" below removes a linker warning about an empty section.
#ifdef CONFIG_HAVE_ZERO_BASED_PER_CPU
#define PERCPU(align) \
.data.percpu.abs = .; \
percpu : { } :percpu \
.data.percpu.header : AT(.data.percpu.abs - LOAD_OFFSET) { \
BYTE(0) \
. = ALIGN(align); \
__per_cpu_load = .; \
} \
.data.percpu 0 : AT(__per_cpu_load - LOAD_OFFSET) { \
*(.data.percpu.first) \
*(.data.percpu.shared_aligned) \
*(.data.percpu) \
*(.data.percpu.page_aligned) \
____per_cpu_size = .; \
} \
. = __per_cpu_load + ____per_cpu_size;Re: [crash, bisected] Re: [PATCH 3/4] x86_64: Fold pda into per cpu area
In reply to Eric W. BiedermanQuoted 1 line · Eric W. Biederman
Mike Travis <[email protected]> writes:
...
Quoted 16 lines
Quoted 1 line
Can we generate a new symbol which would account for
LOAD_OFFSET?Ouch. Absolute symbols indeed. On the 32bit kernel that may play havoc with the relocatable kernel, although we have had similar absolute logic for the last year. With
__per_cpu_startand__per_cpu_endso it may not be a problem.To initialize the percpu data you do want to talk to the virtual address at
__per_coup_load. But it is absolute Ugh.It might be worth saying something like.
.data.percpu.start : AT(.data.percpu.dummy - LOAD_OFFSET) { DATA(0) . = ALIGN(align); __per_cpu_load = . ; }
Quoted 7 lines
To make
__per_cpu_loada relative symbol. ld has a bad habit of taking symbols out of empty sections and making them absolute. Which is why I added the DATA(0).Still I don't think that would be the 64bit problem.
Eric
FYI, I did try this out and it caused the bootloader to scramble the loaded data. The first corruption I found was the .x86cpuvendor.init section contained all zeroes.
Mike
H. Peter Anvin
reviewerRe: [crash, bisected] Re: [PATCH 3/4] x86_64: Fold pda into per cpu area
Quoted 5 lines · Mike Travis
FYI, I did try this out and it caused the bootloader to scramble the loaded data. The first corruption I found was the .x86cpuvendor.init section contained all zeroes.
Explain what you mean with "the bootloader" in this context.
-hpa
Re: [crash, bisected] Re: [PATCH 3/4] x86_64: Fold pda into per cpu area
Quoted 10 lines · H. Peter Anvin
Quoted 5 lines · Mike Travis
FYI, I did try this out and it caused the bootloader to scramble the loaded data. The first corruption I found was the .x86cpuvendor.init section contained all zeroes.
Explain what you mean with "the bootloader" in this context.
-hpa
After the code was loaded (the compressed code, it seems that my GRUB doesn't support uncompressed loading), the above section contained zeroes. I snapped it fairly early, around secondary_startup_64, and then printed it in x86_64_start_kernel.
The object file had the correct data (as displayed by objdump) so I'm assuming that the bootloading process didn't load the section correctly.
Below was the linker script I used:
include/asm-generic/vmlinux.lds.h +8 -4
@@ -373,9 +373,13 @@#ifdef CONFIG_HAVE_ZERO_BASED_PER_CPU #define PERCPU (align) \ - . = ALIGN(align); \ + .data.percpu.abs = .; \ percpu : { } :percpu \ - __per_cpu_load = .; \ + .data.percpu.rel : AT(.data.percpu.abs - LOAD_OFFSET) { \ + BYTE(0) \ + . = ALIGN(align); \ + __per_cpu_load = .; \ + } \ .data.percpu 0 : AT(__per_cpu_load - LOAD_OFFSET) { \ *(.data.percpu.first) \ *(.data.percpu.shared_aligned) \
@@ -383,8 +387,8 @@ *(.data.percpu.page_aligned) \ ____per_cpu_size = .; \ } \ - . = __per_cpu_load + ____per_cpu_size; \ - data : { } :data + . = __per_cpu_load + ____per_cpu_size; +#else #define PERCPU (align) \ . = ALIGN(align); \
It showed all the correct address in the map and __per_cpu_load was a relative symbol (which was the objective.)
Btw, our simulator, which only loads uncompressed code, had the data correct, so it *may* only be a result of the code being compressed.
Thanks,
Mike
Re: [crash, bisected] Re: [PATCH 3/4] x86_64: Fold pda into per cpu area
Quoted 53 lines · Mike Travis
Quoted 10 lines · H. Peter Anvin
Quoted 5 lines · Mike Travis
FYI, I did try this out and it caused the bootloader to scramble the loaded data. The first corruption I found was the .x86cpuvendor.init section contained all zeroes.
Explain what you mean with "the bootloader" in this context.
-hpa
After the code was loaded (the compressed code, it seems that my GRUB doesn't support uncompressed loading), the above section contained zeroes. I snapped it fairly early, around
secondary_startup_64, and then printed it inx86_64_start_kernel.The object file had the correct data (as displayed by objdump) so I'm assuming that the bootloading process didn't load the section correctly.
Below was the linker script I used:
include/asm-generic/vmlinux.lds.h +8
-4@@ -373,9 +373,13 @@#ifdef CONFIG_HAVE_ZERO_BASED_PER_CPU #define PERCPU (align) \ - . = ALIGN(align); \ + .data.percpu.abs = .; \ percpu : { } :percpu \ - __per_cpu_load = .; \ + .data.percpu.rel : AT(.data.percpu.abs - LOAD_OFFSET) { \ + BYTE(0) \ + . = ALIGN(align); \ + __per_cpu_load = .; \ + } \ .data.percpu 0 : AT(__per_cpu_load - LOAD_OFFSET) { \ *(.data.percpu.first) \ *(.data.percpu.shared_aligned) \@@ -383,8 +387,8 @@ *(.data.percpu.page_aligned) \ ____per_cpu_size = .; \ } \ - . = __per_cpu_load + ____per_cpu_size; \ - data : { } :data + . = __per_cpu_load + ____per_cpu_size; +#else #define PERCPU (align) \ . = ALIGN(align); \
Quoted 5 lines
It showed all the correct address in the map and
__per_cpu_loadwas a relative symbol (which was the objective.)Btw, our simulator, which only loads uncompressed code, had the data correct, so it *may* only be a result of the code being compressed.
Weird. Grub doesn't get involved in the decompression the kernel does it all itself so we should be able to track where things go bad.
Last I looked the compressed code was formed by essentially. objcopy vmlinux -O binary vmlinux.bin
gzip vmlinux.bin
And then we take on a magic header to the gzip compressed file.
Are things only bad with the change above?
Eric
Re: [crash, bisected] Re: [PATCH 3/4] x86_64: Fold pda into per cpu area
Quoted 66 lines · Eric W. Biederman
Quoted 53 lines · Mike Travis
Quoted 11 lines · H. Peter Anvin
Quoted 5 lines · Mike Travis
FYI, I did try this out and it caused the bootloader to scramble the loaded data. The first corruption I found was the .x86cpuvendor.init section contained all zeroes.
Explain what you mean with "the bootloader" in this context.
-hpa
After the code was loaded (the compressed code, it seems that my GRUB doesn't support uncompressed loading), the above section contained zeroes. I snapped it fairly early, around
secondary_startup_64, and then printed it inx86_64_start_kernel.The object file had the correct data (as displayed by objdump) so I'm assuming that the bootloading process didn't load the section correctly.
Below was the linker script I used:
include/asm-generic/vmlinux.lds.h +8
-4@@ -373,9 +373,13 @@#ifdef CONFIG_HAVE_ZERO_BASED_PER_CPU #define PERCPU (align) \ - . = ALIGN(align); \ + .data.percpu.abs = .; \ percpu : { } :percpu \ - __per_cpu_load = .; \ + .data.percpu.rel : AT(.data.percpu.abs - LOAD_OFFSET) { \ + BYTE(0) \ + . = ALIGN(align); \ + __per_cpu_load = .; \ + } \ .data.percpu 0 : AT(__per_cpu_load - LOAD_OFFSET) { \ *(.data.percpu.first) \ *(.data.percpu.shared_aligned) \@@ -383,8 +387,8 @@ *(.data.percpu.page_aligned) \ ____per_cpu_size = .; \ } \ - . = __per_cpu_load + ____per_cpu_size; \ - data : { } :data + . = __per_cpu_load + ____per_cpu_size; +#else #define PERCPU (align) \ . = ALIGN(align); \Quoted 6 lines
It showed all the correct address in the map and
__per_cpu_loadwas a relative symbol (which was the objective.)Btw, our simulator, which only loads uncompressed code, had the data correct, so it *may* only be a result of the code being compressed.
Weird. Grub doesn't get involved in the decompression the kernel does it all itself so we should be able to track where things go bad.
Quoted 6 lines
Last I looked the compressed code was formed by essentially. objcopy vmlinux -O binary vmlinux.bin
gzip vmlinux.bin
And then we take on a magic header to the gzip compressed file.Are things only bad with the change above?
No, the original crash being discussed was a GP fault in head_64.S as it tries to initialize the kernel segments. The cause was that the prototype GDT is all zero, even though it's an initialized variable, and inspection of vmlinux shows that it has the right contents. But somehow it's either 1) getting zeroed on load, or 2) is loaded to the wrong place.
The zero-based PDA mechanism requires the introduction of a new ELF segment based at vaddr 0 which is sufficiently unusual that it wouldn't surprise me if its triggering some toolchain bug.
Mike: what would happen if the PDA were based at 4k rather than 0? The stack canary would still be at its small offset (0x20?), but it doesn't need to be initialized. I'm not sure if doing so would fix anything, however.
J
Re: [crash, bisected] Re: [PATCH 3/4] x86_64: Fold pda into per cpu area
Quoted 9 lines · Jeremy Fitzhardinge
No, the original crash being discussed was a GP fault in
head_64.Sas it tries to initialize the kernel segments. The cause was that the prototype GDT is all zero, even though it's an initialized variable, and inspection of vmlinux shows that it has the right contents. But somehow it's either 1) getting zeroed on load, or 2) is loaded to the wrong place.The zero-based PDA mechanism requires the introduction of a new ELF segment based at vaddr 0 which is sufficiently unusual that it wouldn't surprise me if its triggering some toolchain bug.
Agreed. Given the previous description my hunch is that the bug is occurring during objcopy. If vmlinux is good and the compressed kernel is bad.
It should be possible to look at vmlinux.bin and see if that was generated properly.
Quoted 3 lines
Mike: what would happen if the PDA were based at 4k rather than 0? The stack canary would still be at its small offset (
0x20?), but it doesn't need to be initialized. I'm not sure if doing so would fix anything, however.
I'm dense today. Why are we doing a zero based pda? That seems the most likely culprit of linker trouble, and we should be able to put a smaller offset in the segment register to allow for everything to work as expected.
Eric
Re: [crash, bisected] Re: [PATCH 3/4] x86_64: Fold pda into per cpu area
Quoted 21 lines · Eric W. Biederman
Quoted 10 lines · Jeremy Fitzhardinge
No, the original crash being discussed was a GP fault in
head_64.Sas it tries to initialize the kernel segments. The cause was that the prototype GDT is all zero, even though it's an initialized variable, and inspection of vmlinux shows that it has the right contents. But somehow it's either 1) getting zeroed on load, or 2) is loaded to the wrong place.The zero-based PDA mechanism requires the introduction of a new ELF segment based at vaddr 0 which is sufficiently unusual that it wouldn't surprise me if its triggering some toolchain bug.
Agreed. Given the previous description my hunch is that the bug is occurring during objcopy. If vmlinux is good and the compressed kernel is bad.
It should be possible to look at vmlinux.bin and see if that was generated properly.
Quoted 9 lines
Quoted 4 lines
Mike: what would happen if the PDA were based at 4k rather than 0? The stack canary would still be at its small offset (
0x20?), but it doesn't need to be initialized. I'm not sure if doing so would fix anything, however.I'm dense today. Why are we doing a zero based pda? That seems the most likely culprit of linker trouble, and we should be able to put a smaller offset in the segment register to allow for everything to work as expected.
The only reason we need to do a zero-based PDA is because of the boneheaded gcc/x86_64 ABI decision to put the stack canary at a fixed offset from %gs (all they had to do was define it as a weak symbol we could override). If we want to support stack-protector and unify the handling of per-cpu variables, we need to rebase the per-cpu area at zero, starting with the PDA.
My own inclination would be to drop stack-protector support until gcc gets fixed, rather than letting it prevent us from unifying an area which is in need of unification...
J
Re: [crash, bisected] Re: [PATCH 3/4] x86_64: Fold pda into per cpu area
Quoted 50 lines · Jeremy Fitzhardinge
Quoted 36 lines · Eric W. Biederman
Quoted 10 lines · Jeremy Fitzhardinge
No, the original crash being discussed was a GP fault in
head_64.Sas it tries
to initialize the kernel segments. The cause was that the prototype GDT is all
zero, even though it's an initialized variable, and inspection of vmlinux shows
that it has the right contents. But somehow it's either 1) getting zeroed on
load, or 2) is loaded to the wrong place.Quoted 6 lines
The zero-based PDA mechanism requires the introduction of a new ELF segment
based at vaddr 0 which is sufficiently unusual that it wouldn't surprise me if
its triggering some toolchain bug.Agreed. Given the previous description my hunch is that the bug is occurring
during objcopy. If vmlinux is good and the compressed kernel is bad.It should be possible to look at vmlinux.bin and see if that was generated
properly.Quoted 6 lines
Mike: what would happen if the PDA were based at 4k rather than 0? The stack
canary would still be at its small offset (0x20?), but it doesn't need to be
initialized. I'm not sure if doing so would fix anything, however.Quoted 5 lines
I'm dense today. Why are we doing a zero based pda? That seems the most likely culprit of linker trouble, and we should be able to put a smaller offset in the segment register to allow for everything to work as expected.
The only reason we need to do a zero-based PDA is because of the boneheaded gcc/x86_64 ABI decision to put the stack canary at a fixed offset from %gs (all they had to do was define it as a weak symbol we could override). If we want to support stack-protector and unify the handling of per-cpu variables, we need to rebase the per-cpu area at zero, starting with the PDA.
Quoted 5 lines
My own inclination would be to drop stack-protector support until gcc gets fixed, rather than letting it prevent us from unifying an area which is in need of unification...
J
I might be inclined to agree except most of the past few months of finding problems caused by NR_CPUS=4096 has been stack overflow. So any help detecting this condition is very useful. I can get static stacksizes (of course), but there's not a lot of help determining call chains except via actually executing the code.
Thanks,
Mike
H. Peter Anvin
reviewerRe: [crash, bisected] Re: [PATCH 3/4] x86_64: Fold pda into per cpu area
In reply to Eric W. BiedermanQuoted 8 lines · Eric W. Biederman
Quoted 4 lines
The zero-based PDA mechanism requires the introduction of a new ELF segment based at vaddr 0 which is sufficiently unusual that it wouldn't surprise me if its triggering some toolchain bug.
Agreed. Given the previous description my hunch is that the bug is occurring during objcopy. If vmlinux is good and the compressed kernel is bad.
Actually, it's not all that unusual... it's pretty common in various restricted environments. That being said, it's probably uncommon for *64-bit* code.
-hpa
Re: [crash, bisected] Re: [PATCH 3/4] x86_64: Fold pda into per cpu area
Quoted 11 lines · H. Peter Anvin
Quoted 8 lines · Eric W. Biederman
Quoted 4 lines
The zero-based PDA mechanism requires the introduction of a new ELF segment based at vaddr 0 which is sufficiently unusual that it wouldn't surprise me if its triggering some toolchain bug.
Agreed. Given the previous description my hunch is that the bug is occurring during objcopy. If vmlinux is good and the compressed kernel is bad.
Actually, it's not all that unusual... it's pretty common in various restricted environments. That being said, it's probably uncommon for *64-bit* code.
Well, it's also unusual because 1) it's vaddr 0, but paddr <high>, and 2) the PHDRs are not sorted by vaddr order. 2) might actually be a bug.
J
Re: [crash, bisected] Re: [PATCH 3/4] x86_64: Fold pda into per cpu area
Quoted 12 lines · Jeremy Fitzhardinge
Quoted 11 lines · H. Peter Anvin
Quoted 9 lines · Eric W. Biederman
Quoted 5 lines
The zero-based PDA mechanism requires the introduction of a new ELF segment based at vaddr 0 which is sufficiently unusual that it wouldn't surprise me if
its triggering some toolchain bug.Agreed. Given the previous description my hunch is that the bug is occurring during objcopy. If vmlinux is good and the compressed kernel is bad.
Quoted 6 lines
Quoted 3 lines
Actually, it's not all that unusual... it's pretty common in various restricted environments. That being said, it's probably uncommon for *64-bit* code.
Well, it's also unusual because 1) it's vaddr 0, but paddr <high>, and 2) the PHDRs are not sorted by vaddr order. 2) might actually be a bug.
I just looked and gcc does not use this technique for thread local data.
My initial concern about all of this was not making symbols section relative is relieved as this all appears to be a 64bit arch thing where that doesn't matter.
Has anyone investigated using the technique gcc uses for thread local storage?
http://people.redhat.com/drepper/tls.pdf
In particular using the local exec model so we can say:
movq %fs:x@tpoff,%rax
To load the contents of a per cpu variable x into %rax ?
If we can use that model it should make it easier to interface with things like the stack protector code. Although we would still need to be very careful about thread switches.
Eric
Re: [crash, bisected] Re: [PATCH 3/4] x86_64: Fold pda into per cpu area
Quoted 20 lines · Eric W. Biederman
Quoted 17 lines · Jeremy Fitzhardinge
Quoted 15 lines · H. Peter Anvin
Quoted 9 lines · Eric W. Biederman
Quoted 5 lines
The zero-based PDA mechanism requires the introduction of a new ELF segment based at vaddr 0 which is sufficiently unusual that it wouldn't surprise me if
its triggering some toolchain bug.Agreed. Given the previous description my hunch is that the bug is occurring during objcopy. If vmlinux is good and the compressed kernel is bad.
Actually, it's not all that unusual... it's pretty common in various restricted environments. That being said, it's probably uncommon for *64-bit* code.
Quoted 6 lines
Quoted 3 lines
Well, it's also unusual because 1) it's vaddr 0, but paddr <high>, and 2) the PHDRs are not sorted by vaddr order. 2) might actually be a bug.
I just looked and gcc does not use this technique for thread local data.
Which technique? It does assume you put the thread-local data near %gs (%fs in userspace), and it uses a small offset (positive or negative) to reach it.
At present, the x86-64 only uses %gs-relative addressing to reach the pda, which are always small positive offsets. It always accesses per-cpu data in a two-step process of getting the base of per-cpu data, then offsetting to find the particular variable.
x86-32 has no pda, and arranges %fs so that %fs:variable gets the percpu variant of variable. The offsets are always quite large.
Quoted 4 lines
My initial concern about all of this was not making symbols section relative is relieved as this all appears to be a 64bit arch thing where that doesn't matter.
Why's that? I thought you cared particularly about making the x86-64 kernel relocatable for kdump, and that using non-absolute symbols was part of that?
Quoted 3 lines
Has anyone investigated using the technique gcc uses for thread local storage?
http://people.redhat.com/drepper/tls.pdf
The powerpc guys tried using gcc-level thread-local storage, but it doesn't work well. per-cpu data and per-thread data have different constraints, and its hard to tell gcc about them. For example, if you have a section of preemptable code in your function, it's hard to tell gcc not to cache a "thread-local" variable across it, even though we could have switched CPUs in the meantime.
Quoted 9 lines
In particular using the local exec model so we can say:
movq %fs:x@tpoff,%raxTo load the contents of a per cpu variable x into %rax ?
If we can use that model it should make it easier to interface with things like the stack protector code. Although we would still need to be very careful about thread switches.
You mean cpu switches? We don't really have a notion of thread-local data in the kernel, other than things hanging off the kernel stack.
J
Re: [crash, bisected] Re: [PATCH 3/4] x86_64: Fold pda into per cpu area
Quoted 4 lines · Jeremy Fitzhardinge
Quoted 2 lines
I just looked and gcc does not use this technique for thread local data.
Which technique?
A section located at 0.
Quoted 3 lines
It does assume you put the thread-local data near %gs (%fs in userspace), and it uses a small offset (positive or negative) to reach it.
Nope. It achieves that affect with a magic set of relocations instead of linker magic.
Quoted 7 lines
At present, the x86-64 only uses %gs-relative addressing to reach the pda, which are always small positive offsets. It always accesses per-cpu data in a two-step process of getting the base of per-cpu data, then offsetting to find the particular variable.
x86-32 has no pda, and arranges %fs so that %fs:variable gets the percpu variant of variable. The offsets are always quite large.
As a practical matter I like that approach (except for extra code size of the offsets).
Quoted 7 lines
Quoted 4 lines
My initial concern about all of this was not making symbols section relative is relieved as this all appears to be a 64bit arch thing where that doesn't matter.
Why's that? I thought you cared particularly about making the x86-64 kernel relocatable for kdump, and that using non-absolute symbols was part of that?
That is all true but unconnected.
For x86_64 the kernel lives at a fixed virtual address. So absolute or non absolute symbols don't matter. Only __pa and a little bit of code in head64.S that sets up the intial page tables has to be aware of it. So relocation on x86_64 is practically free.
For i386 since virtual address space is precious and because there were concerns about putting code in __pa we actually relocate the kernel symbols during load right after decompression. When we do relocations absolute symbols are a killer.
Quoted 9 lines
Quoted 3 lines
Has anyone investigated using the technique gcc uses for thread local storage?
http://people.redhat.com/drepper/tls.pdfThe powerpc guys tried using gcc-level thread-local storage, but it doesn't work well. per-cpu data and per-thread data have different constraints, and its hard to tell gcc about them. For example, if you have a section of preemptable code in your function, it's hard to tell gcc not to cache a "thread-local" variable across it, even though we could have switched CPUs in the meantime.
Yes, I completely agree with that. It doesn't mean however that we can't keep gcc ignorant and generate the same code manually.
Quoted 5 lines
Quoted 5 lines
In particular using the local exec model so we can say:
movq %fs:x@tpoff,%raxTo load the contents of a per cpu variable x into %rax ?
Quoted 8 lines
Quoted 1 line
If we can use that model it should make it easier to interface with things
like
Quoted 3 lines
the stack protector code. Although we would still need to be very careful about thread switches.
You mean cpu switches? We don't really have a notion of thread-local data in the kernel, other than things hanging off the kernel stack.
Well I was thinking threads switching on a cpu having the kinds of problems you described when it was tried on ppc.
Eric
Re: [crash, bisected] Re: [PATCH 3/4] x86_64: Fold pda into per cpu area
Quoted 3 lines · Eric W. Biederman
Nope. It achieves that affect with a magic set of relocations instead of linker magic.
Well, the code gcc generates for -fstack-protector emits a literal "%gs:40", so there's no relocations at all.
Quoted 5 lines
Quoted 5 lines
At present, the x86-64 only uses %gs-relative addressing to reach the pda, which are always small positive offsets. It always accesses per-cpu data in a two-step process of getting the base of per-cpu data, then offsetting to find the particular variable.
Quoted 7 lines
Quoted 3 lines
x86-32 has no pda, and arranges %fs so that %fs:variable gets the percpu variant of variable. The offsets are always quite large.
As a practical matter I like that approach (except for extra code size of the offsets).
Yes, and there's no reason we couldn't do the same on 64-bit, aside from the stack-protector's use of %gs:40. There's no code-size cost in large offsets, since they're always 32-bits anyway (there's no short absolute addressing mode).
Quoted 10 lines
Quoted 6 lines
The powerpc guys tried using gcc-level thread-local storage, but it doesn't work well. per-cpu data and per-thread data have different constraints, and its hard to tell gcc about them. For example, if you have a section of preemptable code in your function, it's hard to tell gcc not to cache a "thread-local" variable across it, even though we could have switched CPUs in the meantime.
Yes, I completely agree with that. It doesn't mean however that we can't keep gcc ignorant and generate the same code manually.
Yes, I see. I haven't looked at that specifically, but I think both Rusty and Andi have, and it gets tricky with modules and -ve kernel addresses, or something.
Quoted 2 lines
Well I was thinking threads switching on a cpu having the kinds of problems you described when it was tried on ppc.
Uh, I think we're having a nomenclature imprecision here. Strictly speaking, the kernel doesn't have threads, only tasks and CPUs. We only care about per-cpu data, not per-task data, so the concern is not "threads switching on a CPU" but "CPUs switching on (under) a task". But I think we understand each other regardless ;)
If we manually generate %gs-relative references to percpu data, then it's no different to what we do with 32-bit, whether it be a specific symbol address or using the TLS relocations.
J
H. Peter Anvin
reviewerRe: [crash, bisected] Re: [PATCH 3/4] x86_64: Fold pda into per cpu area
Quoted 5 lines · Jeremy Fitzhardinge
Yes, and there's no reason we couldn't do the same on 64-bit, aside from the stack-protector's use of %gs:40. There's no code-size cost in large offsets, since they're always 32-bits anyway (there's no short absolute addressing mode).
If we manually generate %gs-relative references to percpu data, then it's no different to what we do with 32-bit, whether it be a specific symbol address or using the TLS relocations.
If we think the problem is the zero-basing triggering linker bugs, we should probably just use a small offset, like 64 (put a small dummy section before the .percpu.data section to occupy this section.)
I'm going to play with this a bit and see if I come up with something sanish.
-hpa
Re: [crash, bisected] Re: [PATCH 3/4] x86_64: Fold pda into per cpu area
Quoted 12 lines · H. Peter Anvin
Quoted 10 lines · Jeremy Fitzhardinge
Yes, and there's no reason we couldn't do the same on 64-bit, aside from the stack-protector's use of %gs:40. There's no code-size cost in large offsets, since they're always 32-bits anyway (there's no short absolute addressing mode).
If we manually generate %gs-relative references to percpu data, then it's no different to what we do with 32-bit, whether it be a specific symbol address or using the TLS relocations.
Quoted 8 lines
If we think the problem is the zero-basing triggering linker bugs, we should probably just use a small offset, like 64 (put a small dummy section before the .percpu.data section to occupy this section.)
I'm going to play with this a bit and see if I come up with something sanish.
-hpa
One interesting thing I've discovered is the gcc --version may make a difference.
The kernel panic that occurred from Ingo's config, I was able to replicate with GCC 4.2.0 (which is on our devel server). But this one complained about not being able to handle the STACK-PROTECTOR option so I moved everything to another machine that has 4.2.4, and now it seems that it works fine. I'm still re-verifying that the source bits and config options are identical (it was a later git-remote update), and that in fact it is the gcc --version, but that may be the conclusion. (My code also has some patches submitted but not yet included in the tip/master tree. Curiously just enabling some debug options changed the footprint of the panic.)
Are we allowed to insist on a specific level of GCC for compiling the kernel?
Thanks,
Mike
Re: [crash, bisected] Re: [PATCH 3/4] x86_64: Fold pda into per cpu area
Quoted 35 lines · Mike Travis
Quoted 12 lines · H. Peter Anvin
Quoted 10 lines · Jeremy Fitzhardinge
Yes, and there's no reason we couldn't do the same on 64-bit, aside from the stack-protector's use of %gs:40. There's no code-size cost in large offsets, since they're always 32-bits anyway (there's no short absolute addressing mode).
If we manually generate %gs-relative references to percpu data, then it's no different to what we do with 32-bit, whether it be a specific symbol address or using the TLS relocations.
Quoted 8 lines
If we think the problem is the zero-basing triggering linker bugs, we should probably just use a small offset, like 64 (put a small dummy section before the .percpu.data section to occupy this section.)
I'm going to play with this a bit and see if I come up with something sanish.
-hpa
One interesting thing I've discovered is the gcc --version may make a difference.
The kernel panic that occurred from Ingo's config, I was able to replicate with GCC 4.2.0 (which is on our devel server). But this one complained about not being able to handle the STACK-PROTECTOR option so I moved everything to another machine that has 4.2.4, and now it seems that it works fine. I'm still re-verifying that the source bits and config options are identical (it was a later git-remote update), and that in fact it is the gcc --version, but that may be the conclusion. (My code also has some patches submitted but not yet included in the tip/master tree. Curiously just enabling some debug options changed the footprint of the panic.)
Quoted 2 lines
Are we allowed to insist on a specific level of GCC for compiling the kernel?
Depends on the root cause. If it turns out to be something that is buggy in gcc and we can't work around. We might do something. I don't recall that kind of thing happening often. I think our minimum gcc is currently gcc-3.4.
Eric
Re: [crash, bisected] Re: [PATCH 3/4] x86_64: Fold pda into per cpu area
Quoted 37 lines · Eric W. Biederman
Quoted 32 lines · Mike Travis
Quoted 10 lines · H. Peter Anvin
Quoted 9 lines · Jeremy Fitzhardinge
Yes, and there's no reason we couldn't do the same on 64-bit, aside from the stack-protector's use of %gs:40. There's no code-size cost in large offsets, since they're always 32-bits anyway (there's no short absolute addressing mode).
If we manually generate %gs-relative references to percpu data, then it's no different to what we do with 32-bit, whether it be a specific symbol address or using the TLS relocations.
Quoted 8 lines
If we think the problem is the zero-basing triggering linker bugs, we should probably just use a small offset, like 64 (put a small dummy section before the .percpu.data section to occupy this section.)
I'm going to play with this a bit and see if I come up with something sanish.
-hpa
One interesting thing I've discovered is the gcc --version may make a difference.
The kernel panic that occurred from Ingo's config, I was able to replicate with GCC 4.2.0 (which is on our devel server). But this one complained about not being able to handle the STACK-PROTECTOR option so I moved everything to another machine that has 4.2.4, and now it seems that it works fine. I'm still re-verifying that the source bits and config options are identical (it was a later git-remote update), and that in fact it is the gcc --version, but that may be the conclusion. (My code also has some patches submitted but not yet included in the tip/master tree. Curiously just enabling some debug options changed the footprint of the panic.)
Quoted 2 lines
Are we allowed to insist on a specific level of GCC for compiling the kernel?
Quoted 6 lines
Depends on the root cause. If it turns out to be something that is buggy in gcc and we can't work around. We might do something. I don't recall that kind of thing happening often. I think our minimum gcc is currently gcc-3.4.
Eric
Ouch. How far into it do we need to investigate? I can surely compare the vmlinux object files, but I'm not cognizant enough about the linker internals to examine much more than that.
But hey, maybe gcc-3.4 will work ok...? ;-)
[Or it may be the stack-protector thing is introducing better code? I'll try some more config options tomorrow to see if that affects anything.]
Cheers,
Mike
Re: [crash, bisected] Re: [PATCH 3/4] x86_64: Fold pda into per cpu area
Quoted 3 lines · Mike Travis
Ouch. How far into it do we need to investigate? I can surely compare the vmlinux object files, but I'm not cognizant enough about the linker internals to examine much more than that.
As a first step we just need to know what we tell gcc or the linker to do, and what is incorrectly output. Once the problem is understood we can think about how to deal with the problem.
What we really need is a recipe for success.
A recipe for failure.
At that point it should be much easier for someone else to reproduce the problem, and/or look into the specific details and see what is wrong or to suggest patches.
The kernel is a significant enough program and a different enough one it is hard to predict how things go.
Eric
H. Peter Anvin
reviewerRe: [crash, bisected] Re: [PATCH 3/4] x86_64: Fold pda into per cpu area
In reply to Mike TravisQuoted 13 lines · Mike Travis
One interesting thing I've discovered is the gcc --version may make a difference.
The kernel panic that occurred from Ingo's config, I was able to replicate
with GCC 4.2.0 (which is on our devel server). But this one complained
about not being able to handle the STACK-PROTECTOR option so I moved
everything to another machine that has 4.2.4, and now it seems that it
works fine. I'm still re-verifying that the source bits and config options are identical (it was a later git-remote update), and that in fact it is the gcc --version, but that may be the conclusion. (My code also has some
patches submitted but not yet included in the tip/master tree. Curiously
just enabling some debug options changed the footprint of the panic.)
Quoted 3 lines
Are we allowed to insist on a specific level of GCC for compiling the kernel?
Yes, but certainly not anything even close to that recent -- I think right now we're supposed to support back to 3.2-something overall; specific architectures might have more stringent requirements. There are a couple of gcc versions known to miscompile there kernel that we don't support; I don't know if 4.2.0 is one of them.
-hpa
Re: [crash, bisected] Re: [PATCH 3/4] x86_64: Fold pda into per cpu area
In reply to Mike TravisMike Travis wrote:
... I'm still re-verifying that the source bits and config options
Quoted 2 lines
are identical (it was a later git-remote update), and that in fact it is the gcc --version, but that may be the conclusion.
...
Yup, it's the gcc --version that makes the difference. GCC 4.2.0 couldn't boot past the grub screen, GCC 4.2.4 made it to the login prompt.
The only config changes were imposed by the make script:
stapp 125> diff ../configs/config-Tue_Jul__1_16_48_45_CEST_2008.bad ../build/ingo-test-0701/.config 4c4
< # Tue Jul 1 16:53:49 2008
---
Quoted 1 line
# Tue Jul 1 16:09:33 2008
64c64
< CONFIG_LOCALVERSION=""
---
Quoted 1 line
CONFIG_LOCALVERSION="-ingo-test-0701"
120d119
< CONFIG_USE_GENERIC_SMP_HELPERS=y
124d122
< # CONFIG_HAVE_GENERIC_DMA_COHERENT is not set1294d1291
< CONFIG_THERMAL_HWMON=y
Posting the complete patchset RSN... (or tomorrow am so I can test some more configs and functionality.)
Thanks,
Mike
H. Peter Anvin
reviewerRe: [crash, bisected] Re: [PATCH 3/4] x86_64: Fold pda into per cpu area
Quoted 9 lines · Mike Travis
Mike Travis wrote:
... I'm still re-verifying that the source bits and config optionsQuoted 2 lines
are identical (it was a later git-remote update), and that in fact it is the gcc --version, but that may be the conclusion.
...
Yup, it's the gcc --version that makes the difference. GCC 4.2.0 couldn't boot past the grub screen, GCC 4.2.4 made it to the login prompt.
IIRC, 4.2.0, 4.2.1 and 4.3.0 are known to miscompile the kernel in one way or another, however, that is from memory so don't quote me on it.
-hpa
Re: [crash, bisected] Re: [PATCH 3/4] x86_64: Fold pda into per cpu area
Quoted 12 lines · H. Peter Anvin
Quoted 10 lines · Mike Travis
Mike Travis wrote:
... I'm still re-verifying that the source bits and config optionsQuoted 2 lines
are identical (it was a later git-remote update), and that in fact it is the gcc --version, but that may be the conclusion.
...
Yup, it's the gcc --version that makes the difference. GCC 4.2.0 couldn't
boot past the grub screen, GCC 4.2.4 made it to the login prompt.
Quoted 4 lines
IIRC, 4.2.0, 4.2.1 and 4.3.0 are known to miscompile the kernel in one way or another, however, that is from memory so don't quote me on it.
-hpa
Great. That's what's been on my devel server for the past 3 or 4 months now...
[And it's a big shared server that I'm but a small ant wandering around on it. ;-)]
Re: [crash, bisected] Re: [PATCH 3/4] x86_64: Fold pda into per cpu area
In reply to H. Peter AnvinQuoted 12 lines · H. Peter Anvin
Quoted 10 lines · Mike Travis
Mike Travis wrote:
... I'm still re-verifying that the source bits and config optionsQuoted 2 lines
are identical (it was a later git-remote update), and that in fact it is the gcc --version, but that may be the conclusion.
...
Yup, it's the gcc --version that makes the difference. GCC 4.2.0 couldn't
boot past the grub screen, GCC 4.2.4 made it to the login prompt.
Quoted 4 lines
IIRC, 4.2.0, 4.2.1 and 4.3.0 are known to miscompile the kernel in one way or another, however, that is from memory so don't quote me on it.
-hpa
This is definitely getting strange...
Ingo's randconfig at:
http://redhat.com/~mingo/misc/config-Tue_Jul__1_16_48_45_CEST_2008.bad
will only boot and run with gcc-4.2.4, with gcc-4.2.0 it fails at the grub screen.
Other configs like:
defconfig w/NR_CPUS=4096 nonuma
will only boot and run with gcc-4.2.0, and does the "failure at grub" screen with gcc-4.2.4 ...!
The nosmp config works with either.
I'm looking at the generated vmlinux files now (well at least the assembler, I'm not really familiar enough with the linker objects to look at those.) I'm also trying to track which config options changes the behavior so radically.
Any other suggestions?
Thanks!
Mike
Re: [crash, bisected] Re: [PATCH 3/4] x86_64: Fold pda into per cpu area
Quoted 3 lines · Mike Travis
will only boot and run with gcc-4.2.0, and does the "failure at grub" screen with
gcc-4.2.4 ...!
Do these tests have an early serial console enabled? I want to confirm that the failure is very early in boot before or just as we reach C code.
If you don't have an early console we could be failing late in the process just not have visibility.
Quoted 1 line
Any other suggestions?
If you have a serial console to add a little bit of instrumentation super duper early. Although looking at the generated objects might be just as interesting.
Eric
Re: [crash, bisected] Re: [PATCH 3/4] x86_64: Fold pda into per cpu area
Quoted 12 lines · Eric W. Biederman
Quoted 3 lines · Mike Travis
will only boot and run with gcc-4.2.0, and does the "failure at grub" screen with
gcc-4.2.4 ...!Do these tests have an early serial console enabled? I want to confirm that the failure is very early in boot before or just as we reach C code.
If you don't have an early console we could be failing late in the process just not have visibility.
Quoted 6 lines
Quoted 1 line
Any other suggestions?
If you have a serial console to add a little bit of instrumentation super duper early. Although looking at the generated objects might be just as interesting.
Eric
Hi,
Sorry for the delay, been off the past 4 days.
I'll see how closely I can narrow down where the fault is. I have been inserting very early printk's to track how far into the startup it gets before bailing.
Thanks,
Mike
Re: [crash, bisected] Re: [PATCH 3/4] x86_64: Fold pda into per cpu area
Quoted 7 lines · Mike Travis
Hi,
Sorry for the delay, been off the past 4 days.
I'll see how closely I can narrow down where the fault is. I have been inserting
very early printk's to track how far into the startup it gets before bailing.
Thanks. That should help narrow down what is going on.
Eric
Re: [crash, bisected] Re: [PATCH 3/4] x86_64: Fold pda into per cpu area
Quoted 5 lines · Eric W. Biederman
Quoted 4 lines · Mike Travis
Hi,
Sorry for the delay, been off the past 4 days.
Quoted 7 lines
Quoted 3 lines
I'll see how closely I can narrow down where the fault is. I have been inserting
very early printk's to track how far into the startup it gets before bailing.Thanks. That should help narrow down what is going on.
Eric
Unfortunately it's back to the problem of faulting before x86_64_start_kernel() and grub just immediately reboots. So I'm back at analyzing assembler and config differences.
Mike
Re: [crash, bisected] Re: [PATCH 3/4] x86_64: Fold pda into per cpu area
Quoted 3 lines · Mike Travis
Unfortunately it's back to the problem of faulting before
x86_64_start_kernel()and grub just immediately reboots. So I'm back at analyzing assembler and config differences.
Ok. That is a narrow window of code. So it shouldn't be too bad, nasty though.
If you would like to trace through it I have attached my serial port debugging routines that I use in that part of the code.
Eric
#if 1
/* Base Address */
#define TTYS0_BASE 0x3f8
/* Data */
#define TTYS0_RBR (TTYS0_BASE+0x00)
#define TTYS0_TBR (TTYS0_BASE+0x00)
/* Control */
#define TTYS0_IER (TTYS0_BASE+0x01)
#define TTYS0_IIR (TTYS0_BASE+0x02)
#define TTYS0_FCR (TTYS0_BASE+0x02)
#define TTYS0_LCR (TTYS0_BASE+0x03)
#define TTYS0_MCR (TTYS0_BASE+0x04)
#define TTYS0_DLL (TTYS0_BASE+0x00)
#define TTYS0_DLM (TTYS0_BASE+0x01)
/* Status */
#define TTYS0_LSR (TTYS0_BASE+0x05)
#define TTYS0_MSR (TTYS0_BASE+0x06)
#define TTYS0_SCR (TTYS0_BASE+0x07)
#define TTYS0_BAUD 9600
#define TTYS0_DIV (115200/TTYS0_BAUD)
#define TTYS0_DIV_LO (TTYS0_DIV&0xFF)
#define TTYS0_DIV_HI ((TTYS0_DIV >> 8)&0xFF)
#if ((115200%TTYS0_BAUD) != 0)
#error Bad ttyS0 baud rate
#endif
#define TTYS0_INIT \ /* disable interrupts */ \ movb $0x00, %al ; \ movw $TTYS0_IER, %dx ; \ outb %al, %dx ; \ ; \ /* enable fifos */ \ movb $0x01, %al ; \ movw $TTYS0_FCR, %dx ; \ outb %al, %dx ; \ ; \ /* Set Baud Rate Divisor to TTYS0_BAUD */ \ movw $TTYS0_LCR, %dx ; \ movb $0x83, %al ; \ outb %al, %dx ; \ ; \ movw $TTYS0_DLL, %dx ; \ movb $TTYS0_DIV_LO, %al ; \ outb %al, %dx ; \ ; \ movw $TTYS0_DLM, %dx ; \ movb $TTYS0_DIV_HI, %al ; \ outb %al, %dx ; \ ; \ movw $TTYS0_LCR, %dx ; \ movb $0x03, %al ; \ outb %al, %dx /* uses: ax, dx */ #define TTYS0_TX_AL \ mov %al, %ah ; \ 9: mov $TTYS0_LSR, %dx ; \ inb %dx, %al ; \ test $0x20, %al ; \ je 9b ; \ mov $TTYS0_TBR, %dx ; \ mov %ah, %al ; \ outb %al, %dx /* uses: ax, dx */ #define TTYS0_TX_CHAR(byte) \ mov byte, %al ; \ TTYS0_TX_AL /* uses: eax, dx */ #define TTYS0_TX_HEX32(lword) \ mov lword, %eax ; \ shr $28, %eax ; \ and $0x0f, %al ; \ add $'0', %al ; \ cmp $'9', %al ; \ jle 9f ; \ add $39, %al ; \ 9: ; \ TTYS0_TX_AL ; \ ; \ mov lword, %eax ; \ shr $24, %eax ; \ and $0x0f, %al ; \ add $'0', %al ; \ cmp $'9', %al ; \ jle 9f ; \ add $39, %al ; \ 9: ; \ TTYS0_TX_AL ; \ ; \ mov lword, %eax ; \ shr $20, %eax ; \ and $0x0f, %al ; \ add $'0', %al ; \ cmp $'9', %al ; \ jle 9f ; \ add $39, %al ; \ 9: ; \ TTYS0_TX_AL ; \ ; \ mov lword, %eax ; \ shr $16, %eax ; \ and $0x0f, %al ; \ add $'0', %al ; \ cmp $'9', %al ; \ jle 9f ; \ add $39, %al ; \ 9: ; \ TTYS0_TX_AL ; \ ; \ mov lword, %eax ; \ shr $12, %eax ; \ and $0x0f, %al ; \ add $'0', %al ; \ cmp $'9', %al ; \ jle 9f ; \ add $39, %al ; \ 9: ; \ TTYS0_TX_AL ; \ ; \ mov lword, %eax ; \ shr $8, %eax ; \ and $0x0f, %al ; \ add $'0', %al ; \ cmp $'9', %al ; \ jle 9f ; \ add $39, %al ; \ 9: ; \ TTYS0_TX_AL ; \ ; \ mov lword, %eax ; \ shr $4, %eax ; \ and $0x0f, %al ; \ add $'0', %al ; \ cmp $'9', %al ; \ jle 9f ; \ add $39, %al ; \ 9: ; \ TTYS0_TX_AL ; \ ; \ mov lword, %eax ; \ and $0x0f, %al ; \ add $'0', %al ; \ cmp $'9', %al ; \ jle 9f ; \ add $39, %al ; \ 9: ; \ TTYS0_TX_AL /* uses: rax, dx */ #define TTYS0_TX_HEX64(lword) \ mov lword, %rax ; \ shr $60, %rax ; \ and $0x0f, %al ; \ add $'0', %al ; \ cmp $'9', %al ; \ jle 9f ; \ add $39, %al ; \ 9: ; \ TTYS0_TX_AL ; \ ; \ mov lword, %rax ; \ shr $56, %rax ; \ and $0x0f, %al ; \ add $'0', %al ; \ cmp $'9', %al ; \ jle 9f ; \ add $39, %al ; \ 9: ; \ TTYS0_TX_AL ; \ ; \ mov lword, %rax ; \ shr $52, %rax ; \ and $0x0f, %al ; \ add $'0', %al ; \ cmp $'9', %al ; \ jle 9f ; \ add $39, %al ; \ 9: ; \ TTYS0_TX_AL ; \ ; \ mov lword, %rax ; \ shr $48, %rax ; \ and $0x0f, %al ; \ add $'0', %al ; \ cmp $'9', %al ; \ jle 9f ; \ add $39, %al ; \ 9: ; \ TTYS0_TX_AL ; \ ; \ mov lword, %rax ; \ shr $44, %rax ; \ and $0x0f, %al ; \ add $'0', %al ; \ cmp $'9', %al ; \ jle 9f ; \ add $39, %al ; \ 9: ; \ TTYS0_TX_AL ; \ ; \ mov lword, %rax ; \ shr $40, %rax ; \ and $0x0f, %al ; \ add $'0', %al ; \ cmp $'9', %al ; \ jle 9f ; \ add $39, %al ; \ 9: ; \ TTYS0_TX_AL ; \ ; \ mov lword, %rax ; \ shr $36, %rax ; \ and $0x0f, %al ; \ add $'0', %al ; \ cmp $'9', %al ; \ jle 9f ; \ add $39, %al ; \ 9: ; \ TTYS0_TX_AL ; \ ; \ mov lword, %rax ; \ shr $32, %rax ; \ and $0x0f, %al ; \ add $'0', %al ; \ cmp $'9', %al ; \ jle 9f ; \ add $39, %al ; \ 9: ; \ TTYS0_TX_AL ; \ ; \ mov lword, %rax ; \ shr $28, %rax ; \ and $0x0f, %al ; \ add $'0', %al ; \ cmp $'9', %al ; \ jle 9f ; \ add $39, %al ; \ 9: ; \ TTYS0_TX_AL ; \ ; \ mov lword, %rax ; \ shr $24, %rax ; \ and $0x0f, %al ; \ add $'0', %al ; \ cmp $'9', %al ; \ jle 9f ; \ add $39, %al ; \ 9: ; \ TTYS0_TX_AL ; \ ; \ mov lword, %rax ; \ shr $20, %rax ; \ and $0x0f, %al ; \ add $'0', %al ; \ cmp $'9', %al ; \ jle 9f ; \ add $39, %al ; \ 9: ; \ TTYS0_TX_AL ; \ ; \ mov lword, %rax ; \ shr $16, %rax ; \ and $0x0f, %al ; \ add $'0', %al ; \ cmp $'9', %al ; \ jle 9f ; \ add $39, %al ; \ 9: ; \ TTYS0_TX_AL ; \ ; \ mov lword, %rax ; \ shr $12, %rax ; \ and $0x0f, %al ; \ add $'0', %al ; \ cmp $'9', %al ; \ jle 9f ; \ add $39, %al ; \ 9: ; \ TTYS0_TX_AL ; \ ; \ mov lword, %rax ; \ shr $8, %rax ; \ and $0x0f, %al ; \ add $'0', %al ; \ cmp $'9', %al ; \ jle 9f ; \ add $39, %al ; \ 9: ; \ TTYS0_TX_AL ; \ ; \ mov lword, %rax ; \ shr $4, %rax ; \ and $0x0f, %al ; \ add $'0', %al ; \ cmp $'9', %al ; \ jle 9f ; \ add $39, %al ; \ 9: ; \ TTYS0_TX_AL ; \ ; \ mov lword, %rax ; \ and $0x0f, %al ; \ add $'0', %al ; \ cmp $'9', %al ; \ jle 9f ; \ add $39, %al ; \ 9: ; \ TTYS0_TX_AL
#define DEBUG(x) TTYS0_TX_CHAR($x) ; TTYS0_TX_CHAR($'\r') ; TTYS0_TX_CHAR($'\n') #define DEBUG_TX_HEX32(x) TTYS0_TX_HEX32(x); TTYS0_TX_CHAR($'\r') ; TTYS0_TX_CHAR($'\n') #define DEBUG_TX_HEX64(x) TTYS0_TX_HEX64(x); TTYS0_TX_CHAR($'\r') ; TTYS0_TX_CHAR($'\n') #endif
Re: [crash, bisected] Re: [PATCH 3/4] x86_64: Fold pda into per cpu area
Quoted 8 lines · Eric W. Biederman
Quoted 4 lines · Mike Travis
Unfortunately it's back to the problem of faulting before
x86_64_start_kernel()and grub just immediately reboots. So I'm back at analyzing assembler and config differences.
Quoted 4 lines
Ok. That is a narrow window of code. So it shouldn't be too bad, nasty though.
If you would like to trace through it I have attached my serial port debugging routines that I use in that part of the code.
Last time it was doing this, it was a result of a triple-fault caused by loading %ds with an all-zero gdt. I modified Xen to dump the CPU state on triple-faults, so it was easy to pinpoint. I can do that again if it helps.
J
Re: [crash, bisected] Re: [PATCH 3/4] x86_64: Fold pda into per cpu area
Quoted 17 lines · Jeremy Fitzhardinge
Quoted 10 lines · Eric W. Biederman
Quoted 6 lines · Mike Travis
Unfortunately it's back to the problem of faulting before
x86_64_start_kernel()
and grub just immediately reboots. So I'm back at analyzing assembler and
config differences.Quoted 5 lines
Ok. That is a narrow window of code. So it shouldn't be too bad, nasty though.
If you would like to trace through it I have attached my serial port debugging routines that I use in that part of the code.
Quoted 6 lines
Last time it was doing this, it was a result of a triple-fault caused by loading %ds with an all-zero gdt. I modified Xen to dump the CPU state on triple-faults, so it was easy to pinpoint. I can do that again if it helps.
J
Absolutely! I'll repost the latest version of the patchset. Still haven't gotten around to enabling a XEN boot but it sure does sound handy.
Thanks,
Mike
Re: [crash, bisected] Re: [PATCH 3/4] x86_64: Fold pda into per cpu area
In reply to Jeremy FitzhardingeJeremy Fitzhardinge wrote:
...
Quoted 6 lines
Last time it was doing this, it was a result of a triple-fault caused by loading %ds with an all-zero gdt. I modified Xen to dump the CPU state on triple-faults, so it was easy to pinpoint. I can do that again if it helps.
J
Hi Jeremy,
There are two question marks for my patchset. The first is in
arch/x86/xen/smp.c:xen_cpu_up()
287 #ifdef CONFIG_X86_64
288 /* Allocate node local memory for AP pdas */
289 WARN_ON(cpu == 0);
290 if (cpu > 0) {291 rc = get_local_pda(cpu);
292 if (rc)
293 return rc;
294 }
295 #endif
and the second is at:
arch/x86/xen/enlighten.c:xen_start_kernel()
1748 #ifdef CONFIG_X86_64
1749 /* Disable until direct per-cpu data access. */ 1750 have_vcpu_info_placement = 0; 1751 x86_64_init_pda();
1752 #endif
I believe with the pda folded into the percpu area, get_local_pda() and x86_64_init_pda() have been removed, so these are no longer required, yes?
Also, arch/x86/kernel/acpi/sleep.c:acpi_save_state_mem() sets up the startup code address with:
102 initial_code = (unsigned long)wakeup_long64;
103 saved_magic = 0x123456789abcdef0;
Should the pda and gdt_page address also be setup as is done in smpboot.c:do_boot_cpu():
(CONFIG_X86_64)
801 initial_pda = (unsigned long)get_cpu_pda(cpu);
802 #endif
803 early_gdt_descr.address = (unsigned long)get_cpu_gdt_table(cpu);
804 initial_code = (unsigned long)start_secondary;
Thanks!
Mike
Re: [crash, bisected] Re: [PATCH 3/4] x86_64: Fold pda into per cpu area
Quoted 32 lines · Mike Travis
Jeremy Fitzhardinge wrote:
...Quoted 7 lines
Last time it was doing this, it was a result of a triple-fault caused by loading %ds with an all-zero gdt. I modified Xen to dump the CPU state on triple-faults, so it was easy to pinpoint. I can do that again if it helps.
J
Hi Jeremy,
There are two question marks for my patchset. The first is in
arch/x86/xen/smp.c:xen_cpu_up()
287 #ifdef
CONFIG_X86_64288 /* Allocate node local memory for AP pdas */ 289 WARN_ON(cpu == 0); 290 if (cpu > 0) {291 rc =
get_local_pda(cpu);
292 if (rc)
293 return rc;
294 }
295 #endifand the second is at:
arch/x86/xen/enlighten.c:xen_start_kernel()
1748 #ifdef
CONFIG_X86_64
Quoted 9 lines
1749 /* Disable until direct per-cpu data access. */ 1750 have_vcpu_info_placement = 0; 1751 x86_64_init_pda();1752 #endif
I believe with the pda folded into the percpu area,
get_local_pda()andx86_64_init_pda()have been removed, so these are no longer required, yes?
Well, presumably they need to be replaced with whatever setup you need to do now.
xen_start_kernel() is the first function called after a Xen kernel boot, and so it must make sure the early percpu setup is done before it can start using percpu variables.
xen_cpu_up() needs to do whatever initialization needed for a new cpu's percpu area (presumably whatever do_boot_cpu() does).
Quoted 6 lines
Also, arch/x86/kernel/acpi/sleep.c:acpi_save_state_mem() sets up the startup code address with:
102
initial_code= (unsigned long)wakeup_long64;
103saved_magic=0x123456789abcdef0;
Quoted 9 lines
Should the pda and
gdt_pageaddress also be setup as is done in smpboot.c:do_boot_cpu():(
CONFIG_X86_64)
801initial_pda= (unsigned long)get_cpu_pda(cpu);
802 #endif
803 early_gdt_descr.address = (unsigned long)get_cpu_gdt_table(cpu);
804initial_code= (unsigned long)start_secondary;
I don't think so. It looks like it's doing its own gdt save/restore.
J
Re: [crash, bisected] Re: [PATCH 3/4] x86_64: Fold pda into per cpu area
Quoted 30 lines · Jeremy Fitzhardinge
Quoted 19 lines · Mike Travis
... The first is in
arch/x86/xen/smp.c:xen_cpu_up()
287 #ifdef
CONFIG_X86_64288 /* Allocate node local memory for AP pdas */ 289 WARN_ON(cpu == 0); 290 if (cpu > 0) {291 rc =
get_local_pda(cpu);
292 if (rc)
293 return rc;
294 }
295 #endifand the second is at:
arch/x86/xen/enlighten.c:xen_start_kernel()
1748 #ifdef
CONFIG_X86_64Quoted 9 lines
1749 /* Disable until direct per-cpu data access. */ 1750 have_vcpu_info_placement = 0; 1751 x86_64_init_pda();1752 #endif
I believe with the pda folded into the percpu area,
get_local_pda()andx86_64_init_pda()have been removed, so these are no longer required, yes?
Quoted 6 lines
Well, presumably they need to be replaced with whatever setup you need to do now.
xen_start_kernel()is the first function called after a Xen kernel boot, and so it must make sure the early percpu setup is done before it can start using percpu variables.
Is this for the boot cpu (0), or for all cpus? For the boot cpu, I have this now in arch/x86/kernel/setup_percpu.c:
+#ifdef CONFIG_HAVE_ZERO_BASED_PER_CPU
+
+/* Initialize percpu offset for boot cpu (0) */ +unsigned long __per_cpu_offset[NR_CPUS] __read_mostly = {
+ [0] = (unsigned long)__per_cpu_load
+};
+#else
unsigned long __per_cpu_offset[NR_CPUS] __read_mostly;
+#endif
So this should apply as well to the xen startup?
Quoted 4 lines
xen_cpu_up()needs to do whatever initialization needed for a new cpu's percpu area (presumably whateverdo_boot_cpu()does).
Does the startup include executing arch/x86/kernel/head_64.S:startup_64() ? I see arch/x86/xen/xen-head.S:startup_xen() so I'm guessing not?
For the real startup, I do the following two things. But I'm not comfortable enough with xen to think I'll get it right putting this in xen-head.S.
- lgdt early_gdt_descr(%rip)
+
+#ifdef CONFIG_SMP
+ /* + * For zero-based percpu variables, the base (__per_cpu_load) must + * be added to the offset of per_cpu__gdt_page. This is only needed + * for the boot cpu but we can't do this prior to secondary_startup_64. + * So we use a NULL gdt adrs to indicate that we are starting up the + * boot cpu and not the secondary cpus. do_boot_cpu() will fixup + * the gdt adrs for those cpus. + */ +#define PER_CPU_GDT_PAGE 0 + movq early_gdt_descr_base(%rip), %rax + testq %rax, %rax + jnz 1f + movq $__per_cpu_load, %rax + addq $per_cpu__gdt_page, %rax + movq %rax, early_gdt_descr_base(%rip)
+#else
+#define PER_CPU_GDT_PAGE per_cpu__gdt_page
+#endif
+1: lgdt early_gdt_descr(%rip)
and:
+ * Setup up the real PDA.
+ *
+ * For SMP, the boot cpu (0) uses the static pda which is the first
+ * element in the percpu area (@__per_cpu_load). This pda is moved
+ * to the real percpu area once that is allocated. Secondary cpus
+ * will use the initial_pda value setup in do_boot_cpu().
*/
movl $MSR_GS_BASE,%ecx
- movq $empty_zero_page,%rax
+ movq initial_pda(%rip), %rax
movq %rax,%rdx
shrq $32,%rdx wrmsr
+#ifdef CONFIG_SMP
+ movq %rax, %gs:pda_data_offset
+#endif
+ ENTRY(initial_pda)
+#ifdef CONFIG_SMP
+ .quad __per_cpu_load # Overwritten for secondary CPUs
+#else
+ .quad per_cpu__pda
+#endif
Thanks!
Mike
Re: [crash, bisected] Re: [PATCH 3/4] x86_64: Fold pda into per cpu area
Quoted 13 lines · Mike Travis
Is this for the boot cpu (0), or for all cpus? For the boot cpu, I have this now in
arch/x86/kernel/setup_percpu.c:(quoted diff) +8
-0+#ifdef CONFIG_HAVE_ZERO_BASED_PER_CPU + +/* Initialize percpu offset for boot cpu (0) */ +unsigned long __per_cpu_offset[NR_CPUS] __read_mostly = { + [0] = (unsigned long)__per_cpu_load +}; +#else unsigned long __per_cpu_offset[NR_CPUS] __read_mostly; +#endif
Quoted 2 lines
So this should apply as well to the xen startup?
If it's just a static initialization, then it should be fine. But some equivalent of your head_64.S changes are needed to actually set things up?
Quoted 8 lines
Quoted 4 lines
xen_cpu_up()needs to do whatever initialization needed for a new cpu's percpu area (presumably whateverdo_boot_cpu()does).Does the startup include executing arch/x86/kernel/head_64.S:startup_64() ? I see arch/x86/xen/xen-head.S:startup_xen() so I'm guessing not?
No, it doesn't. It bypasses all that startup code. Aside from the few instructions in xen-head.S, xen_start_kernel() is the first thing to get run.
But when bringing up a secondary cpu, where does the new percpu memory actually get allocated?
Quoted 3 lines
For the real startup, I do the following two things. But I'm not comfortable enough with xen to think I'll get it right putting this in
xen-head.S.
Yes, it needn't be in the asm code. I'll work out what to do. Looks like I just need to do an appropriate wrmsr(MSR_GS_BASE, ).
J
Re: [crash, bisected] Re: [PATCH 3/4] x86_64: Fold pda into per cpu area
Ok, I'll just post what I have now (compiles and boots cleanly)... and then we can discuss these more extensively.
Thanks,
Mike
Quoted 47 lines · Jeremy Fitzhardinge
Quoted 13 lines · Mike Travis
Is this for the boot cpu (0), or for all cpus? For the boot cpu, I have this now in
arch/x86/kernel/setup_percpu.c:(quoted diff) +8
-0+#ifdef CONFIG_HAVE_ZERO_BASED_PER_CPU + +/* Initialize percpu offset for boot cpu (0) */ +unsigned long __per_cpu_offset[NR_CPUS] __read_mostly = { + [0] = (unsigned long)__per_cpu_load +}; +#else unsigned long __per_cpu_offset[NR_CPUS] __read_mostly; +#endifQuoted 2 lines
So this should apply as well to the xen startup?
If it's just a static initialization, then it should be fine. But some equivalent of your
head_64.Schanges are needed to actually set things up?Quoted 9 lines
Quoted 4 lines
xen_cpu_up()needs to do whatever initialization needed for a new cpu's percpu area (presumably whateverdo_boot_cpu()does).Does the startup include executing arch/x86/kernel/head_64.S:startup_64() ?
I see arch/x86/xen/xen-head.S:startup_xen() so I'm guessing not?No, it doesn't. It bypasses all that startup code. Aside from the few instructions in
xen-head.S,xen_start_kernel()is the first thing to get run.But when bringing up a secondary cpu, where does the new percpu memory actually get allocated?
Quoted 4 lines
For the real startup, I do the following two things. But I'm not comfortable
enough with xen to think I'll get it right putting this inxen-head.S.Yes, it needn't be in the asm code. I'll work out what to do. Looks like I just need to do an appropriate
wrmsr(MSR_GS_BASE, ).J
Re: [crash, bisected] Re: [PATCH 3/4] x86_64: Fold pda into per cpu area
In reply to Eric W. BiedermanQuoted 6 lines · Eric W. Biederman
Quoted 3 lines · Mike Travis
Unfortunately it's back to the problem of faulting before
x86_64_start_kernel()and grub just immediately reboots. So I'm back at analyzing assembler and config differences.
Quoted 8 lines
Ok. That is a narrow window of code. So it shouldn't be too bad, nasty though.
If you would like to trace through it I have attached my serial port debugging routines that I use in that part of the code.
Eric
Very cool, thanks!!! I will start using this. (I have been using the trick to replace printk with early_printk so messages come out immediately instead of from the log buf.)
I've been able to make some more progress. I've gotten to a point where it panics from stack overflow. I've verified this by bumping THREAD_ORDER and it boots fine. Now tracking down stack usages. (I have found a couple of new functions using set_cpus_allowed(..., CPU_MASK_ALL) instead of set_cpus_allowed_ptr(... , CPU_MASK_ALL_PTR). But these are not in the calling sequence so subsequently are not the cause.
One weird thing is early_idt_handler seems to have been called and that's one thing our simulator does not mimic for standard Intel FSB systems - early pending interrupts. (It's designed after all to mimic our h/w, and of course it's been booting fine under that environment.)
Two patches are in the queue to reduce this stack usage:
Subject: [PATCH 1/1] sched: Reduce stack size in isolated_cpu_setup()
Subject: [PATCH 1/1] kthread: Reduce stack pressure in create_kthread and kthreadd
The other stack pigs are:
1640 sched_domain_node_span
1576 tick_notify
1576 setup_IO_APIC_irq
1576 move_task_off_dead_cpu
1560 arch_setup_ht_irq
1560 __assign_irq_vector
1544 tick_handle_oneshot_broadcast
1352 zc0301_ioctl_v4l2
1336 i2o_cfg_compat_ioctl
1192 sn9c102_ioctl_v4l2
1176 __build_sched_domains
1152 e1000_check_options
1144 __build_all_zonelists
1128 setup_IO_APIC
1096 sched_balance_self
1096 _cpu_down
1080 do_ida_request
1064 sched_rt_period_timer
1064 native_smp_call_function_mask
1048 setup_timer_IRQ0_pin
1048 setup_ioapic_dest
1048 set_ioapic_affinity_irq
1048 set_ht_irq_affinity
1048 pci_device_probe
1048 native_machine_crash_shutdown
1032 tick_do_periodic_broadcast
1032 sched_setaffinity
1032 native_flush_tlb_others
1032 local_cpus_show
1032 local_cpulist_show
1032 irq_select_affinity
1032 irq_complete_move
1032 irq_affinity_write_proc
1032 ioapic_retrigger_irq
1032 flush_tlb_mm
1032 flush_tlb_current_task
1032 fixup_irqs
1032 do_cciss_request
1032 create_irq
1024 uv_vector_allocation_domain
1024 uv_send_IPI_allbutself
1024 smp_call_function_single
1024 smp_call_function
1024 physflat_send_IPI_allbutself
1024 pci_bus_show_cpuaffinity
1024 move_masked_irq
1024 flush_tlb_page
1024 flat_send_IPI_allbutself
1000 security_load_policy
Only a few of these though I would think might get called early in the boot, that might also be contributing to the stack overflow.
Oh yeah, I looked very closely at the differences in the assembler for vmlinux when compiled with 4.2.0 (fails) and 4.2.4 (which boots with the above mentioned THREAD_ORDER change) and except for some weirdness around ident_complete it seems to be the same code. But the per_cpu variables are in a completely different address order. I wouldn't think that the -j10 for make could cause this but I can verify that with -j1. But in any case, I'm sticking with 4.2.4 for now.
Thanks,
Mike
Re: [crash, bisected] Re: [PATCH 3/4] x86_64: Fold pda into per cpu area
Quoted 3 lines · Mike Travis
Very cool, thanks!!! I will start using this. (I have been using the trick to replace printk with
early_printkso messages come out immediately instead of from the log buf.)
Just passing early_printk=xxx on the command line should have that effect. Although I do admit you have to be a little bit into the boot before early_printk is setup.
Quoted 6 lines
I've been able to make some more progress. I've gotten to a point where it panics from stack overflow. I've verified this by bumping
THREAD_ORDERand it boots fine. Now tracking down stack usages. (I have found a couple of new functions usingset_cpus_allowed(..., CPU_MASK_ALL)instead of set_cpus_allowed_ptr(... ,CPU_MASK_ALL_PTR). But these are not in the calling sequence so subsequently are not the cause.
Is stack overflow the only problem you are seeing or are there still other mysteries?
Quoted 5 lines
One weird thing is
early_idt_handlerseems to have been called and that's one thing our simulator does not mimic for standard Intel FSB systems - early pending
interrupts. (It's designed after all to mimic our h/w, and of course it's been booting fine under that environment.)
That usually indicates you are taking an exception during boot not that you have received an external interrupt. Something like a page fault or a division by 0 error.
Quoted 2 lines
Only a few of these though I would think might get called early in the boot, that might also be contributing to the stack overflow.
Still the call chain depth shouldn't really be changing. So why should it matter? Ah. The high cpu count is growing cpumask_t so when you put it on the stack. That makes sense. So what stars out as a 4 byte variable on the stack in a normal setup winds up being a 1k variable with 4k cpus.
Quoted 8 lines
Oh yeah, I looked very closely at the differences in the assembler for vmlinux when compiled with 4.2.0 (fails) and 4.2.4 (which boots with the above mentioned
THREAD_ORDERchange) and except for some weirdness aroundident_completeit seems to be the same code. But theper_cpuvariables are in a completely different address order. I wouldn't think that the -j10 for make could cause this but I can verify that with -j1. But in any case, I'm sticking with 4.2.4 for now.
Reasonable. The practical problem is you are mixing a lot of changes simultaneously and it confuses things. Compiling with NR_CPUS=4096 and working out the bugs from a growing cpumask_t, putting the per cpu area in a zero based segment, and putting putting the pda into the per cpu area all at the same time.
Who knows maybe the only difference between 4.2.0 and 4.2.4 is that 4.2.4 optimizes it's stack usage a little better and you don't see a stack overflow.
It would be very very good if we could separate out these issues especially the segment for the per cpu variables. We need something like that.
Eric
Re: [crash, bisected] Re: [PATCH 3/4] x86_64: Fold pda into per cpu area
Quoted 2 lines · Eric W. Biederman
Mike Travis <[email protected]> writes:
... (I have been using the trick
Quoted 6 lines
Quoted 2 lines
to replace printk with
early_printkso messages come out immediately instead of from the log buf.)Just passing early_printk=xxx on the command line should have that effect. Although I do admit you have to be a little bit into the boot before
early_printkis setup.
What I meant was using early_printk in place of printk, which seems to stuff the messages into the log buf until the serial console is setup fairly late in start_kernel. I did this by removing printk() and renaming early_printk() to be printk (and a couple other things like #define early_printk printk ...
Quoted 9 lines
Quoted 7 lines
I've been able to make some more progress. I've gotten to a point where it panics from stack overflow. I've verified this by bumping
THREAD_ORDERand it boots fine. Now tracking down stack usages. (I have found a couple of new functions usingset_cpus_allowed(..., CPU_MASK_ALL)instead of set_cpus_allowed_ptr(... ,CPU_MASK_ALL_PTR). But these are not in the calling sequence so subsequently are not the cause.Is stack overflow the only problem you are seeing or are there still other mysteries?
I'm not entirely sure it's a stack overflow, the fault has a NULL dereference and then the stack overflow message.
Quoted 10 lines
Quoted 6 lines
One weird thing is
early_idt_handlerseems to have been called and that's one thing our simulator does not mimic for standard Intel FSB systems - early pending
interrupts. (It's designed after all to mimic our h/w, and of course it's been booting fine under that environment.)That usually indicates you are taking an exception during boot not that you have received an external interrupt. Something like a page fault or a division by 0 error.
I was thinking maybe an RTC interrupt? But a fault does sound more likely.
Quoted 9 lines
Quoted 3 lines
Only a few of these though I would think might get called early in the boot, that might also be contributing to the stack overflow.
Still the call chain depth shouldn't really be changing. So why should it matter? Ah. The high cpu count is growing
cpumask_tso when you put it on the stack. That makes sense. So what stars out as a 4 byte variable on the stack in a normal setup winds up being a 1k variable with 4k cpus.
Yes, it's definitely the three related:
NR_CPUS Patch_Applied THREAD_ORDER Results
256 NO 1 works (obviously ;-) 256 YES 1 works 4096 NO 1 works 4096 YES 1 panics 4096 YES 3 works (just happened to pick 3,
2 probably will work as well.)
Quoted 5 lines
Reasonable. The practical problem is you are mixing a lot of changes simultaneously and it confuses things. Compiling with NR_CPUS=4096 and working out the bugs from a growing
cpumask_t, putting the per cpu area in a zero based segment, and putting putting the pda into the per cpu area all at the same time.
I've been testing NR_CPUS=4096 for quite a while and it's been very reliable. It's just weird that this config fails with this new patch applied. (default configs and some fairly normal distro configs also work fine.) And with the zillion config straws we now have, spotting the arbitrary needle is proving difficult. ;-)
Quoted 3 lines
Who knows maybe the only difference between 4.2.0 and 4.2.4 is that 4.2.4 optimizes it's stack usage a little better and you don't see a stack overflow.
I haven't tried the THREAD_ORDER=3 (or 2) under 4.2.0, but that would seem to indicate this may be true.
Quoted 3 lines
It would be very very good if we could separate out these issues especially the segment for the per cpu variables. We need something like that.
One reason I've been sticking with 4.2.4.
Thanks again for your help.
Mike
Re: [crash, bisected] Re: [PATCH 3/4] x86_64: Fold pda into per cpu area
Quoted 6 lines · Mike Travis
What I meant was using
early_printkin place of printk, which seems to stuff the messages into the log buf until the serial console is setup fairly late instart_kernel.
I did this by removingprintk()and renamingearly_printk()to be printk (and a couple
other things like #defineearly_printkprintk ...
Last I looked after the magic early_printk setup. printk calls early_printk and stuff messages in the log buffer.
It matters little though. As long as you get the print messages. Weird cases where you don't get into C code worry me much more.
Once you get into C things are much easier to track.
Quoted 6 lines
Quoted 1 line
Is stack overflow the only problem you are seeing or are there still other
mysteries?
I'm not entirely sure it's a stack overflow, the fault has a NULL dereference and
then the stack overflow message.
Ok. Interesting.
Quoted 17 lines
Quoted 8 lines
Quoted 2 lines
Only a few of these though I would think might get called early in the boot, that might also be contributing to the stack overflow.
Still the call chain depth shouldn't really be changing. So why should it matter? Ah. The high cpu count is growing
cpumask_tso when you put it on the stack. That makes sense. So what stars out as a 4 byte variable on the stack in a normal setup winds up being a 1k variable with 4k cpus.Yes, it's definitely the three related:
NR_CPUSPatch_AppliedTHREAD_ORDERResults256 NO 1 works (obviously ;-) 256 YES 1 works 4096 NO 1 works 4096 YES 1 panics 4096 YES 3 works (just happened to pick 3,
Quoted 7 lines
2 probably will work as well.)
I've been testing NR_CPUS=4096 for quite a while and it's been very reliable. It's just weird that this config fails with this new patch applied. (default configs and some fairly normal distro configs also work fine.) And with the zillion config straws we now have, spotting the arbitrary needle is proving difficult. ;-)
Right. Just please split your patch up. It would be good to see if simply changing the per cpu segment address to 0 is related to your problem. Or if it the other logic changes necessary to put the use the pda as a per cpu variable?
I just noticed that we always allocate the pda in the per cpu section.
Quoted 1 line
One reason I've been sticking with 4.2.4.
Eric
H. Peter Anvin
reviewerRe: [crash, bisected] Re: [PATCH 3/4] x86_64: Fold pda into per cpu area
In reply to Eric W. BiedermanQuoted 6 lines · Eric W. Biederman
For i386 since virtual address space is precious and because there were concerns about putting code in
__pawe actually relocate the kernel symbols during load right after decompression. When we do relocations absolute symbols are a killer.
Well, it means making it clear to the relocator if it should relocate those symbols or not. Since IIRC we're doing "all or nothing" relocation, the relative offsets are always the same, even between sections.
-hpa
Re: [crash, bisected] Re: [PATCH 3/4] x86_64: Fold pda into per cpu area
Quoted 11 lines · H. Peter Anvin
Quoted 6 lines · Eric W. Biederman
For i386 since virtual address space is precious and because there were concerns about putting code in
__pawe actually relocate the kernel symbols during load right after decompression. When we do relocations absolute symbols are a killer.Well, it means making it clear to the relocator if it should relocate those symbols or not. Since IIRC we're doing "all or nothing" relocation, the relative offsets are always the same, even between sections.
Yes the relative offsets stay the same. I don't remember if ld generates useable relocations for what it figures are absolute symbols. I remember the solution was that anything that we wanted to relocate we would make section relative, and anything else we would leave absolute, and that those were easy things to do.
The nasty case is that occasionally ld has a bug where it turns section relative symbols into global symbols if there is a section without data. I don't recall us caring in those instances.
While interesting. All of this is irrelevant until we start talking unification between x86_63 and x86_64 as only x86_32 has this restriction.
Eric
Re: [crash, bisected] Re: [PATCH 3/4] x86_64: Fold pda into per cpu area
In reply to Eric W. BiedermanQuoted 2 lines · [email protected] (Eric W. Biederman) writes:
Has anyone investigated using the technique gcc uses for thread local storage?
I investigated a long time ago (given when the binutils/gcc support was much more primitive) and my conclusion back then was that doing the same for kernel module (negative addresses) would need new relocation types. And the pain of a binutils change didn't seem worth it.
-Andi
Re: [crash, bisected] Re: [PATCH 3/4] x86_64: Fold pda into per cpu area
Quoted 9 lines · Andi Kleen
Quoted 2 lines · [email protected] (Eric W. Biederman) writes:
Has anyone investigated using the technique gcc uses for thread local storage?
I investigated a long time ago (given when the binutils/gcc support was much more primitive) and my conclusion back then was that doing the same for kernel module (negative addresses) would need new relocation types. And the pain of a binutils change didn't seem worth it.
Thanks. That does seem to be the fly in the ointment of using the builtin linker support. The kernel lives at negative addresses which is necessary but weird.
If the @tpoff relocation doesn't work for us we clearly can't use the support. I will have to look and see if usable relocation types are generated from @tpoff.
Eric
Re: [crash, bisected] Re: [PATCH 3/4] x86_64: Fold pda into per cpu area
In reply to H. Peter AnvinQuoted 5 lines · H. Peter Anvin
Quoted 3 lines · Eric W. Biederman
Quoted 3 lines
The zero-based PDA mechanism requires the introduction of a new ELF segment based at vaddr 0 which is sufficiently unusual that it wouldn't surprise me
if
Quoted 8 lines
Quoted 5 lines
Quoted 1 line
its triggering some toolchain bug.
Agreed. Given the previous description my hunch is that the bug is occurring during objcopy. If vmlinux is good and the compressed kernel is bad.
Actually, it's not all that unusual... it's pretty common in various restricted environments. That being said, it's probably uncommon for *64-bit* code.
It is a sensible thing to expect to work. By unusual I mean it isn't triggered by normal userspace code. In general I find that ld features if they aren't used in userspace and they aren't used in the kernel don't work reliably across versions.
Eric
Re: [crash, bisected] Re: [PATCH 3/4] x86_64: Fold pda into per cpu area
In reply to Jeremy FitzhardingeQuoted 104 lines · Jeremy Fitzhardinge
Quoted 86 lines · Eric W. Biederman
Quoted 70 lines · Mike Travis
Quoted 11 lines · H. Peter Anvin
Quoted 5 lines · Mike Travis
FYI, I did try this out and it caused the bootloader to scramble the loaded data. The first corruption I found was the .x86cpuvendor.init section contained all zeroes.
Explain what you mean with "the bootloader" in this context.
-hpa
After the code was loaded (the compressed code, it seems that my GRUB doesn't support uncompressed loading), the above section contained zeroes. I snapped it fairly early, around
secondary_startup_64, and then printed it inx86_64_start_kernel.The object file had the correct data (as displayed by objdump) so I'm assuming that the bootloading process didn't load the section correctly.
Below was the linker script I used:
include/asm-generic/vmlinux.lds.h +1
-2@@ -373,9 +373,13 @@#ifdef CONFIG_HAVE_ZERO_BASED_PER_CPU #define PERCPU (align) \ - . = ALIGN(align); \ + .data.percpu.abs = .; \ percpu : { } :percpu \ - __per_cpu_load =.; \
+ .data.percpu.rel :AT(.data.percpu.abs - LOAD_OFFSET)
{ \
+
BYTE(0) \
+ . =
ALIGN(align); \
+__per_cpu_load=
.; \
+
} \
.data.percpu 0 :AT(__per_cpu_load - LOAD_OFFSET)
{ \*(.data.percpu.first) \
*(.data.percpu.shared_aligned) \
include/asm-generic/vmlinux.lds.h +2
-2@@ -383,8 +387,8 @@ *(.data.percpu.page_aligned) \ ____per_cpu_size = .; \ } \ - . = __per_cpu_load + ____per_cpu_size; \ - data : { } :data + . = __per_cpu_load + ____per_cpu_size; +#else #definePERCPU(align) \ . =Quoted 9 lines
ALIGN(align); \
It showed all the correct address in the map and
__per_cpu_loadwas a relative symbol (which was the objective.)Btw, our simulator, which only loads uncompressed code, had the data correct,
so it *may* only be a result of the code being compressed.Weird. Grub doesn't get involved in the decompression the kernel does it all itself so we should be able to track where things go bad.
Quoted 6 lines
Last I looked the compressed code was formed by essentially. objcopy vmlinux -O binary vmlinux.bin
gzip vmlinux.bin
And then we take on a magic header to the gzip compressed file.Are things only bad with the change above?
No, the original crash being discussed was a GP fault in
head_64.Sas it tries to initialize the kernel segments. The cause was that the prototype GDT is all zero, even though it's an initialized variable, and inspection of vmlinux shows that it has the right contents. But somehow it's either 1) getting zeroed on load, or 2) is loaded to the wrong place.The zero-based PDA mechanism requires the introduction of a new ELF segment based at vaddr 0 which is sufficiently unusual that it wouldn't surprise me if its triggering some toolchain bug.
Quoted 6 lines
Mike: what would happen if the PDA were based at 4k rather than 0? The stack canary would still be at its small offset (
0x20?), but it doesn't need to be initialized. I'm not sure if doing so would fix anything, however.J
I don't know that the basing at 0 or 4k would matter. I'll post the patch in it's current form (as an RFC?) to show what was needed to initialize the pda and gdt page pointer.
Thanks,
Mike
Re: [crash, bisected] Re: [PATCH 3/4] x86_64: Fold pda into per cpu area
In reply to Eric W. BiedermanQuoted 61 lines · Eric W. Biederman
Quoted 50 lines · Mike Travis
Quoted 8 lines · H. Peter Anvin
Quoted 4 lines · Mike Travis
FYI, I did try this out and it caused the bootloader to scramble the loaded data. The first corruption I found was the .x86cpuvendor.init section contained all zeroes.
Explain what you mean with "the bootloader" in this context.
-hpa
After the code was loaded (the compressed code, it seems that my GRUB doesn't support uncompressed loading), the above section contained zeroes. I snapped it fairly early, around
secondary_startup_64, and then printed it inx86_64_start_kernel.The object file had the correct data (as displayed by objdump) so I'm assuming that the bootloading process didn't load the section correctly.
Below was the linker script I used:
include/asm-generic/vmlinux.lds.h +8
-4@@ -373,9 +373,13 @@#ifdef CONFIG_HAVE_ZERO_BASED_PER_CPU #define PERCPU (align) \ - . = ALIGN(align); \ + .data.percpu.abs = .; \ percpu : { } :percpu \ - __per_cpu_load = .; \ + .data.percpu.rel : AT(.data.percpu.abs - LOAD_OFFSET) { \ + BYTE(0) \ + . = ALIGN(align); \ + __per_cpu_load = .; \ + } \ .data.percpu 0 : AT(__per_cpu_load - LOAD_OFFSET) { \ *(.data.percpu.first) \ *(.data.percpu.shared_aligned) \@@ -383,8 +387,8 @@ *(.data.percpu.page_aligned) \ ____per_cpu_size = .; \ } \ - . = __per_cpu_load + ____per_cpu_size; \ - data : { } :data + . = __per_cpu_load + ____per_cpu_size; +#else #define PERCPU (align) \ . = ALIGN(align); \Quoted 5 lines
It showed all the correct address in the map and
__per_cpu_loadwas a relative symbol (which was the objective.)Btw, our simulator, which only loads uncompressed code, had the data correct, so it *may* only be a result of the code being compressed.
Weird. Grub doesn't get involved in the decompression the kernel does it all itself so we should be able to track where things go bad.
Quoted 8 lines
Last I looked the compressed code was formed by essentially. objcopy vmlinux -O binary vmlinux.bin
gzip vmlinux.bin
And then we take on a magic header to the gzip compressed file.Are things only bad with the change above?
Eric
Yes. The failure was "Unsupported CPU" (or some such) which clued me into the vendor section.
I was able to get the zero-based variables working well for standard configs. It's getting tripped up now by some of Ingo's random configs, in very unusual places... And once again, it only fails on real h/w, not on our simulator, so catching the elusive bugger is tricky.
Thanks,
Mike
Re: [crash, bisected] Re: [PATCH 3/4] x86_64: Fold pda into per cpu area
In reply to Mike TravisQuoted 26 lines · Mike Travis
Quoted 2 lines · Eric W. Biederman
Mike Travis <[email protected]> writes:
...
Quoted 20 lines
Quoted 2 lines
Can we generate a new symbol which would account for
LOAD_OFFSET?Ouch. Absolute symbols indeed. On the 32bit kernel that may play havoc with the relocatable kernel, although we have had similar absolute logic for the last year. With
__per_cpu_startand__per_cpu_endso it may not be a problem.To initialize the percpu data you do want to talk to the virtual address at
__per_coup_load. But it is absolute Ugh.It might be worth saying something like.
.data.percpu.start : AT(.data.percpu.dummy - LOAD_OFFSET) { DATA(0) . = ALIGN(align); __per_cpu_load = . ; }To make
__per_cpu_loada relative symbol. ld has a bad habit of taking symbols out of empty sections and making them absolute. Which is why I added the DATA(0).
Quoted 8 lines
Quoted 4 lines
Still I don't think that would be the 64bit problem.
Eric
FYI, I did try this out and it caused the bootloader to scramble the loaded data. The first corruption I found was the .x86cpuvendor.init section contained all zeroes.
Well, that's what appeared to be happening with the pre-initialized GDT as well, so I'm not sure that's a new symptom.
J
PATCH 4/4 x86: Replace xxx_pda() operations with x86_xx_percpu().
In reply to Mike Travis* It is now possible to use percpu operations for pda access since the pda is in the percpu area. Drop the pda operations.
Based on linux-2.6.tip
--- arch/x86/kernel/apic_64.c | 4 - arch/x86/kernel/cpu/mcheck/mce_amd_64.c | 2 arch/x86/kernel/cpu/mcheck/mce_intel_64.c | 2 arch/x86/kernel/nmi.c | 5 + arch/x86/kernel/process_64.c | 12 ++-- arch/x86/kernel/smp.c | 4 - arch/x86/kernel/time_64.c | 2 arch/x86/kernel/tlb_64.c | 12 ++-- arch/x86/kernel/traps_64.c | 2 arch/x86/kernel/x8664_ksyms_64.c | 2 arch/x86/xen/smp.c | 2 include/asm-x86/current.h | 3 - include/asm-x86/hardirq_64.h | 6 +- include/asm-x86/mmu_context_64.h | 12 ++-- include/asm-x86/pda.h | 80 ++---------------------------- include/asm-x86/smp.h | 2 include/asm-x86/stackprotector.h | 2 include/asm-x86/thread_info.h | 3 - include/asm-x86/topology.h | 2 19 files changed, 47 insertions(+), 112 deletions(-)
arch/x86/kernel/apic_64.c +2 -2
@@ -481,7 +481,7 @@ static void local_apic_timer_interrupt(v/* * the NMI deadlock-detector uses this. */ -add_pda (apic_timer_irqs,1 ); +x86_inc_percpu (pda.apic_timer_irqs); evt->event_handler (evt); }
@@ -986,7 +986,7 @@ asmlinkage void smp_spurious_interrupt(vif (v & (1 << (SPURIOUS_APIC_VECTOR &0x1f )))ack_APIC_irq (); -add_pda (irq_spurious_count,1 ); +x86_inc_percpu (pda.irq_spurious_count);irq_exit (); }
arch/x86/kernel/cpu/mcheck/mce_amd_64.c +1 -1
@@ -237,7 +237,7 @@ asmlinkage void mce_threshold_interrupt( } } out: -add_pda (irq_threshold_count,1 ); +x86_inc_percpu (pda.irq_threshold_count);irq_exit (); }
arch/x86/kernel/cpu/mcheck/mce_intel_64.c +1 -1
@@ -26,7 +26,7 @@ asmlinkage void smp_thermal_interrupt(voif (therm_throt_process (msr_val &1 ))mce_log_therm_throt_event (smp_processor_id (), msr_val); -add_pda (irq_thermal_count,1 ); +x86_inc_percpu (pda.irq_thermal_count);irq_exit (); }
arch/x86/kernel/nmi.c +3 -2
@@ -56,7 +56,7 @@ static int endflag __initdata = 0;static inline unsigned int get_nmi_count (int cpu) {#ifdef CONFIG_X86_64 -return cpu_pda (cpu)->__nmi_count; +return x86_read_percpu (pda.__nmi_count);#else return nmi_count (cpu);#endif
@@ -77,7 +77,8 @@ static inline int mce_in_progress(void)static inline unsigned int get_timer_irqs (int cpu) {#ifdef CONFIG_X86_64 -return read_pda (apic_timer_irqs) +read_pda (irq0_irqs); +return x86_read_percpu (pda.apic_timer_irqs) + +x86_read_percpu (pda.irq0_irqs);#else return per_cpu (irq_stat, cpu).apic_timer_irqs +per_cpu (irq_stat, cpu).irq0_irqs;
arch/x86/kernel/process_64.c +6 -6
@@ -75,7 +75,7 @@ void idle_notifier_register(struct notifvoid enter_idle (void ) { -write_pda (isidle,1 ); +x86_write_percpu (pda.isidle,1 );atomic_notifier_call_chain (&idle_notifier,IDLE_START ,NULL ); }
@@ -438,7 +438,7 @@ start_thread(struct pt_regs *regs, unsigload_gs_index (0 ); regs->ip = new_ip; regs->sp = new_sp; -write_pda (oldrsp, new_sp); +x86_write_percpu (pda.oldrsp, new_sp); regs->cs = __USER_CS; regs->ss = __USER_DS; regs->flags =0x200 ;
@@ -674,11 +674,11 @@ __switch_to(struct task_struct *prev_p,/* * Switch the PDA and FPU contexts. */ - prev->usersp =read_pda (oldrsp); -write_pda (oldrsp, next->usersp); -write_pda (pcurrent, next_p); + prev->usersp =x86_read_percpu (pda.oldrsp); +x86_write_percpu (pda.oldrsp, next->usersp); +x86_write_percpu (pda.pcurrent, next_p); -write_pda (kernelstack, +x86_write_percpu (pda.kernelstack, (unsigned long )task_stack_page (next_p) +THREAD_SIZE -PDA_STACKOFFSET );#ifdef CONFIG_CC_STACKPROTECTOR /*
arch/x86/kernel/smp.c +2 -2
@@ -295,7 +295,7 @@ void smp_reschedule_interrupt(struct pt_#ifdef CONFIG_X86_32 __get_cpu_var (irq_stat).irq_resched_count++;#else -add_pda (irq_resched_count,1 ); +x86_inc_percpu (pda.irq_resched_count);#endif }
@@ -320,7 +320,7 @@ void smp_call_function_interrupt(struct#ifdef CONFIG_X86_32 __get_cpu_var (irq_stat).irq_call_count++;#else -add_pda (irq_call_count,1 ); +x86_inc_percpu (pda.irq_call_count);#endif irq_exit ();
arch/x86/kernel/time_64.c +1 -1
@@ -46,7 +46,7 @@ EXPORT_SYMBOL(profile_pc);static irqreturn_t timer_event_interrupt (int irq,void *dev_id) { -add_pda (irq0_irqs,1 ); +x86_inc_percpu (pda.irq0_irqs); global_clock_event->event_handler (global_clock_event);
arch/x86/kernel/tlb_64.c +6 -6
@@ -60,9 +60,9 @@ static DEFINE_PER_CPU(union smp_flush_st*/ void leave_mm (int cpu) { -if (read_pda (mmu_state) ==TLBSTATE_OK ) +if (x86_read_percpu (pda.mmu_state) ==TLBSTATE_OK )BUG (); -cpu_clear (cpu,read_pda (active_mm)->cpu_vm_mask); +cpu_clear (cpu,x86_read_percpu (pda.active_mm)->cpu_vm_mask);load_cr3 (swapper_pg_dir); }EXPORT_SYMBOL_GPL (leave_mm);
@@ -140,8 +140,8 @@ asmlinkage void smp_invalidate_interrupt* BUG(); */ -if (f->flush_mm ==read_pda (active_mm)) { -if (read_pda (mmu_state) ==TLBSTATE_OK ) { +if (f->flush_mm ==x86_read_percpu (pda.active_mm)) { +if (x86_read_percpu (pda.mmu_state) ==TLBSTATE_OK ) {if (f->flush_va ==TLB_FLUSH_ALL )local_flush_tlb ();else
@@ -152,7 +152,7 @@ asmlinkage void smp_invalidate_interrupt out:ack_APIC_irq ();cpu_clear (cpu, f->flush_cpumask); -add_pda (irq_tlb_count,1 ); +x86_inc_percpu (pda.irq_tlb_count); } void native_flush_tlb_others(const cpumask_t *cpumaskp, struct mm_struct *mm,
@@ -264,7 +264,7 @@ static void do_flush_tlb_all(void *info)unsigned long cpu =smp_processor_id ();__flush_tlb_all (); -if (read_pda (mmu_state) ==TLBSTATE_LAZY ) +if (x86_read_percpu (pda.mmu_state) ==TLBSTATE_LAZY )leave_mm (cpu); }
arch/x86/kernel/traps_64.c +1 -1
@@ -878,7 +878,7 @@ asmlinkage notrace __kprobes void do_nmi(struct pt_regs *regs, long error_code) {nmi_enter (); -add_pda (__nmi_count,1 ); +x86_inc_percpu (pda.__nmi_count);if (!ignore_nmis)default_do_nmi (regs);nmi_exit ();
arch/x86/kernel/x8664_ksyms_64.c +0 -2
@@ -59,8 +59,6 @@ EXPORT_SYMBOL(empty_zero_page);EXPORT_SYMBOL (init_level4_pgt);EXPORT_SYMBOL (load_gs_index); -EXPORT_SYMBOL (_proxy_pda); -#ifdef CONFIG_PARAVIRT /* Virtualized guests may want to use it */ EXPORT_SYMBOL_GPL (cpu_gdt_descr);
arch/x86/xen/smp.c +1 -1
@@ -68,7 +68,7 @@ static irqreturn_t xen_reschedule_interr#ifdef CONFIG_X86_32 __get_cpu_var (irq_stat).irq_resched_count++;#else -add_pda (irq_resched_count,1 ); +x86_inc_percpu (pda.irq_resched_count);#endif return IRQ_HANDLED ;
include/asm-x86/current.h +2 -1
@@ -17,12 +17,13 @@ static __always_inline struct task_struc#ifndef __ASSEMBLY__#include <asm/pda.h> +#include <asm/percpu.h> struct task_struct ; static __always_inline struct task_struct *get_current(void) { -return read_pda (pcurrent); +return x86_read_percpu (pda.pcurrent); }#else /* __ASSEMBLY__ */
include/asm-x86/hardirq_64.h +3 -3
@@ -11,12 +11,12 @@#define __ARCH_IRQ_STAT 1 -#define local_softirq_pending () read_pda(__softirq_pending) +#define local_softirq_pending () x86_read_percpu(pda.__softirq_pending)#define __ARCH_SET_SOFTIRQ_PENDING 1 -#define set_softirq_pending (x) write_pda(__softirq_pending, (x)) -#define or_softirq_pending (x) or_pda(__softirq_pending, (x)) +#define set_softirq_pending (x) x86_write_percpu(pda.__softirq_pending, (x)) +#define or_softirq_pending (x) x86_or_percpu(pda.__softirq_pending, (x))extern void ack_bad_irq (unsigned int irq);
include/asm-x86/mmu_context_64.h +6 -6
@@ -20,8 +20,8 @@ void destroy_context(struct mm_struct *mstatic inline void enter_lazy_tlb (struct mm_struct *mm,struct task_struct *tsk) {#ifdef CONFIG_SMP -if (read_pda (mmu_state) ==TLBSTATE_OK ) -write_pda (mmu_state,TLBSTATE_LAZY ); +if (x86_read_percpu (pda.mmu_state) ==TLBSTATE_OK ) +x86_write_percpu (pda.mmu_state,TLBSTATE_LAZY );#endif }
@@ -33,8 +33,8 @@ static inline void switch_mm(struct mm_s/* stop flush ipis for the previous mm */ cpu_clear (cpu, prev->cpu_vm_mask);#ifdef CONFIG_SMP -write_pda (mmu_state,TLBSTATE_OK ); -write_pda (active_mm, next); +x86_write_percpu (pda.mmu_state,TLBSTATE_OK ); +x86_write_percpu (pda.active_mm, next);#endif cpu_set (cpu, next->cpu_vm_mask);load_cr3 (next->pgd);
@@ -44,8 +44,8 @@ static inline void switch_mm(struct mm_s }#ifdef CONFIG_SMP else { -write_pda (mmu_state,TLBSTATE_OK ); -if (read_pda (active_mm) != next) +x86_write_percpu (pda.mmu_state,TLBSTATE_OK ); +if (x86_read_percpu (pda.active_mm) != next)BUG ();if (!cpu_test_and_set (cpu, next->cpu_vm_mask)) {/* We were in lazy tlb mode and leave_mm disabled
include/asm-x86/pda.h +7 -73
106 lines not on this page · raw message
include/asm-x86/smp.h +1 -1
@@ -134,7 +134,7 @@ DECLARE_PER_CPU(int, cpu_number);extern int safe_smp_processor_id (void );#elif defined(CONFIG_X86_64_SMP ) -#define raw_smp_processor_id () read_pda(cpunumber) +#define raw_smp_processor_id () x86_read_percpu(pda.cpunumber)#define stack_smp_processor_id () \ ({ \
include/asm-x86/stackprotector.h +1 -1
@@ -32,7 +32,7 @@ static __always_inline void boot_init_st canary += tsc + (tsc <<32UL ); current->stack_canary = canary; - write_pda(stack_canary, canary); + x86_write_percpu(pda.stack_canary, canary); }#endif
include/asm-x86/thread_info.h +2 -1
@@ -200,7 +200,8 @@ static inline struct thread_info *currenstatic inline struct thread_info *current_thread_info (void ) {struct thread_info *ti; - ti = (void *)(read_pda (kernelstack) +PDA_STACKOFFSET -THREAD_SIZE ); + ti = (void *)(x86_read_percpu (pda.kernelstack) + +PDA_STACKOFFSET -THREAD_SIZE );return ti; }
include/asm-x86/topology.h +1 -1
@@ -72,7 +72,7 @@ extern cpumask_t *node_to_cpumask_map;DECLARE_EARLY_PER_CPU (int, x86_cpu_to_node_map);/* Returns the number of the current Node. */ -#define numa_node_id () read_pda(nodenumber) +#define numa_node_id () x86_read_percpu(pda.nodenumber)#ifdef CONFIG_DEBUG_PER_CPU_MAPS extern int cpu_to_node (int cpu);
Re: [PATCH 4/4] x86: Replace xxx_pda() operations with x86_xx_percpu().
Quoted 2 lines · Mike Travis
* It is now possible to use percpu operations for pda access since the pda is in the percpu area. Drop the pda operations.
FYI, this one didnt build with the attached config.
Ingo
#
# Automatically generated make config: don't edit # Linux kernel version: 2.6.26-rc5
# Mon Jun 9 14:59:39 2008
#CONFIG_64BIT=y
# CONFIG_X86_32 is not setCONFIG_X86_64=yCONFIG_X86=y CONFIG_ARCH_DEFCONFIG="arch/x86/configs/x86_64_defconfig" # CONFIG_GENERIC_LOCKBREAK is not set CONFIG_GENERIC_TIME=yCONFIG_GENERIC_CMOS_UPDATE=y CONFIG_CLOCKSOURCE_WATCHDOG=y CONFIG_GENERIC_CLOCKEVENTS=y CONFIG_GENERIC_CLOCKEVENTS_BROADCAST=y CONFIG_LOCKDEP_SUPPORT=y CONFIG_STACKTRACE_SUPPORT=y CONFIG_HAVE_LATENCYTOP_SUPPORT=y CONFIG_FAST_CMPXCHG_LOCAL=yCONFIG_MMU=yCONFIG_ZONE_DMA=yCONFIG_GENERIC_ISA_DMA=yCONFIG_GENERIC_IOMAP=yCONFIG_GENERIC_HWEIGHT=y
# CONFIG_GENERIC_GPIO is not set CONFIG_ARCH_MAY_HAVE_PC_FDC=y CONFIG_RWSEM_GENERIC_SPINLOCK=y
# CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
# CONFIG_ARCH_HAS_ILOG2_U32 is not set
# CONFIG_ARCH_HAS_ILOG2_U64 is not set CONFIG_ARCH_HAS_CPU_IDLE_WAIT=y CONFIG_GENERIC_CALIBRATE_DELAY=y CONFIG_GENERIC_TIME_VSYSCALL=y CONFIG_ARCH_HAS_CPU_RELAX=y CONFIG_ARCH_HAS_CACHE_LINE_SIZE=y CONFIG_HAVE_SETUP_PER_CPU_AREA=y CONFIG_HAVE_CPUMASK_OF_CPU_MAP=y CONFIG_ARCH_HIBERNATION_POSSIBLE=y CONFIG_ARCH_SUSPEND_POSSIBLE=yCONFIG_ZONE_DMA32=y CONFIG_ARCH_POPULATES_NODE_MAP=y CONFIG_AUDIT_ARCH=yCONFIG_ARCH_SUPPORTS_AOUT=y CONFIG_ARCH_SUPPORTS_OPTIMIZED_INLINING=y CONFIG_GENERIC_HARDIRQS=y CONFIG_GENERIC_IRQ_PROBE=y CONFIG_GENERIC_PENDING_IRQ=yCONFIG_X86_SMP=yCONFIG_X86_64_SMP=yCONFIG_X86_HT=yCONFIG_X86_BIOS_REBOOT=yCONFIG_X86_TRAMPOLINE=y
# CONFIG_KTIME_SCALAR is not set
# CONFIG_BOOTPARAM_SUPPORT_WANTED is not set CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
#
# General setup
#CONFIG_EXPERIMENTAL=yCONFIG_BROKEN_BOOT_ALLOWED3=yCONFIG_BROKEN_BOOT_ALLOWED2=yCONFIG_BROKEN_BOOT_ALLOWED=yCONFIG_BROKEN_BOOT=yCONFIG_BROKEN_BOOT_EUROPE=yCONFIG_BROKEN_BOOT_TITAN=yCONFIG_LOCK_KERNEL=yCONFIG_INIT_ENV_ARG_LIMIT=32CONFIG_LOCALVERSION=""
# CONFIG_LOCALVERSION_AUTO is not set
# CONFIG_SWAP is not set
# CONFIG_SYSVIPC is not set
# CONFIG_POSIX_MQUEUE is not setCONFIG_BSD_PROCESS_ACCT=y
# CONFIG_BSD_PROCESS_ACCT_V3 is not set
# CONFIG_TASKSTATS is not set
# CONFIG_AUDIT is not set
# CONFIG_IKCONFIG is not setCONFIG_LOG_BUF_SHIFT=20CONFIG_CGROUPS=yCONFIG_CGROUP_DEBUG=y
# CONFIG_CGROUP_NS is not setCONFIG_CGROUP_DEVICE=y
# CONFIG_CPUSETS is not setCONFIG_HAVE_UNSTABLE_SCHED_CLOCK=y
# CONFIG_GROUP_SCHED is not set
# CONFIG_CGROUP_CPUACCT is not setCONFIG_RESOURCE_COUNTERS=y
# CONFIG_CGROUP_MEM_RES_CTLR is not setCONFIG_RELAY=y
# CONFIG_NAMESPACES is not set
# CONFIG_BLK_DEV_INITRD is not set
# CONFIG_CC_OPTIMIZE_FOR_SIZE is not setCONFIG_EMBEDDED=y
# CONFIG_UID16 is not set
# CONFIG_SYSCTL_SYSCALL is not setCONFIG_KALLSYMS=yCONFIG_KALLSYMS_ALL=y
# CONFIG_KALLSYMS_EXTRA_PASS is not set
# CONFIG_HOTPLUG is not set
# CONFIG_PRINTK is not set
# CONFIG_BUG is not setCONFIG_ELF_CORE=yCONFIG_PCSPKR_PLATFORM=yCONFIG_COMPAT_BRK=yCONFIG_BASE_FULL=y
# CONFIG_FUTEX is not setCONFIG_ANON_INODES=y
# CONFIG_EPOLL is not setCONFIG_SIGNALFD=yCONFIG_TIMERFD=yCONFIG_EVENTFD=yCONFIG_SHMEM=y
# CONFIG_VM_EVENT_COUNTERS is not set
# CONFIG_SLAB is not setCONFIG_SLUB=y
# CONFIG_SLOB is not set
# CONFIG_PROFILING is not setCONFIG_MARKERS=yCONFIG_HAVE_OPROFILE=yCONFIG_HAVE_KPROBES=yCONFIG_HAVE_KRETPROBES=y
# CONFIG_HAVE_DMA_ATTRS is not setCONFIG_HAVE_IMMEDIATE=y
# CONFIG_IMMEDIATE is not set
# CONFIG_TINY_SHMEM is not setCONFIG_BASE_SMALL=0
# CONFIG_MODULES is not setCONFIG_BLOCK=y
# CONFIG_BLK_DEV_BSG is not setCONFIG_BLOCK_COMPAT=y
#
# IO Schedulers
#CONFIG_IOSCHED_NOOP=y
# CONFIG_IOSCHED_AS is not set
# CONFIG_IOSCHED_DEADLINE is not setCONFIG_IOSCHED_CFQ=y
# CONFIG_DEFAULT_AS is not set
# CONFIG_DEFAULT_DEADLINE is not setCONFIG_DEFAULT_CFQ=y
# CONFIG_DEFAULT_NOOP is not setCONFIG_DEFAULT_IOSCHED="cfq"CONFIG_CLASSIC_RCU=y
#
# Processor type and features
#CONFIG_TICK_ONESHOT=y
# CONFIG_NO_HZ is not setCONFIG_HIGH_RES_TIMERS=yCONFIG_GENERIC_CLOCKEVENTS_BUILD=yCONFIG_SMP_SUPPORT=yCONFIG_UP_WANTED_1=y
# CONFIG_UP_WANTED_2 is not setCONFIG_SMP=yCONFIG_X86_PC=y
# CONFIG_X86_ELAN is not set
# CONFIG_X86_VOYAGER is not set
# CONFIG_X86_VISWS is not set
# CONFIG_X86_GENERICARCH is not set
# CONFIG_X86_RDC321X is not set
# CONFIG_X86_VSMP is not setCONFIG_PARAVIRT_GUEST=y
# CONFIG_KVM_CLOCK is not set
# CONFIG_KVM_GUEST is not setCONFIG_PARAVIRT=y
# CONFIG_MEMTEST is not set
# CONFIG_M386 is not set
# CONFIG_M486 is not set
# CONFIG_M586 is not set
# CONFIG_M586TSC is not set
# CONFIG_M586MMX is not set
# CONFIG_M686 is not set
# CONFIG_MPENTIUMII is not set
# CONFIG_MPENTIUMIII is not set
# CONFIG_MPENTIUMM is not set
# CONFIG_MPENTIUM4 is not set
# CONFIG_MK6 is not set
# CONFIG_MK7 is not set
# CONFIG_MK8 is not set
# CONFIG_MCRUSOE is not set
# CONFIG_MEFFICEON is not set
# CONFIG_MWINCHIPC6 is not set
# CONFIG_MWINCHIP2 is not set
# CONFIG_MWINCHIP3D is not set
# CONFIG_MGEODEGX1 is not set
# CONFIG_MGEODE_LX is not set
# CONFIG_MCYRIXIII is not set
# CONFIG_MVIAC3_2 is not set
# CONFIG_MVIAC7 is not set
# CONFIG_MPSC is not setCONFIG_MCORE2=y
# CONFIG_GENERIC_CPU is not setCONFIG_X86_CPU=yCONFIG_X86_L1_CACHE_BYTES=64CONFIG_X86_INTERNODE_CACHE_BYTES=64CONFIG_X86_CMPXCHG=yCONFIG_X86_L1_CACHE_SHIFT=6CONFIG_X86_GOOD_APIC=yCONFIG_X86_INTEL_USERCOPY=yCONFIG_X86_USE_PPRO_CHECKSUM=yCONFIG_X86_P6_NOP=yCONFIG_X86_TSC=yCONFIG_X86_CMPXCHG64=yCONFIG_X86_CMOV=yCONFIG_X86_MINIMUM_CPU_FAMILY=64CONFIG_X86_DEBUGCTLMSR=y
# CONFIG_X86_DS is not setCONFIG_HPET_TIMER=y
# CONFIG_DMI is not setCONFIG_GART_IOMMU=y
# CONFIG_CALGARY_IOMMU is not setCONFIG_SWIOTLB=yCONFIG_IOMMU_HELPER=y
# CONFIG_MAXSMP is not setCONFIG_NR_CPUS=8
# CONFIG_SCHED_SMT is not set
# CONFIG_SCHED_MC is not setCONFIG_PREEMPT_NONE=y
# CONFIG_PREEMPT_VOLUNTARY is not set
# CONFIG_PREEMPT is not setCONFIG_X86_LOCAL_APIC=yCONFIG_X86_IO_APIC=yCONFIG_X86_MCE=yCONFIG_X86_MCE_INTEL=yCONFIG_X86_MCE_AMD=yCONFIG_I8K=yCONFIG_MICROCODE=yCONFIG_MICROCODE_OLD_INTERFACE=yCONFIG_X86_MSR=y
# CONFIG_X86_CPUID is not set
# CONFIG_NUMA is not setCONFIG_ARCH_SPARSEMEM_DEFAULT=yCONFIG_ARCH_SPARSEMEM_ENABLE=yCONFIG_ARCH_SELECT_MEMORY_MODEL=yCONFIG_ILLEGAL_POINTER_VALUE=0xffffc10000000000CONFIG_SELECT_MEMORY_MODEL=y
# CONFIG_FLATMEM_MANUAL is not set
# CONFIG_DISCONTIGMEM_MANUAL is not setCONFIG_SPARSEMEM_MANUAL=yCONFIG_SPARSEMEM=yCONFIG_HAVE_MEMORY_PRESENT=y
# CONFIG_SPARSEMEM_STATIC is not setCONFIG_SPARSEMEM_EXTREME=yCONFIG_SPARSEMEM_VMEMMAP_ENABLE=y
# CONFIG_SPARSEMEM_VMEMMAP is not setCONFIG_PAGEFLAGS_EXTENDED=yCONFIG_SPLIT_PTLOCK_CPUS=4CONFIG_RESOURCES_64BIT=yCONFIG_ZONE_DMA_FLAG=1CONFIG_BOUNCE=yCONFIG_VIRT_TO_BUS=y
# CONFIG_MTRR is not set
# CONFIG_CC_STACKPROTECTOR is not set
# CONFIG_HZ_100 is not set
# CONFIG_HZ_250 is not setCONFIG_HZ_300=y
# CONFIG_HZ_1000 is not setCONFIG_HZ=300CONFIG_SCHED_HRTICK=yCONFIG_KEXEC=y
# CONFIG_CRASH_DUMP is not setCONFIG_PHYSICAL_START=0x200000CONFIG_RELOCATABLE=yCONFIG_PHYSICAL_ALIGN=0x200000
# CONFIG_COMPAT_VDSO is not setCONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y
#
# Power management options
#
# CONFIG_PM is not set
#
# CPU Frequency scaling
#CONFIG_CPU_FREQ=yCONFIG_CPU_FREQ_TABLE=y
# CONFIG_CPU_FREQ_DEBUG is not set CONFIG_CPU_FREQ_STAT=y
# CONFIG_CPU_FREQ_STAT_DETAILS is not set CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE=y
# CONFIG_CPU_FREQ_DEFAULT_GOV_POWERSAVE is not set # CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE is not set # CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND is not set # CONFIG_CPU_FREQ_DEFAULT_GOV_CONSERVATIVE is not set CONFIG_CPU_FREQ_GOV_PERFORMANCE=y CONFIG_CPU_FREQ_GOV_POWERSAVE=y CONFIG_CPU_FREQ_GOV_USERSPACE=y
# CONFIG_CPU_FREQ_GOV_ONDEMAND is not set
# CONFIG_CPU_FREQ_GOV_CONSERVATIVE is not set
#
# CPUFreq processor drivers
#CONFIG_X86_POWERNOW_K8=y
# CONFIG_X86_P4_CLOCKMOD is not set
#
# shared options # # CONFIG_X86_SPEEDSTEP_LIB is not set # CONFIG_CPU_IDLE is not set
#
# Bus options (PCI etc.)
#CONFIG_PCI=yCONFIG_PCI_DIRECT=yCONFIG_PCI_DOMAINS=yCONFIG_PCIEPORTBUS=y
# CONFIG_PCIEAER is not set
# CONFIG_PCIEASPM is not setCONFIG_ARCH_SUPPORTS_MSI=y
# CONFIG_PCI_MSI is not set
# CONFIG_PCI_LEGACY is not set
# CONFIG_PCI_DEBUG is not set
# CONFIG_HT_IRQ is not setCONFIG_ISA_DMA_API=yCONFIG_K8_NB=y
#
# Executable file formats / Emulations
#CONFIG_BINFMT_ELF=yCONFIG_COMPAT_BINFMT_ELF=y
# CONFIG_BINFMT_MISC is not setCONFIG_IA32_EMULATION=yCONFIG_IA32_AOUT=yCONFIG_COMPAT=yCONFIG_COMPAT_FOR_U64_ALIGNMENT=y
#
# Networking
#CONFIG_NET=y
#
# Networking options
#CONFIG_PACKET=yCONFIG_PACKET_MMAP=yCONFIG_UNIX=yCONFIG_XFRM=y
# CONFIG_XFRM_SUB_POLICY is not setCONFIG_XFRM_MIGRATE=yCONFIG_NET_KEY=y
# CONFIG_NET_KEY_MIGRATE is not set
# CONFIG_INET is not setCONFIG_NETWORK_SECMARK=y
# CONFIG_NETFILTER is not setCONFIG_ATM=yCONFIG_ATM_LANE=y
# CONFIG_BRIDGE is not set
# CONFIG_VLAN_8021Q is not setCONFIG_DECNET=y
# CONFIG_DECNET_ROUTER is not setCONFIG_LLC=yCONFIG_LLC2=y
# CONFIG_IPX is not setCONFIG_ATALK=y
# CONFIG_DEV_APPLETALK is not setCONFIG_X25=y
# CONFIG_LAPB is not setCONFIG_WAN_ROUTER=y
# CONFIG_NET_SCHED is not set
#
# Network testing
#CONFIG_HAMRADIO=y
#
# Packet Radio protocols
#
# CONFIG_AX25 is not setCONFIG_CAN=yCONFIG_CAN_RAW=yCONFIG_CAN_BCM=y
#
# CAN Device Drivers
#
# CONFIG_CAN_VCAN is not setCONFIG_CAN_DEBUG_DEVICES=yCONFIG_IRDA=y
#
# IrDA protocols
#CONFIG_IRLAN=y
# CONFIG_IRCOMM is not set
# CONFIG_IRDA_ULTRA is not set
#
# IrDA options
#CONFIG_IRDA_CACHE_LAST_LSAP=yCONFIG_IRDA_FAST_RR=y
# CONFIG_IRDA_DEBUG is not set
#
# Infrared-port device drivers
#
#
# SIR device drivers
#
# CONFIG_IRTTY_SIR is not set
#
# Dongle support
#
#
# FIR device drivers
#CONFIG_NSC_FIR=y
# CONFIG_WINBOND_FIR is not setCONFIG_SMC_IRCC_FIR=yCONFIG_ALI_FIR=y
# CONFIG_VLSI_FIR is not setCONFIG_VIA_FIR=yCONFIG_BT=y
# CONFIG_BT_L2CAP is not set
# CONFIG_BT_SCO is not set
#
# Bluetooth device drivers
#
# CONFIG_BT_HCIUART is not set
# CONFIG_BT_HCIVHCI is not set
#
# Wireless
#
# CONFIG_CFG80211 is not setCONFIG_WIRELESS_EXT=y
# CONFIG_MAC80211 is not setCONFIG_IEEE80211=y
# CONFIG_IEEE80211_DEBUG is not setCONFIG_IEEE80211_CRYPT_WEP=y
# CONFIG_IEEE80211_CRYPT_CCMP is not setCONFIG_IEEE80211_CRYPT_TKIP=yCONFIG_RFKILL=yCONFIG_RFKILL_INPUT=yCONFIG_NET_9P=y
# CONFIG_NET_9P_DEBUG is not set
#
# Device Drivers
#
#
# Generic Driver Options
#CONFIG_STANDALONE=yCONFIG_PREVENT_FIRMWARE_BUILD=yCONFIG_FW_LOADER=y
# CONFIG_DEBUG_DRIVER is not set
# CONFIG_DEBUG_DEVRES is not set
# CONFIG_SYS_HYPERVISOR is not set
# CONFIG_CONNECTOR is not setCONFIG_MTD=y
# CONFIG_MTD_DEBUG is not setCONFIG_MTD_CONCAT=yCONFIG_MTD_PARTITIONS=y
# CONFIG_MTD_REDBOOT_PARTS is not set
# CONFIG_MTD_CMDLINE_PARTS is not set
# CONFIG_MTD_AR7_PARTS is not set
#
# User Modules And Translation Layers
#
# CONFIG_MTD_CHAR is not setCONFIG_MTD_BLKDEVS=yCONFIG_MTD_BLOCK=y
# CONFIG_FTL is not setCONFIG_NFTL=yCONFIG_NFTL_RW=yCONFIG_INFTL=y
# CONFIG_RFD_FTL is not setCONFIG_SSFDC=y
# CONFIG_MTD_OOPS is not set
#
# RAM/ROM/Flash chip drivers
#CONFIG_MTD_CFI=yCONFIG_MTD_JEDECPROBE=yCONFIG_MTD_GEN_PROBE=yCONFIG_MTD_CFI_ADV_OPTIONS=y
# CONFIG_MTD_CFI_NOSWAP is not set
# CONFIG_MTD_CFI_BE_BYTE_SWAP is not setCONFIG_MTD_CFI_LE_BYTE_SWAP=y
# CONFIG_MTD_CFI_GEOMETRY is not setCONFIG_MTD_MAP_BANK_WIDTH_1=yCONFIG_MTD_MAP_BANK_WIDTH_2=yCONFIG_MTD_MAP_BANK_WIDTH_4=y
# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set
# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set
# CONFIG_MTD_MAP_BANK_WIDTH_32 is not setCONFIG_MTD_CFI_I1=yCONFIG_MTD_CFI_I2=y
# CONFIG_MTD_CFI_I4 is not set
# CONFIG_MTD_CFI_I8 is not setCONFIG_MTD_OTP=y
# CONFIG_MTD_CFI_INTELEXT is not setCONFIG_MTD_CFI_AMDSTD=yCONFIG_MTD_CFI_STAA=yCONFIG_MTD_CFI_UTIL=y
# CONFIG_MTD_RAM is not setCONFIG_MTD_ROM=y
# CONFIG_MTD_ABSENT is not set
#
# Mapping drivers for chip access
#
# CONFIG_MTD_COMPLEX_MAPPINGS is not set
# CONFIG_MTD_PHYSMAP is not set
# CONFIG_MTD_SC520CDP is not set
# CONFIG_MTD_NETSC520 is not setCONFIG_MTD_TS5500=y
# CONFIG_MTD_AMD76XROM is not setCONFIG_MTD_ICHXROM=y
# CONFIG_MTD_ESB2ROM is not set
# CONFIG_MTD_CK804XROM is not setCONFIG_MTD_SCB2_FLASH=y
# CONFIG_MTD_NETtel is not setCONFIG_MTD_L440GX=yCONFIG_MTD_INTEL_VR_NOR=y
# CONFIG_MTD_PLATRAM is not set
#
# Self-contained MTD device drivers
#
# CONFIG_MTD_PMC551 is not set
# CONFIG_MTD_DATAFLASH is not set
# CONFIG_MTD_M25P80 is not setCONFIG_MTD_SLRAM=yCONFIG_MTD_PHRAM=y
# CONFIG_MTD_MTDRAM is not setCONFIG_MTD_BLOCK2MTD=y
#
# Disk-On-Chip Device Drivers
#
# CONFIG_MTD_DOC2000 is not setCONFIG_MTD_DOC2001=yCONFIG_MTD_DOC2001PLUS=yCONFIG_MTD_DOCPROBE=yCONFIG_MTD_DOCECC=y
# CONFIG_MTD_DOCPROBE_ADVANCED is not setCONFIG_MTD_DOCPROBE_ADDRESS=0
# CONFIG_MTD_NAND is not setCONFIG_MTD_NAND_IDS=yCONFIG_MTD_ONENAND=yCONFIG_MTD_ONENAND_VERIFY_WRITE=y
# CONFIG_MTD_ONENAND_OTP is not set
# CONFIG_MTD_ONENAND_2X_PROGRAM is not set
# CONFIG_MTD_ONENAND_SIM is not set
#
# UBI - Unsorted block images
#
# CONFIG_MTD_UBI is not setCONFIG_PARPORT=y
# CONFIG_PARPORT_PC is not set
# CONFIG_PARPORT_GSC is not setCONFIG_PARPORT_AX88796=y
# CONFIG_PARPORT_1284 is not setCONFIG_PARPORT_NOT_PC=y
# CONFIG_BLK_DEV is not set
# CONFIG_MISC_DEVICES is not setCONFIG_HAVE_IDE=yCONFIG_IDE=yCONFIG_IDE_MAX_HWIFS=4
# CONFIG_BLK_DEV_IDE is not set
# CONFIG_BLK_DEV_HD_ONLY is not set
# CONFIG_BLK_DEV_HD is not set
#
# SCSI device support
#
# CONFIG_RAID_ATTRS is not setCONFIG_SCSI=yCONFIG_SCSI_DMA=yCONFIG_SCSI_TGT=yCONFIG_SCSI_NETLINK=y
#
# SCSI support type (disk, tape, CD-ROM)
#CONFIG_BLK_DEV_SD=y
# CONFIG_CHR_DEV_ST is not set
# CONFIG_CHR_DEV_OSST is not set
# CONFIG_BLK_DEV_SR is not set
# CONFIG_CHR_DEV_SG is not set
# CONFIG_CHR_DEV_SCH is not set
#
# Some SCSI devices (e.g. CD jukebox) support multiple LUNs #CONFIG_SCSI_MULTI_LUN=yCONFIG_SCSI_CONSTANTS=y
# CONFIG_SCSI_LOGGING is not set CONFIG_SCSI_SCAN_ASYNC=y
#
# SCSI Transports
#CONFIG_SCSI_SPI_ATTRS=yCONFIG_SCSI_FC_ATTRS=yCONFIG_SCSI_FC_TGT_ATTRS=yCONFIG_SCSI_ISCSI_ATTRS=yCONFIG_SCSI_SRP_ATTRS=yCONFIG_SCSI_SRP_TGT_ATTRS=yCONFIG_SCSI_LOWLEVEL=y
# CONFIG_BLK_DEV_3W_XXXX_RAID is not setCONFIG_SCSI_3W_9XXX=y
# CONFIG_SCSI_ACARD is not set
# CONFIG_SCSI_AACRAID is not set
# CONFIG_SCSI_AIC7XXX is not set
# CONFIG_SCSI_AIC7XXX_OLD is not set
# CONFIG_SCSI_AIC79XX is not setCONFIG_SCSI_DPT_I2O=yCONFIG_SCSI_ADVANSYS=yCONFIG_SCSI_ARCMSR=yCONFIG_MEGARAID_NEWGEN=y
# CONFIG_MEGARAID_MM is not setCONFIG_MEGARAID_LEGACY=y
# CONFIG_MEGARAID_SAS is not setCONFIG_SCSI_HPTIOP=y
# CONFIG_SCSI_BUSLOGIC is not set
# CONFIG_SCSI_DMX3191D is not set
# CONFIG_SCSI_EATA is not set
# CONFIG_SCSI_FUTURE_DOMAIN is not setCONFIG_SCSI_GDTH=yCONFIG_SCSI_IPS=y
# CONFIG_SCSI_INITIO is not setCONFIG_SCSI_INIA100=yCONFIG_SCSI_STEX=yCONFIG_SCSI_SYM53C8XX_2=yCONFIG_SCSI_SYM53C8XX_DMA_ADDRESSING_MODE=1CONFIG_SCSI_SYM53C8XX_DEFAULT_TAGS=16CONFIG_SCSI_SYM53C8XX_MAX_TAGS=64
# CONFIG_SCSI_SYM53C8XX_MMIO is not set
# CONFIG_SCSI_QLOGIC_1280 is not setCONFIG_SCSI_QLA_FC=yCONFIG_SCSI_QLA_ISCSI=yCONFIG_SCSI_LPFC=y
CONFIG_SCSI_DC395x=y
# CONFIG_SCSI_DC390T is not set
# CONFIG_SCSI_DEBUG is not setCONFIG_SCSI_SRP=y
# CONFIG_ATA is not set
# CONFIG_MD is not setCONFIG_FUSION=yCONFIG_FUSION_SPI=yCONFIG_FUSION_FC=y
# CONFIG_FUSION_SAS is not setCONFIG_FUSION_MAX_SGE=128CONFIG_FUSION_CTL=y
# CONFIG_FUSION_LOGGING is not set
#
# IEEE 1394 (FireWire) support
#CONFIG_FIREWIRE=yCONFIG_FIREWIRE_OHCI=yCONFIG_FIREWIRE_OHCI_DEBUG=y
# CONFIG_FIREWIRE_SBP2 is not setCONFIG_IEEE1394=y
#
# Subsystem Options
#CONFIG_IEEE1394_VERBOSEDEBUG=y
#
# Controllers
#
#
# Texas Instruments PCILynx requires I2C
#
# CONFIG_IEEE1394_OHCI1394 is not set
#
# Protocols
#CONFIG_IEEE1394_SBP2=yCONFIG_IEEE1394_SBP2_PHYS_DMA=y
# CONFIG_IEEE1394_ETH1394_ROM_ENTRY is not set
# CONFIG_IEEE1394_RAWIO is not setCONFIG_I2O=y
# CONFIG_I2O_LCT_NOTIFY_ON_CHANGES is not setCONFIG_I2O_EXT_ADAPTEC=y
# CONFIG_I2O_EXT_ADAPTEC_DMA64 is not set
# CONFIG_I2O_CONFIG is not setCONFIG_I2O_BUS=yCONFIG_I2O_BLOCK=yCONFIG_I2O_SCSI=yCONFIG_I2O_PROC=yCONFIG_MACINTOSH_DRIVERS=yCONFIG_MAC_EMUMOUSEBTN=y
# CONFIG_NETDEVICES is not setCONFIG_MLX4_CORE=y
# CONFIG_ISDN is not setCONFIG_PHONE=y
# CONFIG_PHONE_IXJ is not set
#
# Input device support
#CONFIG_INPUT=yCONFIG_INPUT_FF_MEMLESS=yCONFIG_INPUT_POLLDEV=y
#
# Userland interfaces
#
# CONFIG_INPUT_MOUSEDEV is not setCONFIG_INPUT_JOYDEV=yCONFIG_INPUT_EVDEV=y
# CONFIG_INPUT_EVBUG is not set
#
# Input Device Drivers
#
# CONFIG_INPUT_KEYBOARD is not set
# CONFIG_INPUT_MOUSE is not setCONFIG_INPUT_JOYSTICK=y
# CONFIG_JOYSTICK_ANALOG is not setCONFIG_JOYSTICK_A3D=y
# CONFIG_JOYSTICK_ADI is not set
# CONFIG_JOYSTICK_COBRA is not set
# CONFIG_JOYSTICK_GF2K is not set
# CONFIG_JOYSTICK_GRIP is not setCONFIG_JOYSTICK_GRIP_MP=yCONFIG_JOYSTICK_GUILLEMOT=yCONFIG_JOYSTICK_INTERACT=yCONFIG_JOYSTICK_SIDEWINDER=y
# CONFIG_JOYSTICK_TMDC is not setCONFIG_JOYSTICK_IFORCE=y
# CONFIG_JOYSTICK_IFORCE_232 is not set
# CONFIG_JOYSTICK_WARRIOR is not set
# CONFIG_JOYSTICK_MAGELLAN is not set
# CONFIG_JOYSTICK_SPACEORB is not set
# CONFIG_JOYSTICK_SPACEBALL is not set
# CONFIG_JOYSTICK_STINGER is not setCONFIG_JOYSTICK_TWIDJOY=yCONFIG_JOYSTICK_ZHENHUA=yCONFIG_JOYSTICK_DB9=yCONFIG_JOYSTICK_GAMECON=yCONFIG_JOYSTICK_TURBOGRAFX=yCONFIG_JOYSTICK_JOYDUMP=yCONFIG_INPUT_TABLET=yCONFIG_INPUT_TOUCHSCREEN=y
# CONFIG_TOUCHSCREEN_ADS7846 is not setCONFIG_TOUCHSCREEN_FUJITSU=yCONFIG_TOUCHSCREEN_GUNZE=yCONFIG_TOUCHSCREEN_ELO=y
# CONFIG_TOUCHSCREEN_MTOUCH is not set
# CONFIG_TOUCHSCREEN_MK712 is not set
# CONFIG_TOUCHSCREEN_PENMOUNT is not setCONFIG_TOUCHSCREEN_TOUCHRIGHT=yCONFIG_TOUCHSCREEN_TOUCHWIN=y
# CONFIG_TOUCHSCREEN_UCB1400 is not setCONFIG_INPUT_MISC=yCONFIG_INPUT_PCSPKR=y
# CONFIG_INPUT_UINPUT is not set
#
# Hardware I/O ports
#CONFIG_SERIO=y
# CONFIG_SERIO_I8042 is not set
# CONFIG_SERIO_SERPORT is not set
# CONFIG_SERIO_CT82C710 is not setCONFIG_SERIO_PARKBD=yCONFIG_SERIO_PCIPS2=yCONFIG_SERIO_LIBPS2=y
# CONFIG_SERIO_RAW is not setCONFIG_GAMEPORT=yCONFIG_GAMEPORT_NS558=y
# CONFIG_GAMEPORT_L4 is not set
# CONFIG_GAMEPORT_EMU10K1 is not setCONFIG_GAMEPORT_FM801=y
#
# Character devices
#
# CONFIG_VT is not set
# CONFIG_DEVKMEM is not set
# CONFIG_SERIAL_NONSTANDARD is not setCONFIG_NOZOMI=y
#
# Serial drivers
#CONFIG_SERIAL_8250=y
# CONFIG_SERIAL_8250_CONSOLE is not setCONFIG_FIX_EARLYCON_MEM=yCONFIG_SERIAL_8250_PCI=yCONFIG_SERIAL_8250_NR_UARTS=4CONFIG_SERIAL_8250_RUNTIME_UARTS=4
# CONFIG_SERIAL_8250_EXTENDED is not set
#
# Non-8250 serial port support
#CONFIG_SERIAL_CORE=yCONFIG_CONSOLE_POLL=yCONFIG_SERIAL_JSM=y
# CONFIG_UNIX98_PTYS is not set
# CONFIG_LEGACY_PTYS is not set
# CONFIG_PRINTER is not setCONFIG_PPDEV=y
# CONFIG_IPMI_HANDLER is not setCONFIG_HW_RANDOM=y
# CONFIG_HW_RANDOM_INTEL is not set
# CONFIG_HW_RANDOM_AMD is not set
# CONFIG_NVRAM is not set
# CONFIG_R3964 is not setCONFIG_APPLICOM=y
# CONFIG_MWAVE is not set
# CONFIG_PC8736x_GPIO is not setCONFIG_RAW_DRIVER=yCONFIG_MAX_RAW_DEVS=256
# CONFIG_HANGCHECK_TIMER is not setCONFIG_TCG_TPM=y
# CONFIG_TCG_NSC is not setCONFIG_TCG_ATMEL=y
# CONFIG_TELCLOCK is not setCONFIG_DEVPORT=y
# CONFIG_I2C is not setCONFIG_SPI=yCONFIG_SPI_DEBUG=yCONFIG_SPI_MASTER=y
#
# SPI Master Controller Drivers
#CONFIG_SPI_BITBANG=y
# CONFIG_SPI_BUTTERFLY is not setCONFIG_SPI_LM70_LLP=y
#
# SPI Protocol Masters
#CONFIG_SPI_SPIDEV=yCONFIG_W1=y
#
# 1-wire Bus Masters
#CONFIG_W1_MASTER_MATROX=y
#
# 1-wire Slaves
#
# CONFIG_W1_SLAVE_THERM is not setCONFIG_W1_SLAVE_SMEM=y
# CONFIG_W1_SLAVE_DS2433 is not setCONFIG_W1_SLAVE_DS2760=y
# CONFIG_POWER_SUPPLY is not set
# CONFIG_HWMON is not setCONFIG_THERMAL=yCONFIG_WATCHDOG=y
# CONFIG_WATCHDOG_NOWAYOUT is not set
#
# Watchdog Device Drivers
#CONFIG_SOFT_WATCHDOG=yCONFIG_ACQUIRE_WDT=y
# CONFIG_ADVANTECH_WDT is not setCONFIG_ALIM1535_WDT=yCONFIG_ALIM7101_WDT=y
# CONFIG_SC520_WDT is not set
# CONFIG_EUROTECH_WDT is not setCONFIG_IB700_WDT=yCONFIG_IBMASR=yCONFIG_WAFER_WDT=y
# CONFIG_I6300ESB_WDT is not setCONFIG_ITCO_WDT=yCONFIG_ITCO_VENDOR_SUPPORT=y
# CONFIG_IT8712F_WDT is not set
# CONFIG_HP_WATCHDOG is not set
# CONFIG_SC1200_WDT is not set
# CONFIG_PC87413_WDT is not setCONFIG_60XX_WDT=y
# CONFIG_SBC8360_WDT is not setCONFIG_CPU5_WDT=yCONFIG_SMSC37B787_WDT=y
# CONFIG_W83627HF_WDT is not setCONFIG_W83697HF_WDT=y
# CONFIG_W83877F_WDT is not setCONFIG_W83977F_WDT=yCONFIG_MACHZ_WDT=yCONFIG_SBC_EPX_C3_WATCHDOG=y
#
# PCI-based Watchdog Cards
#CONFIG_PCIPCWATCHDOG=yCONFIG_WDTPCI=yCONFIG_WDT_501_PCI=y
#
# Sonics Silicon Backplane
#CONFIG_SSB_POSSIBLE=yCONFIG_SSB=yCONFIG_SSB_SPROM=yCONFIG_SSB_PCIHOST_POSSIBLE=yCONFIG_SSB_PCIHOST=y
# CONFIG_SSB_B43_PCI_BRIDGE is not setCONFIG_SSB_SILENT=yCONFIG_SSB_DRIVER_PCICORE_POSSIBLE=yCONFIG_SSB_DRIVER_PCICORE=y
#
# Multifunction device drivers
#
# CONFIG_MFD_SM501 is not setCONFIG_HTC_PASIC3=y
#
# Multimedia devices
#
#
# Multimedia core support
#
# CONFIG_VIDEO_DEV is not set
# CONFIG_VIDEO_MEDIA is not set
#
# Multimedia drivers
#
# CONFIG_DAB is not set
#
# Graphics support
#CONFIG_AGP=yCONFIG_AGP_AMD64=yCONFIG_AGP_INTEL=y
# CONFIG_AGP_SIS is not setCONFIG_AGP_VIA=yCONFIG_DRM=y
# CONFIG_DRM_TDFX is not set
# CONFIG_DRM_R128 is not set
# CONFIG_DRM_RADEON is not set
# CONFIG_DRM_I810 is not set
# CONFIG_DRM_I830 is not set
# CONFIG_DRM_I915 is not set
# CONFIG_DRM_MGA is not set
# CONFIG_DRM_SIS is not setCONFIG_DRM_VIA=yCONFIG_DRM_SAVAGE=y
# CONFIG_VGASTATE is not setCONFIG_VIDEO_OUTPUT_CONTROL=yCONFIG_FB=y
# CONFIG_FIRMWARE_EDID is not set
# CONFIG_FB_DDC is not setCONFIG_FB_CFB_FILLRECT=yCONFIG_FB_CFB_COPYAREA=yCONFIG_FB_CFB_IMAGEBLIT=y
# CONFIG_FB_CFB_REV_PIXELS_IN_BYTE is not setCONFIG_FB_SYS_FILLRECT=yCONFIG_FB_SYS_COPYAREA=yCONFIG_FB_SYS_IMAGEBLIT=y
# CONFIG_FB_FOREIGN_ENDIAN is not setCONFIG_FB_SYS_FOPS=yCONFIG_FB_DEFERRED_IO=yCONFIG_FB_HECUBA=y
# CONFIG_FB_SVGALIB is not set
# CONFIG_FB_MACMODES is not setCONFIG_FB_BACKLIGHT=yCONFIG_FB_MODE_HELPERS=yCONFIG_FB_TILEBLITTING=y
#
# Frame buffer hardware drivers
#CONFIG_FB_CIRRUS=y
# CONFIG_FB_PM2 is not set
# CONFIG_FB_CYBER2000 is not setCONFIG_FB_ARC=yCONFIG_FB_ASILIANT=y
# CONFIG_FB_IMSTT is not set
# CONFIG_FB_VGA16 is not set
# CONFIG_FB_VESA is not set
# CONFIG_FB_EFI is not setCONFIG_FB_N411=yCONFIG_FB_HGA=y
# CONFIG_FB_HGA_ACCEL is not set
# CONFIG_FB_S1D13XXX is not set
# CONFIG_FB_NVIDIA is not set
# CONFIG_FB_RIVA is not set
# CONFIG_FB_LE80578 is not setCONFIG_FB_INTEL=y
# CONFIG_FB_INTEL_DEBUG is not set
# CONFIG_FB_INTEL_I2C is not set
# CONFIG_FB_MATROX is not setCONFIG_FB_RADEON=y
# CONFIG_FB_RADEON_I2C is not set
# CONFIG_FB_RADEON_BACKLIGHT is not setCONFIG_FB_RADEON_DEBUG=y
# CONFIG_FB_ATY128 is not setCONFIG_FB_ATY=y
# CONFIG_FB_ATY_CT is not setCONFIG_FB_ATY_GX=yCONFIG_FB_ATY_BACKLIGHT=y
# CONFIG_FB_S3 is not set
# CONFIG_FB_SAVAGE is not setCONFIG_FB_SIS=yCONFIG_FB_SIS_300=yCONFIG_FB_SIS_315=y
# CONFIG_FB_NEOMAGIC is not setCONFIG_FB_KYRO=y
# CONFIG_FB_3DFX is not set
# CONFIG_FB_VOODOO1 is not set
# CONFIG_FB_VT8623 is not setCONFIG_FB_TRIDENT=yCONFIG_FB_TRIDENT_ACCEL=y
# CONFIG_FB_ARK is not set
# CONFIG_FB_PM3 is not set
# CONFIG_FB_GEODE is not setCONFIG_FB_VIRTUAL=yCONFIG_BACKLIGHT_LCD_SUPPORT=y
# CONFIG_LCD_CLASS_DEVICE is not setCONFIG_BACKLIGHT_CLASS_DEVICE=y
# CONFIG_BACKLIGHT_CORGI is not set
# CONFIG_BACKLIGHT_PROGEAR is not set
#
# Display device support
#CONFIG_DISPLAY_SUPPORT=y
#
# Display hardware drivers
#CONFIG_LOGO=y
# CONFIG_LOGO_LINUX_MONO is not set
# CONFIG_LOGO_LINUX_VGA16 is not set
# CONFIG_LOGO_LINUX_CLUT224 is not set
#
# Sound
#
# CONFIG_SOUND is not setCONFIG_HID_SUPPORT=y
# CONFIG_HID is not set
# CONFIG_USB_SUPPORT is not set
# CONFIG_MMC is not set
# CONFIG_MEMSTICK is not set
# CONFIG_NEW_LEDS is not set
# CONFIG_ACCESSIBILITY is not setCONFIG_INFINIBAND=yCONFIG_INFINIBAND_USER_MAD=yCONFIG_INFINIBAND_USER_ACCESS=yCONFIG_INFINIBAND_USER_MEM=y
# CONFIG_INFINIBAND_MTHCA is not setCONFIG_INFINIBAND_IPATH=yCONFIG_MLX4_INFINIBAND=y
# CONFIG_INFINIBAND_SRP is not set
# CONFIG_EDAC is not setCONFIG_RTC_LIB=yCONFIG_RTC_CLASS=yCONFIG_RTC_HCTOSYS=yCONFIG_RTC_HCTOSYS_DEVICE="rtc0"
# CONFIG_RTC_DEBUG is not set
#
# RTC interfaces
#
# CONFIG_RTC_INTF_DEV is not setCONFIG_RTC_DRV_TEST=y
#
# SPI RTC drivers
#
# CONFIG_RTC_DRV_MAX6902 is not set
# CONFIG_RTC_DRV_R9701 is not set
# CONFIG_RTC_DRV_RS5C348 is not set
#
# Platform RTC drivers
#
# CONFIG_RTC_DRV_CMOS is not setCONFIG_RTC_DRV_DS1511=y
# CONFIG_RTC_DRV_DS1553 is not setCONFIG_RTC_DRV_DS1742=y
# CONFIG_RTC_DRV_STK17TA8 is not setCONFIG_RTC_DRV_M48T86=y
# CONFIG_RTC_DRV_M48T59 is not setCONFIG_RTC_DRV_V3020=y
#
# on-CPU RTC drivers
#CONFIG_DMADEVICES=y
#
# DMA Devices
#
# CONFIG_INTEL_IOATDMA is not setCONFIG_AUXDISPLAY=yCONFIG_UIO=y
# CONFIG_UIO_CIF is not setCONFIG_UIO_SMX=y
#
# Firmware Drivers
#
# CONFIG_EDD is not set
# CONFIG_DELL_RBU is not setCONFIG_DCDBAS=yCONFIG_ISCSI_IBFT_FIND=y
# CONFIG_ISCSI_IBFT is not set
#
# File systems
#CONFIG_EXT2_FS=y
# CONFIG_EXT2_FS_XATTR is not set
# CONFIG_EXT2_FS_XIP is not setCONFIG_EXT3_FS=yCONFIG_EXT3_FS_XATTR=y
# CONFIG_EXT3_FS_POSIX_ACL is not set
# CONFIG_EXT3_FS_SECURITY is not set
# CONFIG_EXT4DEV_FS is not setCONFIG_JBD=yCONFIG_FS_MBCACHE=y
# CONFIG_REISERFS_FS is not set
# CONFIG_JFS_FS is not setCONFIG_FS_POSIX_ACL=yCONFIG_XFS_FS=y
# CONFIG_XFS_QUOTA is not set
# CONFIG_XFS_POSIX_ACL is not setCONFIG_XFS_RT=y
# CONFIG_XFS_DEBUG is not setCONFIG_GFS2_FS=y
# CONFIG_GFS2_FS_LOCKING_NOLOCK is not setCONFIG_DNOTIFY=y
# CONFIG_INOTIFY is not set
# CONFIG_QUOTA is not set
# CONFIG_AUTOFS_FS is not set
# CONFIG_AUTOFS4_FS is not setCONFIG_FUSE_FS=y
#
# CD-ROM/DVD Filesystems
#
# CONFIG_ISO9660_FS is not set
# CONFIG_UDF_FS is not set
#
# DOS/FAT/NT Filesystems
#CONFIG_FAT_FS=yCONFIG_MSDOS_FS=yCONFIG_VFAT_FS=yCONFIG_FAT_DEFAULT_CODEPAGE=437CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"CONFIG_NTFS_FS=y
# CONFIG_NTFS_DEBUG is not setCONFIG_NTFS_RW=y
#
# Pseudo filesystems
#
# CONFIG_PROC_FS is not set
# CONFIG_SYSFS is not set
# CONFIG_TMPFS is not set
# CONFIG_HUGETLBFS is not set
# CONFIG_HUGETLB_PAGE is not set
#
# Miscellaneous filesystems
#CONFIG_ADFS_FS=y
# CONFIG_ADFS_FS_RW is not setCONFIG_AFFS_FS=y
# CONFIG_ECRYPT_FS is not setCONFIG_HFS_FS=yCONFIG_HFSPLUS_FS=yCONFIG_BEFS_FS=yCONFIG_BEFS_DEBUG=yCONFIG_BFS_FS=yCONFIG_EFS_FS=yCONFIG_JFFS2_FS=yCONFIG_JFFS2_FS_DEBUG=0CONFIG_JFFS2_FS_WRITEBUFFER=y
# CONFIG_JFFS2_FS_WBUF_VERIFY is not set
# CONFIG_JFFS2_SUMMARY is not setCONFIG_JFFS2_FS_XATTR=y
# CONFIG_JFFS2_FS_POSIX_ACL is not setCONFIG_JFFS2_FS_SECURITY=yCONFIG_JFFS2_COMPRESSION_OPTIONS=y
# CONFIG_JFFS2_ZLIB is not setCONFIG_JFFS2_LZO=y
# CONFIG_JFFS2_RTIME is not setCONFIG_JFFS2_RUBIN=y
# CONFIG_JFFS2_CMODE_NONE is not set
# CONFIG_JFFS2_CMODE_PRIORITY is not setCONFIG_JFFS2_CMODE_SIZE=y
# CONFIG_JFFS2_CMODE_FAVOURLZO is not setCONFIG_CRAMFS=yCONFIG_VXFS_FS=y
# CONFIG_MINIX_FS is not setCONFIG_HPFS_FS=y
# CONFIG_QNX4FS_FS is not set
# CONFIG_ROMFS_FS is not set
# CONFIG_SYSV_FS is not setCONFIG_UFS_FS=yCONFIG_UFS_FS_WRITE=y
# CONFIG_UFS_DEBUG is not set
# CONFIG_NETWORK_FILESYSTEMS is not set
#
# Partition Types
#
# CONFIG_PARTITION_ADVANCED is not setCONFIG_AMIGA_PARTITION=yCONFIG_MSDOS_PARTITION=yCONFIG_NLS=yCONFIG_NLS_DEFAULT="iso8859-1"
# CONFIG_NLS_CODEPAGE_437 is not set
# CONFIG_NLS_CODEPAGE_737 is not set
# CONFIG_NLS_CODEPAGE_775 is not setCONFIG_NLS_CODEPAGE_850=y
# CONFIG_NLS_CODEPAGE_852 is not set
# CONFIG_NLS_CODEPAGE_855 is not set
# CONFIG_NLS_CODEPAGE_857 is not setCONFIG_NLS_CODEPAGE_860=yCONFIG_NLS_CODEPAGE_861=y
# CONFIG_NLS_CODEPAGE_862 is not setCONFIG_NLS_CODEPAGE_863=yCONFIG_NLS_CODEPAGE_864=y
# CONFIG_NLS_CODEPAGE_865 is not set
# CONFIG_NLS_CODEPAGE_866 is not set
# CONFIG_NLS_CODEPAGE_869 is not set
# CONFIG_NLS_CODEPAGE_936 is not setCONFIG_NLS_CODEPAGE_950=y
# CONFIG_NLS_CODEPAGE_932 is not set
# CONFIG_NLS_CODEPAGE_949 is not setCONFIG_NLS_CODEPAGE_874=yCONFIG_NLS_ISO8859_8=yCONFIG_NLS_CODEPAGE_1250=y
# CONFIG_NLS_CODEPAGE_1251 is not setCONFIG_NLS_ASCII=yCONFIG_NLS_ISO8859_1=yCONFIG_NLS_ISO8859_2=yCONFIG_NLS_ISO8859_3=y
# CONFIG_NLS_ISO8859_4 is not setCONFIG_NLS_ISO8859_5=yCONFIG_NLS_ISO8859_6=y
# CONFIG_NLS_ISO8859_7 is not setCONFIG_NLS_ISO8859_9=yCONFIG_NLS_ISO8859_13=yCONFIG_NLS_ISO8859_14=y
# CONFIG_NLS_ISO8859_15 is not setCONFIG_NLS_KOI8_R=yCONFIG_NLS_KOI8_U=yCONFIG_NLS_UTF8=y
#
# Kernel hacking
#CONFIG_TRACE_IRQFLAGS_SUPPORT=yCONFIG_ENABLE_WARN_DEPRECATED=yCONFIG_ENABLE_MUST_CHECK=yCONFIG_FRAME_WARN=2048CONFIG_MAGIC_SYSRQ=y
# CONFIG_UNUSED_SYMBOLS is not set
# CONFIG_HEADERS_CHECK is not setCONFIG_DEBUG_KERNEL=yCONFIG_DEBUG_SHIRQ=yCONFIG_DETECT_SOFTLOCKUP=yCONFIG_BOOTPARAM_SOFTLOCKUP_PANIC=yCONFIG_BOOTPARAM_SOFTLOCKUP_PANIC_VALUE=1CONFIG_SCHED_DEBUG=yCONFIG_SCHEDSTATS=y
# CONFIG_DEBUG_OBJECTS is not setCONFIG_DEBUG_SPINLOCK=yCONFIG_DEBUG_MUTEXES=yCONFIG_DEBUG_LOCK_ALLOC=y
# CONFIG_PROVE_LOCKING is not setCONFIG_LOCKDEP=yCONFIG_LOCK_STAT=yCONFIG_DEBUG_LOCKDEP=yCONFIG_DEBUG_SPINLOCK_SLEEP=yCONFIG_DEBUG_LOCKING_API_SELFTESTS=yCONFIG_STACKTRACE=yCONFIG_DEBUG_KOBJECT=yCONFIG_DEBUG_VM=y
# CONFIG_DEBUG_WRITECOUNT is not setCONFIG_DEBUG_LIST=yCONFIG_DEBUG_SG=yCONFIG_FRAME_POINTER=y
# CONFIG_BACKTRACE_SELF_TEST is not setCONFIG_FAULT_INJECTION=yCONFIG_FAILSLAB=y
# CONFIG_FAIL_PAGE_ALLOC is not setCONFIG_FAIL_MAKE_REQUEST=yCONFIG_LATENCYTOP=yCONFIG_HAVE_FTRACE=yCONFIG_HAVE_DYNAMIC_FTRACE=y
# CONFIG_FTRACE is not set
# CONFIG_IRQSOFF_TRACER is not set
# CONFIG_SYSPROF_TRACER is not set
# CONFIG_SCHED_TRACER is not set
# CONFIG_CONTEXT_SWITCH_TRACER is not setCONFIG_PROVIDE_OHCI1394_DMA_INIT=y
# CONFIG_FIREWIRE_OHCI_REMOTE_DMA is not setCONFIG_SAMPLES=yCONFIG_SAMPLE_KOBJECT=yCONFIG_HAVE_ARCH_KGDB=yCONFIG_KGDB=yCONFIG_KGDB_SERIAL_CONSOLE=yCONFIG_KGDB_TESTS=y
# CONFIG_KGDB_TESTS_ON_BOOT is not setCONFIG_NONPROMISC_DEVMEM=y
# CONFIG_EARLY_PRINTK is not set
# CONFIG_DEBUG_STACKOVERFLOW is not set
# CONFIG_DEBUG_STACK_USAGE is not setCONFIG_DEBUG_PAGEALLOC=y
# CONFIG_DEBUG_PER_CPU_MAPS is not set
# CONFIG_X86_PTDUMP is not setCONFIG_DEBUG_RODATA=yCONFIG_DIRECT_GBPAGES=yCONFIG_DEBUG_RODATA_TEST=yCONFIG_X86_MPPARSE=y
# CONFIG_IOMMU_DEBUG is not set
# CONFIG_MMIOTRACE is not setCONFIG_IO_DELAY_TYPE_0X80=0CONFIG_IO_DELAY_TYPE_0XED=1CONFIG_IO_DELAY_TYPE_UDELAY=2CONFIG_IO_DELAY_TYPE_NONE=3
# CONFIG_IO_DELAY_0X80 is not set
# CONFIG_IO_DELAY_0XED is not setCONFIG_IO_DELAY_UDELAY=y
# CONFIG_IO_DELAY_NONE is not setCONFIG_DEFAULT_IO_DELAY_TYPE=2CONFIG_CPA_DEBUG=y
#
# Security options
#CONFIG_KEYS=yCONFIG_KEYS_DEBUG_PROC_KEYS=yCONFIG_SECURITY_FILE_CAPABILITIES=yCONFIG_CRYPTO=y
#
# Crypto core or helper
#CONFIG_CRYPTO_ALGAPI=yCONFIG_CRYPTO_AEAD=yCONFIG_CRYPTO_BLKCIPHER=yCONFIG_CRYPTO_MANAGER=yCONFIG_CRYPTO_GF128MUL=yCONFIG_CRYPTO_NULL=y
# CONFIG_CRYPTO_CRYPTD is not set
# CONFIG_CRYPTO_AUTHENC is not set
#
# Authenticated Encryption with Associated Data
#CONFIG_CRYPTO_CCM=yCONFIG_CRYPTO_GCM=yCONFIG_CRYPTO_SEQIV=y
#
# Block modes
#
# CONFIG_CRYPTO_CBC is not setCONFIG_CRYPTO_CTR=yCONFIG_CRYPTO_CTS=yCONFIG_CRYPTO_ECB=y
# CONFIG_CRYPTO_LRW is not set
# CONFIG_CRYPTO_PCBC is not set
# CONFIG_CRYPTO_XTS is not set
#
# Hash modes
#
# CONFIG_CRYPTO_HMAC is not set
# CONFIG_CRYPTO_XCBC is not set
#
# Digest
#
# CONFIG_CRYPTO_CRC32C is not set
# CONFIG_CRYPTO_MD4 is not set
# CONFIG_CRYPTO_MD5 is not setCONFIG_CRYPTO_MICHAEL_MIC=yCONFIG_CRYPTO_SHA1=y
# CONFIG_CRYPTO_SHA256 is not setCONFIG_CRYPTO_SHA512=y
# CONFIG_CRYPTO_TGR192 is not setCONFIG_CRYPTO_WP512=y
#
# Ciphers
#CONFIG_CRYPTO_AES=yCONFIG_CRYPTO_AES_X86_64=yCONFIG_CRYPTO_ANUBIS=yCONFIG_CRYPTO_ARC4=y
# CONFIG_CRYPTO_BLOWFISH is not set
# CONFIG_CRYPTO_CAMELLIA is not setCONFIG_CRYPTO_CAST5=yCONFIG_CRYPTO_CAST6=yCONFIG_CRYPTO_DES=y
# CONFIG_CRYPTO_FCRYPT is not setCONFIG_CRYPTO_KHAZAD=yCONFIG_CRYPTO_SALSA20=yCONFIG_CRYPTO_SALSA20_X86_64=yCONFIG_CRYPTO_SEED=yCONFIG_CRYPTO_SERPENT=y
# CONFIG_CRYPTO_TEA is not setCONFIG_CRYPTO_TWOFISH=yCONFIG_CRYPTO_TWOFISH_COMMON=y
# CONFIG_CRYPTO_TWOFISH_X86_64 is not set
#
# Compression
#
# CONFIG_CRYPTO_DEFLATE is not setCONFIG_CRYPTO_LZO=y
# CONFIG_CRYPTO_HW is not setCONFIG_HAVE_KVM=y
# CONFIG_VIRTUALIZATION is not set
#
# Library routines
#CONFIG_BITREVERSE=yCONFIG_GENERIC_FIND_FIRST_BIT=yCONFIG_GENERIC_FIND_NEXT_BIT=yCONFIG_CRC_CCITT=yCONFIG_CRC16=yCONFIG_CRC_ITU_T=yCONFIG_CRC32=yCONFIG_CRC7=yCONFIG_LIBCRC32C=yCONFIG_ZLIB_INFLATE=yCONFIG_LZO_COMPRESS=yCONFIG_LZO_DECOMPRESS=yCONFIG_HAS_IOMEM=yCONFIG_HAS_IOPORT=yCONFIG_HAS_DMA=yCONFIG_FORCE_SUCCESSFUL_BUILD=y
Re: [PATCH 4/4] x86: Replace xxx_pda() operations with x86_xx_percpu().
Quoted 9 lines · Ingo Molnar
Quoted 2 lines · Mike Travis
* It is now possible to use percpu operations for pda access since the pda is in the percpu area. Drop the pda operations.
FYI, this one didnt build with the attached config.
Ingo
Ok, thanks, I will check it out.
I'm still having problems getting your previous "instantaneous reboot" problem working. It has something to do with cpu_clock interrupt, but I've still not figured out why it's failing.
THanks,
Mike
Re: [PATCH 4/4] x86: Replace xxx_pda() operations with x86_xx_percpu().
In reply to Ingo MolnarQuoted 9 lines · Ingo Molnar
Quoted 2 lines · Mike Travis
* It is now possible to use percpu operations for pda access since the pda is in the percpu area. Drop the pda operations.
FYI, this one didnt build with the attached config.
Ingo
Hi Ingo,
Can you send me the output from the build? It builds fine on my machine (a few warnings). The silentoldconfig made these changes to the .config file. (I did a git-remote update and reapplied my changes before building.)
Thanks,
Mike
build/ingo-test-9/.config 2008-06-09 10:30:15.273171501 -0700 renamed from configs/ingo-test-9 2008-06-09 10:25:32.148026511 -0700 +13 -15
@@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.26-rc5 -# Mon Jun 9 14:59:39 2008 +# Linux kernel version: 2.6.26-rc4 +# Mon Jun 9 10:30:10 2008 # CONFIG_64BIT=y # CONFIG_X86_32 is not set
@@ -36,6 +36,7 @@ CONFIG_ARCH_HAS_CACHE_LINE_SIZE=y CONFIG_HAVE_SETUP_PER_CPU_AREA=y CONFIG_HAVE_CPUMASK_OF_CPU_MAP=y +CONFIG_HAVE_ZERO_BASED_PER_CPU=y CONFIG_ARCH_HIBERNATION_POSSIBLE=y CONFIG_ARCH_SUSPEND_POSSIBLE=y CONFIG_ZONE_DMA32=y
@@ -52,23 +53,16 @@ CONFIG_X86_BIOS_REBOOT=y CONFIG_X86_TRAMPOLINE=y # CONFIG_KTIME_SCALAR is not set -# CONFIG_BOOTPARAM_SUPPORT_WANTED is not set CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" # # General setup # CONFIG_EXPERIMENTAL=y -CONFIG_BROKEN_BOOT_ALLOWED3=y -CONFIG_BROKEN_BOOT_ALLOWED2=y -CONFIG_BROKEN_BOOT_ALLOWED=y -CONFIG_BROKEN_BOOT=y -CONFIG_BROKEN_BOOT_EUROPE=y -CONFIG_BROKEN_BOOT_TITAN=y CONFIG_LOCK_KERNEL=y CONFIG_INIT_ENV_ARG_LIMIT=32 -CONFIG_LOCALVERSION="" -# CONFIG_LOCALVERSION_AUTO is not set +CONFIG_LOCALVERSION="-ingo-test-9" +CONFIG_LOCALVERSION_AUTO=y # CONFIG_SWAP is not set # CONFIG_SYSVIPC is not set # CONFIG_POSIX_MQUEUE is not set
@@ -152,15 +146,16 @@ # CONFIG_NO_HZ is not set CONFIG_HIGH_RES_TIMERS=y CONFIG_GENERIC_CLOCKEVENTS_BUILD=y -CONFIG_SMP_SUPPORT=y -CONFIG_UP_WANTED_1=y -# CONFIG_UP_WANTED_2 is not set CONFIG_SMP=y CONFIG_X86_PC=y # CONFIG_X86_ELAN is not set # CONFIG_X86_VOYAGER is not set +# CONFIG_X86_NUMAQ is not set +# CONFIG_X86_SUMMIT is not set +# CONFIG_X86_BIGSMP is not set # CONFIG_X86_VISWS is not set # CONFIG_X86_GENERICARCH is not set +# CONFIG_X86_ES7000 is not set # CONFIG_X86_RDC321X is not set # CONFIG_X86_VSMP is not set CONFIG_PARAVIRT_GUEST=y
@@ -616,6 +611,7 @@ CONFIG_SCSI_FC_ATTRS=y CONFIG_SCSI_FC_TGT_ATTRS=y CONFIG_SCSI_ISCSI_ATTRS=y +# CONFIG_SCSI_SAS_LIBSAS is not set CONFIG_SCSI_SRP_ATTRS=y CONFIG_SCSI_SRP_TGT_ATTRS=y CONFIG_SCSI_LOWLEVEL=y
@@ -626,6 +622,7 @@ # CONFIG_SCSI_AIC7XXX is not set # CONFIG_SCSI_AIC7XXX_OLD is not set # CONFIG_SCSI_AIC79XX is not set +# CONFIG_SCSI_AIC94XX is not set CONFIG_SCSI_DPT_I2O=y CONFIG_SCSI_ADVANSYS=y CONFIG_SCSI_ARCMSR=y
@@ -642,6 +639,7 @@ CONFIG_SCSI_IPS=y # CONFIG_SCSI_INITIO is not set CONFIG_SCSI_INIA100=y +# CONFIG_SCSI_MVSAS is not set CONFIG_SCSI_STEX=y CONFIG_SCSI_SYM53C8XX_2=y CONFIG_SCSI_SYM53C8XX_DMA_ADDRESSING_MODE=1
@@ -1302,6 +1300,7 @@ CONFIG_DEBUG_LOCKING_API_SELFTESTS=y CONFIG_STACKTRACE=y CONFIG_DEBUG_KOBJECT=y +# CONFIG_DEBUG_INFO is not set CONFIG_DEBUG_VM=y # CONFIG_DEBUG_WRITECOUNT is not set CONFIG_DEBUG_LIST=y
@@ -1460,4 +1459,3 @@ CONFIG_HAS_IOMEM=y CONFIG_HAS_IOPORT=y CONFIG_HAS_DMA=y -CONFIG_FORCE_SUCCESSFUL_BUILD=y
Re: [PATCH 4/4] x86: Replace xxx_pda() operations with x86_xx_percpu().
Paravirt support is on. We have seen an issue with that in the past. Why was that again?
Also check that there is really no use of the segment register before start_kernel() loads it. If the segment register is used to refer to pda stuff before start_kernel then we need to make sure that the right value is loaded in the asm (head64.c).
Re: [PATCH 4/4] x86: Replace xxx_pda() operations with x86_xx_percpu().
Quoted 2 lines · Christoph Lameter
Paravirt support is on. We have seen an issue with that in the past. Why was that again?
I'm not aware of any paravirt-related percpu bugs (other than the fact that the last major revision of per-cpu variables was done under the aegis of paravirt-ops).
But booting on bare hardware with pvops enabled should be exactly the same as non-pvops with respect to percpu.
J
Re: [PATCH 4/4] x86: Replace xxx_pda() operations with x86_xx_percpu().
In reply to Mike TravisQuoted 11 lines · Mike Travis
Quoted 9 lines · Ingo Molnar
Quoted 2 lines · Mike Travis
* It is now possible to use percpu operations for pda access since the pda is in the percpu area. Drop the pda operations.
FYI, this one didnt build with the attached config.
Ingo
Quoted 6 lines
Hi Ingo,
Can you send me the output from the build? It builds fine on my machine (a few warnings). The silentoldconfig made these changes to the .config file. (I did a git-remote update and reapplied my changes before building.)
dont have the log anymore, but i had to revert 3/4 due to the boot crash, could there be a dependency of 4/4 on 3/4?
the first two patches look fine and survived -tip testing.
Ingo
Re: [PATCH 4/4] x86: Replace xxx_pda() operations with x86_xx_percpu().
Quoted 18 lines · Ingo Molnar
Quoted 7 lines · Mike Travis
Quoted 6 lines · Ingo Molnar
Quoted 2 lines · Mike Travis
* It is now possible to use percpu operations for pda access since the pda is in the percpu area. Drop the pda operations.
FYI, this one didnt build with the attached config.
Quoted 8 lines
Quoted 2 lines
Ingo
Hi Ingo,
Can you send me the output from the build? It builds fine on my machine (a few warnings). The silentoldconfig made these changes to the .config file. (I did a git-remote update and reapplied my changes before building.)
Quoted 6 lines
dont have the log anymore, but i had to revert 3/4 due to the boot crash, could there be a dependency of 4/4 on 3/4?
the first two patches look fine and survived -tip testing.
Ingo
Thanks Ingo. I'm narrowing down the reboot problem by pulling config items out. I managed to get it to boot but now am trying to understand how those config options are causing the problem.
Btw, it does not panic/reboot on linux-next with the original config. Perhaps I should try and bisect to an earlier patch to see what that reveals?
Thanks,
Mike
PATCH 1/1 x86: collapse the various size-dependent percpu accessors together
In reply to Mike TravisWe can use gcc's %z modifier to emit the appropriate size suffix for an instruction, so we don't need to duplicate the asm statement for each size.
---include/asm-x86/percpu.h | 56 +++-------------------------------------------
1 file changed, 4 insertions(+), 52 deletions(-)
===================================================================
include/asm-x86/percpu.h +0 -0
@@ -75,22 +75,10 @@
} \
switch (sizeof(var)) { \
case 1: \
- asm(op "b %1,"__percpu_seg"%0" \
- : "+m" (var) \
- : "ri" ((T__)val)); \
- break; \
case 2: \
- asm(op "w %1,"__percpu_seg"%0" \
- : "+m" (var) \
- : "ri" ((T__)val)); \
- break; \
case 4: \
- asm(op "l %1,"__percpu_seg"%0" \
- : "+m" (var) \
- : "ri" ((T__)val)); \
- break; \
case 8: \
- asm(op "q %1,"__percpu_seg"%0" \
+ asm(op "%z0 %1,"__percpu_seg"%0" \
: "+m" (var) \
: "ri" ((T__)val)); \
break; \
@@ -103,22 +91,10 @@
typeof(var) ret__; \
switch (sizeof(var)) { \
case 1: \
- asm(op "b "__percpu_seg"%1,%0" \
- : "=r" (ret__) \
- : "m" (var)); \
- break; \
case 2: \
- asm(op "w "__percpu_seg"%1,%0" \
- : "=r" (ret__) \
- : "m" (var)); \
- break; \
case 4: \
- asm(op "l "__percpu_seg"%1,%0" \
- : "=r" (ret__) \
- : "m" (var)); \
- break; \
case 8: \
- asm(op "q "__percpu_seg"%1,%0" \
+ asm(op "%z1 "__percpu_seg"%1,%0" \
: "=r" (ret__) \
: "m" (var)); \
break; \
@@ -131,19 +107,10 @@
({ \
switch (sizeof(var)) { \
case 1: \
- asm(op "b "__percpu_seg"%0" \
- : : "m"(var)); \
- break; \
case 2: \
- asm(op "w "__percpu_seg"%0" \
- : : "m"(var)); \
- break; \
case 4: \
- asm(op "l "__percpu_seg"%0" \
- : : "m"(var)); \
- break; \
case 8: \
- asm(op "q "__percpu_seg"%0" \
+ asm(op "%z0 "__percpu_seg"%0" \
: : "m"(var)); \
break; \
default: __bad_percpu_size(); \
@@ -155,25 +122,10 @@
typeof(var) prev; \
switch (sizeof(var)) { \
case 1: \
- asm("cmpxchgb %b1, "__percpu_seg"%2" \
- : "=a"(prev) \
- : "q"(new), "m"(var), "0"(old) \
- : "memory"); \
- break; \
case 2: \
- asm("cmpxchgw %w1, "__percpu_seg"%2" \
- : "=a"(prev) \
- : "r"(new), "m"(var), "0"(old) \
- : "memory"); \
- break; \
case 4: \
- asm("cmpxchgl %k1, "__percpu_seg"%2" \
- : "=a"(prev) \
- : "r"(new), "m"(var), "0"(old) \
- : "memory"); \
- break; \
case 8: \
- asm("cmpxchgq %1, "__percpu_seg"%2" \
+ asm("cmpxchg%z1 %1, "__percpu_seg"%2" \
: "=a"(prev) \
: "r"(new), "m"(var), "0"(old) \
: "memory"); \Re: [PATCH] x86: collapse the various size-dependent percpu accessors together
Quoted 3 lines · Jeremy Fitzhardinge
We can use gcc's %z modifier to emit the appropriate size suffix for an instruction, so we don't need to duplicate the asm statement for each size.
Nah, it's a disaster. Drop this one.
J
Re: [PATCH] x86: collapse the various size-dependent percpu accessors together
Quoted 6 lines · Jeremy Fitzhardinge
Quoted 3 lines · Jeremy Fitzhardinge
We can use gcc's %z modifier to emit the appropriate size suffix for an instruction, so we don't need to duplicate the asm statement for each size.
Nah, it's a disaster. Drop this one.
hm, what's the problem with it? What you are trying to do here looks like a nice cleanup - assuming it results in the same instructions emitted ;-)
Ingo
Re: [PATCH] x86: collapse the various size-dependent percpu accessors together
Quoted 5 lines · Ingo Molnar
Quoted 2 lines · Jeremy Fitzhardinge
Jeremy Fitzhardinge wrote:
Quoted 8 lines
Quoted 6 lines
Quoted 4 lines
We can use gcc's %z modifier to emit the appropriate size suffix for an instruction, so we don't need to duplicate the asm statement for each size.
Nah, it's a disaster. Drop this one.
hm, what's the problem with it? What you are trying to do here looks like a nice cleanup - assuming it results in the same instructions emitted ;-)
Yes, would have been lovely. But gcc emits junk:
CC arch/x86/xen/enlighten.o
{standard input}: Assembler messages:
{standard input}:637: Error: no such instruction: movll %gs:per_cpu__xen_vcpu(%rip),%rax' {standard input}:655: Error: no such instruction: movll %gs:per_cpu__xen_vcpu(%rip),%rax' {standard input}:671: Error: no such instruction: movll %gs:per_cpu__xen_vcpu(%rip),%rax' {standard input}:682: Error: no such instruction: movll %gs:per_cpu__xen_vcpu(%rip),%rax' {standard input}:783: Error: no such instruction: movll %gs:per_cpu__pda+8(%rip),%rbx' {standard input}:834: Error: no such instruction: movll %gs:per_cpu__xen_mc_irq_flags(%rip),%rdi' {standard input}:901: Error: no such instruction: movll %gs:per_cpu__pda+8(%rip),%rbx' {standard input}:978: Error: no such instruction: movll %gs:per_cpu__xen_mc_irq_flags(%rip),%rdi' {standard input}:1064: Error: no such instruction: movll %gs:per_cpu__pda+8(%rip),%rbx' {standard input}:1110: Error: no such instruction: movll %gs:per_cpu__xen_mc_irq_flags(%rip),%rdi'
...
CC arch/x86/vdso/vclock_gettime.o
{standard input}: Assembler messages:
{standard input}:75: Error: suffix or operands invalid for `movs'
(all over the place)
I tried a version to do 64-bit accesses with an explicit "movq" to solve the "movll" problem, but it generates "movs" on occasion and that was the point I gave up.
J
Re: [PATCH] x86: collapse the various size-dependent percpu accessors together
Quoted 3 lines
I tried a version to do 64-bit accesses with an explicit "movq" to solve the "movll" problem, but it generates "movs" on occasion and that was the point I gave up.
Shucks. Would have been a great approach.