|
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-devel] [PATCH v2 7/7] tools: add tools support for Intel CAT
This is the xc/xl changes to support Intel Cache Allocation
Technology(CAT). Two commands are introduced:
- xl psr-cat-cbm-set [-s socket] <domain> <cbm>
Set cache capacity bitmasks(CBM) for a domain.
- xl psr-cat-show <domain>
Show Cache Allocation Technology information.
Signed-off-by: Chao Peng <chao.p.peng@xxxxxxxxxxxxxxx>
---
tools/libxc/include/xenctrl.h | 15 +++
tools/libxc/xc_psr.c | 74 ++++++++++++++
tools/libxl/libxl.h | 18 ++++
tools/libxl/libxl_psr.c | 107 ++++++++++++++++++--
tools/libxl/libxl_types.idl | 4 +
tools/libxl/xl.h | 4 +
tools/libxl/xl_cmdimpl.c | 225 ++++++++++++++++++++++++++++++++++++++++--
tools/libxl/xl_cmdtable.c | 13 +++
8 files changed, 445 insertions(+), 15 deletions(-)
diff --git a/tools/libxc/include/xenctrl.h b/tools/libxc/include/xenctrl.h
index df18292..1373a46 100644
--- a/tools/libxc/include/xenctrl.h
+++ b/tools/libxc/include/xenctrl.h
@@ -2692,6 +2692,12 @@ enum xc_psr_cmt_type {
XC_PSR_CMT_LOCAL_MEM_COUNT,
};
typedef enum xc_psr_cmt_type xc_psr_cmt_type;
+
+enum xc_psr_cat_type {
+ XC_PSR_CAT_L3_CBM = 1,
+};
+typedef enum xc_psr_cat_type xc_psr_cat_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,
@@ -2706,6 +2712,15 @@ int xc_psr_cmt_get_data(xc_interface *xch, uint32_t
rmid, uint32_t cpu,
uint32_t psr_cmt_type, uint64_t *monitor_data,
uint64_t *tsc);
int xc_psr_cmt_enabled(xc_interface *xch);
+
+int xc_psr_cat_set_domain_data(xc_interface *xch, uint32_t domid,
+ xc_psr_cat_type type, uint32_t target,
+ uint64_t data);
+int xc_psr_cat_get_domain_data(xc_interface *xch, uint32_t domid,
+ xc_psr_cat_type type, uint32_t target,
+ uint64_t *data);
+int xc_psr_cat_get_l3_info(xc_interface *xch, uint32_t socket,
+ uint32_t *cos_max, uint32_t *cbm_len);
#endif
#endif /* XENCTRL_H */
diff --git a/tools/libxc/xc_psr.c b/tools/libxc/xc_psr.c
index e367a80..6c670d5 100644
--- a/tools/libxc/xc_psr.c
+++ b/tools/libxc/xc_psr.c
@@ -248,6 +248,80 @@ int xc_psr_cmt_enabled(xc_interface *xch)
return 0;
}
+int xc_psr_cat_set_domain_data(xc_interface *xch, uint32_t domid,
+ xc_psr_cat_type type, uint32_t target,
+ uint64_t data)
+{
+ DECLARE_DOMCTL;
+ uint32_t cmd;
+
+ switch ( type )
+ {
+ case XC_PSR_CAT_L3_CBM:
+ cmd = XEN_DOMCTL_PSR_CAT_OP_SET_L3_CBM;
+ break;
+ default:
+ return -1;
+ }
+
+ domctl.cmd = XEN_DOMCTL_psr_cat_op;
+ domctl.domain = (domid_t)domid;
+ domctl.u.psr_cat_op.cmd = cmd;
+ domctl.u.psr_cat_op.target = target;
+ domctl.u.psr_cat_op.data = data;
+
+ return do_domctl(xch, &domctl);
+}
+
+int xc_psr_cat_get_domain_data(xc_interface *xch, uint32_t domid,
+ xc_psr_cat_type type, uint32_t target,
+ uint64_t *data)
+{
+ int rc;
+ DECLARE_DOMCTL;
+ uint32_t cmd;
+
+ switch ( type )
+ {
+ case XC_PSR_CAT_L3_CBM:
+ cmd = XEN_DOMCTL_PSR_CAT_OP_GET_L3_CBM;
+ break;
+ default:
+ return -1;
+ }
+
+ domctl.cmd = XEN_DOMCTL_psr_cat_op;
+ domctl.domain = (domid_t)domid;
+ domctl.u.psr_cat_op.cmd = cmd;
+ domctl.u.psr_cat_op.target = target;
+
+ rc = do_domctl(xch, &domctl);
+
+ if ( !rc )
+ *data = domctl.u.psr_cat_op.data;
+
+ return rc;
+}
+
+int xc_psr_cat_get_l3_info(xc_interface *xch, uint32_t socket,
+ uint32_t *cos_max, uint32_t *cbm_len)
+{
+ int rc;
+ DECLARE_SYSCTL;
+
+ sysctl.cmd = XEN_SYSCTL_psr_cat_op;
+ sysctl.u.psr_cat_op.cmd = XEN_SYSCTL_PSR_CAT_get_l3_info;
+ sysctl.u.psr_cat_op.target = socket;
+
+ rc = xc_sysctl(xch, &sysctl);
+ if ( !rc )
+ {
+ *cos_max = sysctl.u.psr_cat_op.u.l3_info.cos_max;
+ *cbm_len = sysctl.u.psr_cat_op.u.l3_info.cbm_len;
+ }
+
+ return rc;
+}
/*
* Local variables:
diff --git a/tools/libxl/libxl.h b/tools/libxl/libxl.h
index 6bbc52d..dd2c28f 100644
--- a/tools/libxl/libxl.h
+++ b/tools/libxl/libxl.h
@@ -718,6 +718,13 @@ void libxl_mac_copy(libxl_ctx *ctx, libxl_mac *dst,
libxl_mac *src);
* If this is defined, the Memory Bandwidth Monitoring feature is supported.
*/
#define LIBXL_HAVE_PSR_MBM 1
+
+/*
+ * LIBXL_HAVE_PSR_CAT
+ *
+ * If this is defined, the Cache Allocation Technology feature is supported.
+ */
+#define LIBXL_HAVE_PSR_CAT 1
#endif
typedef char **libxl_string_list;
@@ -1501,6 +1508,17 @@ int libxl_psr_cmt_get_sample(libxl_ctx *ctx,
uint64_t *tsc_r);
#endif
+#ifdef LIBXL_HAVE_PSR_CAT
+int libxl_psr_cat_set_domain_data(libxl_ctx *ctx, uint32_t domid,
+ libxl_psr_cat_type type, uint32_t target,
+ uint64_t data);
+int libxl_psr_cat_get_domain_data(libxl_ctx *ctx, uint32_t domid,
+ libxl_psr_cat_type type, uint32_t target,
+ uint64_t *data_r);
+int libxl_psr_cat_get_l3_info(libxl_ctx *ctx, uint32_t socket,
+ uint32_t *cos_max_r, uint32_t *cbm_len_r);
+#endif
+
/* misc */
/* Each of these sets or clears the flag according to whether the
diff --git a/tools/libxl/libxl_psr.c b/tools/libxl/libxl_psr.c
index 3e1c792..c7f1e9c 100644
--- a/tools/libxl/libxl_psr.c
+++ b/tools/libxl/libxl_psr.c
@@ -19,14 +19,37 @@
#define IA32_QM_CTR_ERROR_MASK (0x3ul << 62)
-static void libxl__psr_cmt_log_err_msg(libxl__gc *gc, int err)
+static void libxl__psr_log_err_msg(libxl__gc *gc, int err)
{
char *msg;
switch (err) {
case ENOSYS:
+ case EOPNOTSUPP:
msg = "unsupported operation";
break;
+ case ESRCH:
+ msg = "invalid domain ID";
+ break;
+ case EBADSLT:
+ msg = "socket is not supported";
+ break;
+ case EFAULT:
+ msg = "failed to exchange data with Xen";
+ break;
+ default:
+ msg = "unknown error";
+ break;
+ }
+
+ LOGE(ERROR, "%s", msg);
+}
+
+static void libxl__psr_cmt_log_err_msg(libxl__gc *gc, int err)
+{
+ char *msg;
+
+ switch (err) {
case ENODEV:
msg = "CMT is not supported in this system";
break;
@@ -39,15 +62,35 @@ static void libxl__psr_cmt_log_err_msg(libxl__gc *gc, int
err)
case EUSERS:
msg = "no free RMID available";
break;
- case ESRCH:
- msg = "invalid domain ID";
+ default:
+ libxl__psr_log_err_msg(gc, err);
+ return;
+ }
+
+ LOGE(ERROR, "%s", msg);
+}
+
+static void libxl__psr_cat_log_err_msg(libxl__gc *gc, int err)
+{
+ char *msg;
+
+ switch (err) {
+ case ENODEV:
+ msg = "CAT is not supported in this system";
break;
- case EFAULT:
- msg = "failed to exchange data with Xen";
+ case ENOENT:
+ msg = "CAT is not enabled on the socket";
break;
- default:
- msg = "unknown error";
+ case EUSERS:
+ msg = "no free COS available";
break;
+ case EEXIST:
+ msg = "The same CBM is already set to this domain";
+ break;
+
+ default:
+ libxl__psr_log_err_msg(gc, err);
+ return;
}
LOGE(ERROR, "%s", msg);
@@ -247,6 +290,56 @@ out:
return rc;
}
+int libxl_psr_cat_set_domain_data(libxl_ctx *ctx, uint32_t domid,
+ libxl_psr_cat_type type, uint32_t target,
+ uint64_t data)
+{
+ GC_INIT(ctx);
+ int rc;
+
+ rc = xc_psr_cat_set_domain_data(ctx->xch, domid, type, target, data);
+ if (rc < 0) {
+ libxl__psr_cat_log_err_msg(gc, errno);
+ rc = ERROR_FAIL;
+ }
+
+ GC_FREE;
+ return rc;
+}
+
+int libxl_psr_cat_get_domain_data(libxl_ctx *ctx, uint32_t domid,
+ libxl_psr_cat_type type, uint32_t target,
+ uint64_t *data_r)
+{
+ GC_INIT(ctx);
+ int rc;
+
+ rc = xc_psr_cat_get_domain_data(ctx->xch, domid, type, target, data_r);
+ if (rc < 0) {
+ libxl__psr_cat_log_err_msg(gc, errno);
+ rc = ERROR_FAIL;
+ }
+
+ GC_FREE;
+ return rc;
+}
+
+int libxl_psr_cat_get_l3_info(libxl_ctx *ctx, uint32_t socket,
+ uint32_t *cos_max_r, uint32_t *cbm_len_r)
+{
+ GC_INIT(ctx);
+ int rc;
+
+ rc = xc_psr_cat_get_l3_info(ctx->xch, socket, cos_max_r, cbm_len_r);
+ if (rc < 0) {
+ libxl__psr_cat_log_err_msg(gc, errno);
+ rc = ERROR_FAIL;
+ }
+
+ GC_FREE;
+ return rc;
+}
+
/*
* Local variables:
* mode: C
diff --git a/tools/libxl/libxl_types.idl b/tools/libxl/libxl_types.idl
index 47af340..228f37c 100644
--- a/tools/libxl/libxl_types.idl
+++ b/tools/libxl/libxl_types.idl
@@ -699,3 +699,7 @@ libxl_psr_cmt_type = Enumeration("psr_cmt_type", [
(2, "TOTAL_MEM_COUNT"),
(3, "LOCAL_MEM_COUNT"),
])
+
+libxl_psr_cat_type = Enumeration("psr_cat_type", [
+ (1, "L3_CBM"),
+ ])
diff --git a/tools/libxl/xl.h b/tools/libxl/xl.h
index 5bc138c..85fa997 100644
--- a/tools/libxl/xl.h
+++ b/tools/libxl/xl.h
@@ -117,6 +117,10 @@ 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);
#endif
+#ifdef LIBXL_HAVE_PSR_CAT
+int main_psr_cat_cbm_set(int argc, char **argv);
+int main_psr_cat_show(int argc, char **argv);
+#endif
void help(const char *command);
diff --git a/tools/libxl/xl_cmdimpl.c b/tools/libxl/xl_cmdimpl.c
index 5c40e84..fb0a9a4 100644
--- a/tools/libxl/xl_cmdimpl.c
+++ b/tools/libxl/xl_cmdimpl.c
@@ -85,6 +85,7 @@ libxl_ctx *ctx;
xlchild children[child_max];
+#define ALL_SOCKETS ~0
#define INVALID_DOMID ~0
static const char *common_domname;
static int fd_lock = -1;
@@ -7824,6 +7825,23 @@ out:
return ret;
}
+static uint32_t get_phy_socket_num(void)
+{
+ int rc;
+ uint32_t nr_sockets;
+ libxl_physinfo info;
+ libxl_physinfo_init(&info);
+ rc = libxl_get_physinfo(ctx, &info);
+ if (rc < 0) {
+ libxl_physinfo_dispose(&info);
+ return 0;
+ }
+ nr_sockets = info.nr_cpus / info.threads_per_core / info.cores_per_socket;
+ libxl_physinfo_dispose(&info);
+ return nr_sockets;
+
+}
+
#ifdef LIBXL_HAVE_PSR_CMT
#define MBM_SAMPLE_RETRY_MAX 4
@@ -7913,7 +7931,6 @@ static int psr_cmt_show(libxl_psr_cmt_type type, 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)) {
@@ -7927,15 +7944,11 @@ static int psr_cmt_show(libxl_psr_cmt_type type,
uint32_t domid)
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);
+ nr_sockets = get_phy_socket_num();
+ if (nr_sockets == 0) {
+ fprintf(stderr, "Failed getting physinfo\n");
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) {
@@ -8057,6 +8070,202 @@ int main_psr_cmt_show(int argc, char **argv)
}
#endif
+#ifdef LIBXL_HAVE_PSR_CAT
+static int psr_cat_l3_cbm_set(uint32_t domid, uint32_t socket, uint64_t cbm)
+{
+ int rc;
+ uint32_t i, nr_sockets;
+
+ if (socket != ALL_SOCKETS) {
+ return libxl_psr_cat_set_domain_data(ctx, domid,
+ LIBXL_PSR_CAT_TYPE_L3_CBM,
+ socket, cbm);
+ } else {
+ nr_sockets = get_phy_socket_num();
+ if (nr_sockets == 0) {
+ fprintf(stderr, "Failed getting physinfo\n");
+ return -1;
+ }
+ for (i = 0; i < nr_sockets; i++) {
+ rc = libxl_psr_cat_set_domain_data(ctx, domid,
+ LIBXL_PSR_CAT_TYPE_L3_CBM,
+ i, cbm);
+ if (rc < 0) {
+ fprintf(stderr, "Failed to set l3 cbm for socket:%d\n", i);
+ return -1;
+ }
+ }
+ }
+ return 0;
+}
+
+struct psr_cat_l3_info
+{
+ uint32_t cos_max;
+ uint32_t cbm_len;
+};
+
+static void psr_cat_print_domain_info(libxl_dominfo *dominfo,
+ struct psr_cat_l3_info *l3_info,
+ uint32_t nr_sockets)
+{
+ char *domain_name;
+ uint32_t socketid;
+ uint64_t cbm;
+
+ 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 (l3_info[socketid].cbm_len > 0 &&
+ !libxl_psr_cat_get_domain_data(ctx, dominfo->domid,
+ LIBXL_PSR_CAT_TYPE_L3_CBM,
+ socketid, &cbm) )
+ printf("%#16"PRIx64, cbm);
+ }
+
+ printf("\n");
+}
+
+static int psr_cat_show(uint32_t domid)
+{
+ uint32_t i, socketid, nr_sockets;
+ int rc, nr_domains;
+ uint32_t l3_cache_size;
+ struct psr_cat_l3_info *l3_info;
+
+ nr_sockets = get_phy_socket_num();
+ if (nr_sockets == 0) {
+ fprintf(stderr, "Failed getting physinfo\n");
+ return -1;
+ }
+
+ /* 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");
+
+ /* Max COS and CBM length */
+ l3_info = malloc(sizeof(l3_info) * nr_sockets);
+ //if (!l3_info)
+ for (socketid = 0; socketid < nr_sockets; socketid++) {
+ rc = libxl_psr_cat_get_l3_info(ctx, socketid,
+ &l3_info[socketid].cos_max,
+ &l3_info[socketid].cbm_len);
+ if (rc < 0) {
+ fprintf(stderr, "Failed to get system l3 info for socket:%d\n",
+ socketid);
+ rc = -1;
+ goto out;
+ }
+ }
+ printf("%-46s", "Max COS");
+ for (socketid = 0; socketid < nr_sockets; socketid++) {
+ printf("%16u", l3_info[socketid].cos_max);
+ }
+ printf("\n");
+ printf("%-46s", "Default CBM");
+ for (socketid = 0; socketid < nr_sockets; socketid++) {
+ printf("%#16"PRIx64, (1ul << l3_info[socketid].cbm_len) - 1);
+ }
+ 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);
+ rc = -1;
+ goto out;
+ }
+ psr_cat_print_domain_info(&dominfo, l3_info, 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");
+ rc = -1;
+ goto out;
+ }
+ for (i = 0; i < nr_domains; i++)
+ psr_cat_print_domain_info(list + i, l3_info, nr_sockets);
+ libxl_dominfo_list_free(list, nr_domains);
+ }
+ rc = 0;
+out:
+ if (l3_info)
+ free(l3_info);
+ return rc;
+}
+
+int main_psr_cat_cbm_set(int argc, char **argv)
+{
+ uint32_t domid;
+ uint32_t socket = ALL_SOCKETS;
+ uint64_t cbm;
+ char *ptr;
+ int opt = 0;
+
+ static struct option opts[] = {
+ {"socket", 0, 0, 's'},
+ {0, 0, 0, 0}
+ };
+
+ SWITCH_FOREACH_OPT(opt, "s", opts, "psr-cat-cbm-set", 1) {
+ case 's':
+ socket = strtol(optarg, NULL, 10);
+ break;
+ }
+
+ domid = find_domain(argv[optind]);
+ ptr = argv[optind + 1];
+ if (strlen(ptr) > 2 && ptr[0] == '0' && ptr[1] == 'x')
+ cbm = strtoll(ptr, NULL , 16);
+ else
+ cbm = strtoll(ptr, NULL , 10);
+
+ return psr_cat_l3_cbm_set(domid, socket, cbm);
+}
+
+int main_psr_cat_show(int argc, char **argv)
+{
+ int opt;
+ uint32_t domid;
+
+ SWITCH_FOREACH_OPT(opt, "", NULL, "psr-cat-show", 0) {
+ /* No options */
+ }
+
+ if (optind >= argc)
+ domid = INVALID_DOMID;
+ else if (optind == argc - 1)
+ domid = find_domain(argv[optind]);
+ else {
+ help("psr-cat-show");
+ return 2;
+ }
+
+ return psr_cat_show(domid);
+}
+
+#endif
+
/*
* Local variables:
* mode: C
diff --git a/tools/libxl/xl_cmdtable.c b/tools/libxl/xl_cmdtable.c
index 22ab63b..ffaf4ed 100644
--- a/tools/libxl/xl_cmdtable.c
+++ b/tools/libxl/xl_cmdtable.c
@@ -542,6 +542,19 @@ struct cmd_spec cmd_table[] = {
"\"total_mem_bandwidth\": Show total memory bandwidth(KB/s)\n"
"\"local_mem_bandwidth\": Show local memory bandwidth(KB/s)\n",
},
+ { "psr-cat-cbm-set",
+ &main_psr_cat_cbm_set, 0, 1,
+ "Set cache capacity bitmasks(CBM) for a domain",
+ "-s <socket> Specify the socket to process, all sockets when not"
+ "specified\n"
+ "<Domain> <CBM>",
+ },
+ { "psr-cat-show",
+ &main_psr_cat_show, 0, 1,
+ "Show Cache Allocation Technology information",
+ "<Domain>",
+ },
+
#endif
};
--
1.9.1
_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxx
http://lists.xen.org/xen-devel
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |