diff options
author | Steven Rostedt <srostedt@redhat.com> | 2009-12-12 15:17:00 -0500 |
---|---|---|
committer | Steven Rostedt <rostedt@goodmis.org> | 2009-12-12 15:17:00 -0500 |
commit | bc19b0283be9c71ba884c1818a92f5316a4cbc48 (patch) | |
tree | 6118e12c1254be1fcbbdc7a3a2524f0d1bf27126 | |
parent | f226e2a601d2ef2b74f7c937743ef97519a3be6e (diff) |
Add generic mmap funcion to read page from cpu data
This patch adds a generic mmap page reading that simply
swaps the old mmap with a new mapping. This avoids needing to use
get_next_page in an awkward and error prone fashion.
Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
-rw-r--r-- | trace-input.c | 108 |
1 files changed, 74 insertions, 34 deletions
diff --git a/trace-input.c b/trace-input.c index 46c5e05..cacc136 100644 --- a/trace-input.c +++ b/trace-input.c | |||
@@ -18,6 +18,8 @@ | |||
18 | 18 | ||
19 | #include "trace-cmd.h" | 19 | #include "trace-cmd.h" |
20 | 20 | ||
21 | /* for debugging read instead of mmap */ | ||
22 | static int force_read = 0; | ||
21 | 23 | ||
22 | struct cpu_data { | 24 | struct cpu_data { |
23 | /* the first two never change */ | 25 | /* the first two never change */ |
@@ -28,6 +30,7 @@ struct cpu_data { | |||
28 | unsigned long long timestamp; | 30 | unsigned long long timestamp; |
29 | struct record *next; | 31 | struct record *next; |
30 | char *page; | 32 | char *page; |
33 | void *read_page; | ||
31 | int cpu; | 34 | int cpu; |
32 | int index; | 35 | int index; |
33 | int page_size; | 36 | int page_size; |
@@ -493,47 +496,83 @@ static int calc_index(struct tracecmd_input *handle, | |||
493 | static void | 496 | static void |
494 | update_cpu_data_index(struct tracecmd_input *handle, int cpu) | 497 | update_cpu_data_index(struct tracecmd_input *handle, int cpu) |
495 | { | 498 | { |
496 | handle->cpu_data[cpu].offset += handle->page_size; | ||
497 | handle->cpu_data[cpu].size -= handle->page_size; | 499 | handle->cpu_data[cpu].size -= handle->page_size; |
498 | handle->cpu_data[cpu].index = 0; | 500 | handle->cpu_data[cpu].index = 0; |
499 | } | 501 | } |
500 | 502 | ||
501 | static int get_next_page(struct tracecmd_input *handle, int cpu) | 503 | static void free_page(struct tracecmd_input *handle, int cpu) |
504 | { | ||
505 | if (!handle->cpu_data[cpu].page) | ||
506 | return; | ||
507 | |||
508 | if (handle->read_page) { | ||
509 | handle->cpu_data[cpu].page = NULL; | ||
510 | return; | ||
511 | } | ||
512 | |||
513 | munmap(handle->cpu_data[cpu].page, handle->page_size); | ||
514 | handle->cpu_data[cpu].page = NULL; | ||
515 | } | ||
516 | |||
517 | static int get_read_page(struct tracecmd_input *handle, int cpu, | ||
518 | off64_t offset) | ||
502 | { | 519 | { |
503 | off64_t save_seek; | 520 | off64_t save_seek; |
504 | off64_t ret; | 521 | off64_t ret; |
505 | 522 | ||
506 | if (!handle->cpu_data[cpu].page) | 523 | free_page(handle, cpu); |
507 | return 0; | ||
508 | 524 | ||
509 | if (handle->read_page) { | 525 | handle->cpu_data[cpu].page = handle->cpu_data[cpu].read_page; |
510 | if (handle->cpu_data[cpu].size <= handle->page_size) { | ||
511 | free(handle->cpu_data[cpu].page); | ||
512 | handle->cpu_data[cpu].page = NULL; | ||
513 | handle->cpu_data[cpu].offset = 0; | ||
514 | return 0; | ||
515 | } | ||
516 | 526 | ||
517 | update_cpu_data_index(handle, cpu); | 527 | /* other parts of the code may expect the pointer to not move */ |
528 | save_seek = lseek64(handle->fd, 0, SEEK_CUR); | ||
518 | 529 | ||
519 | /* other parts of the code may expect the pointer to not move */ | 530 | ret = lseek64(handle->fd, offset, SEEK_SET); |
520 | save_seek = lseek64(handle->fd, 0, SEEK_CUR); | 531 | if (ret < 0) |
532 | return -1; | ||
533 | ret = read(handle->fd, handle->cpu_data[cpu].page, handle->page_size); | ||
534 | if (ret < 0) | ||
535 | return -1; | ||
521 | 536 | ||
522 | ret = lseek64(handle->fd, handle->cpu_data[cpu].offset, SEEK_SET); | 537 | /* reset the file pointer back */ |
523 | if (ret < 0) | 538 | lseek64(handle->fd, save_seek, SEEK_SET); |
524 | return -1; | 539 | |
525 | ret = read(handle->fd, handle->cpu_data[cpu].page, handle->page_size); | 540 | return 0; |
526 | if (ret < 0) | ||
527 | return -1; | ||
528 | 541 | ||
529 | /* reset the file pointer back */ | 542 | } |
530 | lseek64(handle->fd, save_seek, SEEK_SET); | ||
531 | 543 | ||
532 | return 0; | 544 | static int get_page(struct tracecmd_input *handle, int cpu, |
545 | off64_t offset) | ||
546 | { | ||
547 | if (offset & (handle->page_size - 1)) { | ||
548 | errno = -EINVAL; | ||
549 | die("bad page offset %llx", offset); | ||
550 | return -1; | ||
533 | } | 551 | } |
534 | 552 | ||
535 | munmap(handle->cpu_data[cpu].page, handle->page_size); | 553 | if (handle->read_page) |
536 | handle->cpu_data[cpu].page = NULL; | 554 | return get_read_page(handle, cpu, offset); |
555 | |||
556 | if (handle->cpu_data[cpu].page) | ||
557 | free_page(handle, cpu); | ||
558 | |||
559 | handle->cpu_data[cpu].offset = offset; | ||
560 | |||
561 | handle->cpu_data[cpu].page = mmap(NULL, handle->page_size, PROT_READ, MAP_PRIVATE, | ||
562 | handle->fd, offset); | ||
563 | if (handle->cpu_data[cpu].page == MAP_FAILED) | ||
564 | return -1; | ||
565 | |||
566 | return 0; | ||
567 | } | ||
568 | static int get_next_page(struct tracecmd_input *handle, int cpu) | ||
569 | { | ||
570 | off64_t offset; | ||
571 | |||
572 | if (!handle->cpu_data[cpu].page) | ||
573 | return 0; | ||
574 | |||
575 | free_page(handle, cpu); | ||
537 | 576 | ||
538 | if (handle->cpu_data[cpu].size <= handle->page_size) { | 577 | if (handle->cpu_data[cpu].size <= handle->page_size) { |
539 | handle->cpu_data[cpu].offset = 0; | 578 | handle->cpu_data[cpu].offset = 0; |
@@ -542,12 +581,9 @@ static int get_next_page(struct tracecmd_input *handle, int cpu) | |||
542 | 581 | ||
543 | update_cpu_data_index(handle, cpu); | 582 | update_cpu_data_index(handle, cpu); |
544 | 583 | ||
545 | handle->cpu_data[cpu].page = mmap(NULL, handle->page_size, PROT_READ, MAP_PRIVATE, | 584 | offset = handle->cpu_data[cpu].offset + handle->page_size; |
546 | handle->fd, handle->cpu_data[cpu].offset); | ||
547 | if (handle->cpu_data[cpu].page == MAP_FAILED) | ||
548 | return -1; | ||
549 | 585 | ||
550 | return 0; | 586 | return get_page(handle, cpu, offset); |
551 | } | 587 | } |
552 | 588 | ||
553 | enum old_ring_buffer_type { | 589 | enum old_ring_buffer_type { |
@@ -946,10 +982,12 @@ static int init_read(struct tracecmd_input *handle, int cpu) | |||
946 | off64_t ret; | 982 | off64_t ret; |
947 | off64_t save_seek; | 983 | off64_t save_seek; |
948 | 984 | ||
949 | handle->cpu_data[cpu].page = malloc(handle->page_size); | 985 | handle->cpu_data[cpu].read_page = malloc(handle->page_size); |
950 | if (!handle->cpu_data[cpu].page) | 986 | if (!handle->cpu_data[cpu].read_page) |
951 | return -1; | 987 | return -1; |
952 | 988 | ||
989 | handle->cpu_data[cpu].page = handle->cpu_data[cpu].read_page; | ||
990 | |||
953 | /* other parts of the code may expect the pointer to not move */ | 991 | /* other parts of the code may expect the pointer to not move */ |
954 | save_seek = lseek64(handle->fd, 0, SEEK_CUR); | 992 | save_seek = lseek64(handle->fd, 0, SEEK_CUR); |
955 | 993 | ||
@@ -976,9 +1014,11 @@ static int init_cpu(struct tracecmd_input *handle, int cpu) | |||
976 | if (handle->read_page) | 1014 | if (handle->read_page) |
977 | return init_read(handle, cpu); | 1015 | return init_read(handle, cpu); |
978 | 1016 | ||
979 | handle->cpu_data[cpu].page = mmap(NULL, handle->page_size, PROT_READ, | 1017 | if (!force_read) { |
1018 | handle->cpu_data[cpu].page = mmap(NULL, handle->page_size, PROT_READ, | ||
980 | MAP_PRIVATE, handle->fd, handle->cpu_data[cpu].offset); | 1019 | MAP_PRIVATE, handle->fd, handle->cpu_data[cpu].offset); |
981 | if (handle->cpu_data[cpu].page == MAP_FAILED) { | 1020 | } |
1021 | if (force_read || handle->cpu_data[cpu].page == MAP_FAILED) { | ||
982 | /* fall back to just reading pages */ | 1022 | /* fall back to just reading pages */ |
983 | perror("mmap"); | 1023 | perror("mmap"); |
984 | fprintf(stderr, "Can not mmap file, will read instead\n"); | 1024 | fprintf(stderr, "Can not mmap file, will read instead\n"); |