diff options
-rw-r--r-- | arch/x86/kernel/cpu/perf_event_intel_pt.c | 34 |
1 files changed, 22 insertions, 12 deletions
diff --git a/arch/x86/kernel/cpu/perf_event_intel_pt.c b/arch/x86/kernel/cpu/perf_event_intel_pt.c index ffe666c2c6b5..5b804f96ad66 100644 --- a/arch/x86/kernel/cpu/perf_event_intel_pt.c +++ b/arch/x86/kernel/cpu/perf_event_intel_pt.c | |||
@@ -615,7 +615,8 @@ static int pt_buffer_reset_markers(struct pt_buffer *buf, | |||
615 | struct perf_output_handle *handle) | 615 | struct perf_output_handle *handle) |
616 | 616 | ||
617 | { | 617 | { |
618 | unsigned long idx, npages, end; | 618 | unsigned long head = local64_read(&buf->head); |
619 | unsigned long idx, npages, wakeup; | ||
619 | 620 | ||
620 | if (buf->snapshot) | 621 | if (buf->snapshot) |
621 | return 0; | 622 | return 0; |
@@ -634,17 +635,26 @@ static int pt_buffer_reset_markers(struct pt_buffer *buf, | |||
634 | buf->topa_index[buf->stop_pos]->stop = 0; | 635 | buf->topa_index[buf->stop_pos]->stop = 0; |
635 | buf->topa_index[buf->intr_pos]->intr = 0; | 636 | buf->topa_index[buf->intr_pos]->intr = 0; |
636 | 637 | ||
637 | if (pt_cap_get(PT_CAP_topa_multiple_entries)) { | 638 | /* how many pages till the STOP marker */ |
638 | npages = (handle->size + 1) >> PAGE_SHIFT; | 639 | npages = handle->size >> PAGE_SHIFT; |
639 | end = (local64_read(&buf->head) >> PAGE_SHIFT) + npages; | 640 | |
640 | /*if (end > handle->wakeup >> PAGE_SHIFT) | 641 | /* if it's on a page boundary, fill up one more page */ |
641 | end = handle->wakeup >> PAGE_SHIFT;*/ | 642 | if (!offset_in_page(head + handle->size + 1)) |
642 | idx = end & (buf->nr_pages - 1); | 643 | npages++; |
643 | buf->stop_pos = idx; | 644 | |
644 | idx = (local64_read(&buf->head) >> PAGE_SHIFT) + npages - 1; | 645 | idx = (head >> PAGE_SHIFT) + npages; |
645 | idx &= buf->nr_pages - 1; | 646 | idx &= buf->nr_pages - 1; |
646 | buf->intr_pos = idx; | 647 | buf->stop_pos = idx; |
647 | } | 648 | |
649 | wakeup = handle->wakeup >> PAGE_SHIFT; | ||
650 | |||
651 | /* in the worst case, wake up the consumer one page before hard stop */ | ||
652 | idx = (head >> PAGE_SHIFT) + npages - 1; | ||
653 | if (idx > wakeup) | ||
654 | idx = wakeup; | ||
655 | |||
656 | idx &= buf->nr_pages - 1; | ||
657 | buf->intr_pos = idx; | ||
648 | 658 | ||
649 | buf->topa_index[buf->stop_pos]->stop = 1; | 659 | buf->topa_index[buf->stop_pos]->stop = 1; |
650 | buf->topa_index[buf->intr_pos]->intr = 1; | 660 | buf->topa_index[buf->intr_pos]->intr = 1; |