[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Xen-devel] [PATCH v2 2/2] x86/VPMU: implement ipc and arch filter flags


  • To: xen-devel@xxxxxxxxxxxxx
  • From: Dietmar Hahn <dietmar.hahn@xxxxxxxxxxxxxx>
  • Date: Thu, 26 Nov 2015 09:11:37 +0100
  • Cc: boris.ostrovsky@xxxxxxxxxx, Brendan Gregg <bgregg@xxxxxxxxxxx>
  • Delivery-date: Thu, 26 Nov 2015 08:11:52 +0000
  • Domainkey-signature: s=s1536a; d=ts.fujitsu.com; c=nofws; q=dns; h=X-SBRSScore:Received:Received:Received:From:To:Cc: Subject:Date:Message-ID:User-Agent:In-Reply-To:References: MIME-Version:Content-Transfer-Encoding:Content-Type; b=vSDP/PzfMoVzjcIjKGTo86aMDdHkl+jGqD6XLjPH1qZCr6cAX2l82Teh 4SQT5Ok+wmQa1V9Y/I6XJy6GUAzszjwrtSzs2vGhzvHl3D3GoDuQJTU9n dmiatCLji2U2F908lYgd1YcokpV4pWF7GfvXniYup4ZYL9YJn6Gq+25Lo 9546lTGnLxNS/HJKGpI1WZov9hMktb1Bv3W7JnSsXfWxo9nbAzzU00hXK APYOcg2LMVnWu+OCd+WIMWioWNl2Y;
  • List-id: Xen developer discussion <xen-devel.lists.xen.org>

Am Dienstag 24 November 2015, 15:53:12 schrieb Brendan Gregg:
> 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 <bgregg@xxxxxxxxxxx>
> ---
>  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.

Maybe you better should write
section "Pre-defined Architectural Performance Events"
instead of "Table 18-1" because the number may change in the document.
And below in the comment of the code too.

Dietmar.

> +
> +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 )
> +    {
> +        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);
> +        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 )
> +            return -EINVAL;
>          if ( msr_content & 1 )
>              gdprintk(XENLOG_WARNING, "Guest is trying to enable PEBS, "
>                       "which is not supported.\n");
>          core2_vpmu_cxt->pebs_enable = msr_content;
>          return 0;
>      case MSR_IA32_DS_AREA:
> +        if ( (vpmu_features & XENPMU_FEATURE_IPC_ONLY ||
> +             vpmu_features & XENPMU_FEATURE_ARCH_ONLY) &&
> +             !(vpmu_features & XENPMU_FEATURE_INTEL_BTS) )
> +            return -EINVAL;
>          if ( vpmu_is_set(vpmu, VPMU_CPU_HAS_DS) )
>          {
>              if ( !is_canonical_address(msr_content) )
> @@ -652,12 +659,53 @@ static int core2_vpmu_do_wrmsr(unsigned int msr, 
> uint64_t msr_content,
>          tmp = msr - MSR_P6_EVNTSEL(0);
>          if ( tmp >= 0 && tmp < arch_pmc_cnt )
>          {
> +            bool_t blocked = 0;
> +            uint64_t umaskevent;
>              struct xen_pmu_cntr_pair *xen_pmu_cntr_pair =
>                  vpmu_reg_pointer(core2_vpmu_cxt, arch_counters);
>  
>              if ( msr_content & ARCH_CTRL_MASK )
>                  return -EINVAL;
>  
> +            /* PMC filters */
> +            umaskevent = msr_content & MSR_IA32_CMT_EVTSEL_UE_MASK;
> +            if ( vpmu_features & XENPMU_FEATURE_IPC_ONLY ||
> +                 vpmu_features & XENPMU_FEATURE_ARCH_ONLY )
> +            {
> +                blocked = 1;
> +                switch ( umaskevent )
> +                {
> +                /*
> +                 * See Table 18-1 from the Intel 64 and IA-32 Architectures 
> Software
> +                 * Developer's Manual, Volume 3B, System Programming Guide, 
> Part 2.
> +                 */
> +                case 0x003c: /* unhalted core cycles */
> +                case 0x013c: /* unhalted ref cycles */
> +                case 0x00c0: /* instruction retired */
> +                    blocked = 0;
> +                default:
> +                    break;
> +                }
> +            }
> +
> +            if ( vpmu_features & XENPMU_FEATURE_ARCH_ONLY )
> +            {
> +                /* additional counters beyond IPC only; blocked already set 
> */
> +                switch ( umaskevent )
> +                {
> +                case 0x4f2e: /* LLC reference */
> +                case 0x412e: /* LLC misses */
> +                case 0x00c4: /* branch instruction retired */
> +                case 0x00c5: /* branch */
> +                    blocked = 0;
> +                default:
> +                    break;
> +               }
> +            }
> +
> +            if ( blocked )
> +                return -EINVAL;
> +
>              if ( has_hvm_container_vcpu(v) )
>                  vmx_read_guest_msr(MSR_CORE_PERF_GLOBAL_CTRL,
>                                     &core2_vpmu_cxt->global_ctrl);
> diff --git a/xen/include/asm-x86/msr-index.h b/xen/include/asm-x86/msr-index.h
> index b8ad93c..0542064 100644
> --- a/xen/include/asm-x86/msr-index.h
> +++ b/xen/include/asm-x86/msr-index.h
> @@ -328,6 +328,7 @@
>  
>  /* Platform Shared Resource MSRs */
>  #define MSR_IA32_CMT_EVTSEL          0x00000c8d
> +#define MSR_IA32_CMT_EVTSEL_UE_MASK  0x0000ffff
>  #define MSR_IA32_CMT_CTR             0x00000c8e
>  #define MSR_IA32_PSR_ASSOC           0x00000c8f
>  #define MSR_IA32_PSR_L3_QOS_CFG      0x00000c81
> diff --git a/xen/include/public/pmu.h b/xen/include/public/pmu.h
> index 7753df0..c7b5648 100644
> --- a/xen/include/public/pmu.h
> +++ b/xen/include/public/pmu.h
> @@ -84,9 +84,19 @@ DEFINE_XEN_GUEST_HANDLE(xen_pmu_params_t);
>  
>  /*
>   * PMU features:
> - * - XENPMU_FEATURE_INTEL_BTS: Intel BTS support (ignored on AMD)
> + * - XENPMU_FEATURE_INTEL_BTS:  Intel BTS support (ignored on AMD)
> + * - XENPMU_FEATURE_IPC_ONLY:   Restrict PMC to the most minimum set 
> possible.
> + *                              Instructions, cycles, and ref cycles. Can be
> + *                              used to calculate instructions-per-cycle 
> (IPC)
> + *                              (ignored on AMD).
> + * - XENPMU_FEATURE_ARCH_ONLY:  Restrict PMCs to the Intel pre-defined
> + *                              architecteral events exposed by cpuid and
> + *                              listed in Table 18-1 of the developer's 
> manual
> + *                              (ignored on AMD).
>   */
> -#define XENPMU_FEATURE_INTEL_BTS  1
> +#define XENPMU_FEATURE_INTEL_BTS  (1<<0)
> +#define XENPMU_FEATURE_IPC_ONLY   (1<<1)
> +#define XENPMU_FEATURE_ARCH_ONLY  (1<<2)
>  
>  /*
>   * Shared PMU data between hypervisor and PV(H) domains.
> 

-- 
Company details: http://ts.fujitsu.com/imprint.html

_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxx
http://lists.xen.org/xen-devel


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.