perf: set event period

Change-Id: Ibf569de7af8697e766c10b8d70905b8cdc4df083
This commit is contained in:
TOIDA,Suguru
2019-11-19 14:18:17 +09:00
parent 86c45484e3
commit 343121c3d0
5 changed files with 54 additions and 0 deletions

View File

@@ -232,3 +232,43 @@ int hw_perf_event_init(struct mc_perf_event *event)
} }
return 0; return 0;
} }
int ihk_mc_event_set_period(struct mc_perf_event *event)
{
struct hw_perf_event *hwc = &event->hw;
int64_t left = ihk_atomic64_read(&hwc->period_left);
int64_t period = hwc->sample_period;
uint64_t max_period;
int ret = 0;
max_period = arm_pmu_event_max_period(event);
if (unlikely(left <= -period)) {
left = period;
ihk_atomic64_set(&hwc->period_left, left);
hwc->last_period = period;
ret = 1;
}
if (unlikely(left <= 0)) {
left += period;
ihk_atomic64_set(&hwc->period_left, left);
hwc->last_period = period;
ret = 1;
}
/*
* Limit the maximum period to prevent the counter value
* from overtaking the one we are about to program. In
* effect we are reducing max_period to account for
* interrupt latency (and we are being very conservative).
*/
if (left > (max_period >> 1))
left = (max_period >> 1);
ihk_atomic64_set(&hwc->prev_count, (uint64_t)-left);
cpu_pmu.write_counter(event->counter_id,
(uint64_t)(-left) & max_period);
return ret;
}

View File

@@ -788,6 +788,7 @@ static void armv8pmu_handle_irq(void *priv)
long irqstate; long irqstate;
struct mckfd *fdp; struct mckfd *fdp;
struct pt_regs *regs = (struct pt_regs *)priv; struct pt_regs *regs = (struct pt_regs *)priv;
struct mc_perf_event *event = NULL;
/* /*
* Get and reset the IRQ flags * Get and reset the IRQ flags
@@ -821,6 +822,11 @@ static void armv8pmu_handle_irq(void *priv)
else { else {
set_signal(SIGIO, regs, NULL); set_signal(SIGIO, regs, NULL);
} }
if (event) {
ihk_mc_event_set_period(event);
}
return;
} }
static void armv8pmu_enable_user_access_pmu_regs(void) static void armv8pmu_enable_user_access_pmu_regs(void)

View File

@@ -508,3 +508,8 @@ int hw_perf_event_init(struct mc_perf_event *event)
{ {
return 0; return 0;
} }
int ihk_mc_event_set_period(struct mc_perf_event *event)
{
return 0;
}

View File

@@ -4068,6 +4068,7 @@ void perf_start(struct mc_perf_event *event)
leader->base_system_tsc = thread->system_tsc; leader->base_system_tsc = thread->system_tsc;
} }
else { else {
ihk_mc_event_set_period(leader);
perf_counter_set(leader); perf_counter_set(leader);
counter_mask |= 1UL << counter_id; counter_mask |= 1UL << counter_id;
} }
@@ -4097,6 +4098,7 @@ void perf_start(struct mc_perf_event *event)
sub->base_system_tsc = thread->system_tsc; sub->base_system_tsc = thread->system_tsc;
} }
else { else {
ihk_mc_event_set_period(sub);
perf_counter_set(sub); perf_counter_set(sub);
counter_mask |= 1UL << counter_id; counter_mask |= 1UL << counter_id;
} }

View File

@@ -91,6 +91,7 @@ unsigned long ihk_mc_hw_cache_extra_reg_map(unsigned long hw_cache_event);
unsigned long ihk_mc_raw_event_map(unsigned long raw_event); unsigned long ihk_mc_raw_event_map(unsigned long raw_event);
int ihk_mc_validate_event(unsigned long hw_config); int ihk_mc_validate_event(unsigned long hw_config);
int hw_perf_event_init(struct mc_perf_event *event); int hw_perf_event_init(struct mc_perf_event *event);
int ihk_mc_event_set_period(struct mc_perf_event *event);
static inline int is_sampling_event(struct mc_perf_event *event) static inline int is_sampling_event(struct mc_perf_event *event)
{ {