[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-devel] [PATCH v20 10/10] tools: CMDs and APIs for Cache Monitoring Technology
Introduced some new xl commands to enable/disable Cache Monitoring Technology(CMT) feature. The following two commands is to attach/detach the CMT feature to/from a certain domain. $ xl psr-cmt-attach domid $ xl psr-cmt-detach domid This command is to display the CMT information, such as L3 cache occupancy. $ xl psr-cmt-show cache_occupancy <domid> Signed-off-by: Dongxiao Xu <dongxiao.xu@xxxxxxxxx> Signed-off-by: Chao Peng <chao.p.peng@xxxxxxxxxxxxxxx> --- docs/man/xl.pod.1 | 25 +++++ tools/libxc/Makefile | 1 + tools/libxc/xc_msr_x86.h | 36 +++++++ tools/libxc/xc_psr.c | 215 ++++++++++++++++++++++++++++++++++++++++++ tools/libxc/xenctrl.h | 19 ++++ tools/libxl/Makefile | 2 +- tools/libxl/libxl.h | 21 +++++ tools/libxl/libxl_internal.c | 23 +++++ tools/libxl/libxl_internal.h | 3 + tools/libxl/libxl_psr.c | 197 ++++++++++++++++++++++++++++++++++++++ tools/libxl/libxl_types.idl | 4 + tools/libxl/xl.h | 3 + tools/libxl/xl_cmdimpl.c | 158 +++++++++++++++++++++++++++++++ tools/libxl/xl_cmdtable.c | 17 ++++ 14 files changed, 723 insertions(+), 1 deletion(-) create mode 100644 tools/libxc/xc_msr_x86.h create mode 100644 tools/libxc/xc_psr.c create mode 100644 tools/libxl/libxl_psr.c diff --git a/docs/man/xl.pod.1 b/docs/man/xl.pod.1 index f1e95db..7927167 100644 --- a/docs/man/xl.pod.1 +++ b/docs/man/xl.pod.1 @@ -1387,6 +1387,31 @@ Load FLASK policy from the given policy file. The initial policy is provided to the hypervisor as a multiboot module; this command allows runtime updates to the policy. Loading new security policy will reset runtime changes to device labels. +=head1 Cache Monitoring Technology + +Intel Haswell and later server platforms offer monitoring capability in each +logical processor to measure specific platform shared resource metric, for +example, L3 cache occupancy. In Xen implementation, the monitoring granularity +is domain level. To monitor a specific domain, just attach the domain id with +the monitoring service. When the domain doesn't need to be monitored any more, +detach the domain id from the monitoring service. + +=over 4 + +=item B<psr-cmt-attach> [I<domain-id>] + +attach: Attach the platform shared resource monitoring service to a domain. + +=item B<psr-cmt-detach> [I<domain-id>] + +detach: Detach the platform shared resource monitoring service from a domain. + +=item B<psr-cmt-show> [I<psr-monitor-type>] [I<domain-id>] + +Show monitoring data for a certain domain or all domains. Current supported +monitor types are: + - "cache-occupancy": showing the L3 cache occupancy. + =back =head1 TO BE DOCUMENTED diff --git a/tools/libxc/Makefile b/tools/libxc/Makefile index dde6109..3afa0d0 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-$(CONFIG_X86) += xc_psr.c 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 diff --git a/tools/libxc/xc_msr_x86.h b/tools/libxc/xc_msr_x86.h new file mode 100644 index 0000000..7c3e1a3 --- /dev/null +++ b/tools/libxc/xc_msr_x86.h @@ -0,0 +1,36 @@ +/* + * xc_msr_x86.h + * + * MSR definition macros + * + * 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. + */ + +#ifndef XC_MSR_X86_H +#define XC_MSR_X86_H + +#define MSR_IA32_CMT_EVTSEL 0x00000c8d +#define MSR_IA32_CMT_CTR 0x00000c8e + +#endif + +/* + * Local variables: + * mode: C + * c-file-style: "BSD" + * c-basic-offset: 4 + * tab-width: 4 + * indent-tabs-mode: nil + * End: + */ diff --git a/tools/libxc/xc_psr.c b/tools/libxc/xc_psr.c new file mode 100644 index 0000000..872e6dc --- /dev/null +++ b/tools/libxc/xc_psr.c @@ -0,0 +1,215 @@ +/* + * xc_psr.c + * + * platform shared resource related API functions. + * + * 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 "xc_private.h" +#include "xc_msr_x86.h" + +#define IA32_CMT_CTR_ERROR_MASK (0x3ull << 62) + +#define EVTID_L3_OCCUPANCY 0x1 + +int xc_psr_cmt_attach(xc_interface *xch, uint32_t domid) +{ + DECLARE_DOMCTL; + + domctl.cmd = XEN_DOMCTL_psr_cmt_op; + domctl.domain = (domid_t)domid; + domctl.u.psr_cmt_op.cmd = XEN_DOMCTL_PSR_CMT_OP_ATTACH; + + return do_domctl(xch, &domctl); +} + +int xc_psr_cmt_detach(xc_interface *xch, uint32_t domid) +{ + DECLARE_DOMCTL; + + domctl.cmd = XEN_DOMCTL_psr_cmt_op; + domctl.domain = (domid_t)domid; + domctl.u.psr_cmt_op.cmd = XEN_DOMCTL_PSR_CMT_OP_DETACH; + + return do_domctl(xch, &domctl); +} + +int xc_psr_cmt_get_domain_rmid(xc_interface *xch, uint32_t domid, + uint32_t *rmid) +{ + int rc; + DECLARE_DOMCTL; + + domctl.cmd = XEN_DOMCTL_psr_cmt_op; + domctl.domain = (domid_t)domid; + domctl.u.psr_cmt_op.cmd = XEN_DOMCTL_PSR_CMT_OP_QUERY_RMID; + + rc = do_domctl(xch, &domctl); + + if ( !rc ) + *rmid = domctl.u.psr_cmt_op.data; + + return rc; +} + +int xc_psr_cmt_get_total_rmid(xc_interface *xch, uint32_t *total_rmid) +{ + static int val = 0; + int rc; + DECLARE_SYSCTL; + + if ( val ) + { + *total_rmid = val; + return 0; + } + + sysctl.cmd = XEN_SYSCTL_psr_cmt_op; + sysctl.u.psr_cmt_op.cmd = XEN_SYSCTL_PSR_CMT_get_total_rmid; + sysctl.u.psr_cmt_op.flags = 0; + + rc = xc_sysctl(xch, &sysctl); + if ( !rc ) + val = *total_rmid = sysctl.u.psr_cmt_op.u.data; + + return rc; +} + +int xc_psr_cmt_get_l3_upscaling_factor(xc_interface *xch, + uint32_t *upscaling_factor) +{ + static int val = 0; + int rc; + DECLARE_SYSCTL; + + if ( val ) + { + *upscaling_factor = val; + return 0; + } + + sysctl.cmd = XEN_SYSCTL_psr_cmt_op; + sysctl.u.psr_cmt_op.cmd = + XEN_SYSCTL_PSR_CMT_get_l3_upscaling_factor; + sysctl.u.psr_cmt_op.flags = 0; + + rc = xc_sysctl(xch, &sysctl); + if ( !rc ) + val = *upscaling_factor = sysctl.u.psr_cmt_op.u.data; + + return rc; +} + +int xc_psr_cmt_get_l3_cache_size(xc_interface *xch, uint32_t cpu, + uint32_t *l3_cache_size) +{ + static int val = 0; + int rc; + DECLARE_SYSCTL; + + if ( val ) + { + *l3_cache_size = val; + return 0; + } + + sysctl.cmd = XEN_SYSCTL_psr_cmt_op; + sysctl.u.psr_cmt_op.cmd = + XEN_SYSCTL_PSR_CMT_get_l3_cache_size; + sysctl.u.psr_cmt_op.flags = 0; + sysctl.u.psr_cmt_op.u.l3_cache.cpu = cpu; + + rc = xc_sysctl(xch, &sysctl); + if ( !rc ) + val = *l3_cache_size= sysctl.u.psr_cmt_op.u.data; + + return rc; +} + +int xc_psr_cmt_get_data(xc_interface *xch, uint32_t rmid, + uint32_t cpu, xc_psr_cmt_type type, uint64_t *monitor_data) +{ + xc_resource_op_t op; + xc_resource_entry_t entries[2]; + uint32_t evtid; + int rc; + + switch ( type ) + { + case XC_PSR_CMT_L3_OCCUPANCY: + evtid = EVTID_L3_OCCUPANCY; + break; + default: + return -1; + } + + entries[0].u.cmd = XEN_RESOURCE_OP_MSR_WRITE; + entries[0].idx = MSR_IA32_CMT_EVTSEL; + entries[0].val = (uint64_t)rmid << 32 | evtid; + entries[0].rsvd = 0; + + entries[1].u.cmd = XEN_RESOURCE_OP_MSR_READ; + entries[1].idx = MSR_IA32_CMT_CTR; + entries[1].val = 0; + entries[1].rsvd = 0; + + op.cpu = cpu; + op.nr_entries = 2; + op.entries = entries; + + rc = xc_resource_op(xch, 1, &op); + if ( rc < 0 ) + return rc; + + if ( op.result !=2 || entries[1].val & IA32_CMT_CTR_ERROR_MASK ) + return -1; + + *monitor_data = entries[1].val; + + return 0; +} + +int xc_psr_cmt_enabled(xc_interface *xch) +{ + static int val = -1; + int rc; + DECLARE_SYSCTL; + + if ( val >= 0 ) + return val; + + sysctl.cmd = XEN_SYSCTL_psr_cmt_op; + sysctl.u.psr_cmt_op.cmd = XEN_SYSCTL_PSR_CMT_enabled; + sysctl.u.psr_cmt_op.flags = 0; + + rc = do_sysctl(xch, &sysctl); + if ( !rc ) + { + val = sysctl.u.psr_cmt_op.u.data; + return val; + } + + return 0; +} + +/* + * Local variables: + * mode: C + * c-file-style: "BSD" + * c-basic-offset: 4 + * tab-width: 4 + * indent-tabs-mode: nil + * End: + */ diff --git a/tools/libxc/xenctrl.h b/tools/libxc/xenctrl.h index 6edb738..4689ec8 100644 --- a/tools/libxc/xenctrl.h +++ b/tools/libxc/xenctrl.h @@ -2672,6 +2672,25 @@ struct xc_resource_op { typedef struct xc_resource_op xc_resource_op_t; int xc_resource_op(xc_interface *xch, uint32_t nr_ops, xc_resource_op_t *ops); +#if defined(__i386__) || defined(__x86_64__) +enum xc_psr_cmt_type { + XC_PSR_CMT_L3_OCCUPANCY, +}; +typedef enum xc_psr_cmt_type xc_psr_cmt_type; +int xc_psr_cmt_attach(xc_interface *xch, uint32_t domid); +int xc_psr_cmt_detach(xc_interface *xch, uint32_t domid); +int xc_psr_cmt_get_domain_rmid(xc_interface *xch, uint32_t domid, + uint32_t *rmid); +int xc_psr_cmt_get_total_rmid(xc_interface *xch, uint32_t *total_rmid); +int xc_psr_cmt_get_l3_upscaling_factor(xc_interface *xch, + uint32_t *upscaling_factor); +int xc_psr_cmt_get_l3_cache_size(xc_interface *xch, uint32_t cpu, + uint32_t *l3_cache_size); +int xc_psr_cmt_get_data(xc_interface *xch, uint32_t rmid, + uint32_t cpu, uint32_t psr_cmt_type, uint64_t *monitor_data); +int xc_psr_cmt_enabled(xc_interface *xch); +#endif + #endif /* XENCTRL_H */ /* diff --git a/tools/libxl/Makefile b/tools/libxl/Makefile index 990414b..fd9ae28 100644 --- a/tools/libxl/Makefile +++ b/tools/libxl/Makefile @@ -43,7 +43,7 @@ LIBXL_OBJS-y += libxl_blktap2.o else LIBXL_OBJS-y += libxl_noblktap2.o endif -LIBXL_OBJS-$(CONFIG_X86) += libxl_cpuid.o libxl_x86.o +LIBXL_OBJS-$(CONFIG_X86) += libxl_cpuid.o libxl_x86.o libxl_psr.o LIBXL_OBJS-$(CONFIG_ARM) += libxl_nocpuid.o libxl_arm.o ifeq ($(CONFIG_NetBSD),y) diff --git a/tools/libxl/libxl.h b/tools/libxl/libxl.h index bc68cac..af6b475 100644 --- a/tools/libxl/libxl.h +++ b/tools/libxl/libxl.h @@ -640,6 +640,15 @@ typedef uint8_t libxl_mac[6]; #define LIBXL_MAC_BYTES(mac) mac[0], mac[1], mac[2], mac[3], mac[4], mac[5] void libxl_mac_copy(libxl_ctx *ctx, libxl_mac *dst, libxl_mac *src); +#if defined(__i386__) || defined(__x86_64__) +/* + * LIBXL_HAVE_PSR_CMT + * + * If this is defined, the Cache Monitoring Technology feature is supported. + */ +#define LIBXL_HAVE_PSR_CMT 1 +#endif + typedef char **libxl_string_list; void libxl_string_list_dispose(libxl_string_list *sl); int libxl_string_list_length(const libxl_string_list *sl); @@ -1380,6 +1389,18 @@ bool libxl_ms_vm_genid_is_zero(const libxl_ms_vm_genid *id); void libxl_ms_vm_genid_copy(libxl_ctx *ctx, libxl_ms_vm_genid *dst, libxl_ms_vm_genid *src); +#if defined(__i386__) || defined(__x86_64__) +int libxl_psr_cmt_attach(libxl_ctx *ctx, uint32_t domid); +int libxl_psr_cmt_detach(libxl_ctx *ctx, uint32_t domid); +int libxl_psr_cmt_domain_attached(libxl_ctx *ctx, uint32_t domid); +int libxl_psr_cmt_enabled(libxl_ctx *ctx); +int libxl_psr_cmt_get_total_rmid(libxl_ctx *ctx, uint32_t *total_rmid); +int libxl_psr_cmt_get_l3_cache_size(libxl_ctx *ctx, uint32_t socketid, + uint32_t *l3_cache_size); +int libxl_psr_cmt_get_cache_occupancy(libxl_ctx *ctx, uint32_t domid, + uint32_t socketid, uint32_t *l3_cache_occupancy); +#endif + /* misc */ /* Each of these sets or clears the flag according to whether the diff --git a/tools/libxl/libxl_internal.c b/tools/libxl/libxl_internal.c index 02a71cb..b5fd7e3 100644 --- a/tools/libxl/libxl_internal.c +++ b/tools/libxl/libxl_internal.c @@ -539,6 +539,29 @@ void libxl__update_domain_configuration(libxl__gc *gc, dst->b_info.video_memkb = src->b_info.video_memkb; } +int libxl__pick_random_socket_cpu(libxl__gc *gc, uint32_t socketid) +{ + int i, j, cpu, nr_cpus; + libxl_cputopology *topology; + int *socket_cpus; + + topology = libxl_get_cpu_topology(CTX, &nr_cpus); + if (!topology) + return ERROR_FAIL; + + socket_cpus = libxl__malloc(gc, sizeof(int) * nr_cpus); + + for (i = 0, j = 0; i < nr_cpus; i++) + if (topology[i].socket == socketid) + socket_cpus[j++] = i; + + /* load balance among cpus in the same socket. */ + cpu = socket_cpus[rand() % j]; + + libxl_cputopology_list_free(topology, nr_cpus); + return cpu; +} + /* * Local variables: * mode: C diff --git a/tools/libxl/libxl_internal.h b/tools/libxl/libxl_internal.h index f61673c..cdfccf6 100644 --- a/tools/libxl/libxl_internal.h +++ b/tools/libxl/libxl_internal.h @@ -3410,6 +3410,9 @@ static inline void libxl__update_config_vtpm(libxl__gc *gc, libxl_device_##type##_copy(CTX, DA_p, (dev)); \ }) +/* Pick up a random cpu from all the cpus in a specified socket */ +_hidden int libxl__pick_random_socket_cpu(libxl__gc *gc, uint32_t socketid); + #endif /* diff --git a/tools/libxl/libxl_psr.c b/tools/libxl/libxl_psr.c new file mode 100644 index 0000000..a58c4dc --- /dev/null +++ b/tools/libxl/libxl_psr.c @@ -0,0 +1,197 @@ +/* + * 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 void libxl__psr_cmt_log_err_msg(libxl__gc *gc, int err) +{ + char *msg; + + switch (err) { + case ENOSYS: + msg = "unsupported operation"; + break; + case ENODEV: + msg = "CMT is not supported in this system"; + break; + case EEXIST: + msg = "CMT is already attached to this domain"; + break; + case ENOENT: + msg = "CMT is not attached to this domain"; + break; + case EUSERS: + msg = "no free RMID available"; + break; + case ESRCH: + msg = "invalid domain ID"; + break; + case EFAULT: + msg = "failed to exchange data with Xen"; + break; + default: + msg = "unknown error"; + break; + } + + LOGE(ERROR, "%s", msg); +} + +int libxl_psr_cmt_attach(libxl_ctx *ctx, uint32_t domid) +{ + GC_INIT(ctx); + int rc; + + rc = xc_psr_cmt_attach(ctx->xch, domid); + if (rc < 0) { + libxl__psr_cmt_log_err_msg(gc, errno); + rc = ERROR_FAIL; + } + + GC_FREE; + return rc; +} + +int libxl_psr_cmt_detach(libxl_ctx *ctx, uint32_t domid) +{ + GC_INIT(ctx); + int rc; + + rc = xc_psr_cmt_detach(ctx->xch, domid); + if (rc < 0) { + libxl__psr_cmt_log_err_msg(gc, errno); + rc = ERROR_FAIL; + } + + GC_FREE; + return rc; +} + +int libxl_psr_cmt_domain_attached(libxl_ctx *ctx, uint32_t domid) +{ + int rc; + uint32_t rmid; + + rc = xc_psr_cmt_get_domain_rmid(ctx->xch, domid, &rmid); + if (rc < 0) + return 0; + + return !!rmid; +} + +int libxl_psr_cmt_enabled(libxl_ctx *ctx) +{ + return xc_psr_cmt_enabled(ctx->xch); +} + +int libxl_psr_cmt_get_total_rmid(libxl_ctx *ctx, uint32_t *total_rmid) +{ + GC_INIT(ctx); + int rc; + + rc = xc_psr_cmt_get_total_rmid(ctx->xch, total_rmid); + if (rc < 0) { + libxl__psr_cmt_log_err_msg(gc, errno); + rc = ERROR_FAIL; + } + + GC_FREE; + return rc; +} + +int libxl_psr_cmt_get_l3_cache_size(libxl_ctx *ctx, uint32_t socketid, + uint32_t *l3_cache_size) +{ + GC_INIT(ctx); + + int rc; + int cpu = libxl__pick_random_socket_cpu(gc, socketid); + + if (cpu < 0) { + LOGE(ERROR, "failed to get socket cpu"); + rc = ERROR_FAIL; + goto out; + } + + rc = xc_psr_cmt_get_l3_cache_size(ctx->xch, cpu, l3_cache_size); + if (rc < 0) { + libxl__psr_cmt_log_err_msg(gc, errno); + rc = ERROR_FAIL; + } + +out: + GC_FREE; + return rc; +} + +int libxl_psr_cmt_get_cache_occupancy(libxl_ctx *ctx, uint32_t domid, + uint32_t socketid, uint32_t *l3_cache_occupancy) +{ + GC_INIT(ctx); + + unsigned int rmid; + uint32_t upscaling_factor; + uint64_t monitor_data; + int cpu, rc; + xc_psr_cmt_type type; + + rc = xc_psr_cmt_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"); + rc = ERROR_FAIL; + goto out; + } + + cpu = libxl__pick_random_socket_cpu(gc, socketid); + if (cpu < 0) { + LOGE(ERROR, "failed to get socket cpu"); + rc = ERROR_FAIL; + goto out; + } + + type = XC_PSR_CMT_L3_OCCUPANCY; + rc = xc_psr_cmt_get_data(ctx->xch, rmid, cpu, type, &monitor_data); + if (rc < 0) { + LOGE(ERROR, "failed to get monitoring data"); + rc = ERROR_FAIL; + goto out; + } + + rc = xc_psr_cmt_get_l3_upscaling_factor(ctx->xch, &upscaling_factor); + if (rc < 0) { + LOGE(ERROR, "failed to get L3 upscaling factor"); + rc = ERROR_FAIL; + goto out; + } + + *l3_cache_occupancy = upscaling_factor * monitor_data / 1024; + rc = 0; +out: + GC_FREE; + return rc; +} + +/* + * Local variables: + * mode: C + * c-basic-offset: 4 + * indent-tabs-mode: nil + * End: + */ diff --git a/tools/libxl/libxl_types.idl b/tools/libxl/libxl_types.idl index f1fcbc3..27a5022 100644 --- a/tools/libxl/libxl_types.idl +++ b/tools/libxl/libxl_types.idl @@ -635,3 +635,7 @@ libxl_event = Struct("event",[ ])), ("domain_create_console_available", None), ]))]) + +libxl_psr_cmt_type = Enumeration("psr_cmt_type", [ + (1, "CACHE_OCCUPANCY"), + ]) diff --git a/tools/libxl/xl.h b/tools/libxl/xl.h index 10a2e66..abb1fac 100644 --- a/tools/libxl/xl.h +++ b/tools/libxl/xl.h @@ -110,6 +110,9 @@ int main_loadpolicy(int argc, char **argv); int main_remus(int argc, char **argv); #endif int main_devd(int argc, char **argv); +int main_psr_cmt_attach(int argc, char **argv); +int main_psr_cmt_detach(int argc, char **argv); +int main_psr_cmt_show(int argc, char **argv); void help(const char *command); diff --git a/tools/libxl/xl_cmdimpl.c b/tools/libxl/xl_cmdimpl.c index 698b3bc..88123b3 100644 --- a/tools/libxl/xl_cmdimpl.c +++ b/tools/libxl/xl_cmdimpl.c @@ -7428,6 +7428,164 @@ out: return ret; } +static void psr_cmt_print_domain_cache_occupancy(libxl_dominfo *dominfo, + uint32_t nr_sockets) +{ + char *domain_name; + uint32_t socketid; + uint32_t l3_cache_occupancy; + + if (!libxl_psr_cmt_domain_attached(ctx, dominfo->domid)) + return; + + domain_name = libxl_domid_to_name(ctx, dominfo->domid); + printf("%-40s %5d", domain_name, dominfo->domid); + free(domain_name); + + for (socketid = 0; socketid < nr_sockets; socketid++) { + if ( !libxl_psr_cmt_get_cache_occupancy(ctx, dominfo->domid, + socketid, &l3_cache_occupancy) ) + printf("%13u KB", l3_cache_occupancy); + } + + printf("\n"); +} + +static int psr_cmt_show_cache_occupancy(uint32_t domid) +{ + uint32_t i, socketid, nr_sockets, total_rmid; + uint32_t l3_cache_size; + libxl_physinfo info; + int rc, nr_domains; + + if (!libxl_psr_cmt_enabled(ctx)) { + fprintf(stderr, "CMT is disabled in the system\n"); + return -1; + } + + libxl_physinfo_init(&info); + rc = libxl_get_physinfo(ctx, &info); + if (rc < 0) { + fprintf(stderr, "Failed getting physinfo, rc: %d\n", rc); + libxl_physinfo_dispose(&info); + return -1; + } + nr_sockets = info.nr_cpus / info.threads_per_core / info.cores_per_socket; + libxl_physinfo_dispose(&info); + + rc = libxl_psr_cmt_get_total_rmid(ctx, &total_rmid); + if (rc < 0) { + fprintf(stderr, "Failed to get max RMID value\n"); + return -1; + } + + printf("Total RMID: %d\n", total_rmid); + + /* Header */ + printf("%-40s %5s", "Name", "ID"); + for (socketid = 0; socketid < nr_sockets; socketid++) + printf("%14s %d", "Socket", socketid); + printf("\n"); + + /* Total L3 cache size */ + printf("%-46s", "Total L3 Cache Size"); + for (socketid = 0; socketid < nr_sockets; socketid++) { + rc = libxl_psr_cmt_get_l3_cache_size(ctx, socketid, &l3_cache_size); + if (rc < 0) { + fprintf(stderr, "Failed to get system l3 cache size for socket:%d\n", + socketid); + return -1; + } + printf("%13u KB", l3_cache_size); + } + printf("\n"); + + /* Each domain */ + if (domid != INVALID_DOMID) { + libxl_dominfo dominfo; + if (!libxl_domain_info(ctx, &dominfo, domid)) { + fprintf(stderr, "Failed to get domain info for %d\n", domid); + return -1; + } + psr_cmt_print_domain_cache_occupancy(&dominfo, nr_sockets); + } + else + { + libxl_dominfo *list; + if (!(list = libxl_list_domain(ctx, &nr_domains))) { + fprintf(stderr, "Failed to get domain info for domain list.\n"); + return -1; + } + for (i = 0; i < nr_domains; i++) + psr_cmt_print_domain_cache_occupancy(list + i, nr_sockets); + libxl_dominfo_list_free(list, nr_domains); + } + return 0; +} + +int main_psr_cmt_attach(int argc, char **argv) +{ + uint32_t domid; + int opt, ret = 0; + + SWITCH_FOREACH_OPT(opt, "", NULL, "psr-cmt-attach", 1) { + /* No options */ + } + + domid = find_domain(argv[optind]); + ret = libxl_psr_cmt_attach(ctx, domid); + + return ret; +} + +int main_psr_cmt_detach(int argc, char **argv) +{ + uint32_t domid; + int opt, ret = 0; + + SWITCH_FOREACH_OPT(opt, "", NULL, "psr-cmt-detach", 1) { + /* No options */ + } + + domid = find_domain(argv[optind]); + ret = libxl_psr_cmt_detach(ctx, domid); + + return ret; +} + +int main_psr_cmt_show(int argc, char **argv) +{ + int opt, ret = 0; + uint32_t domid; + libxl_psr_cmt_type type; + + SWITCH_FOREACH_OPT(opt, "", NULL, "psr-cmt-show", 1) { + /* No options */ + } + + libxl_psr_cmt_type_from_string(argv[optind], &type); + + if (optind + 1 >= argc) + domid = INVALID_DOMID; + else if (optind + 1 == argc - 1) + domid = find_domain(argv[optind + 1]); + else { + help("psr-cmt-show"); + return 2; + } + + switch (type) { + case LIBXL_PSR_CMT_TYPE_CACHE_OCCUPANCY: + ret = psr_cmt_show_cache_occupancy(domid); + break; + default: + help("psr-cmt-show"); + return 2; + } + + return ret; +} + /* * Local variables: * mode: C diff --git a/tools/libxl/xl_cmdtable.c b/tools/libxl/xl_cmdtable.c index 35f02c4..da25c3f 100644 --- a/tools/libxl/xl_cmdtable.c +++ b/tools/libxl/xl_cmdtable.c @@ -502,6 +502,23 @@ struct cmd_spec cmd_table[] = { "[options]", "-F Run in the foreground", }, + { "psr-cmt-attach", + &main_psr_cmt_attach, 0, 1, + "Attach Cache Monitoring Technology service to a domain", + "<Domain>", + }, + { "psr-cmt-detach", + &main_psr_cmt_detach, 0, 1, + "Detach Cache Monitoring Technology service from a domain", + "<Domain>", + }, + { "psr-cmt-show", + &main_psr_cmt_show, 0, 1, + "Show Cache Monitoring Technology information", + "<PSR-CMT-Type> <Domain>", + "Available monitor types:\n" + "\"cache_occupancy\": Show L3 cache occupancy\n", + }, }; int cmdtable_len = sizeof(cmd_table)/sizeof(struct cmd_spec); -- 1.7.9.5 _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxx http://lists.xen.org/xen-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |