aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/trace/ring_buffer.c
diff options
context:
space:
mode:
authorSteven Rostedt <srostedt@redhat.com>2009-06-03 09:30:10 -0400
committerSteven Rostedt <rostedt@goodmis.org>2009-06-03 10:15:25 -0400
commitea05b57cc19234d8de9887c8a32c2e58e84b56ba (patch)
tree6153db3dab161d495207114359b8c09944567f0c /kernel/trace/ring_buffer.c
parentedd813bffc62a980bb4fb9b1243f31c1cce78da3 (diff)
ring-buffer: discard timestamps that are at the start of the buffer
Every buffer page in the ring buffer includes its own time stamp. When an event is recorded to the ring buffer with a delta time greater than what can be held in the event header, a time stamp event is created. If the the create timestamp falls over to the next buffer page, it is redundant because the buffer page holds a full time stamp. This patch will try to discard the time stamp when it falls to the start of the next page. This change also fixes a issues with disarding events. If most events are discarded, timestamps will start to creep into the ring buffer. If we do not discard the timestamps then they can fill up the ring buffer over time and waste space. This change will keep time stamps from filling up over another page. If something is recorded in the buffer page, and the rest is filtered, then the time stamps can only fill up to the end of the page. [ Impact: prevent time stamps from filling ring buffer ] Reported-by: Tim Bird <tim.bird@am.sony.com> Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
Diffstat (limited to 'kernel/trace/ring_buffer.c')
-rw-r--r--kernel/trace/ring_buffer.c37
1 files changed, 21 insertions, 16 deletions
diff --git a/kernel/trace/ring_buffer.c b/kernel/trace/ring_buffer.c
index 50926601a28d..7102d7a2fadb 100644
--- a/kernel/trace/ring_buffer.c
+++ b/kernel/trace/ring_buffer.c
@@ -370,6 +370,9 @@ static inline int test_time_stamp(u64 delta)
370/* Max payload is BUF_PAGE_SIZE - header (8bytes) */ 370/* Max payload is BUF_PAGE_SIZE - header (8bytes) */
371#define BUF_MAX_DATA_SIZE (BUF_PAGE_SIZE - (sizeof(u32) * 2)) 371#define BUF_MAX_DATA_SIZE (BUF_PAGE_SIZE - (sizeof(u32) * 2))
372 372
373/* Max number of timestamps that can fit on a page */
374#define RB_TIMESTAMPS_PER_PAGE (BUF_PAGE_SIZE / RB_LEN_TIME_STAMP)
375
373int ring_buffer_print_page_header(struct trace_seq *s) 376int ring_buffer_print_page_header(struct trace_seq *s)
374{ 377{
375 struct buffer_data_page field; 378 struct buffer_data_page field;
@@ -1409,8 +1412,12 @@ rb_add_time_stamp(struct ring_buffer_per_cpu *cpu_buffer,
1409 event->array[0] = *delta >> TS_SHIFT; 1412 event->array[0] = *delta >> TS_SHIFT;
1410 } else { 1413 } else {
1411 cpu_buffer->commit_page->page->time_stamp = *ts; 1414 cpu_buffer->commit_page->page->time_stamp = *ts;
1412 event->time_delta = 0; 1415 /* try to discard, since we do not need this */
1413 event->array[0] = 0; 1416 if (!rb_try_to_discard(cpu_buffer, event)) {
1417 /* nope, just zero it */
1418 event->time_delta = 0;
1419 event->array[0] = 0;
1420 }
1414 } 1421 }
1415 cpu_buffer->write_stamp = *ts; 1422 cpu_buffer->write_stamp = *ts;
1416 /* let the caller know this was the commit */ 1423 /* let the caller know this was the commit */
@@ -2268,8 +2275,8 @@ static void rb_advance_iter(struct ring_buffer_iter *iter)
2268 * Check if we are at the end of the buffer. 2275 * Check if we are at the end of the buffer.
2269 */ 2276 */
2270 if (iter->head >= rb_page_size(iter->head_page)) { 2277 if (iter->head >= rb_page_size(iter->head_page)) {
2271 if (RB_WARN_ON(buffer, 2278 /* discarded commits can make the page empty */
2272 iter->head_page == cpu_buffer->commit_page)) 2279 if (iter->head_page == cpu_buffer->commit_page)
2273 return; 2280 return;
2274 rb_inc_iter(iter); 2281 rb_inc_iter(iter);
2275 return; 2282 return;
@@ -2312,12 +2319,10 @@ rb_buffer_peek(struct ring_buffer *buffer, int cpu, u64 *ts)
2312 /* 2319 /*
2313 * We repeat when a timestamp is encountered. It is possible 2320 * We repeat when a timestamp is encountered. It is possible
2314 * to get multiple timestamps from an interrupt entering just 2321 * to get multiple timestamps from an interrupt entering just
2315 * as one timestamp is about to be written. The max times 2322 * as one timestamp is about to be written, or from discarded
2316 * that this can happen is the number of nested interrupts we 2323 * commits. The most that we can have is the number on a single page.
2317 * can have. Nesting 10 deep of interrupts is clearly
2318 * an anomaly.
2319 */ 2324 */
2320 if (RB_WARN_ON(cpu_buffer, ++nr_loops > 10)) 2325 if (RB_WARN_ON(cpu_buffer, ++nr_loops > RB_TIMESTAMPS_PER_PAGE))
2321 return NULL; 2326 return NULL;
2322 2327
2323 reader = rb_get_reader_page(cpu_buffer); 2328 reader = rb_get_reader_page(cpu_buffer);
@@ -2383,14 +2388,14 @@ rb_iter_peek(struct ring_buffer_iter *iter, u64 *ts)
2383 2388
2384 again: 2389 again:
2385 /* 2390 /*
2386 * We repeat when a timestamp is encountered. It is possible 2391 * We repeat when a timestamp is encountered.
2387 * to get multiple timestamps from an interrupt entering just 2392 * We can get multiple timestamps by nested interrupts or also
2388 * as one timestamp is about to be written. The max times 2393 * if filtering is on (discarding commits). Since discarding
2389 * that this can happen is the number of nested interrupts we 2394 * commits can be frequent we can get a lot of timestamps.
2390 * can have. Nesting 10 deep of interrupts is clearly 2395 * But we limit them by not adding timestamps if they begin
2391 * an anomaly. 2396 * at the start of a page.
2392 */ 2397 */
2393 if (RB_WARN_ON(cpu_buffer, ++nr_loops > 10)) 2398 if (RB_WARN_ON(cpu_buffer, ++nr_loops > RB_TIMESTAMPS_PER_PAGE))
2394 return NULL; 2399 return NULL;
2395 2400
2396 if (rb_per_cpu_empty(cpu_buffer)) 2401 if (rb_per_cpu_empty(cpu_buffer))