<div>
<br>
</div>
<div><div><br></div><div>-- </div><div><div style="color: rgb(34, 34, 34); font-family: arial, sans-serif; font-size: 14px; font-variant-ligatures: normal; orphans: 2; widows: 2; background-color: rgb(255, 255, 255);">Best regards </div><div style="color: rgb(34, 34, 34); font-family: arial, sans-serif; font-size: 14px; font-variant-ligatures: normal; orphans: 2; widows: 2; background-color: rgb(255, 255, 255);">Eli</div><div style="color: rgb(34, 34, 34); font-family: arial, sans-serif; font-size: 14px; font-variant-ligatures: normal; orphans: 2; widows: 2; background-color: rgb(255, 255, 255);"><br></div><div style="color: rgb(34, 34, 34); font-family: arial, sans-serif; font-size: 14px; font-variant-ligatures: normal; orphans: 2; widows: 2; background-color: rgb(255, 255, 255);">天涯无处不重逢</div><div style="color: rgb(34, 34, 34); font-family: arial, sans-serif; font-size: 14px; font-variant-ligatures: normal; orphans: 2; widows: 2; background-color: rgb(255, 255, 255);"><span style="color: rgb(0, 0, 0); font-family: "Microsoft YaHei", Verdana, arial, sans-serif;">a leaf duckweed belongs to the sea, where not to meet in life </span></div></div><div>Sent with <a href="http://www.sparrowmailapp.com/?sig">Sparrow</a></div><div><br></div></div>
<p style="color: #A0A0A8;">On Friday, 17 February 2017 at 8:47 PM, Martin Kletzander wrote:</p><blockquote type="cite"><div>
<span><div><div><div>On Thu, Feb 16, 2017 at 06:03:50PM +0100, Martin Kletzander wrote:</div><blockquote type="cite"><div><div>On Thu, Feb 16, 2017 at 05:35:12PM +0800, Eli Qiao wrote:</div><blockquote type="cite"><div><div>This patch adds some utils struct and functions to expose resctrl</div><div>information.</div></div></blockquote><div><br></div><div>One tiny nitpick, but it might actually help you as well. You can use</div><div>-v7 parameter to git send-email or git format-patch to automatically add</div><div>'v7' to the subject-prefix keeping the "PATCH" in there. Not only could</div><div>this be easier for you, but people like me, who filter patches and other</div><div>mails on the list to different folders, would have these properly</div><div>categorized.</div><div><br></div><div>Anyway, for the review now.</div><div><br></div><blockquote type="cite"><div><div>virResCtrlAvailable: If resctrl interface exist on host</div><div>virResCtrlGet: get specify type resource contral information</div></div></blockquote><div><br></div><div>"get specific resource control information" ???</div><div><br></div><blockquote type="cite"><div><div>virResCtrlInit: initialize resctrl struct from the host's sys fs.</div><div>resctrlall[]: an array to maintain resource control information.</div><div><br></div><div>Signed-off-by: Eli Qiao <<a href="mailto:liyong.qiao@intel.com">liyong.qiao@intel.com</a>></div><div>---</div><div>include/libvirt/virterror.h | 1 +</div><div>po/<a href="http://POTFILES.in">POTFILES.in</a> | 1 +</div><div>src/<a href="http://Makefile.am">Makefile.am</a> | 1 +</div><div>src/libvirt_private.syms | 4 +</div><div>src/util/virerror.c | 1 +</div><div>src/util/virresctrl.c | 343 ++++++++++++++++++++++++++++++++++++++++++++</div><div>src/util/virresctrl.h | 80 +++++++++++</div><div>7 files changed, 431 insertions(+)</div><div>create mode 100644 src/util/virresctrl.c</div><div>create mode 100644 src/util/virresctrl.h</div><div><br></div><div>diff --git a/src/util/virresctrl.c b/src/util/virresctrl.c</div><div>new file mode 100644</div><div>index 0000000..80481bc</div><div>--- /dev/null</div><div>+++ b/src/util/virresctrl.c</div><div>@@ -0,0 +1,343 @@</div><div>+/*</div><div>+ * virresctrl.c: methods for managing resource contral</div><div>+ *</div><div>+ * This library is free software; you can redistribute it and/or</div><div>+ * modify it under the terms of the GNU Lesser General Public</div><div>+ * License as published by the Free Software Foundation; either</div><div>+ * version 2.1 of the License, or (at your option) any later version.</div><div>+ *</div><div>+ * This library is distributed in the hope that it will be useful,</div><div>+ * but WITHOUT ANY WARRANTY; without even the implied warranty of</div><div>+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU</div><div>+ * Lesser General Public License for more details.</div><div>+ *</div><div>+ * You should have received a copy of the GNU Lesser General Public</div><div>+ * License along with this library. If not, see</div><div>+ * <<a href="http://www.gnu.org/licenses/">http://www.gnu.org/licenses/</a>>.</div><div>+ *</div><div>+ * Authors:</div><div>+ * Eli Qiao <<a href="mailto:liyong.qiao@intel.com">liyong.qiao@intel.com</a>></div><div>+ */</div><div>+#include <config.h></div><div>+</div><div>+#include <sys/ioctl.h></div><div>+#if defined HAVE_SYS_SYSCALL_H</div><div>+# include <sys/syscall.h></div></div></blockquote><div><br></div><div>What do you need syscall.h for?</div><div><br></div><blockquote type="cite"><div><div>+#endif</div><div>+#include <sys/types.h></div><div>+#include <sys/stat.h></div><div>+#include <fcntl.h></div><div>+</div><div>+#include "virresctrl.h"</div><div>+#include "viralloc.h"</div><div>+#include "virerror.h"</div><div>+#include "virfile.h"</div><div>+#include "virhostcpu.h"</div><div>+#include "virlog.h"</div><div>+#include "virstring.h"</div><div>+#include "nodeinfo.h"</div><div>+</div><div>+VIR_LOG_INIT("util.resctrl");</div><div>+</div><div>+#define VIR_FROM_THIS VIR_FROM_RESCTRL</div><div>+</div><div>+#define RESCTRL_DIR "/sys/fs/resctrl"</div><div>+#define RESCTRL_INFO_DIR "/sys/fs/resctrl/info"</div><div>+#define SYSFS_SYSTEM_PATH "/sys/devices/system"</div><div>+</div></div></blockquote><div><br></div><div>If you need SYSFS_..._PATH for anything, it probably could be split into</div><div>other src/util/ files. Example below.</div><div><br></div><blockquote type="cite"><div><div>+#define MAX_CPU_SOCKET_NUM 8</div><div>+#define MAX_CBM_BIT_LEN 32</div><div>+#define MAX_SCHEMATA_LEN 1024</div><div>+#define MAX_FILE_LEN ( 10 * 1024 * 1024)</div><div>+</div><div>+</div><div>+static unsigned int host_id;</div><div>+</div><div>+static virResCtrl resctrlall[] = {</div><div>+ {</div><div>+ .name = "L3",</div><div>+ .cache_level = "l3",</div><div>+ },</div><div>+ {</div><div>+ .name = "L3DATA",</div><div>+ .cache_level = "l3",</div><div>+ },</div><div>+ {</div><div>+ .name = "L3CODE",</div><div>+ .cache_level = "l3",</div><div>+ },</div><div>+ {</div><div>+ .name = "L2",</div><div>+ .cache_level = "l2",</div><div>+ },</div><div>+};</div><div>+</div><div>+static int virResCtrlGetInfoStr(const int type, const char *item, char **str)</div><div>+{</div><div>+ int ret = 0;</div><div>+ char *tmp;</div><div>+ char *path;</div><div>+</div><div>+ if (virAsprintf(&path, "%s/%s/%s", RESCTRL_INFO_DIR, resctrlall[type].name, item) < 0)</div><div>+ return -1;</div><div>+ if (virFileReadAll(path, 10, str) < 0) {</div><div>+ ret = -1;</div><div>+ goto cleanup;</div><div>+ }</div><div>+</div><div>+ if ((tmp = strchr(*str, '\n'))) *tmp = '\0';</div><div>+</div><div>+ cleanup:</div><div>+ VIR_FREE(path);</div><div>+ return ret;</div><div>+}</div><div>+</div><div>+</div><div>+static int virResCtrlGetCPUValue(const char *path, char **value)</div></div></blockquote><div><br></div><div>It would be more consistent if you reused parts of virHostCPUGetValue(),</div><div>put them in a function, and use that one in both this one an the</div><div>original one. It chould be also put in the virhostcpu.c since that's</div><div>about the host cpu.</div><div><br></div><blockquote type="cite"><div>+static int virResctrlGetCPUSocketID(const size_t cpu, int *socket_id)</div></blockquote><div><br></div><div>No need for this function, just use virHostCPUParseSocket()</div><div><br></div><blockquote type="cite"><div>+static int virResCtrlGetCPUCache(const size_t cpu, int type, int *cache)</div></blockquote><div><br></div><div>So we have some places in the code that get info from sysfs. I</div><div>understand that cache is controlled in the resctrl, but one doesn't have</div><div>to have resctrl to get some cache info, so I would move this function</div><div>into virhostcpu.c and keep here only the stuff strictly related to</div><div>resource control.</div><div><br></div><blockquote type="cite"><div><div>+{</div><div>+ int ret = -1;</div><div>+ char *cache_dir = NULL;</div><div>+ char *cache_str = NULL;</div><div>+ char *tmp;</div><div>+ int carry = -1;</div><div>+</div><div>+ if (virAsprintf(&cache_dir,</div><div>+ "%s/cpu/cpu%zu/cache/index%d/size",</div><div>+ SYSFS_SYSTEM_PATH, cpu, type) < 0)</div><div>+ return -1;</div><div>+</div><div>+ if (virResCtrlGetCPUValue(cache_dir, &cache_str) < 0)</div><div>+ goto cleanup;</div><div>+</div><div>+ tmp = cache_str;</div><div>+</div><div>+ while (*tmp != '\0') tmp++;</div><div>+</div><div>+ if (*(tmp - 1) == 'K') {</div><div>+ *(tmp - 1) = '\0';</div><div>+ carry = 1;</div><div>+ } else if (*(tmp - 1) == 'M') {</div><div>+ *(tmp - 1) = '\0';</div><div>+ carry = 1024;</div><div>+ }</div><div>+</div><div>+ if (virStrToLong_i(cache_str, NULL, 0, cache) < 0)</div><div>+ goto cleanup;</div><div>+</div><div>+ *cache = (*cache) * carry;</div><div>+</div><div>+ if (*cache < 0)</div><div>+ goto cleanup;</div><div>+</div><div>+ ret = 0;</div><div>+ cleanup:</div><div>+ VIR_FREE(cache_dir);</div><div>+ VIR_FREE(cache_str);</div><div>+ return ret;</div><div>+}</div><div>+</div></div></blockquote><div><br></div><div>Why all this fuzz? You should instead pass pointer to virStrToLong_i to</div><div>get where the number ends and then use virScaleInteger() to multiply it</div><div>properly.</div><div><br></div><blockquote type="cite"><div><div>+/* Fill all cache bank informations */</div><div>+static virResCacheBankPtr virResCtrlGetCacheBanks(int type, int *n_sockets)</div><div>+{</div></div></blockquote><div><br></div><div>Still could be in virhostcpu.c</div><div><br></div><blockquote type="cite"><div><div>+ int npresent_cpus;</div><div>+ int idx = -1;</div><div>+ size_t i;</div><div>+ virResCacheBankPtr bank;</div><div>+</div><div>+ *n_sockets = 1;</div><div>+ if ((npresent_cpus = virHostCPUGetCount()) < 0)</div><div>+ return NULL;</div><div>+</div><div>+ if (type == VIR_RDT_RESOURCE_L3</div><div>+ || type == VIR_RDT_RESOURCE_L3DATA</div><div>+ || type == VIR_RDT_RESOURCE_L3CODE)</div><div>+ idx = 3;</div><div>+ else if (type == VIR_RDT_RESOURCE_L2)</div><div>+ idx = 2;</div><div>+</div><div>+ if (idx == -1)</div><div>+ return NULL;</div><div>+</div></div></blockquote><div><br></div><div>Indentation, "||" should be on the previous line but, most importantly,</div><div>why not switch? That'd make sure you won't miss any enum value and if</div><div>someone adds a new one, compilator will see it's missing here.</div><div><br></div><blockquote type="cite"><div><div>+ if (VIR_ALLOC_N(bank, *n_sockets) < 0) {</div><div>+ *n_sockets = 0;</div></div></blockquote><div><br></div><div>set this before the first return so that this function guarantees</div><div>n_sockets to be 0 on fail. Moreover, n_sockets is always set to 1</div><div>here. Due to the way the rest of the function is designed, this doesn't</div><div>have to be here at all.</div><div><br></div><blockquote type="cite"><div><div>+ return NULL;</div><div>+ }</div><div>+</div><div>+ for (i = 0; i < npresent_cpus; i ++) {</div><div>+ int s_id;</div><div>+ int cache_size;</div><div>+</div><div>+ if (virResctrlGetCPUSocketID(i, &s_id) < 0)</div><div>+ goto error;</div><div>+</div><div>+ if (s_id > (*n_sockets - 1)) {</div><div>+ size_t cur = *n_sockets;</div><div>+ size_t exp = s_id - (*n_sockets) + 1;</div><div>+ if (VIR_EXPAND_N(bank, cur, exp) < 0)</div><div>+ goto error;</div><div>+ *n_sockets = s_id + 1;</div><div>+ }</div><div>+</div><div>+ if (bank[s_id].cpu_mask == NULL) {</div><div>+ if (!(bank[s_id].cpu_mask = virBitmapNew(npresent_cpus)))</div><div>+ goto error;</div><div>+ }</div><div>+</div><div>+ ignore_value(virBitmapSetBit(bank[s_id].cpu_mask, i));</div><div>+</div><div>+ if (bank[s_id].cache_size == 0) {</div><div>+ if (virResCtrlGetCPUCache(i, idx, &cache_size) < 0)</div><div>+ goto error;</div><div>+</div><div>+ bank[s_id].cache_size = cache_size;</div><div>+ bank[s_id].cache_min = cache_size / resctrlall[type].cbm_len;</div><div>+ }</div><div>+ }</div><div>+ return bank;</div><div>+</div></div></blockquote><div><br></div><div>Wouldn't it be easier to have list of virResCacheBankPtr *banks; and</div><div>size_t nbanks; and then just populate each pointer when that socket is</div><div>on the system, so that you that NULL means the socket info was not</div><div>filled yet. Or just a list that isn't sparse (like yours is now). The</div><div>logic here seems hard to read.</div><div><br></div><div>I'll continue the review tomorrow.</div><div><br></div><div>Martin</div><div><br></div><blockquote type="cite"><div><div>+ error:</div><div>+ *n_sockets = 0;</div><div>+ VIR_FREE(bank);</div><div>+ return NULL;</div><div>+}</div><div>+</div><div>+static int virResCtrlGetConfig(int type)</div></div></blockquote></div></blockquote><div><br></div><div>I feel like 'Get' implies you're returning it, I'd go with 'Read' instead.</div></div></div></span></div></blockquote><div><br></div><div>Done</div><blockquote type="cite"><div><span><div><div><div><br></div><blockquote type="cite"><blockquote type="cite"><div><div>+{</div><div>+ int ret;</div><div>+ size_t i;</div><div>+ char *str;</div><div>+</div><div>+ /* Read min_cbm_bits from resctrl.</div><div>+ eg: /sys/fs/resctrl/info/L3/num_closids</div><div>+ */</div><div>+ if ((ret = virResCtrlGetInfoStr(type, "num_closids", &str)) < 0)</div><div>+ return ret;</div><div>+</div><div>+ if (virStrToLong_i(str, NULL, 10, &resctrlall[type].num_closid) < 0)</div><div>+ return -1;</div></div></blockquote></blockquote><div><br></div><div>You leak str here ^^</div></div></div></span></div></blockquote><div>Done </div><blockquote type="cite"><div><span><div><div><div><br></div><blockquote type="cite"><blockquote type="cite"><div><div>+</div><div>+ VIR_FREE(str);</div><div>+</div><div>+ /* Read min_cbm_bits from resctrl.</div><div>+ eg: /sys/fs/resctrl/info/L3/cbm_mask</div><div>+ */</div><div>+ if ((ret = virResCtrlGetInfoStr(type, "min_cbm_bits", &str)) < 0)</div><div>+ return ret;</div><div>+</div><div>+ if (virStrToLong_i(str, NULL, 10, &resctrlall[type].min_cbm_bits) < 0)</div><div>+ return -1;</div></div></blockquote></blockquote><div><br></div><div>Same here</div></div></div></span></div></blockquote><div>Done </div><blockquote type="cite"><div><span><div><div><div><br></div><blockquote type="cite"><blockquote type="cite"><div><div>+</div><div>+ VIR_FREE(str);</div><div>+</div><div>+ /* Read cbm_mask string from resctrl.</div><div>+ eg: /sys/fs/resctrl/info/L3/cbm_mask</div><div>+ */</div><div>+ if ((ret = virResCtrlGetInfoStr(type, "cbm_mask", &str)) < 0)</div><div>+ return ret;</div><div>+</div><div>+ /* Calculate cbm length from the default cbm_mask. */</div></div></blockquote></blockquote><div><br></div><div>The comment could say the mask is in hex and that's why strlen(s) * 4 is</div><div>OK.</div><div><br></div><div>Question: It can never be, for example, 38 bits or just 2? Just asking</div><div>to be sure.</div><div><br></div><blockquote type="cite"><blockquote type="cite"><div><div>+ resctrlall[type].cbm_len = strlen(str) * 4;</div><div>+ VIR_FREE(str);</div><div>+</div><div>+ /* Get all cache bank informations */</div><div>+ resctrlall[type].cache_banks = virResCtrlGetCacheBanks(type,</div><div>+ &(resctrlall[type].num_banks));</div><div>+</div><div>+ if (resctrlall[type].cache_banks == NULL)</div><div>+ return -1;</div><div>+</div><div>+ for (i = 0; i < resctrlall[type].num_banks; i++) {</div><div>+ /*L3CODE and L3DATA shares same L3 resource, so they should</div><div>+ * have same host_id. */</div><div>+ if (type == VIR_RDT_RESOURCE_L3CODE)</div><div>+ resctrlall[type].cache_banks[i].host_id = resctrlall[VIR_RDT_RESOURCE_L3DATA].cache_banks[i].host_id;</div><div>+ else</div><div>+ resctrlall[type].cache_banks[i].host_id = host_id++;</div></div></blockquote></blockquote><div><br></div><div>Shouldn't this be done only if CDP is not supported?</div></div></div></span></div></blockquote><div><br></div><div>Not really, here ’s tricky.</div><div><br></div><div>only host id for VIR_RDT_RESOURCE_L3CODE set to VIR_RDT_RESOURCE_L3DATA</div><div><br></div><div><br></div><div> </div><blockquote type="cite"><div><span><div><div><div><br></div><blockquote type="cite"><blockquote type="cite"><div><div>+ }</div><div>+</div><div>+ resctrlall[type].enabled = true;</div><div>+</div><div>+ return ret;</div><div>+}</div><div>+</div><div>+int</div><div>+virResCtrlInit(void)</div><div>+{</div><div>+ size_t i = 0;</div><div>+ char *tmp;</div><div>+ int rc = 0;</div><div>+</div><div>+ for (i = 0; i < VIR_RDT_RESOURCE_LAST; i++) {</div><div>+ if ((rc = virAsprintf(&tmp, "%s/%s", RESCTRL_INFO_DIR, resctrlall[i].name)) < 0) {</div><div>+ VIR_ERROR(_("Failed to initialize resource control config"));</div><div>+ return -1;</div><div>+ }</div><div>+ if (virFileExists(tmp)) {</div><div>+ if ((rc = virResCtrlGetConfig(i)) < 0)</div><div>+ VIR_ERROR(_("Failed to get resource control config"));</div></div></blockquote></blockquote><div><br></div><div>virReportError should be used here, VIR_ERROR has a specific use case</div><div>that's not applicable here.</div><div><br></div></div></div></span></div></blockquote><div>Done. </div><blockquote type="cite"><div><span><div><div><blockquote type="cite"><blockquote type="cite"><div>+ return -1;</div></blockquote></blockquote><div><br></div><div>tmp leaks here</div><div><br></div></div></div></span></div></blockquote><div>Done. </div><blockquote type="cite"><div><span><div><div><blockquote type="cite"><blockquote type="cite"><div><div>+ }</div><div>+</div><div>+ VIR_FREE(tmp);</div><div>+ }</div><div>+ return rc;</div><div>+}</div><div>+</div><div>+/*</div><div>+ * Test whether the host support resource control</div><div>+ */</div><div>+bool</div><div>+virResCtrlAvailable(void)</div><div>+{</div><div>+ if (!virFileExists(RESCTRL_INFO_DIR))</div><div>+ return false;</div><div>+ return true;</div><div>+}</div><div>+</div><div>+/*</div><div>+ * Return an virResCtrlPtr point to virResCtrl object,</div><div>+ * We should not modify it out side of virresctrl.c</div><div>+ */</div></div></blockquote></blockquote><div><br></div><div>That's easy to achieve. If you only put the typedef into the header</div><div>file and accessors into this file, then no other code will be able to</div><div>modify the data because the pointer will be opaque. Even if it is</div><div>modifiable, that should be the way to go.</div><div><br></div></div></div></span></div></blockquote><div>I tried to move accessors to .c file, but failed, I can not even reference it outside. </div><blockquote type="cite"><div><span><div><div><blockquote type="cite"><blockquote type="cite"><div><div>+virResCtrlPtr</div><div>+virResCtrlGet(int type)</div><div>+{</div><div>+ return &resctrlall[type];</div><div>+}</div><div>diff --git a/src/util/virresctrl.h b/src/util/virresctrl.h</div><div>new file mode 100644</div><div>index 0000000..aa113f4</div><div>--- /dev/null</div><div>+++ b/src/util/virresctrl.h</div><div>@@ -0,0 +1,80 @@</div><div>+/*</div><div>+ * * virresctrl.h: methods for managing rscctrl</div><div>+ * *</div><div>+ * * Copyright (C) 2016 Intel, Inc.</div><div>+ * *</div><div>+ * * This library is free software; you can redistribute it and/or</div><div>+ * * modify it under the terms of the GNU Lesser General Public</div><div>+ * * License as published by the Free Software Foundation; either</div><div>+ * * version 2.1 of the License, or (at your option) any later version.</div><div>+ *</div></div></blockquote></blockquote><div><br></div><div>Too many asterisks.</div></div></div></span></div></blockquote><div>Done. </div><blockquote type="cite"><div><span><div><div><div><br></div><blockquote type="cite"><blockquote type="cite"><div><div>+ * This library is distributed in the hope that it will be useful,</div><div>+ * but WITHOUT ANY WARRANTY; without even the implied warranty of</div><div>+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU</div><div>+ * Lesser General Public License for more details.</div><div>+ *</div><div>+ * You should have received a copy of the GNU Lesser General Public</div><div>+ * License along with this library. If not, see</div><div>+ * <<a href="http://www.gnu.org/licenses/">http://www.gnu.org/licenses/</a>>.</div><div>+ *</div><div>+ * Authors:</div><div>+ * Eli Qiao <<a href="mailto:liyong.qiao@intel.com">liyong.qiao@intel.com</a>></div><div>+ */</div><div>+</div><div>+#ifndef __VIR_RESCTRL_H__</div><div>+# define __VIR_RESCTRL_H__</div><div>+</div><div>+# include "virutil.h"</div></div></blockquote></blockquote><div><br></div><div>What do you need virutil in the header file for?</div><div><br></div></div></div></span></div></blockquote><div>Removed </div><blockquote type="cite"><div><span><div><div><blockquote type="cite"><div><blockquote type="cite"><div><div>+# include "virbitmap.h"</div><div>+</div><div>+enum {</div><div>+ VIR_RDT_RESOURCE_L3,</div><div>+ VIR_RDT_RESOURCE_L3DATA,</div><div>+ VIR_RDT_RESOURCE_L3CODE,</div><div>+ VIR_RDT_RESOURCE_L2,</div><div>+ /* Must be the last */</div><div>+ VIR_RDT_RESOURCE_LAST,</div><div>+};</div><div>+</div><div>+</div><div>+typedef struct _virResCacheBank virResCacheBank;</div><div>+typedef virResCacheBank *virResCacheBankPtr;</div><div>+struct _virResCacheBank {</div><div>+ unsigned int host_id;</div><div>+ unsigned long long cache_size;</div><div>+ unsigned long long cache_left;</div><div>+ unsigned long long cache_min;</div><div>+ virBitmapPtr cpu_mask;</div><div>+};</div><div>+</div><div>+/**</div><div>+ * struct rdt_resource - attributes of an RDT resource</div><div>+ * @enabled: Is this feature enabled on this machine</div><div>+ * @name: Name to use in "schemata" file</div><div>+ * @num_closid: Number of CLOSIDs available</div><div>+ * @max_cbm: Largest Cache Bit Mask allowed</div><div>+ * @min_cbm_bits: Minimum number of consecutive bits to be set</div><div>+ * in a cache bit mask</div><div>+ * @cache_level: Which cache level defines scope of this domain</div><div>+ * @num_banks: Number of cache bank on this machine.</div><div>+ * @cache_banks: Array of cache bank</div><div>+ */</div><div>+typedef struct _virResCtrl virResCtrl;</div><div>+typedef virResCtrl *virResCtrlPtr;</div><div>+struct _virResCtrl {</div><div>+ bool enabled;</div><div>+ const char *name;</div><div>+ int num_closid;</div><div>+ int cbm_len;</div><div>+ int min_cbm_bits;</div><div>+ const char* cache_level;</div><div>+ int num_banks;</div><div>+ virResCacheBankPtr cache_banks;</div><div>+};</div><div>+</div><div>+</div><div>+bool virResCtrlAvailable(void);</div><div>+int virResCtrlInit(void);</div><div>+virResCtrlPtr virResCtrlGet(int);</div><div>+</div><div>+#endif</div><div>--</div><div>1.9.1</div></div></blockquote><div>--</div><div>libvir-list mailing list</div><div><a href="mailto:libvir-list@redhat.com">libvir-list@redhat.com</a></div><div><a href="https://www.redhat.com/mailman/listinfo/libvir-list">https://www.redhat.com/mailman/listinfo/libvir-list</a></div></div></blockquote></div></div></span>
</div></blockquote><div>
<br>
</div>