From cb1522ca92eea689384049023d5a366d9b67fa49 Mon Sep 17 00:00:00 2001 From: Ken Sato Date: Thu, 26 Jul 2018 09:20:29 +0900 Subject: [PATCH] perf_event: Handle fixed-pmc in arch-dep part Fujitsu: POSTK_DEBUG_TEMP_FIX_31 Refs: #1003 Change-Id: I66c7d18b9137894cf5764464482e2ebd5ecb9d52 --- arch/x86_64/kernel/perfctr.c | 81 ++++++++++++++++++------------------ ihk | 2 +- kernel/syscall.c | 59 ++++++++++++-------------- 3 files changed, 68 insertions(+), 74 deletions(-) diff --git a/arch/x86_64/kernel/perfctr.c b/arch/x86_64/kernel/perfctr.c index 01aab0f6..4adad87b 100644 --- a/arch/x86_64/kernel/perfctr.c +++ b/arch/x86_64/kernel/perfctr.c @@ -20,9 +20,7 @@ extern unsigned int *x86_march_perfmap; extern int running_on_kvm(void); -#ifdef POSTK_DEBUG_TEMP_FIX_31 int ihk_mc_perfctr_fixed_init(int counter, int mode); -#endif/*POSTK_DEBUG_TEMP_FIX_31*/ //#define PERFCTR_DEBUG #ifdef PERFCTR_DEBUG @@ -41,11 +39,11 @@ int ihk_mc_perfctr_fixed_init(int counter, int mode); } \ } while(0) -int perf_counters_discovered = 0; -int X86_IA32_NUM_PERF_COUNTERS = 0; -unsigned long X86_IA32_PERF_COUNTERS_MASK = 0; -int X86_IA32_NUM_FIXED_PERF_COUNTERS = 0; -unsigned long X86_IA32_FIXED_PERF_COUNTERS_MASK = 0; +int perf_counters_discovered; +int NUM_PERF_COUNTERS; +unsigned long PERF_COUNTERS_MASK; +int NUM_FIXED_PERF_COUNTERS; +unsigned long FIXED_PERF_COUNTERS_MASK; void x86_init_perfctr(void) { @@ -76,17 +74,17 @@ void x86_init_perfctr(void) op = 0x0a; asm volatile("cpuid" : "=a"(eax),"=b"(ebx),"=c"(ecx),"=d"(edx):"a"(op)); - X86_IA32_NUM_PERF_COUNTERS = ((eax & 0xFF00) >> 8); - X86_IA32_PERF_COUNTERS_MASK = (1 << X86_IA32_NUM_PERF_COUNTERS) - 1; + NUM_PERF_COUNTERS = ((eax & 0xFF00) >> 8); + PERF_COUNTERS_MASK = (1 << NUM_PERF_COUNTERS) - 1; - X86_IA32_NUM_FIXED_PERF_COUNTERS = (edx & 0x0F); - X86_IA32_FIXED_PERF_COUNTERS_MASK = - ((1UL << X86_IA32_NUM_FIXED_PERF_COUNTERS) - 1) << - X86_IA32_BASE_FIXED_PERF_COUNTERS; + NUM_FIXED_PERF_COUNTERS = (edx & 0x0F); + FIXED_PERF_COUNTERS_MASK = + ((1UL << NUM_FIXED_PERF_COUNTERS) - 1) << + BASE_FIXED_PERF_COUNTERS; perf_counters_discovered = 1; - kprintf("X86_IA32_NUM_PERF_COUNTERS: %d, X86_IA32_NUM_FIXED_PERF_COUNTERS: %d\n", - X86_IA32_NUM_PERF_COUNTERS, X86_IA32_NUM_FIXED_PERF_COUNTERS); + kprintf("NUM_PERF_COUNTERS: %d, NUM_FIXED_PERF_COUNTERS: %d\n", + NUM_PERF_COUNTERS, NUM_FIXED_PERF_COUNTERS); } /* Clear Fixed Counter Control */ @@ -95,20 +93,20 @@ void x86_init_perfctr(void) wrmsr(MSR_PERF_FIXED_CTRL, value); /* Clear Generic Counter Control */ - for(i = 0; i < X86_IA32_NUM_PERF_COUNTERS; i++) { + for (i = 0; i < NUM_PERF_COUNTERS; i++) { wrmsr(MSR_IA32_PERFEVTSEL0 + i, 0); } /* Enable PMC Control */ value = rdmsr(MSR_PERF_GLOBAL_CTRL); - value |= X86_IA32_PERF_COUNTERS_MASK; - value |= X86_IA32_FIXED_PERF_COUNTERS_MASK; + value |= PERF_COUNTERS_MASK; + value |= FIXED_PERF_COUNTERS_MASK; wrmsr(MSR_PERF_GLOBAL_CTRL, value); } static int set_perfctr_x86_direct(int counter, int mode, unsigned int value) { - if (counter < 0 || counter >= X86_IA32_NUM_PERF_COUNTERS) { + if (counter < 0 || counter >= NUM_PERF_COUNTERS) { return -EINVAL; } @@ -147,13 +145,14 @@ static int set_pmc_x86_direct(int counter, long val) val &= 0x000000ffffffffff; // 40bit Mask cnt_bit = 1UL << counter; - if ( cnt_bit & X86_IA32_PERF_COUNTERS_MASK ) { + if (cnt_bit & PERF_COUNTERS_MASK) { // set generic pmc wrmsr(MSR_IA32_PMC0 + counter, val); } - else if ( cnt_bit & X86_IA32_FIXED_PERF_COUNTERS_MASK ) { + else if (cnt_bit & FIXED_PERF_COUNTERS_MASK) { // set fixed pmc - wrmsr(MSR_IA32_FIXED_CTR0 + counter - X86_IA32_BASE_FIXED_PERF_COUNTERS, val); + wrmsr(MSR_IA32_FIXED_CTR0 + + counter - BASE_FIXED_PERF_COUNTERS, val); } else { return -EINVAL; @@ -173,10 +172,10 @@ static int set_fixed_counter(int counter, int mode) { unsigned long value = 0; unsigned int ctr_mask = 0xf; - int counter_idx = counter - X86_IA32_BASE_FIXED_PERF_COUNTERS ; + int counter_idx = counter - BASE_FIXED_PERF_COUNTERS; unsigned int set_val = 0; - if (counter_idx < 0 || counter_idx >= X86_IA32_NUM_FIXED_PERF_COUNTERS) { + if (counter_idx < 0 || counter_idx >= NUM_FIXED_PERF_COUNTERS) { return -EINVAL; } @@ -206,14 +205,13 @@ int ihk_mc_perfctr_init_raw(int counter, uint64_t config, int mode) int ihk_mc_perfctr_init_raw(int counter, unsigned int code, int mode) #endif /*POSTK_DEBUG_TEMP_FIX_29*/ { -#ifdef POSTK_DEBUG_TEMP_FIX_31 // PAPI_REF_CYC counted by fixed counter - if (counter >= X86_IA32_BASE_FIXED_PERF_COUNTERS) { + if (counter >= BASE_FIXED_PERF_COUNTERS && + counter < BASE_FIXED_PERF_COUNTERS + NUM_FIXED_PERF_COUNTERS) { return ihk_mc_perfctr_fixed_init(counter, mode); } -#endif /*POSTK_DEBUG_TEMP_FIX_31*/ - if (counter < 0 || counter >= X86_IA32_NUM_PERF_COUNTERS) { + if (counter < 0 || counter >= NUM_PERF_COUNTERS) { return -EINVAL; } @@ -246,7 +244,7 @@ int ihk_mc_perfctr_init(int counter, enum ihk_perfctr_type type, int mode) } #endif /*POSTK_DEBUG_TEMP_FIX_29*/ - if (counter < 0 || counter >= X86_IA32_NUM_PERF_COUNTERS) { + if (counter < 0 || counter >= NUM_PERF_COUNTERS) { return -EINVAL; } if (type < 0 || type >= PERFCTR_MAX_TYPE) { @@ -306,7 +304,7 @@ int ihk_mc_perfctr_start(unsigned long counter_mask) { int ret = 0; unsigned long value = 0; - unsigned long mask = X86_IA32_PERF_COUNTERS_MASK | X86_IA32_FIXED_PERF_COUNTERS_MASK; + unsigned long mask = PERF_COUNTERS_MASK | FIXED_PERF_COUNTERS_MASK; #ifdef POSTK_DEBUG_TEMP_FIX_30 unsigned long counter_mask = 1UL << counter; #endif /*POSTK_DEBUG_TEMP_FIX_30*/ @@ -334,7 +332,7 @@ int ihk_mc_perfctr_stop(unsigned long counter_mask) { int ret = 0; unsigned long value; - unsigned long mask = X86_IA32_PERF_COUNTERS_MASK | X86_IA32_FIXED_PERF_COUNTERS_MASK; + unsigned long mask = PERF_COUNTERS_MASK | FIXED_PERF_COUNTERS_MASK; #ifdef POSTK_DEBUG_TEMP_FIX_30 unsigned long counter_mask = 1UL << counter; #endif/*POSTK_DEBUG_TEMP_FIX_30*/ @@ -374,10 +372,10 @@ int ihk_mc_perfctr_fixed_init(int counter, int mode) { unsigned long value = 0; unsigned int ctr_mask = 0xf; - int counter_idx = counter - X86_IA32_BASE_FIXED_PERF_COUNTERS ; + int counter_idx = counter - BASE_FIXED_PERF_COUNTERS; unsigned int set_val = 0; - if (counter_idx < 0 || counter_idx >= X86_IA32_NUM_FIXED_PERF_COUNTERS) { + if (counter_idx < 0 || counter_idx >= NUM_FIXED_PERF_COUNTERS) { return -EINVAL; } @@ -418,7 +416,7 @@ int ihk_mc_perfctr_read_mask(unsigned long counter_mask, unsigned long *value) { int i, j; - for (i = 0, j = 0; i < X86_IA32_NUM_PERF_COUNTERS && counter_mask; + for (i = 0, j = 0; i < NUM_PERF_COUNTERS && counter_mask; i++, counter_mask >>= 1) { if (counter_mask & 1) { value[j++] = rdpmc(i); @@ -438,13 +436,14 @@ unsigned long ihk_mc_perfctr_read(int counter) cnt_bit = 1UL << counter; - if ( cnt_bit & X86_IA32_PERF_COUNTERS_MASK ) { + if (cnt_bit & PERF_COUNTERS_MASK) { // read generic pmc retval = rdpmc(counter); } - else if ( cnt_bit & X86_IA32_FIXED_PERF_COUNTERS_MASK ) { + else if (cnt_bit & FIXED_PERF_COUNTERS_MASK) { // read fixed pmc - retval = rdpmc((1 << 30) + (counter - X86_IA32_BASE_FIXED_PERF_COUNTERS)); + retval = rdpmc((1 << 30) + + (counter - BASE_FIXED_PERF_COUNTERS)); } else { retval = -EINVAL; @@ -466,12 +465,12 @@ unsigned long ihk_mc_perfctr_read_msr(int counter) cnt_bit = 1UL << counter; - if ( cnt_bit & X86_IA32_PERF_COUNTERS_MASK ) { + if (cnt_bit & PERF_COUNTERS_MASK) { // read generic pmc idx = MSR_IA32_PMC0 + counter; retval = (unsigned long) rdmsr(idx); } - else if ( cnt_bit & X86_IA32_FIXED_PERF_COUNTERS_MASK ) { + else if (cnt_bit & FIXED_PERF_COUNTERS_MASK) { // read fixed pmc idx = MSR_IA32_FIXED_CTR0 + counter; retval = (unsigned long) rdmsr(idx); @@ -504,8 +503,8 @@ int ihk_mc_perfctr_alloc_counter(unsigned int *type, unsigned long *config, unsi } // find avail generic counter - for(i = 0; i < X86_IA32_NUM_PERF_COUNTERS; i++) { - if(!(pmc_status & (1 << i))) { + for (i = 0; i < NUM_PERF_COUNTERS; i++) { + if (!(pmc_status & (1 << i))) { ret = i; break; } diff --git a/ihk b/ihk index 3410b5c7..779390b2 160000 --- a/ihk +++ b/ihk @@ -1 +1 @@ -Subproject commit 3410b5c732b4daab3819868906385710e3c287c4 +Subproject commit 779390b27b81c6c98ae54811333e066ae3823391 diff --git a/kernel/syscall.c b/kernel/syscall.c index 43ea8ebd..f5bc47ec 100644 --- a/kernel/syscall.c +++ b/kernel/syscall.c @@ -3407,7 +3407,7 @@ perf_counter_alloc(struct thread *thread) int i = 0; // find avail generic counter - for(i = 0; i < X86_IA32_NUM_PERF_COUNTERS; i++) { + for (i = 0; i < NUM_PERF_COUNTERS; i++) { if(!(thread->pmc_alloc_map & (1 << i))) { ret = i; break; @@ -3431,25 +3431,20 @@ perf_counter_start(struct mc_perf_event *event) mode |= PERFCTR_USER_MODE; } - if(event->counter_id >= 0 && event->counter_id < X86_IA32_NUM_PERF_COUNTERS) { - if (event->extra_reg.reg) { - if (ihk_mc_perfctr_set_extra(event)) { - ret = -1; - goto out; - } + if (event->extra_reg.reg) { + if (ihk_mc_perfctr_set_extra(event)) { + ret = -1; + goto out; } - ret = ihk_mc_perfctr_init_raw(event->counter_id, event->hw_config, mode); - ihk_mc_perfctr_start(1UL << event->counter_id); } - else if(event->counter_id >= X86_IA32_BASE_FIXED_PERF_COUNTERS && - event->counter_id < X86_IA32_BASE_FIXED_PERF_COUNTERS + X86_IA32_NUM_FIXED_PERF_COUNTERS) { - ret = ihk_mc_perfctr_fixed_init(event->counter_id, mode); - ihk_mc_perfctr_start(1UL << event->counter_id); - } - else { - ret = -1; + ret = ihk_mc_perfctr_init_raw(event->counter_id, + event->hw_config, mode); + if (ret) { + goto out; } + ihk_mc_perfctr_start(1UL << event->counter_id); + out: return ret; } @@ -3578,15 +3573,15 @@ perf_start(struct mc_perf_event *event) struct mc_perf_event *leader = event->group_leader, *sub; counter_id = leader->counter_id; - if((1UL << counter_id & X86_IA32_PERF_COUNTERS_MASK) | - (1UL << counter_id & X86_IA32_FIXED_PERF_COUNTERS_MASK)) { + if ((1UL << counter_id & PERF_COUNTERS_MASK) | + (1UL << counter_id & FIXED_PERF_COUNTERS_MASK)) { perf_counter_start(leader); } list_for_each_entry(sub, &leader->sibling_list, group_entry) { counter_id = sub->counter_id; - if((1UL << counter_id & X86_IA32_PERF_COUNTERS_MASK) | - (1UL << counter_id & X86_IA32_FIXED_PERF_COUNTERS_MASK)) { + if ((1UL << counter_id & PERF_COUNTERS_MASK) | + (1UL << counter_id & FIXED_PERF_COUNTERS_MASK)) { perf_counter_start(sub); } } @@ -3600,15 +3595,15 @@ perf_reset(struct mc_perf_event *event) struct mc_perf_event *leader = event->group_leader, *sub; counter_id = leader->counter_id; - if((1UL << counter_id & X86_IA32_PERF_COUNTERS_MASK) | - (1UL << counter_id & X86_IA32_FIXED_PERF_COUNTERS_MASK)) { + if ((1UL << counter_id & PERF_COUNTERS_MASK) | + (1UL << counter_id & FIXED_PERF_COUNTERS_MASK)) { ihk_mc_perfctr_reset(counter_id); } list_for_each_entry(sub, &leader->sibling_list, group_entry) { counter_id = sub->counter_id; - if((1UL << counter_id & X86_IA32_PERF_COUNTERS_MASK) | - (1UL << counter_id & X86_IA32_FIXED_PERF_COUNTERS_MASK)) { + if ((1UL << counter_id & PERF_COUNTERS_MASK) | + (1UL << counter_id & FIXED_PERF_COUNTERS_MASK)) { ihk_mc_perfctr_reset(counter_id); } } @@ -3622,29 +3617,29 @@ perf_stop(struct mc_perf_event *event) #ifdef POSTK_DEBUG_TEMP_FIX_30 counter_id = leader->counter_id; - if((1UL << counter_id & X86_IA32_PERF_COUNTERS_MASK) | - (1UL << counter_id & X86_IA32_FIXED_PERF_COUNTERS_MASK)) { + if ((1UL << counter_id & PERF_COUNTERS_MASK) | + (1UL << counter_id & FIXED_PERF_COUNTERS_MASK)) { ihk_mc_perfctr_stop(counter_id); } list_for_each_entry(sub, &leader->sibling_list, group_entry) { counter_id = sub->counter_id; - if((1UL << counter_id & X86_IA32_PERF_COUNTERS_MASK) | - (1UL << counter_id & X86_IA32_FIXED_PERF_COUNTERS_MASK)) { + if ((1UL << counter_id & PERF_COUNTERS_MASK) | + (1UL << counter_id & FIXED_PERF_COUNTERS_MASK)) { ihk_mc_perfctr_stop(counter_id); } } #else counter_id = leader->counter_id; - if((1UL << counter_id & X86_IA32_PERF_COUNTERS_MASK) | - (1UL << counter_id & X86_IA32_FIXED_PERF_COUNTERS_MASK)) { + if ((1UL << counter_id & PERF_COUNTERS_MASK) | + (1UL << counter_id & FIXED_PERF_COUNTERS_MASK)) { ihk_mc_perfctr_stop(1UL << counter_id); } list_for_each_entry(sub, &leader->sibling_list, group_entry) { counter_id = sub->counter_id; - if((1UL << counter_id & X86_IA32_PERF_COUNTERS_MASK) | - (1UL << counter_id & X86_IA32_FIXED_PERF_COUNTERS_MASK)) { + if ((1UL << counter_id & PERF_COUNTERS_MASK) | + (1UL << counter_id & FIXED_PERF_COUNTERS_MASK)) { ihk_mc_perfctr_stop(1UL << counter_id); } }