Hi, Isaku

Isaku Yamahata wrote:
> On Tue, Apr 21, 2009 at 11:49:55AM +0900, Isaku Yamahata wrote:
>> On Tue, Apr 21, 2009 at 11:19:06AM +0900, Isaku Yamahata wrote:
>>> On Tue, Apr 21, 2009 at 10:27:02AM +0900, Akio Takebe wrote:
>>>> Hi,
>>>>
>>>> The following changeset broke booting xen-ia64 on some kinds of ia64 boxes.
>>>> http://xenbits.xensource.com/ext/ia64/xen-unstable.hg/rev/3fd8f9b34941
>>>>
>>>> The tasklet_schedule call raise_softirq().
>>>> Because raise_softirq() use per_cpu, if we access per_cpu before cpu_init()
>>>> the behavior would be unexpected.
>>>>
>>>> I make the following patch for this investigation.
>>>> It can boot xen-ia64 on the ia64 boxes.
>>>> I'm not sure why Tiger4 can boot the latest xen-ia64.
>>>> I didn't find a good-looking solution, what do you think about it?
>>> Unfortunately, it happened to boot on my tiger4 so that I pushed out
>>> the change set.
>>> I Understood the issue. Looking into the boot sequence, it seems
>>> to somewhat difficult to move down init_console() after cpu_init()
>>> and remove all the printk() before cpu_init().
>>> Hmm, it needs some consideration.
>>>
>>> BTW, is there similar issue on ia64 linux case before?
>> Yes, there was.
>> commit 10617bbe84628eb18ab5f723d3ba35005adde143
>> and
>> commit c459ce8b5a7d933a3bcf6915ab17ac1e036e2ac4
>>
>> The mails were
>> Jul 14 Christian Kande Initialization order problem
>> and
>> Aug 07 Luck, Tony      [RFC] Fix early access to per-cpu variables
>> thread.
> 
> I created the patch following ia64 linux way.
> Could you try it?
> This is not intrusive to the common code, and prevent
> future similar breakage.
> 
I tried it, and I could boot the latest xen-ia64 on the ia64 box.
I agree with you. Please commit this.

Best Regards,

Akio Takebe

