diff --git a/arch/arm64/kernel/perfctr.c b/arch/arm64/kernel/perfctr.c index 259014e3..d3b3766c 100644 --- a/arch/arm64/kernel/perfctr.c +++ b/arch/arm64/kernel/perfctr.c @@ -148,30 +148,32 @@ int ihk_mc_perfctr_start(unsigned long counter_mask) return ret; } -int ihk_mc_perfctr_stop(unsigned long counter_mask) +int ihk_mc_perfctr_stop(unsigned long counter_mask, int flags) { - int ret = 0; - int counter; - unsigned long counter_bit; + int i = 0; - for (counter = 0, counter_bit = 1; - counter_bit < counter_mask; - counter++, counter_bit <<= 1) { - if (!(counter_mask & counter_bit)) + for (i = 0; i < sizeof(counter_mask) * BITS_PER_BYTE; i++) { + if (!(counter_mask & (1UL << i))) continue; - ret = cpu_pmu.disable_counter(counter); - if (ret < 0) - break; + int ret = 0; - // ihk_mc_perfctr_startが呼ばれるときには、 - // init系関数が呼ばれるのでdisableにする。 - ret = cpu_pmu.disable_intens(counter); - if (ret < 0) - break; + ret = cpu_pmu.disable_counter(i); + if (ret < 0) { + continue; + } + + if (flags & IHK_MC_PERFCTR_DISABLE_INTERRUPT) { + // when ihk_mc_perfctr_start is called, + // ihk_mc_perfctr_init is also called so disable + // interrupt + ret = cpu_pmu.disable_intens(i); + if (ret < 0) { + continue; + } + } } - - return ret < 0 ? ret : 0; + return 0; } int ihk_mc_perfctr_reset(int counter) diff --git a/arch/x86_64/kernel/perfctr.c b/arch/x86_64/kernel/perfctr.c index 41edc843..a9828704 100644 --- a/arch/x86_64/kernel/perfctr.c +++ b/arch/x86_64/kernel/perfctr.c @@ -318,7 +318,7 @@ int ihk_mc_perfctr_start(unsigned long counter_mask) goto fn_exit; } -int ihk_mc_perfctr_stop(unsigned long counter_mask) +int ihk_mc_perfctr_stop(unsigned long counter_mask, int flags) { int ret = 0; unsigned long value; diff --git a/kernel/host.c b/kernel/host.c index 8ccac6ef..7a9f5a74 100644 --- a/kernel/host.c +++ b/kernel/host.c @@ -729,7 +729,7 @@ static int syscall_packet_handler(struct ihk_ikc_channel_desc *c, break; } - ret = ihk_mc_perfctr_stop(1 << pcd->target_cntr); + ret = ihk_mc_perfctr_stop(1 << pcd->target_cntr, 0); if (ret != 0) { break; } @@ -742,7 +742,8 @@ static int syscall_packet_handler(struct ihk_ikc_channel_desc *c, break; case PERF_CTRL_DISABLE: - ret = ihk_mc_perfctr_stop(pcd->target_cntr_mask); + ret = ihk_mc_perfctr_stop(pcd->target_cntr_mask, + IHK_MC_PERFCTR_DISABLE_INTERRUPT); break; case PERF_CTRL_GET: diff --git a/kernel/syscall.c b/kernel/syscall.c index b5b375e5..710c817a 100644 --- a/kernel/syscall.c +++ b/kernel/syscall.c @@ -3974,7 +3974,7 @@ perf_stop(struct mc_perf_event *event) } if (counter_mask) { - ihk_mc_perfctr_stop(counter_mask); + ihk_mc_perfctr_stop(counter_mask, 0); cpu_local_var(current)->proc->monitoring_event = NULL; cpu_local_var(current)->proc->perf_status = PP_NONE; } @@ -9302,13 +9302,15 @@ SYSCALL_DECLARE(pmc_start) SYSCALL_DECLARE(pmc_stop) { unsigned long counter = ihk_mc_syscall_arg0(ctx); - return ihk_mc_perfctr_stop((int)counter); + return ihk_mc_perfctr_stop((int)counter, + IHK_MC_PERFCTR_DISABLE_INTERRUPT); } #else SYSCALL_DECLARE(pmc_stop) { unsigned long counter = ihk_mc_syscall_arg0(ctx); - return ihk_mc_perfctr_stop(1 << counter); + return ihk_mc_perfctr_stop(1 << counter, + IHK_MC_PERFCTR_DISABLE_INTERRUPT); } #endif /*POSTK_DEBUG_TEMP_FIX_30*/ diff --git a/lib/include/ihk/perfctr.h b/lib/include/ihk/perfctr.h index 301fcaa1..15554e3d 100644 --- a/lib/include/ihk/perfctr.h +++ b/lib/include/ihk/perfctr.h @@ -55,6 +55,8 @@ enum ihk_perfctr_type { PERFCTR_MAX_TYPE, }; +#define IHK_MC_PERFCTR_DISABLE_INTERRUPT 1 + #ifdef POSTK_DEBUG_TEMP_FIX_29 int ihk_mc_perfctr_init(int counter, uint64_t config, int mode); int ihk_mc_perfctr_init_raw(int counter, uint64_t config, int mode); @@ -64,7 +66,7 @@ int ihk_mc_perfctr_init_raw(int counter, unsigned int code, int mode); #endif/*POSTK_DEBUG_TEMP_FIX_29*/ int ihk_mc_perfctr_set_extra(struct mc_perf_event *event); int ihk_mc_perfctr_start(unsigned long counter_mask); -int ihk_mc_perfctr_stop(unsigned long counter_mask); +int ihk_mc_perfctr_stop(unsigned long counter_mask, int flags); int ihk_mc_perfctr_reset(int counter); int ihk_mc_perfctr_set(int counter, long value); int ihk_mc_perfctr_read_mask(unsigned long counter_mask, unsigned long *value);