From: He Chuyue hechuyue@wxiat.com
Sunway inclusion category: bugfix bugzilla: https://gitee.com/openeuler/kernel/issues/I56X48
--------------------------------
To read raw event count, perf stat calls sw64_pmu_start() to start the event and then calls sw64_perf_event_set_period() to set a new period to sample over.
It used to initialize hwc.prev_count and PMC with different values and this will result in error sample values. To fix this problem, initialize them to 0 consistently.
Signed-off-by: He Chuyue hechuyue@wxiat.com
Signed-off-by: Gu Zitao guzitao@wxiat.com --- arch/sw_64/kernel/perf_event.c | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-)
diff --git a/arch/sw_64/kernel/perf_event.c b/arch/sw_64/kernel/perf_event.c index e9aae53a56f6..52ec34e33269 100644 --- a/arch/sw_64/kernel/perf_event.c +++ b/arch/sw_64/kernel/perf_event.c @@ -297,31 +297,33 @@ static int sw64_perf_event_set_period(struct perf_event *event, { long left = local64_read(&hwc->period_left); long period = hwc->sample_period; - int ret = 0; + int overflow = 0; + unsigned long value;
if (unlikely(left <= -period)) { left = period; local64_set(&hwc->period_left, left); hwc->last_period = period; - ret = 1; + overflow = 1; }
if (unlikely(left <= 0)) { left += period; local64_set(&hwc->period_left, left); hwc->last_period = period; - ret = 1; + overflow = 1; }
if (left > (long)sw64_pmu->pmc_max_period) left = sw64_pmu->pmc_max_period;
- local64_set(&hwc->prev_count, (unsigned long)(-left)); - sw64_write_pmc(idx, (unsigned long)(sw64_pmu->pmc_max_period - left)); + value = sw64_pmu->pmc_max_period - left; + local64_set(&hwc->prev_count, value); + sw64_write_pmc(idx, value);
perf_event_update_userpage(event);
- return ret; + return overflow; }
/*