diff options
| -rw-r--r-- | parse-events.c | 41 | ||||
| -rw-r--r-- | parse-events.h | 2 | ||||
| -rw-r--r-- | trace-input.c | 40 | ||||
| -rw-r--r-- | trace-read.c | 6 |
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 | ||
| 4043 | static void parse_header_field(const char *field, | 4043 | static 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, | |||
| 4123 | int pevent_parse_header_page(struct pevent *pevent, char *buf, unsigned long size, | 4148 | int 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 @@ | |||
| 38 | struct record { | 38 | struct 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 */ |
| 43 | static int force_read = 0; | 48 | static 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 | ||
| 53 | struct cpu_data { | 59 | struct 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 | ||
| 1470 | read_again: | 1503 | read_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 | ||
