* RE: ip_contrack refuses to load if built UP as a module on IA64 [not found] ` <ed5aea43050830150112ee6103@mail.gmail.com> @ 2005-09-01 4:59 ` Peter Chubb 2005-09-22 22:04 ` dann frazier 0 siblings, 1 reply; 5+ messages in thread From: Peter Chubb @ 2005-09-01 4:59 UTC (permalink / raw) To: linux-ia64, tony.luck, dmosberger; +Cc: linux-kernel This patch makes UP and SMP do the same thing as far as module per-cpu data go. Unfortunately it affects core code. To repeat the problem: IA64 keeps per-cpu data in a small data area that is referenced by a 22-bit offset, for both UP and SMP cases. If a module defines per-cpu data, it too will end up in the small-data area. But the module loader at present special-cases the UP treatment of per-cpu data, assumes that it is in the GP-relative data area, and does nothing (for SMP it allocates space, and copies initialised data items into it) The effect is that modules defining per-cpu data fail to load if they're built UP, because of an impossible relocation. The appended patch makes the treatment of per-cpu data uniform between UP and SMP cases. For most architectures, the per-cpu data section will be empty for UP, and so the per-cpu setup code will not be invoked. Signed-off-by: Peter Chubb <peterc@gelato.unsw.edu.au> diff --git a/arch/ia64/kernel/module.c b/arch/ia64/kernel/module.c --- a/arch/ia64/kernel/module.c +++ b/arch/ia64/kernel/module.c @@ -951,4 +951,10 @@ percpu_modcopy (void *pcpudst, const voi if (cpu_possible(i)) memcpy(pcpudst + __per_cpu_offset[i], src, size); } +#else +void +percpu_modcopy (void *pcpudst, const void *src, unsigned long size) +{ + memcpy(pcpudst, src, size); +} #endif /* CONFIG_SMP */ diff --git a/kernel/module.c b/kernel/module.c --- a/kernel/module.c +++ b/kernel/module.c @@ -209,7 +209,6 @@ static struct module *find_module(const return NULL; } -#ifdef CONFIG_SMP /* Number of blocks used and allocated. */ static unsigned int pcpu_num_used, pcpu_num_allocated; /* Size of each block. -ve means used. */ @@ -352,29 +351,7 @@ static int percpu_modinit(void) return 0; } __initcall(percpu_modinit); -#else /* ... !CONFIG_SMP */ -static inline void *percpu_modalloc(unsigned long size, unsigned long align, - const char *name) -{ - return NULL; -} -static inline void percpu_modfree(void *pcpuptr) -{ - BUG(); -} -static inline unsigned int find_pcpusec(Elf_Ehdr *hdr, - Elf_Shdr *sechdrs, - const char *secstrings) -{ - return 0; -} -static inline void percpu_modcopy(void *pcpudst, const void *src, - unsigned long size) -{ - /* pcpusec should be 0, and size of that section should be 0. */ - BUG_ON(size != 0); -} -#endif /* CONFIG_SMP */ + #ifdef CONFIG_MODULE_UNLOAD #define MODINFO_ATTR(field) \ ^ permalink raw reply [flat|nested] 5+ messages in thread
* RE: ip_contrack refuses to load if built UP as a module on IA64 2005-09-01 4:59 ` ip_contrack refuses to load if built UP as a module on IA64 Peter Chubb @ 2005-09-22 22:04 ` dann frazier 2005-12-19 21:07 ` Luck, Tony 0 siblings, 1 reply; 5+ messages in thread From: dann frazier @ 2005-09-22 22:04 UTC (permalink / raw) To: Peter Chubb; +Cc: linux-ia64, tony.luck, dmosberger, linux-kernel On Thu, 2005-09-01 at 14:59 +1000, Peter Chubb wrote: > > This patch makes UP and SMP do the same thing as far as module per-cpu > data go. > > Unfortunately it affects core code. It causes 2.6.13/x86 to fail to link: kernel/built-in.o: In function `load_module': : undefined reference to `percpu_modcopy' make: *** [.tmp_vmlinux1] Error 1 fyi, this is a problem we're seeing in the Debian UP packages: http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=325070 ^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: ip_contrack refuses to load if built UP as a module on IA64 2005-09-22 22:04 ` dann frazier @ 2005-12-19 21:07 ` Luck, Tony 2006-01-10 21:21 ` dann frazier 0 siblings, 1 reply; 5+ messages in thread From: Luck, Tony @ 2005-12-19 21:07 UTC (permalink / raw) To: dann frazier; +Cc: Peter Chubb, linux-ia64, dmosberger, linux-kernel On Thu, Sep 22, 2005 at 04:04:59PM -0600, dann frazier wrote: > On Thu, 2005-09-01 at 14:59 +1000, Peter Chubb wrote: > > > > This patch makes UP and SMP do the same thing as far as module per-cpu > > data go. > > > > Unfortunately it affects core code. > > It causes 2.6.13/x86 to fail to link: > kernel/built-in.o: In function `load_module': > : undefined reference to `percpu_modcopy' > make: *** [.tmp_vmlinux1] Error 1 > > fyi, this is a problem we're seeing in the Debian UP packages: > http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=325070 Another possible solution is to make ia64 more like other architectures and make per-cpu variables just turn into ordinary variables on UP. There are some pros and cons to this: +) Being more like other architectures makes it less likely that we'll be burned by changes in generic code/tools that depend on implementation details -) We probably get worse code to access per-cpu variables from C-compiled code, and definitely get worse code in a couple of critical paths in assembler (where an "addl" becomes a "movl") Here's the patch ... lightly tested (just booted and checked that I could load the ip_conntrack module). -Tony diff --git a/arch/ia64/kernel/entry.S b/arch/ia64/kernel/entry.S index 0741b06..c678224 100644 --- a/arch/ia64/kernel/entry.S +++ b/arch/ia64/kernel/entry.S @@ -766,7 +766,11 @@ ENTRY(ia64_leave_syscall) ld8.fill r15=[r3] // M0|1 restore r15 mov b6=r18 // I0 restore b6 +#ifdef CONFIG_SMP addl r17=THIS_CPU(ia64_phys_stacked_size_p8),r0 // A +#else + movl r17=THIS_CPU(ia64_phys_stacked_size_p8) +#endif mov f9=f0 // F clear f9 (pKStk) br.cond.dpnt.many skip_rbs_switch // B @@ -952,7 +956,11 @@ GLOBAL_ENTRY(ia64_leave_kernel) shr.u r18=r19,16 // get byte size of existing "dirty" partition ;; mov r16=ar.bsp // get existing backing store pointer +#ifdef CONFIG_SMP addl r17=THIS_CPU(ia64_phys_stacked_size_p8),r0 +#else + movl r17=THIS_CPU(ia64_phys_stacked_size_p8) +#endif ;; ld4 r17=[r17] // r17 = cpu_data->phys_stacked_size_p8 (pKStk) br.cond.dpnt skip_rbs_switch diff --git a/arch/ia64/kernel/head.S b/arch/ia64/kernel/head.S index bfe65b2..4414970 100644 --- a/arch/ia64/kernel/head.S +++ b/arch/ia64/kernel/head.S @@ -980,7 +980,11 @@ END(ia64_delay_loop) * intermediate precision so that we can produce a full 64-bit result. */ GLOBAL_ENTRY(sched_clock) +#ifdef CONFIG_SMP addl r8=THIS_CPU(cpu_info) + IA64_CPUINFO_NSEC_PER_CYC_OFFSET,r0 +#else + movl r8=THIS_CPU(cpu_info) + IA64_CPUINFO_NSEC_PER_CYC_OFFSET +#endif mov.m r9=ar.itc // fetch cycle-counter (35 cyc) ;; ldf8 f8=[r8] diff --git a/arch/ia64/kernel/mca.c b/arch/ia64/kernel/mca.c index 355af15..b6391c9 100644 --- a/arch/ia64/kernel/mca.c +++ b/arch/ia64/kernel/mca.c @@ -1474,12 +1474,14 @@ ia64_mca_cpu_init(void *cpu_data) */ __get_cpu_var(ia64_mca_data) = __per_cpu_mca[smp_processor_id()]; +#ifdef CONFIG_SMP /* * Stash away a copy of the PTE needed to map the per-CPU page. * We may need it during MCA recovery. */ __get_cpu_var(ia64_mca_per_cpu_pte) = pte_val(mk_pte_phys(__pa(cpu_data), PAGE_KERNEL)); +#endif /* * Also, stash away a copy of the PAL address and the PTE diff --git a/arch/ia64/kernel/mca_asm.S b/arch/ia64/kernel/mca_asm.S index db32fc1..45d8b30 100644 --- a/arch/ia64/kernel/mca_asm.S +++ b/arch/ia64/kernel/mca_asm.S @@ -102,6 +102,7 @@ ia64_do_tlb_purge: ;; srlz.d ;; +#ifdef CONFIG_SMP // 2. Purge DTR for PERCPU data. movl r16=PERCPU_ADDR mov r18=PERCPU_PAGE_SHIFT<<2 @@ -110,6 +111,7 @@ ia64_do_tlb_purge: ;; srlz.d ;; +#endif // 3. Purge ITR for PAL code. GET_THIS_PADDR(r2, ia64_mca_pal_base) ;; @@ -197,6 +199,7 @@ ia64_reload_tr: srlz.i srlz.d ;; +#ifdef CONFIG_SMP // 2. Reload DTR register for PERCPU data. GET_THIS_PADDR(r2, ia64_mca_per_cpu_pte) ;; @@ -213,6 +216,7 @@ ia64_reload_tr: ;; srlz.d ;; +#endif // 3. Reload ITR for PAL code. GET_THIS_PADDR(r2, ia64_mca_pal_pte) ;; diff --git a/arch/ia64/kernel/setup.c b/arch/ia64/kernel/setup.c index 5add0bc..ef2dc6c 100644 --- a/arch/ia64/kernel/setup.c +++ b/arch/ia64/kernel/setup.c @@ -752,6 +752,7 @@ cpu_init (void) struct cpuinfo_ia64 *cpu_info; void *cpu_data; +#ifdef CONFIG_SMP cpu_data = per_cpu_init(); /* @@ -761,9 +762,11 @@ cpu_init (void) */ ia64_set_kr(IA64_KR_PER_CPU_DATA, ia64_tpa(cpu_data) - (long) __per_cpu_start); +#endif get_max_cacheline_size(); +#ifdef CONFIG_SMP /* * We can't pass "local_cpu_data" to identify_cpu() because we haven't called * ia64_mmu_init() yet. And we can't call ia64_mmu_init() first because it @@ -771,6 +774,11 @@ cpu_init (void) * accessing cpu_data() through the canonical per-CPU address. */ cpu_info = cpu_data + ((char *) &__ia64_per_cpu_var(cpu_info) - __per_cpu_start); + cpu_data = ia64_imva(cpu_data); +#else + cpu_info = &per_cpu(cpu_info, 0); + cpu_data = 0; +#endif identify_cpu(cpu_info); #ifdef CONFIG_MCKINLEY @@ -817,8 +825,8 @@ cpu_init (void) if (current->mm) BUG(); - ia64_mmu_init(ia64_imva(cpu_data)); - ia64_mca_cpu_init(ia64_imva(cpu_data)); + ia64_mmu_init(cpu_data); + ia64_mca_cpu_init(cpu_data); #ifdef CONFIG_IA32_SUPPORT ia32_cpu_init(); diff --git a/arch/ia64/kernel/vmlinux.lds.S b/arch/ia64/kernel/vmlinux.lds.S index 30d8564..2b3fa83 100644 --- a/arch/ia64/kernel/vmlinux.lds.S +++ b/arch/ia64/kernel/vmlinux.lds.S @@ -19,7 +19,9 @@ ENTRY(phys_start) jiffies = jiffies_64; PHDRS { code PT_LOAD; +#ifdef CONFIG_SMP percpu PT_LOAD; +#endif data PT_LOAD; } SECTIONS @@ -180,6 +182,7 @@ SECTIONS .data.cacheline_aligned : AT(ADDR(.data.cacheline_aligned) - LOAD_OFFSET) { *(.data.cacheline_aligned) } +#ifdef CONFIG_SMP /* Per-cpu data: */ percpu : { } :percpu . = ALIGN(PERCPU_PAGE_SIZE); @@ -191,6 +194,7 @@ SECTIONS __per_cpu_end = .; } . = __phys_per_cpu_start + PERCPU_PAGE_SIZE; /* ensure percpu data fits into percpu page size */ +#endif data : { } :data .data : AT(ADDR(.data) - LOAD_OFFSET) diff --git a/arch/ia64/mm/init.c b/arch/ia64/mm/init.c index e3215ba..5def017 100644 --- a/arch/ia64/mm/init.c +++ b/arch/ia64/mm/init.c @@ -332,7 +332,7 @@ setup_gate (void) void __devinit ia64_mmu_init (void *my_cpu_data) { - unsigned long psr, pta, impl_va_bits; + unsigned long pta, impl_va_bits; extern void __devinit tlb_init (void); #ifdef CONFIG_DISABLE_VHPT @@ -341,6 +341,10 @@ ia64_mmu_init (void *my_cpu_data) # define VHPT_ENABLE_BIT 1 #endif +#ifdef CONFIG_SMP +{ + unsigned long psr; + /* Pin mapping for percpu area into TLB */ psr = ia64_clear_ic(); ia64_itr(0x2, IA64_TR_PERCPU_DATA, PERCPU_ADDR, @@ -349,6 +353,8 @@ ia64_mmu_init (void *my_cpu_data) ia64_set_psr(psr); ia64_srlz_i(); +} +#endif /* * Check if the virtually mapped linear page table (VMLPT) overlaps with a mapped diff --git a/include/asm-ia64/mca_asm.h b/include/asm-ia64/mca_asm.h index 27c9203..26d8710 100644 --- a/include/asm-ia64/mca_asm.h +++ b/include/asm-ia64/mca_asm.h @@ -48,9 +48,14 @@ mov temp = 0x7 ;; \ dep addr = temp, addr, 61, 3 +#ifdef CONFIG_SMP #define GET_THIS_PADDR(reg, var) \ mov reg = IA64_KR(PER_CPU_DATA);; \ addl reg = THIS_CPU(var), reg +#else +#define GET_THIS_PADDR(reg, var) \ + LOAD_PHYSICAL(p0, reg, per_cpu__##var) +#endif /* * This macro jumps to the instruction at the given virtual address diff --git a/include/asm-ia64/percpu.h b/include/asm-ia64/percpu.h index 2b14dee..9248d17 100644 --- a/include/asm-ia64/percpu.h +++ b/include/asm-ia64/percpu.h @@ -16,7 +16,7 @@ #include <linux/threads.h> -#ifdef HAVE_MODEL_SMALL_ATTRIBUTE +#if defined(HAVE_MODEL_SMALL_ATTRIBUTE) && defined(CONFIG_SMP) # define __SMALL_ADDR_AREA __attribute__((__model__ (__small__))) #else # define __SMALL_ADDR_AREA @@ -25,6 +25,7 @@ #define DECLARE_PER_CPU(type, name) \ extern __SMALL_ADDR_AREA __typeof__(type) per_cpu__##name +#ifdef CONFIG_SMP /* Separate out the type, so (int[3], foo) works. */ #define DEFINE_PER_CPU(type, name) \ __attribute__((__section__(".data.percpu"))) \ @@ -34,7 +35,6 @@ * Pretty much a literal copy of asm-generic/percpu.h, except that percpu_modcopy() is an * external routine, to avoid include-hell. */ -#ifdef CONFIG_SMP extern unsigned long __per_cpu_offset[NR_CPUS]; @@ -50,6 +50,9 @@ extern void *per_cpu_init(void); #else /* ! SMP */ +#define DEFINE_PER_CPU(type, name) \ + __typeof__(type) per_cpu__##name + #define per_cpu(var, cpu) (*((void)(cpu), &per_cpu__##var)) #define __get_cpu_var(var) per_cpu__##var #define per_cpu_init() (__phys_per_cpu_start) ^ permalink raw reply related [flat|nested] 5+ messages in thread
* Re: ip_contrack refuses to load if built UP as a module on IA64 2005-12-19 21:07 ` Luck, Tony @ 2006-01-10 21:21 ` dann frazier 2006-01-22 19:31 ` dann frazier 0 siblings, 1 reply; 5+ messages in thread From: dann frazier @ 2006-01-10 21:21 UTC (permalink / raw) To: Luck, Tony; +Cc: Peter Chubb, linux-ia64, dmosberger, linux-kernel On Mon, 2005-12-19 at 13:07 -0800, Luck, Tony wrote: > On Thu, Sep 22, 2005 at 04:04:59PM -0600, dann frazier wrote: > > On Thu, 2005-09-01 at 14:59 +1000, Peter Chubb wrote: > > > > > > This patch makes UP and SMP do the same thing as far as module per-cpu > > > data go. > > > > > > Unfortunately it affects core code. > > > > It causes 2.6.13/x86 to fail to link: > > kernel/built-in.o: In function `load_module': > > : undefined reference to `percpu_modcopy' > > make: *** [.tmp_vmlinux1] Error 1 > > > > fyi, this is a problem we're seeing in the Debian UP packages: > > http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=325070 > > Another possible solution is to make ia64 more like other > architectures and make per-cpu variables just turn into > ordinary variables on UP. There are some pros and cons to > this: > > +) Being more like other architectures makes it less likely that > we'll be burned by changes in generic code/tools that depend > on implementation details > > -) We probably get worse code to access per-cpu variables from > C-compiled code, and definitely get worse code in a couple of > critical paths in assembler (where an "addl" becomes a "movl") > > Here's the patch ... lightly tested (just booted and checked that > I could load the ip_conntrack module). Thanks Tony; sorry for taking so long to test this. I required an additional change to discontig.c to get this to build w/ the Debian config. With this additional patch, a UP kernel boots fine on my rx2600. --- build-ia64-none-mckinley/arch/ia64/mm/discontig.c~ 2006-01-02 20:21:10.000000000 -0700 +++ build-ia64-none-mckinley/arch/ia64/mm/discontig.c 2006-01-09 19:56:58.000000000 -0700 @@ -339,8 +339,7 @@ struct cpuinfo_ia64 *cpu0_cpu_info; cpu = 0; node = node_cpuid[cpu].nid; - cpu0_cpu_info = (struct cpuinfo_ia64 *)(__phys_per_cpu_start + - ((char *)&per_cpu__cpu_info - __per_cpu_start)); + cpu0_cpu_info = &per_cpu(cpu_info, 0); cpu0_cpu_info->node_data = mem_data[node].node_data; } #endif /* CONFIG_SMP */ ^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: ip_contrack refuses to load if built UP as a module on IA64 2006-01-10 21:21 ` dann frazier @ 2006-01-22 19:31 ` dann frazier 0 siblings, 0 replies; 5+ messages in thread From: dann frazier @ 2006-01-22 19:31 UTC (permalink / raw) To: Luck, Tony; +Cc: Peter Chubb, linux-ia64, dmosberger, linux-kernel On Tue, 2006-01-10 at 14:21 -0700, dann frazier wrote: > On Mon, 2005-12-19 at 13:07 -0800, Luck, Tony wrote: > > On Thu, Sep 22, 2005 at 04:04:59PM -0600, dann frazier wrote: > > > On Thu, 2005-09-01 at 14:59 +1000, Peter Chubb wrote: > > > > > > > > This patch makes UP and SMP do the same thing as far as module per-cpu > > > > data go. > > > > > > > > Unfortunately it affects core code. > > > > > > It causes 2.6.13/x86 to fail to link: > > > kernel/built-in.o: In function `load_module': > > > : undefined reference to `percpu_modcopy' > > > make: *** [.tmp_vmlinux1] Error 1 > > > > > > fyi, this is a problem we're seeing in the Debian UP packages: > > > http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=325070 > > > > Another possible solution is to make ia64 more like other > > architectures and make per-cpu variables just turn into > > ordinary variables on UP. There are some pros and cons to > > this: > > > > +) Being more like other architectures makes it less likely that > > we'll be burned by changes in generic code/tools that depend > > on implementation details > > > > -) We probably get worse code to access per-cpu variables from > > C-compiled code, and definitely get worse code in a couple of > > critical paths in assembler (where an "addl" becomes a "movl") > > > > Here's the patch ... lightly tested (just booted and checked that > > I could load the ip_conntrack module). > > Thanks Tony; sorry for taking so long to test this. I required an > additional change to discontig.c to get this to build w/ the Debian > config. With this additional patch, a UP kernel boots fine on my > rx2600. fyi, just noticed that the efivars module still doesn't load. ^ permalink raw reply [flat|nested] 5+ messages in thread
end of thread, other threads:[~2006-01-22 19:31 UTC | newest] Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- [not found] <B8E391BBE9FE384DAA4C5C003888BE6F0443A5FA@scsmsx401.amr.corp.intel.com> [not found] ` <ed5aea430508301229386fc596@mail.gmail.com> [not found] ` <17172.54563.329758.846131@wombat.chubb.wattle.id.au> [not found] ` <ed5aea43050830150112ee6103@mail.gmail.com> 2005-09-01 4:59 ` ip_contrack refuses to load if built UP as a module on IA64 Peter Chubb 2005-09-22 22:04 ` dann frazier 2005-12-19 21:07 ` Luck, Tony 2006-01-10 21:21 ` dann frazier 2006-01-22 19:31 ` dann frazier
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for NNTP newsgroup(s).