]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
3.0 patches
authorGreg Kroah-Hartman <gregkh@suse.de>
Tue, 11 Oct 2011 14:34:28 +0000 (08:34 -0600)
committerGreg Kroah-Hartman <gregkh@suse.de>
Tue, 11 Oct 2011 14:34:28 +0000 (08:34 -0600)
queue-3.0/ftrace-fix-regression-of-mod-module-function-enabling.patch [new file with mode: 0644]
queue-3.0/ftrace-fix-regression-where-ftrace-breaks-when-modules-are-loaded.patch [new file with mode: 0644]
queue-3.0/ftrace-fix-warning-when-config_function_tracer-is-not-defined.patch [new file with mode: 0644]
queue-3.0/series

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 (file)
index 0000000..a03f94b
--- /dev/null
@@ -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 (file)
index 0000000..732dfaa
--- /dev/null
@@ -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 (file)
index 0000000..c2978c2
--- /dev/null
@@ -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,
index f4600196b2411470e9f5d21ac2f75d9cce3c59b8..be0d8b542f9a390ecbde483108f7b18b419e7551 100644 (file)
@@ -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