> [IA64] fix early access to per cpu area.
> 
> The following changeset broke booting xen-ia64 on some kinds of ia64 boxes.
> http://xenbits.xensource.com/ext/ia64/xen-unstable.hg/rev/3fd8f9b34941
> 
> The tasklet_schedule call raise_softirq().
> Because raise_softirq() use per_cpu, if we access per_cpu before cpu_init()
> the behavior would be unexpected.
> 
> There was a similar issueson Linux/ia64.
> The following change sets resolved it.
>       10617bbe84628eb18ab5f723d3ba35005adde143
>       c459ce8b5a7d933a3bcf6915ab17ac1e036e2ac4
> 
> This patch fixes the issue following the linux/ia64 solution.
> Allocate per cpu area for cpu0 in .data section and initialize
> it early.
> 
> reported-by: Akio Takebe <takebe_a...@jp.fujitsu.com>
> Signed-off-by: Isaku Yamahata <yamah...@valinux.co.jp>
> 
> diff --git a/xen/arch/ia64/linux-xen/head.S b/xen/arch/ia64/linux-xen/head.S
> --- a/xen/arch/ia64/linux-xen/head.S
> +++ b/xen/arch/ia64/linux-xen/head.S
> @@ -382,6 +382,35 @@ 1:       // now we are in virtual mode
>       mov ar.rsc=0            // place RSE in enforced lazy mode
>       ;;
>       loadrs                  // clear the dirty partition
> +#ifdef XEN
> +(isAP)       br.few 2f
> +     movl r19=__phys_per_cpu_start
> +     mov r18=PERCPU_PAGE_SIZE
> +#ifndef CONFIG_SMP
> +     add r19=r19,r18
> +     ;;
> +#else
> +     movl r20=__cpu0_per_cpu
> +     ;;
> +     shr.u r18=r18,3
> +1:
> +     ld8 r21=[r19],8 ;;
> +     st8[r20]=r21,8
> +     adds r18=-1,r18
> +     ;;
> +     cmp4.lt p7,p6=0,r18
> +(p7) br.cond.dptk.few 1b
> +     ;;
> +#endif
> +     movl r18=__per_cpu_offset
> +     movl r19=__cpu0_per_cpu
> +     movl r20=__per_cpu_start
> +     ;;
> +     sub r20=r19,r20
> +     ;;
> +     st8 [r18]=r20
> +2:
> +#endif
>       ;;
>       mov ar.bspstore=r2      // establish the new RSE stack
>       ;;
> diff --git a/xen/arch/ia64/linux-xen/mm_contig.c 
> b/xen/arch/ia64/linux-xen/mm_contig.c
> --- a/xen/arch/ia64/linux-xen/mm_contig.c
> +++ b/xen/arch/ia64/linux-xen/mm_contig.c
> @@ -183,7 +183,7 @@ void *percpu_area __initdata = NULL;
>  void* __init
>  per_cpu_allocate(void *xen_heap_start, unsigned long end_in_pa)
>  {
> -     int order = get_order(NR_CPUS * PERCPU_PAGE_SIZE);
> +     int order = get_order((NR_CPUS - 1) * PERCPU_PAGE_SIZE);
>       unsigned long size = 1UL << (order + PAGE_SHIFT);
>       unsigned long start = ALIGN_UP((unsigned long)xen_heap_start,
>                                      PERCPU_PAGE_SIZE);
> @@ -226,19 +226,31 @@ per_cpu_init (void)
>        */
>       if (smp_processor_id() == 0) {
>  #ifdef XEN
> +             void *cpu0_data = __cpu0_per_cpu;
> +
> +             __per_cpu_offset[0] = (char *)cpu0_data - __per_cpu_start;
> +             per_cpu(local_per_cpu_offset, 0) = __per_cpu_offset[0];
> +
>               cpu_data = get_per_cpu_area();
>               if (cpu_data == NULL) 
>                       panic("can't allocate per cpu area.\n");
> +
> +             for (cpu = 1; cpu < NR_CPUS; cpu++) {
> +                     memcpy(cpu_data, __phys_per_cpu_start, __per_cpu_end - 
> __per_cpu_start);
> +                     __per_cpu_offset[cpu] = (char *) cpu_data - 
> __per_cpu_start;
> +                     cpu_data += PERCPU_PAGE_SIZE;
> +                     per_cpu(local_per_cpu_offset, cpu) = 
> __per_cpu_offset[cpu];
> +             }
>  #else
>               cpu_data = __alloc_bootmem(PERCPU_PAGE_SIZE * NR_CPUS,
>                                          PERCPU_PAGE_SIZE, 
> __pa(MAX_DMA_ADDRESS));
> -#endif
>               for (cpu = 0; cpu < NR_CPUS; cpu++) {
>                       memcpy(cpu_data, __phys_per_cpu_start, __per_cpu_end - 
> __per_cpu_start);
>                       __per_cpu_offset[cpu] = (char *) cpu_data - 
> __per_cpu_start;
>                       cpu_data += PERCPU_PAGE_SIZE;
>                       per_cpu(local_per_cpu_offset, cpu) = 
> __per_cpu_offset[cpu];
>               }
> +#endif
>       }
>       return __per_cpu_start + __per_cpu_offset[smp_processor_id()];
>  }
> diff --git a/xen/arch/ia64/linux-xen/smpboot.c 
> b/xen/arch/ia64/linux-xen/smpboot.c
> --- a/xen/arch/ia64/linux-xen/smpboot.c
> +++ b/xen/arch/ia64/linux-xen/smpboot.c
> @@ -449,8 +449,8 @@ start_secondary (void *unused)
>  {
>       /* Early console may use I/O ports */
>       ia64_set_kr(IA64_KR_IO_BASE, __pa(ia64_iobase));
> +#ifndef XEN
>       Dprintk("start_secondary: starting CPU 0x%x\n", 
> hard_smp_processor_id());
> -#ifndef XEN
>       efi_map_pal_code();
>  #endif
>       cpu_init();
> diff --git a/xen/arch/ia64/xen/xen.lds.S b/xen/arch/ia64/xen/xen.lds.S
> --- a/xen/arch/ia64/xen/xen.lds.S
> +++ b/xen/arch/ia64/xen/xen.lds.S
> @@ -195,7 +195,17 @@ SECTIONS
>  
>    data : { } :data
>    .data : AT(ADDR(.data) - LOAD_OFFSET)
> -     { *(.data) *(.data1) *(.gnu.linkonce.d*) CONSTRUCTORS }
> +     {
> +#ifdef CONFIG_SMP
> +  . = ALIGN(PERCPU_PAGE_SIZE);
> +             __cpu0_per_cpu = .;
> + . = . + PERCPU_PAGE_SIZE;    /* cpu0 per-cpu space */
> +#endif
> +             *(.data)
> +             *(.data1)
> +             *(.gnu.linkonce.d*)
> +             CONSTRUCTORS
> +     }
>  
>    . = ALIGN(16);     /* gp must be 16-byte aligned for exc. table */
>    .got : AT(ADDR(.got) - LOAD_OFFSET)
> diff --git a/xen/include/asm-ia64/linux-xen/asm/README.origin 
> b/xen/include/asm-ia64/linux-xen/asm/README.origin
> --- a/xen/include/asm-ia64/linux-xen/asm/README.origin
> +++ b/xen/include/asm-ia64/linux-xen/asm/README.origin
> @@ -22,6 +22,7 @@ pgtable.h           -> linux/include/asm-ia64/pgt
>  processor.h          -> linux/include/asm-ia64/processor.h
>  ptrace.h             -> linux/include/asm-ia64/ptrace.h
>  sal.h                        -> linux/include/asm-ia64/sal.h
> +sections.h           -> linux/include/asm-ia64/sections.h
>  smp.h                        -> linux/include/asm-ia64/smp.h
>  spinlock.h           -> linux/include/asm-ia64/spinlock.h
>  system.h             -> linux/include/asm-ia64/system.h
> diff --git a/xen/include/asm-ia64/linux/asm/sections.h 
> b/xen/include/asm-ia64/linux-xen/asm/sections.h
> rename from xen/include/asm-ia64/linux/asm/sections.h
> rename to xen/include/asm-ia64/linux-xen/asm/sections.h
> --- a/xen/include/asm-ia64/linux/asm/sections.h
> +++ b/xen/include/asm-ia64/linux-xen/asm/sections.h
> @@ -9,6 +9,9 @@
>  #include <asm-generic/sections.h>
>  
>  extern char __per_cpu_start[], __per_cpu_end[], __phys_per_cpu_start[];
> +#ifdef CONFIG_SMP
> +extern char __cpu0_per_cpu[];
> +#endif
>  extern char __start___vtop_patchlist[], __end___vtop_patchlist[];
>  extern char __start___mckinley_e9_bundles[], __end___mckinley_e9_bundles[];
>  extern char __start_gate_section[];
> diff --git a/xen/include/asm-ia64/linux/asm/README.origin 
> b/xen/include/asm-ia64/linux/asm/README.origin
> --- a/xen/include/asm-ia64/linux/asm/README.origin
> +++ b/xen/include/asm-ia64/linux/asm/README.origin
> @@ -29,7 +29,6 @@ param.h                     -> linux/include/asm-ia64/para
>  patch.h                      -> linux/include/asm-ia64/patch.h
>  pci.h                        -> linux/include/asm-ia64/pci.h
>  rse.h                        -> linux/include/asm-ia64/rse.h
> -sections.h           -> linux/include/asm-ia64/sections.h
>  setup.h                      -> linux/include/asm-ia64/setup.h
>  string.h             -> linux/include/asm-ia64/string.h
>  thread_info.h                -> linux/include/asm-ia64/thread_info.h
> 
> 

_______________________________________________
Xen-ia64-devel mailing list
Xen-ia64-devel@lists.xensource.com
http://lists.xensource.com/xen-ia64-devel

Reply via email to