aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc/kernel/ftrace.c
diff options
context:
space:
mode:
authorSteven Rostedt <srostedt@redhat.com>2012-04-26 04:31:17 -0400
committerBenjamin Herrenschmidt <benh@kernel.crashing.org>2012-07-03 00:14:38 -0400
commitee456bb346e75a9b6d941224b108250e6ee5f79f (patch)
treeaa6b3c6f3ebd396d458ebcdaf3dab7809df3f06a /arch/powerpc/kernel/ftrace.c
parentb81f18e55e9f4ea81759bcb00fea295de679bbe8 (diff)
powerpc/ftrace: Have PPC skip updating with stop_machine()
PowerPC does not have the synchronization issues that x86 has with modifying code on one CPU while another CPU is executing it. The other CPU will either see the old or new code without any issues, unlike x86 which may issue a GPF. Instead of calling the heavy stop_machine, just update the code. Signed-off-by: Steven Rostedt <rostedt@goodmis.org> Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Diffstat (limited to 'arch/powerpc/kernel/ftrace.c')
-rw-r--r--arch/powerpc/kernel/ftrace.c52
1 files changed, 52 insertions, 0 deletions
diff --git a/arch/powerpc/kernel/ftrace.c b/arch/powerpc/kernel/ftrace.c
index bf99cfa6bbfe..d56848afd2cf 100644
--- a/arch/powerpc/kernel/ftrace.c
+++ b/arch/powerpc/kernel/ftrace.c
@@ -484,6 +484,58 @@ int ftrace_update_ftrace_func(ftrace_func_t func)
484 return ret; 484 return ret;
485} 485}
486 486
487static int __ftrace_replace_code(struct dyn_ftrace *rec, int enable)
488{
489 unsigned long ftrace_addr = (unsigned long)FTRACE_ADDR;
490 int ret;
491
492 ret = ftrace_update_record(rec, enable);
493
494 switch (ret) {
495 case FTRACE_UPDATE_IGNORE:
496 return 0;
497 case FTRACE_UPDATE_MAKE_CALL:
498 return ftrace_make_call(rec, ftrace_addr);
499 case FTRACE_UPDATE_MAKE_NOP:
500 return ftrace_make_nop(NULL, rec, ftrace_addr);
501 }
502
503 return 0;
504}
505
506void ftrace_replace_code(int enable)
507{
508 struct ftrace_rec_iter *iter;
509 struct dyn_ftrace *rec;
510 int ret;
511
512 for (iter = ftrace_rec_iter_start(); iter;
513 iter = ftrace_rec_iter_next(iter)) {
514 rec = ftrace_rec_iter_record(iter);
515 ret = __ftrace_replace_code(rec, enable);
516 if (ret) {
517 ftrace_bug(ret, rec->ip);
518 return;
519 }
520 }
521}
522
523void arch_ftrace_update_code(int command)
524{
525 if (command & FTRACE_UPDATE_CALLS)
526 ftrace_replace_code(1);
527 else if (command & FTRACE_DISABLE_CALLS)
528 ftrace_replace_code(0);
529
530 if (command & FTRACE_UPDATE_TRACE_FUNC)
531 ftrace_update_ftrace_func(ftrace_trace_function);
532
533 if (command & FTRACE_START_FUNC_RET)
534 ftrace_enable_ftrace_graph_caller();
535 else if (command & FTRACE_STOP_FUNC_RET)
536 ftrace_disable_ftrace_graph_caller();
537}
538
487int __init ftrace_dyn_arch_init(void *data) 539int __init ftrace_dyn_arch_init(void *data)
488{ 540{
489 /* caller expects data to be zero */ 541 /* caller expects data to be zero */