On Wed, Nov 25, 2015 at 7:13 AM, Boris Ostrovsky <boris.ostrov...@oracle.com > wrote:
> On 11/24/2015 06:53 PM, Brendan Gregg wrote: > >> This introduces a way to have a restricted VPMU, by specifying one of two >> predefined groups of PMCs to make available. For secure environments, this >> allows the VPMU to be used without needing to enable all PMCs. >> >> Signed-off-by: Brendan Gregg <bgr...@netflix.com> >> --- >> docs/misc/xen-command-line.markdown | 14 +++++++++- >> xen/arch/x86/cpu/vpmu.c | 51 >> +++++++++++++++++++++++++++++-------- >> xen/arch/x86/cpu/vpmu_intel.c | 48 >> ++++++++++++++++++++++++++++++++++ >> xen/include/asm-x86/msr-index.h | 1 + >> xen/include/public/pmu.h | 14 ++++++++-- >> 5 files changed, 115 insertions(+), 13 deletions(-) >> >> diff --git a/docs/misc/xen-command-line.markdown >> b/docs/misc/xen-command-line.markdown >> index 70daa84..6055a68 100644 >> --- a/docs/misc/xen-command-line.markdown >> +++ b/docs/misc/xen-command-line.markdown >> @@ -1452,7 +1452,7 @@ Use Virtual Processor ID support if available. >> This prevents the need for TLB >> flushes on VM entry and exit, increasing performance. >> ### vpmu >> -> `= ( bts )` >> +> `= ( <boolean> | { bts | ipc | arch [, ...] } )` >> > Default: `off` >> @@ -1468,6 +1468,18 @@ wrong behaviour (see handle\_pmc\_quirk()). >> If 'vpmu=bts' is specified the virtualisation of the Branch Trace Store >> (BTS) >> feature is switched on on Intel processors supporting this feature. >> +vpmu=ipc enables performance monitoring, but restricts the counters to >> the >> +most minimum set possible: instructions, cycles, and reference cycles. >> These >> +can be used to calculate instructions per cycle (IPC). >> + >> +vpmu=arch enables performance monitoring, but restricts the counters to >> the >> +pre-defined architectural events only. These are exposed by cpuid, and >> listed >> +in Table 18-1 from the Intel 64 and IA-32 Architectures Software >> Developer's >> +Manual, Volume 3B, System Programming Guide, Part 2. >> + >> +If a boolean is not used, combinations of flags are allowed, comma >> separated. >> +For example, vpmu=arch,bts. >> + >> Note that if **watchdog** option is also specified vpmu will be turned >> off. >> *Warning:* >> diff --git a/xen/arch/x86/cpu/vpmu.c b/xen/arch/x86/cpu/vpmu.c >> index 2f5156a..bb0ca37 100644 >> --- a/xen/arch/x86/cpu/vpmu.c >> +++ b/xen/arch/x86/cpu/vpmu.c >> @@ -43,33 +43,64 @@ CHECK_pmu_data; >> CHECK_pmu_params; >> /* >> - * "vpmu" : vpmu generally enabled >> - * "vpmu=off" : vpmu generally disabled >> - * "vpmu=bts" : vpmu enabled and Intel BTS feature switched on. >> + * "vpmu" : vpmu generally enabled (all counters) >> + * "vpmu=off" : vpmu generally disabled >> + * "vpmu=bts" : vpmu enabled and Intel BTS feature switched on. >> + * "vpmu=ipc" : vpmu enabled for IPC counters only (most restrictive) >> + * "vpmu=arch" : vpmu enabled for predef arch counters only (restrictive) >> + * flag combinations are allowed, eg, "vpmu=ipc,bts". >> */ >> static unsigned int __read_mostly opt_vpmu_enabled; >> unsigned int __read_mostly vpmu_mode = XENPMU_MODE_OFF; >> unsigned int __read_mostly vpmu_features = 0; >> -static void parse_vpmu_param(char *s); >> -custom_param("vpmu", parse_vpmu_param); >> +static void parse_vpmu_params(char *s); >> +custom_param("vpmu", parse_vpmu_params); >> static DEFINE_SPINLOCK(vpmu_lock); >> static unsigned vpmu_count; >> static DEFINE_PER_CPU(struct vcpu *, last_vcpu); >> -static void __init parse_vpmu_param(char *s) >> +static int parse_vpmu_param(char *s, int len) >> { >> + if ( ! *s || ! len ) >> + return 0; >> + if ( !strncmp(s, "bts", len) ) >> + vpmu_features |= XENPMU_FEATURE_INTEL_BTS; >> + else if ( !strncmp(s, "ipc", len) ) >> + vpmu_features |= XENPMU_FEATURE_IPC_ONLY; >> + else if ( !strncmp(s, "arch", len) ) >> + vpmu_features |= XENPMU_FEATURE_ARCH_ONLY; >> + else if ( *s ) >> > > Why not just "else return 1;" ? We've already tested above that *s is not > '\0'. (And you don't need curly braces for single-line clauses) > > Ok, thanks. > + { >> + return 1; >> + } >> + return 0; >> +} >> + >> +static void __init parse_vpmu_params(char *s) >> +{ >> + bool_t badflag = 0; >> + char *sep, *p = s; >> + >> switch ( parse_bool(s) ) >> { >> case 0: >> break; >> default: >> - if ( !strcmp(s, "bts") ) >> - vpmu_features |= XENPMU_FEATURE_INTEL_BTS; >> - else if ( *s ) >> + sep = strchr(p, ','); >> + while (sep != NULL) >> + { >> + if ( parse_vpmu_param(p, sep - p) ) >> + badflag = 1; >> + p = sep + 1; >> + sep = strchr(p, ','); >> + } >> + sep = strchr(p, 0); >> + parse_vpmu_param(p, sep - p); >> > > This can find unsupported flag too but we are not setting badflag so we > will miss it (i.e. "vpmu=foo"). > > Can you just say something like > sep = strchr(p, ',') > if ( sep == NULL ) > sep = strchr(p, 0); > > and keep both parse_vpmu_param() invocations in a single loop? And then, > instead of having badflags simply print the warning and break. Ah, thanks, I'll tidy it up. I still need to do something to avoid the fall through and enabling the VPMU, so either use of a badflags, or a goto error, or something. > > + if ( badflag ) >> { >> - printk("VPMU: unknown flag: %s - vpmu disabled!\n", s); >> + printk("VPMU: unknown flags: %s - vpmu disabled!\n", s); >> break; >> } >> /* fall through */ >> diff --git a/xen/arch/x86/cpu/vpmu_intel.c b/xen/arch/x86/cpu/vpmu_intel.c >> index 8d83a1a..b26a20b 100644 >> --- a/xen/arch/x86/cpu/vpmu_intel.c >> +++ b/xen/arch/x86/cpu/vpmu_intel.c >> @@ -602,12 +602,19 @@ static int core2_vpmu_do_wrmsr(unsigned int msr, >> uint64_t msr_content, >> "MSR_PERF_GLOBAL_STATUS(0x38E)!\n"); >> return -EINVAL; >> case MSR_IA32_PEBS_ENABLE: >> + if ( vpmu_features & XENPMU_FEATURE_IPC_ONLY || >> + vpmu_features & XENPMU_FEATURE_ARCH_ONLY ) >> > > It's is a matter of taste but you could also use > vpmu_features & (XENPMU_FEATURE_IPC_ONLY | XENPMU_FEATURE_ARCH_ONLY) Ok, thanks! Brendan > > > -boris > > -- Brendan Gregg, Senior Performance Architect, Netflix
_______________________________________________ Xen-devel mailing list Xen-devel@lists.xen.org http://lists.xen.org/xen-devel