aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-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