]> pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - arch/x86/kernel/ftrace.c
Merge branch 'irq/sparseirq' into cpus4096
[linux-2.6-omap-h63xx.git] / arch / x86 / kernel / ftrace.c
index 1a5b8f8cb3cc556b9953c83d80276d7dcf590a55..1b43086b097a8489a85adcd41a3336fb0cde4f88 100644 (file)
@@ -420,12 +420,23 @@ static void pop_return_trace(struct ftrace_graph_ret *trace, unsigned long *ret)
        int index;
 
        index = current->curr_ret_stack;
+
+       if (unlikely(index < 0)) {
+               ftrace_graph_stop();
+               WARN_ON(1);
+               /* Might as well panic, otherwise we have no where to go */
+               *ret = (unsigned long)panic;
+               return;
+       }
+
        *ret = current->ret_stack[index].ret;
        trace->func = current->ret_stack[index].func;
        trace->calltime = current->ret_stack[index].calltime;
        trace->overrun = atomic_read(&current->trace_overrun);
        trace->depth = index;
+       barrier();
        current->curr_ret_stack--;
+
 }
 
 /*
@@ -441,6 +452,13 @@ unsigned long ftrace_return_to_handler(void)
        trace.rettime = cpu_clock(raw_smp_processor_id());
        ftrace_graph_return(&trace);
 
+       if (unlikely(!ret)) {
+               ftrace_graph_stop();
+               WARN_ON(1);
+               /* Might as well panic. What else to do? */
+               ret = (unsigned long)panic;
+       }
+
        return ret;
 }
 
@@ -458,7 +476,10 @@ void prepare_ftrace_return(unsigned long *parent, unsigned long self_addr)
                                &return_to_handler;
 
        /* Nmi's are currently unsupported */
-       if (atomic_read(&in_nmi))
+       if (unlikely(atomic_read(&in_nmi)))
+               return;
+
+       if (unlikely(atomic_read(&current->tracing_graph_pause)))
                return;
 
        /*
@@ -484,14 +505,16 @@ void prepare_ftrace_return(unsigned long *parent, unsigned long self_addr)
                : "memory"
        );
 
-       if (WARN_ON(faulted)) {
-               unregister_ftrace_graph();
+       if (unlikely(faulted)) {
+               ftrace_graph_stop();
+               WARN_ON(1);
                return;
        }
 
-       if (WARN_ON(!__kernel_text_address(old))) {
-               unregister_ftrace_graph();
+       if (unlikely(!__kernel_text_address(old))) {
+               ftrace_graph_stop();
                *parent = old;
+               WARN_ON(1);
                return;
        }
 
@@ -504,7 +527,11 @@ void prepare_ftrace_return(unsigned long *parent, unsigned long self_addr)
        }
 
        trace.func = self_addr;
-       ftrace_graph_entry(&trace);
 
+       /* Only trace if the calling function expects to */
+       if (!ftrace_graph_entry(&trace)) {
+               current->curr_ret_stack--;
+               *parent = old;
+       }
 }
 #endif /* CONFIG_FUNCTION_GRAPH_TRACER */