From bf5438fca2950b03c21ad868090cc1a8fcd49536 Mon Sep 17 00:00:00 2001 From: Jason Baron Date: Fri, 17 Sep 2010 11:09:00 -0400 Subject: jump label: Base patch for jump label base patch to implement 'jump labeling'. Based on a new 'asm goto' inline assembly gcc mechanism, we can now branch to labels from an 'asm goto' statment. This allows us to create a 'no-op' fastpath, which can subsequently be patched with a jump to the slowpath code. This is useful for code which might be rarely used, but which we'd like to be able to call, if needed. Tracepoints are the current usecase that these are being implemented for. Acked-by: David S. Miller Signed-off-by: Jason Baron LKML-Reference: [ cleaned up some formating ] Signed-off-by: Steven Rostedt --- include/asm-generic/vmlinux.lds.h | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'include/asm-generic/vmlinux.lds.h') diff --git a/include/asm-generic/vmlinux.lds.h b/include/asm-generic/vmlinux.lds.h index 8a92a170fb7d..ef2af9948eac 100644 --- a/include/asm-generic/vmlinux.lds.h +++ b/include/asm-generic/vmlinux.lds.h @@ -220,6 +220,8 @@ \ BUG_TABLE \ \ + JUMP_TABLE \ + \ /* PCI quirks */ \ .pci_fixup : AT(ADDR(.pci_fixup) - LOAD_OFFSET) { \ VMLINUX_SYMBOL(__start_pci_fixups_early) = .; \ @@ -563,6 +565,14 @@ #define BUG_TABLE #endif +#define JUMP_TABLE \ + . = ALIGN(8); \ + __jump_table : AT(ADDR(__jump_table) - LOAD_OFFSET) { \ + VMLINUX_SYMBOL(__start___jump_table) = .; \ + *(__jump_table) \ + VMLINUX_SYMBOL(__stop___jump_table) = .; \ + } + #ifdef CONFIG_PM_TRACE #define TRACEDATA \ . = ALIGN(4); \ -- cgit v1.2.3 From ffe8018c3424892c9590048fc36caa6c3e0c8a76 Mon Sep 17 00:00:00 2001 From: Hendrik Brueckner Date: Fri, 17 Sep 2010 15:24:11 -0700 Subject: initramfs: fix initramfs size calculation The size of a built-in initramfs is calculated in init/initramfs.c by "__initramfs_end - __initramfs_start". Those symbols are defined in the linker script include/asm-generic/vmlinux.lds.h: #define INIT_RAM_FS \ . = ALIGN(PAGE_SIZE); \ VMLINUX_SYMBOL(__initramfs_start) = .; \ *(.init.ramfs) \ VMLINUX_SYMBOL(__initramfs_end) = .; If the initramfs file has an odd number of bytes, the "__initramfs_end" symbol points to an odd address, for example, the symbols in the System.map might look like: 0000000000572000 T __initramfs_start 00000000005bcd05 T __initramfs_end <-- odd address At least on s390 this causes a problem: Certain s390 instructions, especially instructions for loading addresses (larl) or branch addresses must be on even addresses. The compiler loads the symbol addresses with the "larl" instruction. This instruction sets the last bit to 0 and, therefore, for odd size files, the calculated size is one byte less than it should be: 0000000000540a9c : 540a9c: eb cf f0 78 00 24 stmg %r12,%r15,120(%r15), 540aa2: c0 10 00 01 8a af larl %r1,572000 <__initramfs_start> 540aa8: c0 c0 00 03 e1 2e larl %r12,5bcd04 (Instead of 5bcd05) ... 540abe: 1b c1 sr %r12,%r1 To fix the problem, this patch introduces the global variable __initramfs_size, which is calculated in the "usr/initramfs_data.S" file. The populate_rootfs() function can then use the start marker of the .init.ramfs section and the value of __initramfs_size for loading the initramfs. Because the start marker and size is sufficient, the __initramfs_end symbol is no longer needed and is removed. Signed-off-by: Michael Holzheu Signed-off-by: Hendrik Brueckner Reviewed-by: WANG Cong Acked-by: Michal Marek Acked-by: "H. Peter Anvin" Cc: Heiko Carstens Cc: Martin Schwidefsky Signed-off-by: Andrew Morton Signed-off-by: Michal Marek --- include/asm-generic/vmlinux.lds.h | 3 ++- init/initramfs.c | 9 ++++----- usr/initramfs_data.S | 16 +++++++++++----- 3 files changed, 17 insertions(+), 11 deletions(-) (limited to 'include/asm-generic/vmlinux.lds.h') diff --git a/include/asm-generic/vmlinux.lds.h b/include/asm-generic/vmlinux.lds.h index 030a954ed292..0c6387d6a6ae 100644 --- a/include/asm-generic/vmlinux.lds.h +++ b/include/asm-generic/vmlinux.lds.h @@ -633,7 +633,8 @@ . = ALIGN(PAGE_SIZE); \ VMLINUX_SYMBOL(__initramfs_start) = .; \ *(.init.ramfs) \ - VMLINUX_SYMBOL(__initramfs_end) = .; + . = ALIGN(8); \ + *(.init.ramfs.info) #else #define INIT_RAM_FS #endif diff --git a/init/initramfs.c b/init/initramfs.c index 4b9c20205092..371c3da64ad3 100644 --- a/init/initramfs.c +++ b/init/initramfs.c @@ -483,7 +483,8 @@ static int __init retain_initrd_param(char *str) } __setup("retain_initrd", retain_initrd_param); -extern char __initramfs_start[], __initramfs_end[]; +extern char __initramfs_start[]; +extern unsigned long __initramfs_size; #include #include @@ -570,8 +571,7 @@ static void __init clean_rootfs(void) static int __init populate_rootfs(void) { - char *err = unpack_to_rootfs(__initramfs_start, - __initramfs_end - __initramfs_start); + char *err = unpack_to_rootfs(__initramfs_start, __initramfs_size); if (err) panic(err); /* Failed to decompress INTERNAL initramfs */ if (initrd_start) { @@ -585,8 +585,7 @@ static int __init populate_rootfs(void) return 0; } else { clean_rootfs(); - unpack_to_rootfs(__initramfs_start, - __initramfs_end - __initramfs_start); + unpack_to_rootfs(__initramfs_start, __initramfs_size); } printk(KERN_INFO "rootfs image is not initramfs (%s)" "; looks like an initrd\n", err); diff --git a/usr/initramfs_data.S b/usr/initramfs_data.S index 49a545fea120..b9efed5e35cc 100644 --- a/usr/initramfs_data.S +++ b/usr/initramfs_data.S @@ -11,11 +11,7 @@ -T initramfs_data.scr initramfs_data.cpio.gz -o initramfs_data.o ld -m elf_i386 -r -o built-in.o initramfs_data.o - initramfs_data.scr looks like this: -SECTIONS -{ - .init.ramfs : { *(.data) } -} + For including the .init.ramfs sections, see include/asm-generic/vmlinux.lds. The above example is for i386 - the parameters vary from architectures. Eventually look up LDFLAGS_BLOB in an older version of the @@ -28,4 +24,14 @@ SECTIONS #include .section .init.ramfs,"a" +__irf_start: .incbin __stringify(INITRAMFS_IMAGE) +__irf_end: +.section .init.ramfs.info,"a" +.globl __initramfs_size +__initramfs_size: +#ifdef CONFIG_32BIT + .long __irf_end - __irf_start +#else + .quad __irf_end - __irf_start +#endif -- cgit v1.2.3 From c957ef2c59e952803766ddc22e89981ab534606f Mon Sep 17 00:00:00 2001 From: Shaohua Li Date: Wed, 20 Oct 2010 11:07:02 +0800 Subject: percpu: Introduce a read-mostly percpu API Add a new readmostly percpu section and API. This can be used to avoid dirtying data lines which are generally not written to, which is especially important for data which may be accessed by processors other than the one for which the percpu area belongs to. [ hpa: moved it *after* the page-aligned section, for obvious reasons. ] Signed-off-by: Shaohua Li LKML-Reference: <1287544022.4571.7.camel@sli10-conroe.sh.intel.com> Cc: Eric Dumazet Signed-off-by: H. Peter Anvin --- include/asm-generic/vmlinux.lds.h | 4 ++++ include/linux/percpu-defs.h | 9 +++++++++ 2 files changed, 13 insertions(+) (limited to 'include/asm-generic/vmlinux.lds.h') diff --git a/include/asm-generic/vmlinux.lds.h b/include/asm-generic/vmlinux.lds.h index 8a92a170fb7d..d7e7b21511b1 100644 --- a/include/asm-generic/vmlinux.lds.h +++ b/include/asm-generic/vmlinux.lds.h @@ -677,7 +677,9 @@ - LOAD_OFFSET) { \ VMLINUX_SYMBOL(__per_cpu_start) = .; \ *(.data..percpu..first) \ + . = ALIGN(PAGE_SIZE); \ *(.data..percpu..page_aligned) \ + *(.data..percpu..readmostly) \ *(.data..percpu) \ *(.data..percpu..shared_aligned) \ VMLINUX_SYMBOL(__per_cpu_end) = .; \ @@ -703,6 +705,8 @@ VMLINUX_SYMBOL(__per_cpu_load) = .; \ VMLINUX_SYMBOL(__per_cpu_start) = .; \ *(.data..percpu..first) \ + . = ALIGN(PAGE_SIZE); \ + *(.data..percpu..readmostly) \ *(.data..percpu..page_aligned) \ *(.data..percpu) \ *(.data..percpu..shared_aligned) \ diff --git a/include/linux/percpu-defs.h b/include/linux/percpu-defs.h index ce2dc655cd1d..27ef6b190ea6 100644 --- a/include/linux/percpu-defs.h +++ b/include/linux/percpu-defs.h @@ -138,6 +138,15 @@ DEFINE_PER_CPU_SECTION(type, name, "..page_aligned") \ __aligned(PAGE_SIZE) +/* + * Declaration/definition used for per-CPU variables that must be read mostly. + */ +#define DECLARE_PER_CPU_READ_MOSTLY(type, name) \ + DECLARE_PER_CPU_SECTION(type, name, "..readmostly") + +#define DEFINE_PER_CPU_READ_MOSTLY(type, name) \ + DEFINE_PER_CPU_SECTION(type, name, "..readmostly") + /* * Intermodule exports for per-CPU variables. sparse forgets about * address space across EXPORT_SYMBOL(), change EXPORT_SYMBOL() to -- cgit v1.2.3 From 2aeb66d3036dbafc297ac553a257a40283dadb3e Mon Sep 17 00:00:00 2001 From: "H. Peter Anvin" Date: Thu, 21 Oct 2010 00:15:00 -0700 Subject: x86-32, percpu: Correct the ordering of the percpu readmostly section Checkin c957ef2c59e952803766ddc22e89981ab534606f had inconsistent ordering of .data..percpu..page_aligned and .data..percpu..readmostly; the still-broken version affected x86-32 at least. The page aligned version really must be page aligned... Signed-off-by: H. Peter Anvin LKML-Reference: <1287544022.4571.7.camel@sli10-conroe.sh.intel.com> Cc: Shaohua Li Cc: Eric Dumazet --- include/asm-generic/vmlinux.lds.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'include/asm-generic/vmlinux.lds.h') diff --git a/include/asm-generic/vmlinux.lds.h b/include/asm-generic/vmlinux.lds.h index d7e7b21511b1..1457b81357af 100644 --- a/include/asm-generic/vmlinux.lds.h +++ b/include/asm-generic/vmlinux.lds.h @@ -706,8 +706,8 @@ VMLINUX_SYMBOL(__per_cpu_start) = .; \ *(.data..percpu..first) \ . = ALIGN(PAGE_SIZE); \ - *(.data..percpu..readmostly) \ *(.data..percpu..page_aligned) \ + *(.data..percpu..readmostly) \ *(.data..percpu) \ *(.data..percpu..shared_aligned) \ VMLINUX_SYMBOL(__per_cpu_end) = .; \ -- cgit v1.2.3 From d356c0b680d15e0187de48aa303e541b461ea794 Mon Sep 17 00:00:00 2001 From: Mike Frysinger Date: Tue, 26 Oct 2010 14:22:29 -0700 Subject: vmlinux.lds.h: gather .data..shared_aligned sections in DATA_DATA With the recent change "net: remove time limit in process_backlog()", the softnet_data variable changed from "DEFINE_PER_CPU()" to "DEFINE_PER_CPU_ALIGNED()" which moved it from the .data section to the .data.shared_align section. I'm not saying this patch is wrong, just that is what caused me to notice this larger problem. No one else in the kernel is using this aligned macro variant, so I imagine that's why no one has noticed yet. Since .data..shared_align isn't declared in any vmlinux files that I can see, the linker just places it last. This "just works" for most people, but when building a ROM kernel on Blackfin systems, it causes section overlap errors: bfin-uclinux-ld.real: section .init.data [00000000202e06b8 -> 00000000202e48b7] overlaps section .data.shared_aligned [00000000202e06b8 -> 00000000202e0723] I imagine other arches which support the ROM config option and thus do funky placement would see similar issues ... On x86, it is stuck in a dedicated section at the end: [8] .data PROGBITS ffffffff810ec000 2ec0000303a8 00 WA 0 0 4096 [9] .data.shared_alig PROGBITS ffffffff8111c3c0 31c3c00000c8 00 WA 0 0 64 So make sure we include this section in the DATA_DATA macro so that it is placed in the right location. Signed-off-by: Mike Frysinger Cc: Sam Ravnborg Cc: Jeremy Fitzhardinge Cc: Rusty Russell Cc: Alan Jenkins Cc: Greg Ungerer Cc: Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/asm-generic/vmlinux.lds.h | 1 + 1 file changed, 1 insertion(+) (limited to 'include/asm-generic/vmlinux.lds.h') diff --git a/include/asm-generic/vmlinux.lds.h b/include/asm-generic/vmlinux.lds.h index f4229fb315e1..aaf1105d9d91 100644 --- a/include/asm-generic/vmlinux.lds.h +++ b/include/asm-generic/vmlinux.lds.h @@ -150,6 +150,7 @@ #define DATA_DATA \ *(.data) \ *(.ref.data) \ + *(.data..shared_aligned) /* percpu related */ \ DEV_KEEP(init.data) \ DEV_KEEP(exit.data) \ CPU_KEEP(init.data) \ -- cgit v1.2.3 From d88262623fb58853ed60fb110141c435de26e3de Mon Sep 17 00:00:00 2001 From: Mike Frysinger Date: Tue, 26 Oct 2010 14:22:30 -0700 Subject: vmlinux.lds.h: lower init ramfs alignment to 4 The new init ramfs format (cpio based) requires an alignment of 4 (per the documentation and per the source files themselves). As for compressed sources, the decompressors can all deal with unaligned buffers. The cpio source is also found in the __init sections of the kernel, so once they are read and expanded into a tmpfs, the source is freed. That means there is no need to force page alignment here either. This has been used on Blackfin systems for many releases without issue. Signed-off-by: Mike Frysinger Cc: Al Viro Cc: Sam Ravnborg Cc: Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/asm-generic/vmlinux.lds.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'include/asm-generic/vmlinux.lds.h') diff --git a/include/asm-generic/vmlinux.lds.h b/include/asm-generic/vmlinux.lds.h index aaf1105d9d91..2c0fc10956ba 100644 --- a/include/asm-generic/vmlinux.lds.h +++ b/include/asm-generic/vmlinux.lds.h @@ -637,7 +637,7 @@ #ifdef CONFIG_BLK_DEV_INITRD #define INIT_RAM_FS \ - . = ALIGN(PAGE_SIZE); \ + . = ALIGN(4); \ VMLINUX_SYMBOL(__initramfs_start) = .; \ *(.init.ramfs) \ VMLINUX_SYMBOL(__initramfs_end) = .; -- cgit v1.2.3