diff options
Diffstat (limited to 'kernel')
-rw-r--r-- | kernel/perf_event.c | 17 |
1 files changed, 11 insertions, 6 deletions
diff --git a/kernel/perf_event.c b/kernel/perf_event.c index 1dfb6cc4fdea..8e55b440e28a 100644 --- a/kernel/perf_event.c +++ b/kernel/perf_event.c | |||
@@ -3759,16 +3759,16 @@ again: | |||
3759 | return nr; | 3759 | return nr; |
3760 | } | 3760 | } |
3761 | 3761 | ||
3762 | static void perf_swevent_overflow(struct perf_event *event, | 3762 | static void perf_swevent_overflow(struct perf_event *event, u64 overflow, |
3763 | int nmi, struct perf_sample_data *data, | 3763 | int nmi, struct perf_sample_data *data, |
3764 | struct pt_regs *regs) | 3764 | struct pt_regs *regs) |
3765 | { | 3765 | { |
3766 | struct hw_perf_event *hwc = &event->hw; | 3766 | struct hw_perf_event *hwc = &event->hw; |
3767 | int throttle = 0; | 3767 | int throttle = 0; |
3768 | u64 overflow; | ||
3769 | 3768 | ||
3770 | data->period = event->hw.last_period; | 3769 | data->period = event->hw.last_period; |
3771 | overflow = perf_swevent_set_period(event); | 3770 | if (!overflow) |
3771 | overflow = perf_swevent_set_period(event); | ||
3772 | 3772 | ||
3773 | if (hwc->interrupts == MAX_INTERRUPTS) | 3773 | if (hwc->interrupts == MAX_INTERRUPTS) |
3774 | return; | 3774 | return; |
@@ -3801,14 +3801,19 @@ static void perf_swevent_add(struct perf_event *event, u64 nr, | |||
3801 | 3801 | ||
3802 | atomic64_add(nr, &event->count); | 3802 | atomic64_add(nr, &event->count); |
3803 | 3803 | ||
3804 | if (!regs) | ||
3805 | return; | ||
3806 | |||
3804 | if (!hwc->sample_period) | 3807 | if (!hwc->sample_period) |
3805 | return; | 3808 | return; |
3806 | 3809 | ||
3807 | if (!regs) | 3810 | if (nr == 1 && hwc->sample_period == 1 && !event->attr.freq) |
3811 | return perf_swevent_overflow(event, 1, nmi, data, regs); | ||
3812 | |||
3813 | if (atomic64_add_negative(nr, &hwc->period_left)) | ||
3808 | return; | 3814 | return; |
3809 | 3815 | ||
3810 | if (!atomic64_add_negative(nr, &hwc->period_left)) | 3816 | perf_swevent_overflow(event, 0, nmi, data, regs); |
3811 | perf_swevent_overflow(event, nmi, data, regs); | ||
3812 | } | 3817 | } |
3813 | 3818 | ||
3814 | static int perf_swevent_is_counting(struct perf_event *event) | 3819 | static int perf_swevent_is_counting(struct perf_event *event) |