aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSteven Rostedt <srostedt@redhat.com>2012-06-27 20:46:14 -0400
committerSteven Rostedt <rostedt@goodmis.org>2012-06-28 13:52:15 -0400
commit6d158a813efcd09661c23f16ddf7e2ff834cb20c (patch)
treec3937902e8ef5196638a9c31fd3b6280540a101d
parentb102f1d0f1cd0bb5ec82e5aeb1e33502d6ad6710 (diff)
tracing: Remove NR_CPUS array from trace_iterator
Replace the NR_CPUS array of buffer_iter from the trace_iterator with an allocated array. This will just create an array of possible CPUS instead of the max number specified. The use of NR_CPUS in that array caused allocation failures for machines that were tight on memory. This did not cause any failures to the system itself (no crashes), but caused unnecessary failures for reading the trace files. Added a helper function called 'trace_buffer_iter()' that returns the buffer_iter item or NULL if it is not defined or the array was not allocated. Some routines do not require the array (tracing_open_pipe() for one). Reported-by: Dave Jones <davej@redhat.com> Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
-rw-r--r--include/linux/ftrace_event.h2
-rw-r--r--kernel/trace/trace.c27
-rw-r--r--kernel/trace/trace.h8
-rw-r--r--kernel/trace/trace_functions_graph.c2
4 files changed, 28 insertions, 11 deletions
diff --git a/include/linux/ftrace_event.h b/include/linux/ftrace_event.h
index 1aff18346c71..af961d6f7ab1 100644
--- a/include/linux/ftrace_event.h
+++ b/include/linux/ftrace_event.h
@@ -65,7 +65,7 @@ struct trace_iterator {
65 void *private; 65 void *private;
66 int cpu_file; 66 int cpu_file;
67 struct mutex mutex; 67 struct mutex mutex;
68 struct ring_buffer_iter *buffer_iter[NR_CPUS]; 68 struct ring_buffer_iter **buffer_iter;
69 unsigned long iter_flags; 69 unsigned long iter_flags;
70 70
71 /* trace_seq for __print_flags() and __print_symbolic() etc. */ 71 /* trace_seq for __print_flags() and __print_symbolic() etc. */
diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c
index 748f6401edf6..b2af14e94c28 100644
--- a/kernel/trace/trace.c
+++ b/kernel/trace/trace.c
@@ -1710,9 +1710,11 @@ EXPORT_SYMBOL_GPL(trace_vprintk);
1710 1710
1711static void trace_iterator_increment(struct trace_iterator *iter) 1711static void trace_iterator_increment(struct trace_iterator *iter)
1712{ 1712{
1713 struct ring_buffer_iter *buf_iter = trace_buffer_iter(iter, iter->cpu);
1714
1713 iter->idx++; 1715 iter->idx++;
1714 if (iter->buffer_iter[iter->cpu]) 1716 if (buf_iter)
1715 ring_buffer_read(iter->buffer_iter[iter->cpu], NULL); 1717 ring_buffer_read(buf_iter, NULL);
1716} 1718}
1717 1719
1718static struct trace_entry * 1720static struct trace_entry *
@@ -1720,7 +1722,7 @@ peek_next_entry(struct trace_iterator *iter, int cpu, u64 *ts,
1720 unsigned long *lost_events) 1722 unsigned long *lost_events)
1721{ 1723{
1722 struct ring_buffer_event *event; 1724 struct ring_buffer_event *event;
1723 struct ring_buffer_iter *buf_iter = iter->buffer_iter[cpu]; 1725 struct ring_buffer_iter *buf_iter = trace_buffer_iter(iter, cpu);
1724 1726
1725 if (buf_iter) 1727 if (buf_iter)
1726 event = ring_buffer_iter_peek(buf_iter, ts); 1728 event = ring_buffer_iter_peek(buf_iter, ts);
@@ -1858,10 +1860,10 @@ void tracing_iter_reset(struct trace_iterator *iter, int cpu)
1858 1860
1859 tr->data[cpu]->skipped_entries = 0; 1861 tr->data[cpu]->skipped_entries = 0;
1860 1862
1861 if (!iter->buffer_iter[cpu]) 1863 buf_iter = trace_buffer_iter(iter, cpu);
1864 if (!buf_iter)
1862 return; 1865 return;
1863 1866
1864 buf_iter = iter->buffer_iter[cpu];
1865 ring_buffer_iter_reset(buf_iter); 1867 ring_buffer_iter_reset(buf_iter);
1866 1868
1867 /* 1869 /*
@@ -2207,13 +2209,15 @@ static enum print_line_t print_bin_fmt(struct trace_iterator *iter)
2207 2209
2208int trace_empty(struct trace_iterator *iter) 2210int trace_empty(struct trace_iterator *iter)
2209{ 2211{
2212 struct ring_buffer_iter *buf_iter;
2210 int cpu; 2213 int cpu;
2211 2214
2212 /* If we are looking at one CPU buffer, only check that one */ 2215 /* If we are looking at one CPU buffer, only check that one */
2213 if (iter->cpu_file != TRACE_PIPE_ALL_CPU) { 2216 if (iter->cpu_file != TRACE_PIPE_ALL_CPU) {
2214 cpu = iter->cpu_file; 2217 cpu = iter->cpu_file;
2215 if (iter->buffer_iter[cpu]) { 2218 buf_iter = trace_buffer_iter(iter, cpu);
2216 if (!ring_buffer_iter_empty(iter->buffer_iter[cpu])) 2219 if (buf_iter) {
2220 if (!ring_buffer_iter_empty(buf_iter))
2217 return 0; 2221 return 0;
2218 } else { 2222 } else {
2219 if (!ring_buffer_empty_cpu(iter->tr->buffer, cpu)) 2223 if (!ring_buffer_empty_cpu(iter->tr->buffer, cpu))
@@ -2223,8 +2227,9 @@ int trace_empty(struct trace_iterator *iter)
2223 } 2227 }
2224 2228
2225 for_each_tracing_cpu(cpu) { 2229 for_each_tracing_cpu(cpu) {
2226 if (iter->buffer_iter[cpu]) { 2230 buf_iter = trace_buffer_iter(iter, cpu);
2227 if (!ring_buffer_iter_empty(iter->buffer_iter[cpu])) 2231 if (buf_iter) {
2232 if (!ring_buffer_iter_empty(buf_iter))
2228 return 0; 2233 return 0;
2229 } else { 2234 } else {
2230 if (!ring_buffer_empty_cpu(iter->tr->buffer, cpu)) 2235 if (!ring_buffer_empty_cpu(iter->tr->buffer, cpu))
@@ -2383,6 +2388,8 @@ __tracing_open(struct inode *inode, struct file *file)
2383 if (!iter) 2388 if (!iter)
2384 return ERR_PTR(-ENOMEM); 2389 return ERR_PTR(-ENOMEM);
2385 2390
2391 iter->buffer_iter = kzalloc(sizeof(*iter->buffer_iter) * num_possible_cpus(),
2392 GFP_KERNEL);
2386 /* 2393 /*
2387 * We make a copy of the current tracer to avoid concurrent 2394 * We make a copy of the current tracer to avoid concurrent
2388 * changes on it while we are reading. 2395 * changes on it while we are reading.
@@ -2443,6 +2450,7 @@ __tracing_open(struct inode *inode, struct file *file)
2443 fail: 2450 fail:
2444 mutex_unlock(&trace_types_lock); 2451 mutex_unlock(&trace_types_lock);
2445 kfree(iter->trace); 2452 kfree(iter->trace);
2453 kfree(iter->buffer_iter);
2446 seq_release_private(inode, file); 2454 seq_release_private(inode, file);
2447 return ERR_PTR(-ENOMEM); 2455 return ERR_PTR(-ENOMEM);
2448} 2456}
@@ -2483,6 +2491,7 @@ static int tracing_release(struct inode *inode, struct file *file)
2483 mutex_destroy(&iter->mutex); 2491 mutex_destroy(&iter->mutex);
2484 free_cpumask_var(iter->started); 2492 free_cpumask_var(iter->started);
2485 kfree(iter->trace); 2493 kfree(iter->trace);
2494 kfree(iter->buffer_iter);
2486 seq_release_private(inode, file); 2495 seq_release_private(inode, file);
2487 return 0; 2496 return 0;
2488} 2497}
diff --git a/kernel/trace/trace.h b/kernel/trace/trace.h
index 5aec220d2de0..55e1f7f0db12 100644
--- a/kernel/trace/trace.h
+++ b/kernel/trace/trace.h
@@ -317,6 +317,14 @@ struct tracer {
317 317
318#define TRACE_PIPE_ALL_CPU -1 318#define TRACE_PIPE_ALL_CPU -1
319 319
320static inline struct ring_buffer_iter *
321trace_buffer_iter(struct trace_iterator *iter, int cpu)
322{
323 if (iter->buffer_iter && iter->buffer_iter[cpu])
324 return iter->buffer_iter[cpu];
325 return NULL;
326}
327
320int tracer_init(struct tracer *t, struct trace_array *tr); 328int tracer_init(struct tracer *t, struct trace_array *tr);
321int tracing_is_enabled(void); 329int tracing_is_enabled(void);
322void trace_wake_up(void); 330void trace_wake_up(void);
diff --git a/kernel/trace/trace_functions_graph.c b/kernel/trace/trace_functions_graph.c
index a7d2a4c653d8..ce27c8ba8d31 100644
--- a/kernel/trace/trace_functions_graph.c
+++ b/kernel/trace/trace_functions_graph.c
@@ -538,7 +538,7 @@ get_return_for_leaf(struct trace_iterator *iter,
538 next = &data->ret; 538 next = &data->ret;
539 } else { 539 } else {
540 540
541 ring_iter = iter->buffer_iter[iter->cpu]; 541 ring_iter = trace_buffer_iter(iter, iter->cpu);
542 542
543 /* First peek to compare current entry and the next one */ 543 /* First peek to compare current entry and the next one */
544 if (ring_iter) 544 if (ring_iter)