From: Steven Rostedt <rostedt@goodmis.org>
To: linux-kernel@vger.kernel.org
Cc: Ingo Molnar <mingo@elte.hu>, Thomas Gleixner <tglx@linutronix.de>,
Peter Zijlstra <peterz@infradead.org>,
Andrew Morton <akpm@linux-foundation.org>,
David Miller <davem@davemloft.net>,
Linus Torvalds <torvalds@linux-foundation.org>,
Steven Rostedt <srostedt@redhat.com>
Subject: [PATCH 1/2] ftrace: make dynamic ftrace more robust
Date: Tue, 21 Oct 2008 12:40:19 -0400 [thread overview]
Message-ID: <20081021164302.399002797@goodmis.org> (raw)
In-Reply-To: 20081021164018.889518687@goodmis.org
[-- Attachment #1: ftrace-more-robust-cleanup.patch --]
[-- Type: text/plain, Size: 6906 bytes --]
This patch cleans up some of the ftrace code as well as adds some
more sanity checks. If any of the sanity checks fail, a warning will
be printed and ftrace will be disabled.
Signed-off-by: Steven Rostedt <srostedt@redhat.com>
---
arch/x86/kernel/ftrace.c | 15 ++++++++++-----
include/linux/ftrace.h | 7 ++++++-
include/linux/init.h | 10 +++++-----
kernel/trace/ftrace.c | 35 +++++++++++++++++++++++++++++++----
4 files changed, 52 insertions(+), 15 deletions(-)
Index: linux-compile.git/arch/x86/kernel/ftrace.c
===================================================================
--- linux-compile.git.orig/arch/x86/kernel/ftrace.c 2008-10-20 19:39:54.000000000 -0400
+++ linux-compile.git/arch/x86/kernel/ftrace.c 2008-10-20 19:42:02.000000000 -0400
@@ -66,19 +66,24 @@ ftrace_modify_code(unsigned long ip, uns
/*
* Note: Due to modules and __init, code can
* disappear and change, we need to protect against faulting
- * as well as code changing.
+ * as well as code changing. We do this by using the
+ * __copy_*_user functions.
*
* No real locking needed, this code is run through
* kstop_machine, or before SMP starts.
*/
+
+ /* read the text we want to modify */
if (__copy_from_user_inatomic(replaced, (char __user *)ip, MCOUNT_INSN_SIZE))
- return 1;
+ return FTRACE_CODE_FAILED_READ;
+ /* Make sure it is what we expect it to be */
if (memcmp(replaced, old_code, MCOUNT_INSN_SIZE) != 0)
- return 2;
+ return FTRACE_CODE_FAILED_CMP;
- WARN_ON_ONCE(__copy_to_user_inatomic((char __user *)ip, new_code,
- MCOUNT_INSN_SIZE));
+ /* replace the text with the new text */
+ if (__copy_to_user_inatomic((char __user *)ip, new_code, MCOUNT_INSN_SIZE))
+ return FTRACE_CODE_FAILED_WRITE;
sync_core();
Index: linux-compile.git/include/linux/ftrace.h
===================================================================
--- linux-compile.git.orig/include/linux/ftrace.h 2008-10-20 19:39:54.000000000 -0400
+++ linux-compile.git/include/linux/ftrace.h 2008-10-20 19:47:23.000000000 -0400
@@ -232,6 +232,11 @@ static inline void start_boot_trace(void
static inline void stop_boot_trace(void) { }
#endif
-
+enum {
+ FTRACE_CODE_MODIFIED,
+ FTRACE_CODE_FAILED_READ,
+ FTRACE_CODE_FAILED_CMP,
+ FTRACE_CODE_FAILED_WRITE,
+};
#endif /* _LINUX_FTRACE_H */
Index: linux-compile.git/include/linux/init.h
===================================================================
--- linux-compile.git.orig/include/linux/init.h 2008-10-20 19:39:54.000000000 -0400
+++ linux-compile.git/include/linux/init.h 2008-10-20 19:40:06.000000000 -0400
@@ -75,15 +75,15 @@
#ifdef MODULE
-#define __exitused
+#define __exitused notrace
#else
-#define __exitused __used
+#define __exitused __used notrace
#endif
#define __exit __section(.exit.text) __exitused __cold
/* Used for HOTPLUG */
-#define __devinit __section(.devinit.text) __cold
+#define __devinit __section(.devinit.text) __cold notrace
#define __devinitdata __section(.devinit.data)
#define __devinitconst __section(.devinit.rodata)
#define __devexit __section(.devexit.text) __exitused __cold
@@ -91,7 +91,7 @@
#define __devexitconst __section(.devexit.rodata)
/* Used for HOTPLUG_CPU */
-#define __cpuinit __section(.cpuinit.text) __cold
+#define __cpuinit __section(.cpuinit.text) __cold notrace
#define __cpuinitdata __section(.cpuinit.data)
#define __cpuinitconst __section(.cpuinit.rodata)
#define __cpuexit __section(.cpuexit.text) __exitused __cold
@@ -99,7 +99,7 @@
#define __cpuexitconst __section(.cpuexit.rodata)
/* Used for MEMORY_HOTPLUG */
-#define __meminit __section(.meminit.text) __cold
+#define __meminit __section(.meminit.text) __cold notrace
#define __meminitdata __section(.meminit.data)
#define __meminitconst __section(.meminit.rodata)
#define __memexit __section(.memexit.text) __exitused __cold
Index: linux-compile.git/kernel/trace/ftrace.c
===================================================================
--- linux-compile.git.orig/kernel/trace/ftrace.c 2008-10-20 19:39:54.000000000 -0400
+++ linux-compile.git/kernel/trace/ftrace.c 2008-10-20 19:46:00.000000000 -0400
@@ -318,6 +318,14 @@ static inline void ftrace_del_hash(struc
static void ftrace_free_rec(struct dyn_ftrace *rec)
{
+ /*
+ * No locking, only called from kstop_machine, or
+ * from module unloading with module locks and interrupts
+ * disabled to prevent kstop machine from running.
+ */
+
+ WARN_ON(rec->flags & FTRACE_FL_FREE);
+
rec->ip = (unsigned long)ftrace_free_records;
ftrace_free_records = rec;
rec->flags |= FTRACE_FL_FREE;
@@ -346,7 +354,6 @@ void ftrace_release(void *start, unsigne
}
}
spin_unlock(&ftrace_lock);
-
}
static struct dyn_ftrace *ftrace_alloc_dyn_node(unsigned long ip)
@@ -556,9 +563,12 @@ static void ftrace_replace_code(int enab
failed = __ftrace_replace_code(rec, old, new, enable);
if (failed && (rec->flags & FTRACE_FL_CONVERTED)) {
+ /* kprobes can cause this failure */
rec->flags |= FTRACE_FL_FAILED;
if ((system_state == SYSTEM_BOOTING) ||
!core_kernel_text(rec->ip)) {
+ /* kprobes was not the fault */
+ ftrace_kill_atomic();
ftrace_del_hash(rec);
ftrace_free_rec(rec);
}
@@ -601,12 +611,12 @@ ftrace_code_disable(struct dyn_ftrace *r
failed = ftrace_modify_code(ip, call, nop);
if (failed) {
switch (failed) {
- case 1:
+ case FTRACE_CODE_FAILED_READ:
WARN_ON_ONCE(1);
pr_info("ftrace faulted on modifying ");
print_ip_sym(ip);
break;
- case 2:
+ case FTRACE_CODE_FAILED_CMP:
WARN_ON_ONCE(1);
pr_info("ftrace failed to modify ");
print_ip_sym(ip);
@@ -615,7 +625,18 @@ ftrace_code_disable(struct dyn_ftrace *r
print_ip_ins(" replace: ", nop);
printk(KERN_CONT "\n");
break;
+ case FTRACE_CODE_FAILED_WRITE:
+ WARN_ON_ONCE(1);
+ pr_info("ftrace failed to write ");
+ print_ip_sym(ip);
+ break;
+ default:
+ WARN_ON_ONCE(1);
+ pr_info("ftrace unkown error ");
+ print_ip_sym(ip);
+ break;
}
+ ftrace_kill_atomic();
rec->flags |= FTRACE_FL_FAILED;
return 0;
@@ -789,6 +810,11 @@ static int __ftrace_update_code(void *ig
/* No locks needed, the machine is stopped! */
for (i = 0; i < FTRACE_HASHSIZE; i++) {
+
+ /* If something went wrong, bail without enabling anything */
+ if (unlikely(ftrace_disabled))
+ return;
+
INIT_HLIST_HEAD(&temp_list);
head = &ftrace_hash[i];
@@ -796,7 +822,8 @@ static int __ftrace_update_code(void *ig
hlist_for_each_entry_safe(p, t, n, head, node) {
/* Skip over failed records which have not been
* freed. */
- if (p->flags & FTRACE_FL_FAILED)
+ if (p->flags & FTRACE_FL_FAILED ||
+ p->flags & FTRACE_FL_FREE)
continue;
/* Unconverted records are always at the head of the
--
next prev parent reply other threads:[~2008-10-21 16:43 UTC|newest]
Thread overview: 9+ messages / expand[flat|nested] mbox.gz Atom feed top
2008-10-21 16:40 [PATCH 0/2] ftrace: clean ups and sanity checks Steven Rostedt
2008-10-21 16:40 ` Steven Rostedt [this message]
2008-10-22 6:53 ` [PATCH 1/2] ftrace: make dynamic ftrace more robust Ingo Molnar
2008-10-22 11:07 ` Steven Rostedt
2008-10-22 11:28 ` Steven Rostedt
2008-10-22 11:47 ` Ingo Molnar
2008-10-22 12:07 ` Steven Rostedt
2008-10-21 16:40 ` [PATCH 2/2] ftrace: release functions from hash Steven Rostedt
2008-10-21 18:27 ` Steven Rostedt
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20081021164302.399002797@goodmis.org \
--to=rostedt@goodmis.org \
--cc=akpm@linux-foundation.org \
--cc=davem@davemloft.net \
--cc=linux-kernel@vger.kernel.org \
--cc=mingo@elte.hu \
--cc=peterz@infradead.org \
--cc=srostedt@redhat.com \
--cc=tglx@linutronix.de \
--cc=torvalds@linux-foundation.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox