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

Re: [Xen-devel] [PATCH v12 9/9] tools: CMDs and APIs for Platform QoS Monitoring



> -----Original Message-----
> From: xen-devel-bounces@xxxxxxxxxxxxx
> [mailto:xen-devel-bounces@xxxxxxxxxxxxx] On Behalf Of Ian Campbell
> Sent: Thursday, July 10, 2014 11:50 PM
> To: Xu, Dongxiao
> Cc: keir@xxxxxxx; stefano.stabellini@xxxxxxxxxxxxx;
> George.Dunlap@xxxxxxxxxxxxx; andrew.cooper3@xxxxxxxxxx;
> Ian.Jackson@xxxxxxxxxxxxx; xen-devel@xxxxxxxxxxxxx; JBeulich@xxxxxxxx;
> dgdegra@xxxxxxxxxxxxx
> Subject: Re: [Xen-devel] [PATCH v12 9/9] tools: CMDs and APIs for Platform QoS
> Monitoring

Hi Ian,

Thanks for the comments, some answers below.

> 
> On Fri, 2014-07-04 at 16:34 +0800, Dongxiao Xu wrote:
> > Introduced some new xl commands to handle the platform QoS monitoring
> > related services.
> >
> > The following two commands is to attach/detach the QoS monitoring
> > service to/from a certain domain.
> 
> Is there a literal "service" here to attach to? Or are these operations
> more like enable/disable?

It's more like enable/disable, so I will change the service word...

> 
> > diff --git a/tools/libxc/Makefile b/tools/libxc/Makefile
> > index b8b28c1..91e65c4 100644
> > --- a/tools/libxc/Makefile
> > +++ b/tools/libxc/Makefile
> > @@ -35,6 +35,7 @@ CTRL_SRCS-y       += xc_kexec.c
> >  CTRL_SRCS-y       += xtl_core.c
> >  CTRL_SRCS-y       += xtl_logger_stdio.c
> >  CTRL_SRCS-y       += xc_resource.c
> > +CTRL_SRCS-y       += xc_pqos.c
> 
> CONFIG_X86?

For CQM xl commands and libxl APIs are not architectural specific, if we define 
libxc functions to be x86 specific, will it be a problem when compiling on 
non-x86 platform?

> 
> >  CTRL_SRCS-$(CONFIG_X86) += xc_pagetab.c
> >  CTRL_SRCS-$(CONFIG_Linux) += xc_linux.c xc_linux_osdep.c
> >  CTRL_SRCS-$(CONFIG_FreeBSD) += xc_freebsd.c xc_freebsd_osdep.c
> 
> > +int xc_pqos_monitor_get_domain_rmid(xc_interface *xch, uint32_t domid,
> > +                                    uint32_t *rmid)
> > +{
> > +    int rc;
> > +    DECLARE_DOMCTL;
> > +
> > +    domctl.cmd = XEN_DOMCTL_pqos_monitor_op;
> > +    domctl.domain = (domid_t)domid;
> > +    domctl.u.pqos_monitor_op.cmd =
> XEN_DOMCTL_PQOS_MONITOR_OP_QUERY_RMID;
> > +
> > +    rc = do_domctl(xch, &domctl);
> > +
> > +    *rmid = domctl.u.pqos_monitor_op.data;
> 
> Only if rc indicates success.

Okay.

> 
> > +
> > +    return rc;
> > +}
> > +
> > +int xc_pqos_monitor_get_total_rmid(xc_interface *xch, uint32_t
> *total_rmid)
> > +{
> > +    static int val = 0;
> > +    int rc;
> > +    DECLARE_SYSCTL;
> > +
> > +    if ( val )
> > +    {
> > +        *total_rmid = val;
> 
> This can never change dynamically?
> 
> Likewise for several more similar things further down.

The total_rmid, L3 scaling factor, and L3 cache total size are platform 
characteristic, and will not change in runtime.

> 
> > diff --git a/tools/libxl/libxl.h b/tools/libxl/libxl.h
> > index 69ceac8..f510ade 100644
> > --- a/tools/libxl/libxl.h
> > +++ b/tools/libxl/libxl.h
> > @@ -533,6 +533,13 @@ typedef uint8_t libxl_mac[6];
> >  #define LIBXL_MAC_FMTLEN ((2*6)+5) /* 6 hex bytes plus 5 colons */
> >  #define LIBXL_MAC_BYTES(mac) mac[0], mac[1], mac[2], mac[3], mac[4],
> mac[5]
> >
> > +/*
> > + * LIBXL_HAVE_PQOS_MONITOR_CQM
> > + *
> > + * If this is defined, the cache QoS monitoring feature is suported.
> 
> "supported"

Thanks!

> 
> > +int libxl_pqos_monitor_get_l3_cache_size(libxl_ctx *ctx,
> > +    uint32_t *l3_cache_size);
> > +int libxl_pqos_monitor_get_cache_occupancy(libxl_ctx *ctx, uint32_t
> > domid,
> > +    uint32_t socketid, uint64_t *l3_cache_occupancy);
> 
> What are the units of the outputs of these functions?

The l3_cache_occupancy unit is Byte, while l3_cache_size is K-Byte.

> 
> Why is cache size 32 bits but occupancy is 64 ?

Total cache size is derived from boot_cpu->x86_cache_size, which is a 32bit 
integer type variable.
l3_cache_occupancy is derived from a multiply of two 32-bit variables, so I set 
l3_cache_occupancy to 64 bit variable.

I will set them to be both 32bit and use K-Byte as the unit.

> 
> > diff --git a/tools/libxl/libxl_pqos.c b/tools/libxl/libxl_pqos.c
> > new file mode 100644
> > index 0000000..8c56e67
> > --- /dev/null
> > +++ b/tools/libxl/libxl_pqos.c
> > @@ -0,0 +1,171 @@
> > +/*
> > + * Copyright (C) 2014      Intel Corporation
> > + * Author Dongxiao Xu <dongxiao.xu@xxxxxxxxx>
> > + *
> > + * This program is free software; you can redistribute it and/or modify
> > + * it under the terms of the GNU Lesser General Public License as published
> > + * by the Free Software Foundation; version 2.1 only. with the special
> > + * exception on linking described in file LICENSE.
> > + *
> > + * This program is distributed in the hope that it will be useful,
> > + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> > + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> > + * GNU Lesser General Public License for more details.
> > + */
> > +
> > +#include "libxl_osdeps.h" /* must come before any other headers */
> > +#include "libxl_internal.h"
> > +
> > +
> > +#define IA32_QM_CTR_ERROR_MASK         (0x3ul << 62)
> > +
> > +static const char * const msg[] = {
> 
> Could this be local to the error printing function?

Okay.

> 
> > +    [ENOSYS] = "unsupported operation",
> > +    [ENODEV] = "Platform QoS Monitoring is not supported in this system",
> > +    [EEXIST] = "Platform QoS Monitoring is already attached to this 
> > domain",
> > +    [ENOENT] = "Platform QoS Monitoring is not attached to this domain",
> > +    [EUSERS] = "there is no free RMID available",
> > +    [ESRCH]  = "is this Domain ID valid?",
> > +    [EFAULT] = "cannot find a valid CPU belonging to this socket",
> > +};
> > +
> > +static void libxl_pqos_monitor_err_msg(libxl_ctx *ctx, int err)
> > +{
> > +    GC_INIT(ctx);
> > +
> > +    switch (err) {
> > +    case EINVAL:
> > +    case ENODEV:
> > +    case EEXIST:
> > +    case EUSERS:
> > +    case ESRCH:
> > +    case ENOENT:
> 
> This enumeration of the valid errnos is bound to get out of sync I
> think.
> 
> You can compare err to ARRAY_SIZE(msg) and if it is within bounds check
> it for NULL.
> 
> or  perhaps
> case EINVAL: msg = "unsupported operation"; break;
> etc

Okay.

> 
> > +
> > +int libxl_pqos_monitor_domain_attached(libxl_ctx *ctx, uint32_t domid)
> > +{
> > +    int rc;
> > +    uint32_t rmid;
> > +
> > +    rc = xc_pqos_monitor_get_domain_rmid(ctx->xch, domid, &rmid);
> > +    if (rc < 0)
> > +        return 0;
> 
> don't you mean return rc here?

Here 0 means "not" attached, while 1 means attached...

> 
> > +int libxl_pqos_monitor_get_cache_occupancy(libxl_ctx *ctx, uint32_t domid,
> > +    uint32_t socketid, uint64_t *l3_cache_occupancy)
> > +{
> > +    GC_INIT(ctx);
> > +
> > +    unsigned int rmid;
> > +    uint32_t upscaling_factor;
> > +    uint64_t monitor_data;
> > +    int cpu, rc;
> > +    xc_pqos_monitor_type type;
> > +
> > +    rc = xc_pqos_monitor_get_domain_rmid(ctx->xch, domid, &rmid);
> > +    if (rc < 0 || rmid == 0) {
> > +        LOGE(ERROR, "fail to get the domain rmid, "
> > +            "or domain is not attached with platform QoS monitoring
> service");
> > +        return ERROR_FAIL;
> 
> All of these error paths fail to GC_FREE. You should follow the
>     if (error thing) {
>         rc = ERROR_FAIL;
>         goto out;
>     }
> 
>     ...
> 
>     rc = 0
> out:
>     GC_FREE;
>     return 0
> idiom.

Okay.

> 
> > diff --git a/tools/libxl/libxl_types.idl b/tools/libxl/libxl_types.idl
> > index 1018142..2e7668b 100644
> > --- a/tools/libxl/libxl_types.idl
> > +++ b/tools/libxl/libxl_types.idl
> > @@ -604,3 +604,7 @@ libxl_event = Struct("event",[
> >                                   ])),
> >             ("domain_create_console_available", None),
> >             ]))])
> > +
> > +libxl_pqos_monitor_type = Enumeration("pqos_monitor_type", [
> > +    (1, "CACHE_OCCUPANCY"),
> > +    ])
> 
> This is used purely for the libxl_pqos_monitor_type_from_string helper
> in xl and never in the libxl API, is that correct?
> 
> I'm not sure we want to expose this in the libxl api just for stat.
> maybe just strcmp for now and if this list grows unwieldy we can
> revisit.

I suggest we use this API since we will soon have patches to implement "local 
memory bandwidth", "total memory bandwidth", and so on...

> 
> > +    print_header = 1;
> > +    for (domid = first_domain; domid < first_domain + nr_domains; domid++)
> {
> > +        if (!libxl_pqos_monitor_domain_attached(ctx, domid)) {
> > +            if (!ignore_domain_err)
> > +                printf("No CQM info for Domain %d.\n", domid);
> 
> There might be an argument for printing a line anyway with "Unknown".

If we use libxl_list_domain() to get the exact domain list as you suggested, 
then we can get avoid of this "ignore_domain_err" stuff.

> 
> > +            continue;
> > +        }
> > +        if (print_header) {
> > +            printf("Name                                        ID");
> 
> printf("%-40s %5s", "Name", "ID") would be easier to relate to the list
> below.

Okay.

> 
> > +            for (socketid = 0; socketid < nr_sockets; socketid++)
> > +                printf("\tSocketID\tL3C_Usage");
> > +            printf("\n");
> > +            print_header = 0;
> > +        }
> 
> So the output on a two socket system would be:
> Name                                      ID  SocketID        L3CUsage
>       SocketID        L3CUsage
> Blahblah                                   1           0
> 123KB              1              456KB
> 
> ?
> 
> The socketid column seems weird to me. Why not:
> 
> Name                                      ID        Socket 0  Socket 1
> Blahblah                                   1           123KB
> 456KB
> 

Okay, this is fine to me. :)

> 
> Or
> 
> Name                                      ID        Socket    L3C
> Usage
> Blahblah                                   1             0      456KB
>                                                          1      123KB
> 
> ...
> 
> "xl list" takes a bunch of flags to include extra info. Maybe you want
> to think about listing this stuff there instead?

I ever thought about integrating the pqos stuff into xl list, however it is 
difficult for me to make the output looks elegant...
Can we firstly implement it still in a specific command line?

> 
> > +        domain_name = libxl_domid_to_name(ctx, domid);
> > +        printf("%-40s %5d", domain_name, domid);
> > +        free(domain_name);
> > +        for (socketid = 0; socketid < nr_sockets; socketid++) {
> > +            rc = libxl_pqos_monitor_get_cache_occupancy(ctx, domid,
> socketid,
> > +
> &l3_cache_occupancy);
> > +            printf("%10u %13lu KB     ", socketid,
> l3_cache_occupancy/1024);
> > +        }
> > +        printf("\n");
> > +    }
> > +
> > +    return 0;
> > +}
> > +
> > +
> > +int main_pqos_monitor_show(int argc, char **argv)
> > +{
> > +    int opt, ret = 0;
> > +    uint32_t first_domain, nr_domains;
> > +    libxl_pqos_monitor_type type;
> > +
> > +    SWITCH_FOREACH_OPT(opt, "", NULL, "pqos-monitor-show", 1) {
> > +        /* No options */
> > +    }
> > +
> > +    libxl_pqos_monitor_type_from_string(argv[optind], &type);
> > +
> > +    if (optind + 1 >= argc) {
> > +        first_domain = 0;
> > +        nr_domains = 1024;
> 
> 
> When an explicit domain is not given please use libxl_list_domain() and
> print the status for all of them instead of hardcoding the first 1024
> domains.

Okay.

Thanks,
Dongxiao

> 
> 
> > +    } else if (optind + 1 == argc - 1){
> > +        first_domain = find_domain(argv[optind + 1]);
> > +        nr_domains = 1;
> 
> Ian.
> 
> 
> _______________________________________________
> Xen-devel mailing list
> Xen-devel@xxxxxxxxxxxxx
> http://lists.xen.org/xen-devel

_______________________________________________
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®.