diff options
| -rw-r--r-- | kernel/trace/ring_buffer.c | 63 |
1 files changed, 36 insertions, 27 deletions
diff --git a/kernel/trace/ring_buffer.c b/kernel/trace/ring_buffer.c index e206951603c1..8619c5345889 100644 --- a/kernel/trace/ring_buffer.c +++ b/kernel/trace/ring_buffer.c | |||
| @@ -195,20 +195,24 @@ void *ring_buffer_event_data(struct ring_buffer_event *event) | |||
| 195 | #define TS_MASK ((1ULL << TS_SHIFT) - 1) | 195 | #define TS_MASK ((1ULL << TS_SHIFT) - 1) |
| 196 | #define TS_DELTA_TEST (~TS_MASK) | 196 | #define TS_DELTA_TEST (~TS_MASK) |
| 197 | 197 | ||
| 198 | /* | 198 | struct buffer_data_page { |
| 199 | * This hack stolen from mm/slob.c. | ||
| 200 | * We can store per page timing information in the page frame of the page. | ||
| 201 | * Thanks to Peter Zijlstra for suggesting this idea. | ||
| 202 | */ | ||
| 203 | struct buffer_page { | ||
| 204 | u64 time_stamp; /* page time stamp */ | 199 | u64 time_stamp; /* page time stamp */ |
| 205 | local_t write; /* index for next write */ | ||
| 206 | local_t commit; /* write commited index */ | 200 | local_t commit; /* write commited index */ |
| 201 | unsigned char data[]; /* data of buffer page */ | ||
| 202 | }; | ||
| 203 | |||
| 204 | struct buffer_page { | ||
| 205 | local_t write; /* index for next write */ | ||
| 207 | unsigned read; /* index for next read */ | 206 | unsigned read; /* index for next read */ |
| 208 | struct list_head list; /* list of free pages */ | 207 | struct list_head list; /* list of free pages */ |
| 209 | void *page; /* Actual data page */ | 208 | struct buffer_data_page *page; /* Actual data page */ |
| 210 | }; | 209 | }; |
| 211 | 210 | ||
| 211 | static void rb_init_page(struct buffer_data_page *page) | ||
| 212 | { | ||
| 213 | local_set(&page->commit, 0); | ||
| 214 | } | ||
| 215 | |||
| 212 | /* | 216 | /* |
| 213 | * Also stolen from mm/slob.c. Thanks to Mathieu Desnoyers for pointing | 217 | * Also stolen from mm/slob.c. Thanks to Mathieu Desnoyers for pointing |
| 214 | * this issue out. | 218 | * this issue out. |
| @@ -230,7 +234,7 @@ static inline int test_time_stamp(u64 delta) | |||
| 230 | return 0; | 234 | return 0; |
| 231 | } | 235 | } |
| 232 | 236 | ||
| 233 | #define BUF_PAGE_SIZE PAGE_SIZE | 237 | #define BUF_PAGE_SIZE (PAGE_SIZE - sizeof(struct buffer_data_page)) |
| 234 | 238 | ||
| 235 | /* | 239 | /* |
| 236 | * head_page == tail_page && head == tail then buffer is empty. | 240 | * head_page == tail_page && head == tail then buffer is empty. |
| @@ -333,6 +337,7 @@ static int rb_allocate_pages(struct ring_buffer_per_cpu *cpu_buffer, | |||
| 333 | if (!addr) | 337 | if (!addr) |
| 334 | goto free_pages; | 338 | goto free_pages; |
| 335 | page->page = (void *)addr; | 339 | page->page = (void *)addr; |
| 340 | rb_init_page(page->page); | ||
| 336 | } | 341 | } |
| 337 | 342 | ||
| 338 | list_splice(&pages, head); | 343 | list_splice(&pages, head); |
| @@ -378,6 +383,7 @@ rb_allocate_cpu_buffer(struct ring_buffer *buffer, int cpu) | |||
| 378 | if (!addr) | 383 | if (!addr) |
| 379 | goto fail_free_reader; | 384 | goto fail_free_reader; |
| 380 | page->page = (void *)addr; | 385 | page->page = (void *)addr; |
| 386 | rb_init_page(page->page); | ||
| 381 | 387 | ||
| 382 | INIT_LIST_HEAD(&cpu_buffer->reader_page->list); | 388 | INIT_LIST_HEAD(&cpu_buffer->reader_page->list); |
| 383 | 389 | ||
| @@ -647,6 +653,7 @@ int ring_buffer_resize(struct ring_buffer *buffer, unsigned long size) | |||
| 647 | if (!addr) | 653 | if (!addr) |
| 648 | goto free_pages; | 654 | goto free_pages; |
| 649 | page->page = (void *)addr; | 655 | page->page = (void *)addr; |
| 656 | rb_init_page(page->page); | ||
| 650 | } | 657 | } |
| 651 | } | 658 | } |
| 652 | 659 | ||
| @@ -682,7 +689,7 @@ static inline int rb_null_event(struct ring_buffer_event *event) | |||
| 682 | 689 | ||
| 683 | static inline void *__rb_page_index(struct buffer_page *page, unsigned index) | 690 | static inline void *__rb_page_index(struct buffer_page *page, unsigned index) |
| 684 | { | 691 | { |
| 685 | return page->page + index; | 692 | return page->page->data + index; |
| 686 | } | 693 | } |
| 687 | 694 | ||
| 688 | static inline struct ring_buffer_event * | 695 | static inline struct ring_buffer_event * |
| @@ -712,7 +719,7 @@ static inline unsigned rb_page_write(struct buffer_page *bpage) | |||
| 712 | 719 | ||
| 713 | static inline unsigned rb_page_commit(struct buffer_page *bpage) | 720 | static inline unsigned rb_page_commit(struct buffer_page *bpage) |
| 714 | { | 721 | { |
| 715 | return local_read(&bpage->commit); | 722 | return local_read(&bpage->page->commit); |
| 716 | } | 723 | } |
| 717 | 724 | ||
| 718 | /* Size is determined by what has been commited */ | 725 | /* Size is determined by what has been commited */ |
| @@ -804,14 +811,15 @@ rb_set_commit_event(struct ring_buffer_per_cpu *cpu_buffer, | |||
| 804 | if (RB_WARN_ON(cpu_buffer, | 811 | if (RB_WARN_ON(cpu_buffer, |
| 805 | cpu_buffer->commit_page == cpu_buffer->tail_page)) | 812 | cpu_buffer->commit_page == cpu_buffer->tail_page)) |
| 806 | return; | 813 | return; |
| 807 | cpu_buffer->commit_page->commit = | 814 | cpu_buffer->commit_page->page->commit = |
| 808 | cpu_buffer->commit_page->write; | 815 | cpu_buffer->commit_page->write; |
| 809 | rb_inc_page(cpu_buffer, &cpu_buffer->commit_page); | 816 | rb_inc_page(cpu_buffer, &cpu_buffer->commit_page); |
| 810 | cpu_buffer->write_stamp = cpu_buffer->commit_page->time_stamp; | 817 | cpu_buffer->write_stamp = |
| 818 | cpu_buffer->commit_page->page->time_stamp; | ||
| 811 | } | 819 | } |
| 812 | 820 | ||
| 813 | /* Now set the commit to the event's index */ | 821 | /* Now set the commit to the event's index */ |
| 814 | local_set(&cpu_buffer->commit_page->commit, index); | 822 | local_set(&cpu_buffer->commit_page->page->commit, index); |
| 815 | } | 823 | } |
| 816 | 824 | ||
| 817 | static inline void | 825 | static inline void |
| @@ -826,16 +834,17 @@ rb_set_commit_to_write(struct ring_buffer_per_cpu *cpu_buffer) | |||
| 826 | * assign the commit to the tail. | 834 | * assign the commit to the tail. |
| 827 | */ | 835 | */ |
| 828 | while (cpu_buffer->commit_page != cpu_buffer->tail_page) { | 836 | while (cpu_buffer->commit_page != cpu_buffer->tail_page) { |
| 829 | cpu_buffer->commit_page->commit = | 837 | cpu_buffer->commit_page->page->commit = |
| 830 | cpu_buffer->commit_page->write; | 838 | cpu_buffer->commit_page->write; |
| 831 | rb_inc_page(cpu_buffer, &cpu_buffer->commit_page); | 839 | rb_inc_page(cpu_buffer, &cpu_buffer->commit_page); |
| 832 | cpu_buffer->write_stamp = cpu_buffer->commit_page->time_stamp; | 840 | cpu_buffer->write_stamp = |
| 841 | cpu_buffer->commit_page->page->time_stamp; | ||
| 833 | /* add barrier to keep gcc from optimizing too much */ | 842 | /* add barrier to keep gcc from optimizing too much */ |
| 834 | barrier(); | 843 | barrier(); |
| 835 | } | 844 | } |
| 836 | while (rb_commit_index(cpu_buffer) != | 845 | while (rb_commit_index(cpu_buffer) != |
| 837 | rb_page_write(cpu_buffer->commit_page)) { | 846 | rb_page_write(cpu_buffer->commit_page)) { |
| 838 | cpu_buffer->commit_page->commit = | 847 | cpu_buffer->commit_page->page->commit = |
| 839 | cpu_buffer->commit_page->write; | 848 | cpu_buffer->commit_page->write; |
| 840 | barrier(); | 849 | barrier(); |
| 841 | } | 850 | } |
| @@ -843,7 +852,7 @@ rb_set_commit_to_write(struct ring_buffer_per_cpu *cpu_buffer) | |||
| 843 | 852 | ||
| 844 | static void rb_reset_reader_page(struct ring_buffer_per_cpu *cpu_buffer) | 853 | static void rb_reset_reader_page(struct ring_buffer_per_cpu *cpu_buffer) |
| 845 | { | 854 | { |
| 846 | cpu_buffer->read_stamp = cpu_buffer->reader_page->time_stamp; | 855 | cpu_buffer->read_stamp = cpu_buffer->reader_page->page->time_stamp; |
| 847 | cpu_buffer->reader_page->read = 0; | 856 | cpu_buffer->reader_page->read = 0; |
| 848 | } | 857 | } |
| 849 | 858 | ||
| @@ -862,7 +871,7 @@ static inline void rb_inc_iter(struct ring_buffer_iter *iter) | |||
| 862 | else | 871 | else |
| 863 | rb_inc_page(cpu_buffer, &iter->head_page); | 872 | rb_inc_page(cpu_buffer, &iter->head_page); |
| 864 | 873 | ||
| 865 | iter->read_stamp = iter->head_page->time_stamp; | 874 | iter->read_stamp = iter->head_page->page->time_stamp; |
| 866 | iter->head = 0; | 875 | iter->head = 0; |
| 867 | } | 876 | } |
| 868 | 877 | ||
| @@ -998,12 +1007,12 @@ __rb_reserve_next(struct ring_buffer_per_cpu *cpu_buffer, | |||
| 998 | */ | 1007 | */ |
| 999 | if (tail_page == cpu_buffer->tail_page) { | 1008 | if (tail_page == cpu_buffer->tail_page) { |
| 1000 | local_set(&next_page->write, 0); | 1009 | local_set(&next_page->write, 0); |
| 1001 | local_set(&next_page->commit, 0); | 1010 | local_set(&next_page->page->commit, 0); |
| 1002 | cpu_buffer->tail_page = next_page; | 1011 | cpu_buffer->tail_page = next_page; |
| 1003 | 1012 | ||
| 1004 | /* reread the time stamp */ | 1013 | /* reread the time stamp */ |
| 1005 | *ts = ring_buffer_time_stamp(cpu_buffer->cpu); | 1014 | *ts = ring_buffer_time_stamp(cpu_buffer->cpu); |
| 1006 | cpu_buffer->tail_page->time_stamp = *ts; | 1015 | cpu_buffer->tail_page->page->time_stamp = *ts; |
| 1007 | } | 1016 | } |
| 1008 | 1017 | ||
| 1009 | /* | 1018 | /* |
| @@ -1048,7 +1057,7 @@ __rb_reserve_next(struct ring_buffer_per_cpu *cpu_buffer, | |||
| 1048 | * this page's time stamp. | 1057 | * this page's time stamp. |
| 1049 | */ | 1058 | */ |
| 1050 | if (!tail && rb_is_commit(cpu_buffer, event)) | 1059 | if (!tail && rb_is_commit(cpu_buffer, event)) |
| 1051 | cpu_buffer->commit_page->time_stamp = *ts; | 1060 | cpu_buffer->commit_page->page->time_stamp = *ts; |
| 1052 | 1061 | ||
| 1053 | return event; | 1062 | return event; |
| 1054 | 1063 | ||
| @@ -1099,7 +1108,7 @@ rb_add_time_stamp(struct ring_buffer_per_cpu *cpu_buffer, | |||
| 1099 | event->time_delta = *delta & TS_MASK; | 1108 | event->time_delta = *delta & TS_MASK; |
| 1100 | event->array[0] = *delta >> TS_SHIFT; | 1109 | event->array[0] = *delta >> TS_SHIFT; |
| 1101 | } else { | 1110 | } else { |
| 1102 | cpu_buffer->commit_page->time_stamp = *ts; | 1111 | cpu_buffer->commit_page->page->time_stamp = *ts; |
| 1103 | event->time_delta = 0; | 1112 | event->time_delta = 0; |
| 1104 | event->array[0] = 0; | 1113 | event->array[0] = 0; |
| 1105 | } | 1114 | } |
| @@ -1552,7 +1561,7 @@ static void rb_iter_reset(struct ring_buffer_iter *iter) | |||
| 1552 | if (iter->head) | 1561 | if (iter->head) |
| 1553 | iter->read_stamp = cpu_buffer->read_stamp; | 1562 | iter->read_stamp = cpu_buffer->read_stamp; |
| 1554 | else | 1563 | else |
| 1555 | iter->read_stamp = iter->head_page->time_stamp; | 1564 | iter->read_stamp = iter->head_page->page->time_stamp; |
| 1556 | } | 1565 | } |
| 1557 | 1566 | ||
| 1558 | /** | 1567 | /** |
| @@ -1696,7 +1705,7 @@ rb_get_reader_page(struct ring_buffer_per_cpu *cpu_buffer) | |||
| 1696 | cpu_buffer->reader_page->list.prev = reader->list.prev; | 1705 | cpu_buffer->reader_page->list.prev = reader->list.prev; |
| 1697 | 1706 | ||
| 1698 | local_set(&cpu_buffer->reader_page->write, 0); | 1707 | local_set(&cpu_buffer->reader_page->write, 0); |
| 1699 | local_set(&cpu_buffer->reader_page->commit, 0); | 1708 | local_set(&cpu_buffer->reader_page->page->commit, 0); |
| 1700 | 1709 | ||
| 1701 | /* Make the reader page now replace the head */ | 1710 | /* Make the reader page now replace the head */ |
| 1702 | reader->list.prev->next = &cpu_buffer->reader_page->list; | 1711 | reader->list.prev->next = &cpu_buffer->reader_page->list; |
| @@ -2088,7 +2097,7 @@ rb_reset_cpu(struct ring_buffer_per_cpu *cpu_buffer) | |||
| 2088 | cpu_buffer->head_page | 2097 | cpu_buffer->head_page |
| 2089 | = list_entry(cpu_buffer->pages.next, struct buffer_page, list); | 2098 | = list_entry(cpu_buffer->pages.next, struct buffer_page, list); |
| 2090 | local_set(&cpu_buffer->head_page->write, 0); | 2099 | local_set(&cpu_buffer->head_page->write, 0); |
| 2091 | local_set(&cpu_buffer->head_page->commit, 0); | 2100 | local_set(&cpu_buffer->head_page->page->commit, 0); |
| 2092 | 2101 | ||
| 2093 | cpu_buffer->head_page->read = 0; | 2102 | cpu_buffer->head_page->read = 0; |
| 2094 | 2103 | ||
| @@ -2097,7 +2106,7 @@ rb_reset_cpu(struct ring_buffer_per_cpu *cpu_buffer) | |||
| 2097 | 2106 | ||
| 2098 | INIT_LIST_HEAD(&cpu_buffer->reader_page->list); | 2107 | INIT_LIST_HEAD(&cpu_buffer->reader_page->list); |
| 2099 | local_set(&cpu_buffer->reader_page->write, 0); | 2108 | local_set(&cpu_buffer->reader_page->write, 0); |
| 2100 | local_set(&cpu_buffer->reader_page->commit, 0); | 2109 | local_set(&cpu_buffer->reader_page->page->commit, 0); |
| 2101 | cpu_buffer->reader_page->read = 0; | 2110 | cpu_buffer->reader_page->read = 0; |
| 2102 | 2111 | ||
| 2103 | cpu_buffer->overrun = 0; | 2112 | cpu_buffer->overrun = 0; |
