tracing: A few more fixes
Subsystems (3)
Steven Rostedt
maintainerLinus,
A few more fixes for ftrace infrastructure.
I was cleaning out my INBOX and found two fixes from zhangwei from a year ago that were lost in my mail. These fix an inconsistency between trace_puts() and the way trace_printk() works. The reason this is important to fix is because when trace_printk() doesn't have any arguments, it turns into a trace_puts(). Not being able to enable a stack trace against trace_printk() because it does not have any arguments is quite confusing. Also, the fix is rather trivial and low risk.
While porting some changes to PowerPC I discovered that it still has the function graph tracer filter bug that if you also enable stack tracing the function graph tracer filter is ignored. I fixed that up.
Finally, Martin Lau, fixed a bug that would cause readers of the ftrace ring buffer to block forever even though it was suppose to be NONBLOCK.
This is based on top of the last pull request that I sent you earlier today.
Please pull the latest trace-fixes-v3.16-rc5-v2 tree, which can be found at:
git://git.kernel.org/pub/scm/linux/kernel/git/rostedt/linux-trace.git
trace-fixes-v3.16-rc5-v2
Tag SHA1: 4932f1a76294c2e60930de9c3179e54fd95e3771 Head SHA1: 97b8ee845393701edc06e27ccec2876ff9596019
Martin Lau (1):
ring-buffer: Fix polling on trace_pipe
Steven Rostedt (Red Hat) (1):
tracing: Fix graph tracer with stack tracer on other archs
zhangwei(Jovi) (2):
tracing: Add ftrace_trace_stack into __trace_puts/__trace_bputs
tracing: Add TRACE_ITER_PRINTK flag check in __trace_puts/__trace_bputs
----
kernel/trace/ftrace.c | 4 ++-- kernel/trace/ring_buffer.c | 4 ---- kernel/trace/trace.c | 18 ++++++++++++++++-- 3 files changed, 18 insertions(+), 8 deletions(-)
Steven Rostedt
maintainerPATCH 1/4 tracing: Add ftrace_trace_stack into __trace_puts/__trace_bputs
From: "zhangwei(Jovi)" <[email protected]>
Currently trace option stacktrace is not applicable for trace_printk with constant string argument, the reason is in __trace_puts/__trace_bputs ftrace_trace_stack is missing.
In contrast, when using trace_printk with non constant string argument(will call into __trace_printk/__trace_bprintk), then trace option stacktrace is workable, this inconstant result will confuses users a lot.
--- kernel/trace/trace.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-)
kernel/trace/trace.c +10 -2
@@ -466,6 +466,9 @@ int __trace_puts(unsigned long ip, const char *str, int size)struct print_entry *entry;unsigned long irq_flags;int alloc; +int pc; + + pc =preempt_count ();if (unlikely (tracing_selftest_running || tracing_disabled))return 0 ;
@@ -475,7 +478,7 @@ int __trace_puts(unsigned long ip, const char *str, int size)local_save_flags (irq_flags); buffer = global_trace.trace_buffer.buffer; event =trace_buffer_lock_reserve (buffer,TRACE_PRINT , alloc, - irq_flags,preempt_count ()); + irq_flags, pc);if (!event)return 0 ;
@@ -492,6 +495,7 @@ int __trace_puts(unsigned long ip, const char *str, int size) entry->buf[size] ='\0' ;__buffer_unlock_commit (buffer, event); +ftrace_trace_stack (buffer, irq_flags,4 , pc);return size; }
@@ -509,6 +513,9 @@ int __trace_bputs(unsigned long ip, const char *str)struct bputs_entry *entry;unsigned long irq_flags;int size =sizeof (struct bputs_entry ); +int pc; + + pc =preempt_count ();if (unlikely (tracing_selftest_running || tracing_disabled))return 0 ;
@@ -516,7 +523,7 @@ int __trace_bputs(unsigned long ip, const char *str)local_save_flags (irq_flags); buffer = global_trace.trace_buffer.buffer; event =trace_buffer_lock_reserve (buffer,TRACE_BPUTS , size, - irq_flags,preempt_count ()); + irq_flags, pc);if (!event)return 0 ;
@@ -525,6 +532,7 @@ int __trace_bputs(unsigned long ip, const char *str) entry->str = str;__buffer_unlock_commit (buffer, event); +ftrace_trace_stack (buffer, irq_flags,4 , pc);return 1 ; }
Signature · 1 line
2.0.0
Steven Rostedt
maintainerPATCH 2/4 tracing: Fix graph tracer with stack tracer on other archs
In reply to Steven RostedtFrom: "Steven Rostedt (Red Hat)" <[email protected]>
Running my ftrace tests on PowerPC, it failed the test that checks if function_graph tracer is affected by the stack tracer. It was. Looking into this, I found that the update_function_graph_func() must be called even if the trampoline function is not changed. This is because archs like PowerPC do not support ftrace_ops being passed by assembly and instead uses a helper function (what the trampoline function points to). Since this function is not changed even when multiple ftrace_ops are added to the code, the test that falls out before calling update_function_graph_func() will miss that the update must still be done.
Call update_function_graph_function() for all calls to update_ftrace_function()
--- kernel/trace/ftrace.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
kernel/trace/ftrace.c +2 -2
@@ -265,12 +265,12 @@ static void update_ftrace_function(void) func = ftrace_ops_list_func; } +update_function_graph_func (); +/* If there's no change, then do nothing more here */ if (ftrace_trace_function == func)return ; -update_function_graph_func (); -/* * If we are using the list function, it doesn't care * about the function_trace_ops.
Signature · 1 line
2.0.0
Steven Rostedt
maintainerPATCH 3/4 tracing: Add TRACE_ITER_PRINTK flag check in __trace_puts/__trace_bputs
In reply to Steven RostedtFrom: "zhangwei(Jovi)" <[email protected]>
The TRACE_ITER_PRINTK check in __trace_puts/__trace_bputs is missing, so add it, to be consistent with __trace_printk/__trace_bprintk. Those functions are all called by the same function: trace_printk().
--- kernel/trace/trace.c | 6 ++++++ 1 file changed, 6 insertions(+)
kernel/trace/trace.c +6 -0
@@ -468,6 +468,9 @@ int __trace_puts(unsigned long ip, const char *str, int size)int alloc;int pc; +if (!(trace_flags &TRACE_ITER_PRINTK )) +return 0 ; + pc =preempt_count ();if (unlikely (tracing_selftest_running || tracing_disabled))
@@ -515,6 +518,9 @@ int __trace_bputs(unsigned long ip, const char *str)int size =sizeof (struct bputs_entry );int pc; +if (!(trace_flags &TRACE_ITER_PRINTK )) +return 0 ; + pc =preempt_count ();if (unlikely (tracing_selftest_running || tracing_disabled))
Signature · 1 line
2.0.0
Steven Rostedt
maintainerPATCH 4/4 ring-buffer: Fix polling on trace_pipe
In reply to Steven RostedtFrom: Martin Lau <[email protected]>
ring_buffer_poll_wait() should always put the poll_table to its wait_queue even there is immediate data available. Otherwise, the following epoll and read sequence will eventually hang forever:
1. Put some data to make the trace_pipe ring_buffer read ready first
2. epoll_ctl(efd, EPOLL_CTL_ADD, trace_pipe_fd, ee)
3. epoll_wait()
4. read(trace_pipe_fd) till EAGAIN
5. Add some more data to the trace_pipe ring_buffer
6. epoll_wait() -> this epoll_wait() will block forever
~ During the epoll_ctl(efd, EPOLL_CTL_ADD,...) call in step 2,
ring_buffer_poll_wait() returns immediately without adding poll_table, which has poll_table->_qproc pointing to ep_poll_callback(), to its wait_queue.
~ During the epoll_wait() call in step 3 and step 6,
ring_buffer_poll_wait() cannot add ep_poll_callback() to its wait_queue because the poll_table->_qproc is NULL and it is how epoll works.
~ When there is new data available in step 6, ring_buffer does not know
it has to call ep_poll_callback() because it is not in its wait queue. Hence, block forever.
Other poll implementation seems to call poll_wait() unconditionally as the very first thing to do. For example, tcp_poll() in tcp.c.
--- kernel/trace/ring_buffer.c | 4 ---- 1 file changed, 4 deletions(-)
kernel/trace/ring_buffer.c +0 -4
@@ -616,10 +616,6 @@ int ring_buffer_poll_wait(struct ring_buffer *buffer, int cpu,struct ring_buffer_per_cpu *cpu_buffer;struct rb_irq_work *work; -if ((cpu ==RING_BUFFER_ALL_CPUS && !ring_buffer_empty (buffer)) || - (cpu !=RING_BUFFER_ALL_CPUS && !ring_buffer_empty_cpu (buffer, cpu))) -return POLLIN |POLLRDNORM ; -if (cpu ==RING_BUFFER_ALL_CPUS ) work = &buffer->irq_work;else {
Signature · 1 line
2.0.0