[kernel] r16848 - in dists/trunk/linux-2.6/debian: . patches/bugfix/sparc patches/series

Ben Hutchings benh at alioth.debian.org
Mon Jan 24 02:12:46 UTC 2011


Author: benh
Date: Mon Jan 24 02:12:36 2011
New Revision: 16848

Log:
[sparc] Fix misaligned tracing information (Closes: #609371)

Added:
   dists/trunk/linux-2.6/debian/patches/bugfix/sparc/introduce-u64-aligned.patch
   dists/trunk/linux-2.6/debian/patches/bugfix/sparc/tracing-use-u64-aligned-as-type-and-variable-attribute.patch
Modified:
   dists/trunk/linux-2.6/debian/changelog
   dists/trunk/linux-2.6/debian/patches/series/1~experimental.2

Modified: dists/trunk/linux-2.6/debian/changelog
==============================================================================
--- dists/trunk/linux-2.6/debian/changelog	Mon Jan 24 01:54:24 2011	(r16847)
+++ dists/trunk/linux-2.6/debian/changelog	Mon Jan 24 02:12:36 2011	(r16848)
@@ -5,6 +5,8 @@
     in another build failure
   * r8169: Keep firmware in memory (Closes: #609538)
   * r8712u: Firmware filename is rtlwifi/rtl8712u.bin (Closes: #602450)
+  * [sparc] Fix misaligned tracing information which the module loader
+    does not support (Closes: #609371)
 
   [ Aurelien Jarno ]
   * [sh4] Export cpu_core_map to fix build failure with CONFIG_SFC=m.

Added: dists/trunk/linux-2.6/debian/patches/bugfix/sparc/introduce-u64-aligned.patch
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ dists/trunk/linux-2.6/debian/patches/bugfix/sparc/introduce-u64-aligned.patch	Mon Jan 24 02:12:36 2011	(r16848)
@@ -0,0 +1,136 @@
+From: Mathieu Desnoyers <mathieu.desnoyers at efficios.com>
+Subject: introduce __u64_aligned and U64_ALIGN() for structure alignment in custom sections (v3)
+Date: Fri, 21 Jan 2011 15:36:31 -0500
+
+Problem description:
+
+gcc happily align on 32-byte structures defined statically. Ftrace trace events
+and Tracepoints both statically define structures into custom sections (using
+the "section" attribute), to then assign these to symbols with the linker
+scripts to iterate the these sections as an array.
+
+However, gcc uses different alignments for these structures when they are
+defined statically than when they are globally visible and/or in an array.
+Therefore iteration on these arrays sees "holes" of padding. gcc is within its
+rights to increase the alignment of the statically defined structures because,
+normally, there should be no other accesses to them than in the local object. We
+are actually iterating on the generated structures as if they were an array
+without letting gcc knowing anything about it.
+
+This patch introduces __u64_aligned to force gcc to use the u64 type and
+variable alignment, up-aligning or down-aligning the target type if necessary.
+The memory accesses to the target structure are efficient (does not require
+bytewise memory accesses) and the atomic pointer update guarantees required by
+RCU are kept. u64 is considered as the largest type that can generate a trap for
+unaligned accesses (u64 on sparc32 needs to be aligned on 64-bit).
+
+This alignment should be used for both structure definitions and declarations
+(as *both* the type and variable attribute) when using the "section"
+attribute to generate arrays of structures. Given that gcc only uses the type
+attribute "aligned" as a lower-bound for alignment, the structures should not
+contain types which require alignment larger than that of u64. The "aligned"
+variable attribute, on the other hand, forces gcc to use exactly the specified
+alignment.
+
+Also introduce the linker script U64_ALIGN() macro for specification of custom
+section alignment that matches that of __u64_aligned.
+
+Changelog since v2:
+- Drop the "packed" type attribute, because it causes gcc to drop the padding
+  between consecutive "int" and "pointer"/"long" fields, which leads to
+  unaligned accesses on sparc64.
+
+Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers at efficios.com>
+CC: David Miller <davem at davemloft.net>
+CC: Steven Rostedt <rostedt at goodmis.org>
+CC: Frederic Weisbecker <fweisbec at gmail.com>
+CC: Ingo Molnar <mingo at elte.hu>
+---
+ include/asm-generic/vmlinux.lds.h |    6 ++++
+ include/linux/align-section.h     |   54 ++++++++++++++++++++++++++++++++++++++
+ include/linux/compiler.h          |    2 +
+ 3 files changed, 62 insertions(+)
+
+--- a/include/linux/compiler.h
++++ b/include/linux/compiler.h
+@@ -57,6 +57,8 @@ extern void __chk_io_ptr(const volatile
+ # include <linux/compiler-intel.h>
+ #endif
+ 
++#include <linux/align-section.h>
++
+ /*
+  * Generic compiler-dependent macros required for kernel
+  * build go below this comment. Actual compiler/compiler version
+--- a/include/asm-generic/vmlinux.lds.h
++++ b/include/asm-generic/vmlinux.lds.h
+@@ -69,6 +69,12 @@
+  */
+ #define STRUCT_ALIGN() . = ALIGN(32)
+ 
++/*
++ * Align to a 8 byte boundary. For use with custom section made from structures
++ * declared and defined with __u64_aligned.
++ */
++#define U64_ALIGN() . = ALIGN(8)
++
+ /* The actual configuration determine if the init/exit sections
+  * are handled as text/data or they can be discarded (which
+  * often happens at runtime)
+--- /dev/null
++++ b/include/linux/align-section.h
+@@ -0,0 +1,54 @@
++#ifndef _LINUX_ALIGN_SECTION_H
++#define _LINUX_ALIGN_SECTION_H
++
++/*
++ * __u64_aligned:
++ *
++ * __u64_aligned should be used as type and variable attribute for structure
++ * definitions when using the "section" attribute to generate arrays of
++ * structures. U64_ALIGN() must be used prior to these section definitions in
++ * the linker script.
++ *
++ * It forces the compiler to use the u64 type alignment, up-aligning or
++ * down-aligning the target type if necessary. The memory accesses to the target
++ * structure are efficient (does not require bytewise memory accesses) and the
++ * atomic pointer update guarantees required by RCU are kept. u64 is considered
++ * as the largest type that can generate a trap for unaligned accesses (u64 on
++ * sparc32 needs to be aligned on 64-bit).
++ *
++ * Given that gcc only uses the type attribute "aligned" as a lower-bound for
++ * alignment, the structures should not contain types which require alignment
++ * larger than that of u64. The "aligned" variable attribute, on the other hand,
++ * forces gcc to use exactly the specified alignment.
++ */
++
++/*
++ * Use __u64_aligned as type and variable attribute for custom section structure
++ * declaration and definition.  It should also be applied to any static or
++ * extern definition of the structure that would override the definition to
++ * which the "section" attribute is applied, e.g.
++ *
++ * struct custom {
++ *         unsigned long field;
++ *         ...
++ * } __u64_aligned;
++ *
++ * extern struct __u64_aligned custom;
++ * struct custom  __u64_aligned __attribute__((section("__custom")) identifier;
++ *
++ * The array can then be defined with:
++ *
++ * extern struct custom __start___custom[];
++ * extern struct custom __stop___custom[];
++ *
++ * With linking performed by the linker script:
++ *
++ * U64_ALIGN();
++ * VMLINUX_SYMBOL(__start___custom) = .;
++ * *(__custom)
++ * VMLINUX_SYMBOL(__stop___custom) = .;
++ */
++
++#define __u64_aligned	__attribute__((__aligned__(__alignof__(long long))))
++
++#endif /* _LINUX_ALIGN_SECTION_H */

Added: dists/trunk/linux-2.6/debian/patches/bugfix/sparc/tracing-use-u64-aligned-as-type-and-variable-attribute.patch
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ dists/trunk/linux-2.6/debian/patches/bugfix/sparc/tracing-use-u64-aligned-as-type-and-variable-attribute.patch	Mon Jan 24 02:12:36 2011	(r16848)
@@ -0,0 +1,283 @@
+From: Mathieu Desnoyers <mathieu.desnoyers at efficios.com>
+Subject: tracing: fix sparc64 alignment crash with __u64_aligned/U64_ALIGN()
+Date: Fri, 21 Jan 2011 15:36:32 -0500
+
+Problem description:
+
+gcc happily align structures defined statically on 32-byte. Ftrace trace events
+and Tracepoints both statically define structures into sections (using the
+"section" attribute), to then assign these to symbols with the linker scripts to
+iterate the these sections as an array.
+
+However, gcc uses different alignments for these structures when they are
+defined statically and when they are globally visible and/or in an array.
+Therefore iteration on these arrays sees "holes" of padding.
+
+Use the __u64_aligned for type declarations and variable definitions to ensure
+that gcc:
+
+a) iterates on the correctly aligned type. (type attribute)
+b) generates the definitions within the sections with the appropriate alignment.
+   (variable attribute)
+
+The Ftrace code introduced the "aligned(4)" variable attribute in commit
+1473e4417c79f12d91ef91a469699bfa911f510f to try to work around this problem that
+showed up on x86_64, but it causes unaligned accesses on sparc64, and is
+generally a bad idea on 64-bit if RCU pointers are contained within the
+structure. Moreover, it did not use the same attribute as type attribute, which
+could cause the iteration on the extern array structure not to match the
+variable definitions for some structure sizes.
+
+We should also ensure proper alignment of each Ftrace section in
+include/asm-generic/vmlinux.lds.h.
+
+Moving all STRUCT_ALIGN() for FTRACE_EVENTS() and TRACE_SYSCALLS() into the
+definitions, so the alignment is only done if these infrastructures are
+configured in. Use U64_ALIGN instead of STRUCT_ALIGN.
+
+Also align TRACE_PRINTKS on U64_ALIGN to make sure the beginning of the section
+is aligned on pointer size.
+
+Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers at efficios.com>
+CC: David Miller <davem at davemloft.net>
+CC: Steven Rostedt <rostedt at goodmis.org>
+CC: Frederic Weisbecker <fweisbec at gmail.com>
+CC: Ingo Molnar <mingo at elte.hu>
+---
+ include/asm-generic/vmlinux.lds.h |   19 ++++++++++---------
+ include/linux/compiler.h          |    6 +++---
+ include/linux/ftrace_event.h      |    2 +-
+ include/linux/syscalls.h          |   18 ++++++++----------
+ include/trace/ftrace.h            |    8 ++++----
+ include/trace/syscall.h           |    2 +-
+ kernel/trace/trace.h              |    2 +-
+ kernel/trace/trace_export.c       |    2 +-
+ 8 files changed, 29 insertions(+), 30 deletions(-)
+
+--- a/include/linux/compiler.h
++++ b/include/linux/compiler.h
+@@ -80,7 +80,7 @@ struct ftrace_branch_data {
+ 		};
+ 		unsigned long miss_hit[2];
+ 	};
+-};
++} __u64_aligned;
+ 
+ /*
+  * Note: DISABLE_BRANCH_PROFILING can be used by special lowlevel code
+@@ -96,7 +96,7 @@ void ftrace_likely_update(struct ftrace_
+ #define __branch_check__(x, expect) ({					\
+ 			int ______r;					\
+ 			static struct ftrace_branch_data		\
+-				__attribute__((__aligned__(4)))		\
++				__u64_aligned				\
+ 				__attribute__((section("_ftrace_annotated_branch"))) \
+ 				______f = {				\
+ 				.func = __func__,			\
+@@ -131,7 +131,7 @@ void ftrace_likely_update(struct ftrace_
+ 	({								\
+ 		int ______r;						\
+ 		static struct ftrace_branch_data			\
+-			__attribute__((__aligned__(4)))			\
++			__u64_aligned					\
+ 			__attribute__((section("_ftrace_branch")))	\
+ 			______f = {					\
+ 				.func = __func__,			\
+--- a/include/linux/syscalls.h
++++ b/include/linux/syscalls.h
+@@ -126,12 +126,11 @@ extern struct trace_event_functions exit
+ 
+ #define SYSCALL_TRACE_ENTER_EVENT(sname)				\
+ 	static struct syscall_metadata					\
+-	__attribute__((__aligned__(4))) __syscall_meta_##sname;		\
++	  __u64_aligned __syscall_meta_##sname;				\
+ 	static struct ftrace_event_call					\
+-	__attribute__((__aligned__(4))) event_enter_##sname;		\
++	  __u64_aligned event_enter_##sname;				\
+ 	static struct ftrace_event_call __used				\
+-	  __attribute__((__aligned__(4)))				\
+-	  __attribute__((section("_ftrace_events")))			\
++	  __u64_aligned __attribute__((section("_ftrace_events")))	\
+ 	  event_enter_##sname = {					\
+ 		.name                   = "sys_enter"#sname,		\
+ 		.class			= &event_class_syscall_enter,	\
+@@ -141,12 +140,11 @@ extern struct trace_event_functions exit
+ 
+ #define SYSCALL_TRACE_EXIT_EVENT(sname)					\
+ 	static struct syscall_metadata					\
+-	__attribute__((__aligned__(4))) __syscall_meta_##sname;		\
++	__u64_aligned __syscall_meta_##sname;				\
+ 	static struct ftrace_event_call					\
+-	__attribute__((__aligned__(4))) event_exit_##sname;		\
++	__u64_aligned event_exit_##sname;				\
+ 	static struct ftrace_event_call __used				\
+-	  __attribute__((__aligned__(4)))				\
+-	  __attribute__((section("_ftrace_events")))			\
++	  __u64_aligned __attribute__((section("_ftrace_events")))	\
+ 	  event_exit_##sname = {					\
+ 		.name                   = "sys_exit"#sname,		\
+ 		.class			= &event_class_syscall_exit,	\
+@@ -158,7 +156,7 @@ extern struct trace_event_functions exit
+ 	SYSCALL_TRACE_ENTER_EVENT(sname);			\
+ 	SYSCALL_TRACE_EXIT_EVENT(sname);			\
+ 	static struct syscall_metadata __used			\
+-	  __attribute__((__aligned__(4)))			\
++	  __u64_aligned						\
+ 	  __attribute__((section("__syscalls_metadata")))	\
+ 	  __syscall_meta_##sname = {				\
+ 		.name 		= "sys"#sname,			\
+@@ -174,7 +172,7 @@ extern struct trace_event_functions exit
+ 	SYSCALL_TRACE_ENTER_EVENT(_##sname);			\
+ 	SYSCALL_TRACE_EXIT_EVENT(_##sname);			\
+ 	static struct syscall_metadata __used			\
+-	  __attribute__((__aligned__(4)))			\
++	  __u64_aligned						\
+ 	  __attribute__((section("__syscalls_metadata")))	\
+ 	  __syscall_meta__##sname = {				\
+ 		.name 		= "sys_"#sname,			\
+--- a/include/trace/ftrace.h
++++ b/include/trace/ftrace.h
+@@ -69,7 +69,7 @@
+ #undef DEFINE_EVENT
+ #define DEFINE_EVENT(template, name, proto, args)	\
+ 	static struct ftrace_event_call	__used		\
+-	__attribute__((__aligned__(4))) event_##name
++	__u64_aligned event_##name;
+ 
+ #undef DEFINE_EVENT_PRINT
+ #define DEFINE_EVENT_PRINT(template, name, proto, args, print)	\
+@@ -434,7 +434,7 @@ static inline notrace int ftrace_get_off
+  * };
+  *
+  * static struct ftrace_event_call __used
+- * __attribute__((__aligned__(4)))
++ * __u64_aligned
+  * __attribute__((section("_ftrace_events"))) event_<call> = {
+  *	.name			= "<call>",
+  *	.class			= event_class_<template>,
+@@ -567,7 +567,7 @@ static struct ftrace_event_class __used
+ #define DEFINE_EVENT(template, call, proto, args)			\
+ 									\
+ static struct ftrace_event_call __used					\
+-__attribute__((__aligned__(4)))						\
++__u64_aligned								\
+ __attribute__((section("_ftrace_events"))) event_##call = {		\
+ 	.name			= #call,				\
+ 	.class			= &event_class_##template,		\
+@@ -581,7 +581,7 @@ __attribute__((section("_ftrace_events")
+ static const char print_fmt_##call[] = print;				\
+ 									\
+ static struct ftrace_event_call __used					\
+-__attribute__((__aligned__(4)))						\
++__u64_aligned								\
+ __attribute__((section("_ftrace_events"))) event_##call = {		\
+ 	.name			= #call,				\
+ 	.class			= &event_class_##template,		\
+--- a/kernel/trace/trace.h
++++ b/kernel/trace/trace.h
+@@ -749,7 +749,7 @@ extern const char *__stop___trace_bprint
+ #undef FTRACE_ENTRY
+ #define FTRACE_ENTRY(call, struct_name, id, tstruct, print)		\
+ 	extern struct ftrace_event_call					\
+-	__attribute__((__aligned__(4))) event_##call;
++	__u64_aligned event_##call;
+ #undef FTRACE_ENTRY_DUP
+ #define FTRACE_ENTRY_DUP(call, struct_name, id, tstruct, print)		\
+ 	FTRACE_ENTRY(call, struct_name, id, PARAMS(tstruct), PARAMS(print))
+--- a/kernel/trace/trace_export.c
++++ b/kernel/trace/trace_export.c
+@@ -156,7 +156,7 @@ struct ftrace_event_class event_class_ft
+ };									\
+ 									\
+ struct ftrace_event_call __used						\
+-__attribute__((__aligned__(4)))						\
++__u64_aligned								\
+ __attribute__((section("_ftrace_events"))) event_##call = {		\
+ 	.name			= #call,				\
+ 	.event.type		= etype,				\
+--- a/include/linux/ftrace_event.h
++++ b/include/linux/ftrace_event.h
+@@ -194,7 +194,7 @@ struct ftrace_event_call {
+ 	int				perf_refcount;
+ 	struct hlist_head __percpu	*perf_events;
+ #endif
+-};
++} __u64_aligned;
+ 
+ #define PERF_MAX_TRACE_SIZE	2048
+ 
+--- a/include/trace/syscall.h
++++ b/include/trace/syscall.h
+@@ -29,7 +29,7 @@ struct syscall_metadata {
+ 
+ 	struct ftrace_event_call *enter_event;
+ 	struct ftrace_event_call *exit_event;
+-};
++} __u64_aligned;
+ 
+ #ifdef CONFIG_FTRACE_SYSCALLS
+ extern unsigned long arch_syscall_addr(int nr);
+--- a/include/asm-generic/vmlinux.lds.h
++++ b/include/asm-generic/vmlinux.lds.h
+@@ -113,7 +113,8 @@
+ #endif
+ 
+ #ifdef CONFIG_TRACE_BRANCH_PROFILING
+-#define LIKELY_PROFILE()	VMLINUX_SYMBOL(__start_annotated_branch_profile) = .; \
++#define LIKELY_PROFILE()	U64_ALIGN();					      \
++				VMLINUX_SYMBOL(__start_annotated_branch_profile) = .; \
+ 				*(_ftrace_annotated_branch)			      \
+ 				VMLINUX_SYMBOL(__stop_annotated_branch_profile) = .;
+ #else
+@@ -121,7 +122,8 @@
+ #endif
+ 
+ #ifdef CONFIG_PROFILE_ALL_BRANCHES
+-#define BRANCH_PROFILE()	VMLINUX_SYMBOL(__start_branch_profile) = .;   \
++#define BRANCH_PROFILE()	U64_ALIGN();				      \
++				VMLINUX_SYMBOL(__start_branch_profile) = .;   \
+ 				*(_ftrace_branch)			      \
+ 				VMLINUX_SYMBOL(__stop_branch_profile) = .;
+ #else
+@@ -129,7 +131,8 @@
+ #endif
+ 
+ #ifdef CONFIG_EVENT_TRACING
+-#define FTRACE_EVENTS()	VMLINUX_SYMBOL(__start_ftrace_events) = .;	\
++#define FTRACE_EVENTS()	U64_ALIGN();					\
++			VMLINUX_SYMBOL(__start_ftrace_events) = .;	\
+ 			*(_ftrace_events)				\
+ 			VMLINUX_SYMBOL(__stop_ftrace_events) = .;
+ #else
+@@ -137,7 +140,8 @@
+ #endif
+ 
+ #ifdef CONFIG_TRACING
+-#define TRACE_PRINTKS() VMLINUX_SYMBOL(__start___trace_bprintk_fmt) = .;      \
++#define TRACE_PRINTKS()  U64_ALIGN();					       \
++			 VMLINUX_SYMBOL(__start___trace_bprintk_fmt) = .;      \
+ 			 *(__trace_printk_fmt) /* Trace_printk fmt' pointer */ \
+ 			 VMLINUX_SYMBOL(__stop___trace_bprintk_fmt) = .;
+ #else
+@@ -145,7 +149,8 @@
+ #endif
+ 
+ #ifdef CONFIG_FTRACE_SYSCALLS
+-#define TRACE_SYSCALLS() VMLINUX_SYMBOL(__start_syscalls_metadata) = .;	\
++#define TRACE_SYSCALLS() U64_ALIGN();					\
++			 VMLINUX_SYMBOL(__start_syscalls_metadata) = .;	\
+ 			 *(__syscalls_metadata)				\
+ 			 VMLINUX_SYMBOL(__stop_syscalls_metadata) = .;
+ #else
+@@ -175,11 +180,7 @@
+ 	LIKELY_PROFILE()		       				\
+ 	BRANCH_PROFILE()						\
+ 	TRACE_PRINTKS()							\
+-									\
+-	STRUCT_ALIGN();							\
+ 	FTRACE_EVENTS()							\
+-									\
+-	STRUCT_ALIGN();							\
+ 	TRACE_SYSCALLS()
+ 
+ /*

Modified: dists/trunk/linux-2.6/debian/patches/series/1~experimental.2
==============================================================================
--- dists/trunk/linux-2.6/debian/patches/series/1~experimental.2	Mon Jan 24 01:54:24 2011	(r16847)
+++ dists/trunk/linux-2.6/debian/patches/series/1~experimental.2	Mon Jan 24 02:12:36 2011	(r16848)
@@ -3,3 +3,5 @@
 + bugfix/all/r8169-keep-firmware-in-memory.patch
 - features/all/r8712u-Fix-external-firmware-loading.patch
 + features/all/r8712u-Firmware-changes-for-driver.patch
++ bugfix/sparc/introduce-u64-aligned.patch
++ bugfix/sparc/tracing-use-u64-aligned-as-type-and-variable-attribute.patch



More information about the Kernel-svn-changes mailing list