summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGreg Kroah-Hartman <gregkh@suse.de>2011-10-11 08:34:28 -0600
committerGreg Kroah-Hartman <gregkh@suse.de>2011-10-11 08:34:28 -0600
commit2cf0ea4e90022f7cab94f40f02886cbf9f93faa6 (patch)
treed1b9d71cfaad16ef667c584865d4802e9f731bae
parent4a0768d2793d85cc41a0e507b4503c226be1a185 (diff)
downloadstable-queue-2cf0ea4e90022f7cab94f40f02886cbf9f93faa6.tar.gz
3.0 patches
-rw-r--r--queue-3.0/ftrace-fix-regression-of-mod-module-function-enabling.patch132
-rw-r--r--queue-3.0/ftrace-fix-regression-where-ftrace-breaks-when-modules-are-loaded.patch114
-rw-r--r--queue-3.0/ftrace-fix-warning-when-config_function_tracer-is-not-defined.patch39
-rw-r--r--queue-3.0/series3
4 files changed, 288 insertions, 0 deletions
diff --git a/queue-3.0/ftrace-fix-regression-of-mod-module-function-enabling.patch b/queue-3.0/ftrace-fix-regression-of-mod-module-function-enabling.patch
new file mode 100644
index 0000000000..a03f94ba53
--- /dev/null
+++ b/queue-3.0/ftrace-fix-regression-of-mod-module-function-enabling.patch
@@ -0,0 +1,132 @@
+From 43dd61c9a09bd413e837df829e6bfb42159be52a Mon Sep 17 00:00:00 2001
+From: Steven Rostedt <srostedt@redhat.com>
+Date: Thu, 7 Jul 2011 11:09:22 -0400
+Subject: ftrace: Fix regression of :mod:module function enabling
+
+From: Steven Rostedt <srostedt@redhat.com>
+
+commit 43dd61c9a09bd413e837df829e6bfb42159be52a upstream.
+
+The new code that allows different utilities to pick and choose
+what functions they trace broke the :mod: hook that allows users
+to trace only functions of a particular module.
+
+The reason is that the :mod: hook bypasses the hash that is setup
+to allow individual users to trace their own functions and uses
+the global hash directly. But if the global hash has not been
+set up, it will cause a bug:
+
+echo '*:mod:radeon' > /sys/kernel/debug/set_ftrace_filter
+
+produces:
+
+ [drm:drm_mode_getfb] *ERROR* invalid framebuffer id
+ [drm:radeon_crtc_page_flip] *ERROR* failed to reserve new rbo buffer before flip
+ BUG: unable to handle kernel paging request at ffffffff8160ec90
+ IP: [<ffffffff810d9136>] add_hash_entry+0x66/0xd0
+ PGD 1a05067 PUD 1a09063 PMD 80000000016001e1
+ Oops: 0003 [#1] SMP Jul 7 04:02:28 phyllis kernel: [55303.858604] CPU 1
+ Modules linked in: cryptd aes_x86_64 aes_generic binfmt_misc rfcomm bnep ip6table_filter hid radeon r8169 ahci libahci mii ttm drm_kms_helper drm video i2c_algo_bit intel_agp intel_gtt
+
+ Pid: 10344, comm: bash Tainted: G WC 3.0.0-rc5 #1 Dell Inc. Inspiron N5010/0YXXJJ
+ RIP: 0010:[<ffffffff810d9136>] [<ffffffff810d9136>] add_hash_entry+0x66/0xd0
+ RSP: 0018:ffff88003a96bda8 EFLAGS: 00010246
+ RAX: ffff8801301735c0 RBX: ffffffff8160ec80 RCX: 0000000000306ee0
+ RDX: 0000000000000000 RSI: 0000000000000000 RDI: ffff880137c92940
+ RBP: ffff88003a96bdb8 R08: ffff880137c95680 R09: 0000000000000000
+ R10: 0000000000000001 R11: 0000000000000000 R12: ffffffff81c9df78
+ R13: ffff8801153d1000 R14: 0000000000000000 R15: 0000000000000000
+ FS: 00007f329c18a700(0000) GS:ffff880137c80000(0000) knlGS:0000000000000000
+ CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
+ CR2: ffffffff8160ec90 CR3: 000000003002b000 CR4: 00000000000006e0
+ DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
+ DR3: 0000000000000000 DR6: 00000000ffff0ff0 DR7: 0000000000000400
+ Process bash (pid: 10344, threadinfo ffff88003a96a000, task ffff88012fcfc470)
+ Stack:
+ 0000000000000fd0 00000000000000fc ffff88003a96be38 ffffffff810d92f5
+ ffff88011c4c4e00 ffff880000000000 000000000b69f4d0 ffffffff8160ec80
+ ffff8800300e6f06 0000000081130295 0000000000000282 ffff8800300e6f00
+ Call Trace:
+ [<ffffffff810d92f5>] match_records+0x155/0x1b0
+ [<ffffffff810d940c>] ftrace_mod_callback+0xbc/0x100
+ [<ffffffff810dafdf>] ftrace_regex_write+0x16f/0x210
+ [<ffffffff810db09f>] ftrace_filter_write+0xf/0x20
+ [<ffffffff81166e48>] vfs_write+0xc8/0x190
+ [<ffffffff81167001>] sys_write+0x51/0x90
+ [<ffffffff815c7e02>] system_call_fastpath+0x16/0x1b
+ Code: 48 8b 33 31 d2 48 85 f6 75 33 49 89 d4 4c 03 63 08 49 8b 14 24 48 85 d2 48 89 10 74 04 48 89 42 08 49 89 04 24 4c 89 60 08 31 d2
+ RIP [<ffffffff810d9136>] add_hash_entry+0x66/0xd0
+ RSP <ffff88003a96bda8>
+ CR2: ffffffff8160ec90
+ ---[ end trace a5d031828efdd88e ]---
+
+Reported-by: Brian Marete <marete@toshnix.com>
+Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ include/linux/ftrace.h | 3 ++-
+ kernel/trace/ftrace.c | 12 +++---------
+ kernel/trace/trace_functions.c | 3 ++-
+ 3 files changed, 7 insertions(+), 11 deletions(-)
+
+--- a/include/linux/ftrace.h
++++ b/include/linux/ftrace.h
+@@ -123,7 +123,8 @@ stack_trace_sysctl(struct ctl_table *tab
+ struct ftrace_func_command {
+ struct list_head list;
+ char *name;
+- int (*func)(char *func, char *cmd,
++ int (*func)(struct ftrace_hash *hash,
++ char *func, char *cmd,
+ char *params, int enable);
+ };
+
+--- a/kernel/trace/ftrace.c
++++ b/kernel/trace/ftrace.c
+@@ -2407,10 +2407,9 @@ ftrace_match_module_records(struct ftrac
+ */
+
+ static int
+-ftrace_mod_callback(char *func, char *cmd, char *param, int enable)
++ftrace_mod_callback(struct ftrace_hash *hash,
++ char *func, char *cmd, char *param, int enable)
+ {
+- struct ftrace_ops *ops = &global_ops;
+- struct ftrace_hash *hash;
+ char *mod;
+ int ret = -EINVAL;
+
+@@ -2430,11 +2429,6 @@ ftrace_mod_callback(char *func, char *cm
+ if (!strlen(mod))
+ return ret;
+
+- if (enable)
+- hash = ops->filter_hash;
+- else
+- hash = ops->notrace_hash;
+-
+ ret = ftrace_match_module_records(hash, func, mod);
+ if (!ret)
+ ret = -EINVAL;
+@@ -2760,7 +2754,7 @@ static int ftrace_process_regex(struct f
+ mutex_lock(&ftrace_cmd_mutex);
+ list_for_each_entry(p, &ftrace_commands, list) {
+ if (strcmp(p->name, command) == 0) {
+- ret = p->func(func, command, next, enable);
++ ret = p->func(hash, func, command, next, enable);
+ goto out_unlock;
+ }
+ }
+--- a/kernel/trace/trace_functions.c
++++ b/kernel/trace/trace_functions.c
+@@ -324,7 +324,8 @@ ftrace_trace_onoff_unreg(char *glob, cha
+ }
+
+ static int
+-ftrace_trace_onoff_callback(char *glob, char *cmd, char *param, int enable)
++ftrace_trace_onoff_callback(struct ftrace_hash *hash,
++ char *glob, char *cmd, char *param, int enable)
+ {
+ struct ftrace_probe_ops *ops;
+ void *count = (void *)-1;
diff --git a/queue-3.0/ftrace-fix-regression-where-ftrace-breaks-when-modules-are-loaded.patch b/queue-3.0/ftrace-fix-regression-where-ftrace-breaks-when-modules-are-loaded.patch
new file mode 100644
index 0000000000..732dfaac6b
--- /dev/null
+++ b/queue-3.0/ftrace-fix-regression-where-ftrace-breaks-when-modules-are-loaded.patch
@@ -0,0 +1,114 @@
+From f7bc8b61f65726ff98f52e286b28e294499d7a08 Mon Sep 17 00:00:00 2001
+From: Steven Rostedt <srostedt@redhat.com>
+Date: Thu, 14 Jul 2011 23:02:27 -0400
+Subject: ftrace: Fix regression where ftrace breaks when modules are loaded
+
+From: Steven Rostedt <srostedt@redhat.com>
+
+commit f7bc8b61f65726ff98f52e286b28e294499d7a08 upstream.
+
+Enabling function tracer to trace all functions, then load a module and
+then disable function tracing will cause ftrace to fail.
+
+This can also happen by enabling function tracing on the command line:
+
+ ftrace=function
+
+and during boot up, modules are loaded, then you disable function tracing
+with 'echo nop > current_tracer' you will trigger a bug in ftrace that
+will shut itself down.
+
+The reason is, the new ftrace code keeps ref counts of all ftrace_ops that
+are registered for tracing. When one or more ftrace_ops are registered,
+all the records that represent the functions that the ftrace_ops will
+trace have a ref count incremented. If this ref count is not zero,
+when the code modification runs, that function will be enabled for tracing.
+If the ref count is zero, that function will be disabled from tracing.
+
+To make sure the accounting was working, FTRACE_WARN_ON()s were added
+to updating of the ref counts.
+
+If the ref count hits its max (> 2^30 ftrace_ops added), or if
+the ref count goes below zero, a FTRACE_WARN_ON() is triggered which
+disables all modification of code.
+
+Since it is common for ftrace_ops to trace all functions in the kernel,
+instead of creating > 20,000 hash items for the ftrace_ops, the hash
+count is just set to zero, and it represents that the ftrace_ops is
+to trace all functions. This is where the issues arrise.
+
+If you enable function tracing to trace all functions, and then add
+a module, the modules function records do not get the ref count updated.
+When the function tracer is disabled, all function records ref counts
+are subtracted. Since the modules never had their ref counts incremented,
+they go below zero and the FTRACE_WARN_ON() is triggered.
+
+The solution to this is rather simple. When modules are loaded, and
+their functions are added to the the ftrace pool, look to see if any
+ftrace_ops are registered that trace all functions. And for those,
+update the ref count for the module function records.
+
+Reported-by: Thomas Gleixner <tglx@linutronix.de>
+Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
+
+---
+ kernel/trace/ftrace.c | 30 ++++++++++++++++++++++++++++--
+ 1 file changed, 28 insertions(+), 2 deletions(-)
+
+--- a/kernel/trace/ftrace.c
++++ b/kernel/trace/ftrace.c
+@@ -1744,10 +1744,36 @@ static cycle_t ftrace_update_time;
+ static unsigned long ftrace_update_cnt;
+ unsigned long ftrace_update_tot_cnt;
+
++static int ops_traces_mod(struct ftrace_ops *ops)
++{
++ struct ftrace_hash *hash;
++
++ hash = ops->filter_hash;
++ return !!(!hash || !hash->count);
++}
++
+ static int ftrace_update_code(struct module *mod)
+ {
+ struct dyn_ftrace *p;
+ cycle_t start, stop;
++ unsigned long ref = 0;
++
++ /*
++ * When adding a module, we need to check if tracers are
++ * currently enabled and if they are set to trace all functions.
++ * If they are, we need to enable the module functions as well
++ * as update the reference counts for those function records.
++ */
++ if (mod) {
++ struct ftrace_ops *ops;
++
++ for (ops = ftrace_ops_list;
++ ops != &ftrace_list_end; ops = ops->next) {
++ if (ops->flags & FTRACE_OPS_FL_ENABLED &&
++ ops_traces_mod(ops))
++ ref++;
++ }
++ }
+
+ start = ftrace_now(raw_smp_processor_id());
+ ftrace_update_cnt = 0;
+@@ -1760,7 +1786,7 @@ static int ftrace_update_code(struct mod
+
+ p = ftrace_new_addrs;
+ ftrace_new_addrs = p->newlist;
+- p->flags = 0L;
++ p->flags = ref;
+
+ /*
+ * Do the initial record conversion from mcount jump
+@@ -1783,7 +1809,7 @@ static int ftrace_update_code(struct mod
+ * conversion puts the module to the correct state, thus
+ * passing the ftrace_make_call check.
+ */
+- if (ftrace_start_up) {
++ if (ftrace_start_up && ref) {
+ int failed = __ftrace_replace_code(p, 1);
+ if (failed) {
+ ftrace_bug(failed, p->ip);
diff --git a/queue-3.0/ftrace-fix-warning-when-config_function_tracer-is-not-defined.patch b/queue-3.0/ftrace-fix-warning-when-config_function_tracer-is-not-defined.patch
new file mode 100644
index 0000000000..c2978c2dbd
--- /dev/null
+++ b/queue-3.0/ftrace-fix-warning-when-config_function_tracer-is-not-defined.patch
@@ -0,0 +1,39 @@
+From 04da85b86188f224cc9b391b5bdd92a3ba20ffcf Mon Sep 17 00:00:00 2001
+From: Steven Rostedt <srostedt@redhat.com>
+Date: Mon, 11 Jul 2011 10:12:59 -0400
+Subject: ftrace: Fix warning when CONFIG_FUNCTION_TRACER is not defined
+
+From: Steven Rostedt <srostedt@redhat.com>
+
+commit 04da85b86188f224cc9b391b5bdd92a3ba20ffcf upstream.
+
+The struct ftrace_hash was declared within CONFIG_FUNCTION_TRACER
+but was referenced outside of it.
+
+Reported-by: Ingo Molnar <mingo@elte.hu>
+Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
+
+---
+ include/linux/ftrace.h | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+--- a/include/linux/ftrace.h
++++ b/include/linux/ftrace.h
+@@ -19,6 +19,8 @@
+
+ #include <asm/ftrace.h>
+
++struct ftrace_hash;
++
+ #ifdef CONFIG_FUNCTION_TRACER
+
+ extern int ftrace_enabled;
+@@ -29,8 +31,6 @@ ftrace_enable_sysctl(struct ctl_table *t
+
+ typedef void (*ftrace_func_t)(unsigned long ip, unsigned long parent_ip);
+
+-struct ftrace_hash;
+-
+ enum {
+ FTRACE_OPS_FL_ENABLED = 1 << 0,
+ FTRACE_OPS_FL_GLOBAL = 1 << 1,
diff --git a/queue-3.0/series b/queue-3.0/series
index f4600196b2..be0d8b542f 100644
--- a/queue-3.0/series
+++ b/queue-3.0/series
@@ -34,3 +34,6 @@ drm-radeon-kms-use-hardcoded-dig-encoder-to-transmitter-mapping-for-dce4.1.patch
ipv6-fix-null-dereference-in-udp6_ufo_fragment.patch
ahci-enable-sb600-64bit-dma-on-asus-m3a.patch
mips-pm-use-struct-syscore_ops-instead-of-sysdevs-for-pm.patch
+ftrace-fix-regression-of-mod-module-function-enabling.patch
+ftrace-fix-regression-where-ftrace-breaks-when-modules-are-loaded.patch
+ftrace-fix-warning-when-config_function_tracer-is-not-defined.patch