aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSteven Rostedt <srostedt@redhat.com>2010-04-01 10:09:06 -0400
committerSteven Rostedt <rostedt@goodmis.org>2010-04-01 10:09:06 -0400
commit73effebdbe6b887ed2683f15175a65dda9cddfbf (patch)
tree2f80e6d1485df627418259bc2fc7818c823b8056
parent949211343925466f137c8e19938a857763c02e23 (diff)
trace-cmd: Show lost events if buffer supports it
If the ring buffer in the kernel sends information via the commit field of the sub buffer header. Than this patch will display where events were lost. If the sub buffer has space and can store the count of dropped events, this patch will show the count as well. Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
-rw-r--r--parse-events.c41
-rw-r--r--parse-events.h2
-rw-r--r--trace-input.c40
-rw-r--r--trace-read.c6
4 files changed, 80 insertions, 9 deletions
diff --git a/parse-events.c b/parse-events.c
index e9f122a..59596ae 100644
--- a/parse-events.c
+++ b/parse-events.c
@@ -4041,11 +4041,16 @@ static void print_args(struct print_arg *args)
4041} 4041}
4042 4042
4043static void parse_header_field(const char *field, 4043static void parse_header_field(const char *field,
4044 int *offset, int *size) 4044 int *offset, int *size, int mandatory)
4045{ 4045{
4046 unsigned long long save_input_buf_ptr;
4047 unsigned long long save_input_buf_siz;
4046 char *token; 4048 char *token;
4047 int type; 4049 int type;
4048 4050
4051 save_input_buf_ptr = input_buf_ptr;
4052 save_input_buf_siz = input_buf_siz;
4053
4049 if (read_expected(EVENT_ITEM, "field") < 0) 4054 if (read_expected(EVENT_ITEM, "field") < 0)
4050 return; 4055 return;
4051 if (read_expected(EVENT_OP, ":") < 0) 4056 if (read_expected(EVENT_OP, ":") < 0)
@@ -4056,8 +4061,20 @@ static void parse_header_field(const char *field,
4056 goto fail; 4061 goto fail;
4057 free_token(token); 4062 free_token(token);
4058 4063
4059 if (read_expected(EVENT_ITEM, field) < 0) 4064 /*
4060 return; 4065 * If this is not a mandatory field, then test it first.
4066 */
4067 if (mandatory) {
4068 if (read_expected(EVENT_ITEM, field) < 0)
4069 return;
4070 } else {
4071 if (read_expect_type(EVENT_ITEM, &token) < 0)
4072 goto fail;
4073 if (strcmp(token, field) != 0)
4074 goto discard;
4075 free_token(token);
4076 }
4077
4061 if (read_expected(EVENT_OP, ";") < 0) 4078 if (read_expected(EVENT_OP, ";") < 0)
4062 return; 4079 return;
4063 if (read_expected(EVENT_ITEM, "offset") < 0) 4080 if (read_expected(EVENT_ITEM, "offset") < 0)
@@ -4106,6 +4123,14 @@ static void parse_header_field(const char *field,
4106 } 4123 }
4107 fail: 4124 fail:
4108 free_token(token); 4125 free_token(token);
4126 return;
4127
4128 discard:
4129 input_buf_ptr = save_input_buf_ptr;
4130 input_buf_siz = save_input_buf_siz;
4131 *offset = 0;
4132 *size = 0;
4133 free_token(token);
4109} 4134}
4110 4135
4111/** 4136/**
@@ -4123,6 +4148,8 @@ static void parse_header_field(const char *field,
4123int pevent_parse_header_page(struct pevent *pevent, char *buf, unsigned long size, 4148int pevent_parse_header_page(struct pevent *pevent, char *buf, unsigned long size,
4124 int long_size) 4149 int long_size)
4125{ 4150{
4151 int ignore;
4152
4126 if (!size) { 4153 if (!size) {
4127 /* 4154 /*
4128 * Old kernels did not have header page info. 4155 * Old kernels did not have header page info.
@@ -4137,11 +4164,13 @@ int pevent_parse_header_page(struct pevent *pevent, char *buf, unsigned long siz
4137 init_input_buf(buf, size); 4164 init_input_buf(buf, size);
4138 4165
4139 parse_header_field("timestamp", &pevent->header_page_ts_offset, 4166 parse_header_field("timestamp", &pevent->header_page_ts_offset,
4140 &pevent->header_page_ts_size); 4167 &pevent->header_page_ts_size, 1);
4141 parse_header_field("commit", &pevent->header_page_size_offset, 4168 parse_header_field("commit", &pevent->header_page_size_offset,
4142 &pevent->header_page_size_size); 4169 &pevent->header_page_size_size, 1);
4170 parse_header_field("overwrite", &pevent->header_page_overwrite,
4171 &ignore, 0);
4143 parse_header_field("data", &pevent->header_page_data_offset, 4172 parse_header_field("data", &pevent->header_page_data_offset,
4144 &pevent->header_page_data_size); 4173 &pevent->header_page_data_size, 1);
4145 4174
4146 return 0; 4175 return 0;
4147} 4176}
diff --git a/parse-events.h b/parse-events.h
index 03b382e..d79f4e0 100644
--- a/parse-events.h
+++ b/parse-events.h
@@ -38,6 +38,7 @@
38struct record { 38struct record {
39 unsigned long long ts; 39 unsigned long long ts;
40 unsigned long long offset; 40 unsigned long long offset;
41 long long missed_events; /* buffer dropped events before */
41 int record_size; /* size of binary record */ 42 int record_size; /* size of binary record */
42 int size; /* size of data */ 43 int size; /* size of data */
43 void *data; 44 void *data;
@@ -284,6 +285,7 @@ struct pevent {
284 int header_page_size_size; 285 int header_page_size_size;
285 int header_page_data_offset; 286 int header_page_data_offset;
286 int header_page_data_size; 287 int header_page_data_size;
288 int header_page_overwrite;
287 289
288 int file_bigendian; 290 int file_bigendian;
289 int host_bigendian; 291 int host_bigendian;
diff --git a/trace-input.c b/trace-input.c
index c919cd0..c70dc6b 100644
--- a/trace-input.c
+++ b/trace-input.c
@@ -39,6 +39,11 @@
39#include "trace-cmd-local.h" 39#include "trace-cmd-local.h"
40#include "list.h" 40#include "list.h"
41 41
42#define MISSING_EVENTS (1 << 31)
43#define MISSING_STORED (1 << 30)
44
45#define COMMIT_MASK ((1 << 27) - 1)
46
42/* for debugging read instead of mmap */ 47/* for debugging read instead of mmap */
43static int force_read = 0; 48static int force_read = 0;
44 49
@@ -48,6 +53,7 @@ struct page {
48 struct tracecmd_input *handle; 53 struct tracecmd_input *handle;
49 void *map; 54 void *map;
50 int ref_count; 55 int ref_count;
56 long long lost_events;
51}; 57};
52 58
53struct cpu_data { 59struct cpu_data {
@@ -679,6 +685,7 @@ static int update_page_info(struct tracecmd_input *handle, int cpu)
679{ 685{
680 struct pevent *pevent = handle->pevent; 686 struct pevent *pevent = handle->pevent;
681 void *ptr = handle->cpu_data[cpu].page->map; 687 void *ptr = handle->cpu_data[cpu].page->map;
688 unsigned int flags;
682 689
683 /* FIXME: handle header page */ 690 /* FIXME: handle header page */
684 if (pevent->header_page_ts_size != 8) { 691 if (pevent->header_page_ts_size != 8) {
@@ -690,16 +697,39 @@ static int update_page_info(struct tracecmd_input *handle, int cpu)
690 ptr += 8; 697 ptr += 8;
691 switch (pevent->header_page_size_size) { 698 switch (pevent->header_page_size_size) {
692 case 4: 699 case 4:
693 handle->cpu_data[cpu].page_size = data2host4(pevent, ptr); 700 flags = data2host4(pevent, ptr);
701 ptr += 4;
694 break; 702 break;
695 case 8: 703 case 8:
696 handle->cpu_data[cpu].page_size = data2host8(pevent, ptr); 704 flags = (unsigned int)data2host8(pevent, ptr);
705 ptr += 8;
697 break; 706 break;
698 default: 707 default:
699 warning("bad long size"); 708 warning("bad long size");
700 return -1; 709 return -1;
701 } 710 }
702 711
712 handle->cpu_data[cpu].page_size = flags & COMMIT_MASK;
713
714 if (flags & MISSING_EVENTS) {
715 breakpoint();
716 if (flags & MISSING_STORED) {
717 ptr += handle->cpu_data[cpu].page_size;
718 switch (pevent->header_page_size_size) {
719 case 4:
720 handle->cpu_data[cpu].page->lost_events =
721 data2host4(pevent, ptr);
722 break;
723 case 8:
724 handle->cpu_data[cpu].page->lost_events =
725 data2host8(pevent, ptr);
726 break;
727 }
728 } else
729 handle->cpu_data[cpu].page->lost_events = -1;
730 } else
731 handle->cpu_data[cpu].page->lost_events = 0;
732
703 handle->cpu_data[cpu].index = 0; 733 handle->cpu_data[cpu].index = 0;
704 734
705 return 0; 735 return 0;
@@ -1435,6 +1465,7 @@ tracecmd_peek_data(struct tracecmd_input *handle, int cpu)
1435 void *ptr; 1465 void *ptr;
1436 unsigned long long extend; 1466 unsigned long long extend;
1437 unsigned int type_len; 1467 unsigned int type_len;
1468 long long missed_events = 0;
1438 int length; 1469 int length;
1439 1470
1440 if (index < 0) 1471 if (index < 0)
@@ -1464,8 +1495,10 @@ tracecmd_peek_data(struct tracecmd_input *handle, int cpu)
1464 1495
1465 ptr = page->map + index; 1496 ptr = page->map + index;
1466 1497
1467 if (!index) 1498 if (!index) {
1499 missed_events = page->lost_events;
1468 ptr = handle->cpu_data[cpu].page->map + pevent->header_page_data_offset; 1500 ptr = handle->cpu_data[cpu].page->map + pevent->header_page_data_offset;
1501 }
1469 1502
1470read_again: 1503read_again:
1471 index = calc_index(handle, ptr, cpu); 1504 index = calc_index(handle, ptr, cpu);
@@ -1520,6 +1553,7 @@ read_again:
1520 record->cpu = cpu; 1553 record->cpu = cpu;
1521 record->data = ptr; 1554 record->data = ptr;
1522 record->offset = handle->cpu_data[cpu].offset + index; 1555 record->offset = handle->cpu_data[cpu].offset + index;
1556 record->missed_events = missed_events;
1523 1557
1524 ptr += length; 1558 ptr += length;
1525 1559
diff --git a/trace-read.c b/trace-read.c
index 80173f9..bbe34ba 100644
--- a/trace-read.c
+++ b/trace-read.c
@@ -462,6 +462,12 @@ static void show_data(struct tracecmd_input *handle,
462 test_save(record, cpu); 462 test_save(record, cpu);
463 463
464 trace_seq_init(&s); 464 trace_seq_init(&s);
465 if (record->missed_events > 0)
466 trace_seq_printf(&s, "CPU:%d [%lld EVENTS DROPPED]\n",
467 record->cpu, record->missed_events);
468 else if (record->missed_events < 0)
469 trace_seq_printf(&s, "CPU:%d [EVENTS DROPPED]\n",
470 record->cpu);
465 pevent_print_event(pevent, &s, record); 471 pevent_print_event(pevent, &s, record);
466 trace_seq_do_printf(&s); 472 trace_seq_do_printf(&s);
467 473