<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 Wednesday, 15 March 2017 at 8:53 PM, Martin Kletzander wrote:</p>
                <blockquote type="cite" style="border-left-style:solid;border-width:1px;margin-left:0px;padding-left:10px;">
                    <span><div><div><div>On Mon, Mar 06, 2017 at 06:06:31PM +0800, Eli Qiao wrote:</div><blockquote type="cite"><div><div>This patch expose cache information to host's capabilites xml.</div><div><br></div><div>For l3 cache allocation</div><div><cache></div><div> <bank id='0' type='l3' size='56320' unit='KiB' cpus='0-21,44-65'></div><div>   <control min='2816' reserved='2816' unit='KiB' scope='L3'/></div><div> </bank></div><div> <bank id='1' type='l3' size='56320' unit='KiB' cpus='22-43,66-87'></div><div>   <control min='2816' reserved='2816' unit='KiB' scope='L3'/></div><div> </bank></div><div></cache></div><div><br></div><div>For l3 cache allocation supported cdp(seperate data/code):</div><div><cache></div><div> <bank id='0' type='l3' size='56320' unit='KiB' cpus='0-21,44-65'></div><div>   <control min='2816' reserved='2816' unit='KiB' scope='L3DATA'/></div><div>   <control min='2816' reserved='2816' unit='KiB' scope='L3CODE'/></div></div></blockquote><div><br></div><div>I know this was discussed before, but why having a vector value in a</div><div>single attribute?  Why don't we split it to two scalars?  It will also</div><div>be SOO much more readable and close to what other tools expose, e.g.:</div><div><br></div><div><control scope="data"/></div><div><control scope="instruction"/></div><div><br></div><div>or</div><div><br></div><div><control scope="both"/></div><div><br></div><div>I also skipped the 'l3' because that is already in the <bank/> and will</div><div>never be different, right?</div><div><br></div></div></div></span></blockquote><div><br></div><div> I am okay to ether of them, just follow with previous discussion.</div><div> </div><blockquote type="cite" style="border-left-style:solid;border-width:1px;margin-left:0px;padding-left:10px;"><span><div><div><div></div><blockquote type="cite"><div><div> </bank></div><div> <bank id='1' type='l3' size='56320' unit='KiB' cpus='22-43,66-87'></div><div>   <control min='2816' reserved='2816' unit='KiB' scope='L3DATA'/></div><div>   <control min='2816' reserved='2816' unit='KiB' scope='L3CODE'/></div><div> </bank></div><div></cache></div><div><br></div><div>RFC on mailing list.</div><div><a href="https://www.redhat.com/archives/libvir-list/2017-January/msg00644.html">https://www.redhat.com/archives/libvir-list/2017-January/msg00644.html</a></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>src/conf/capabilities.c      | 56 ++++++++++++++++++++++++++++++++++++++</div><div>src/conf/capabilities.h      | 23 ++++++++++++++++</div><div>src/libvirt_private.syms     |  3 +++</div><div>src/nodeinfo.c               | 64 ++++++++++++++++++++++++++++++++++++++++++++</div><div>src/nodeinfo.h               |  1 +</div><div>src/qemu/qemu_capabilities.c |  8 ++++++</div><div>src/qemu/qemu_driver.c       |  4 +++</div><div>7 files changed, 159 insertions(+)</div><div><br></div><div>diff --git a/src/conf/capabilities.c b/src/conf/capabilities.c</div><div>index 9ab343b..23e21e4 100644</div><div>--- a/src/conf/capabilities.c</div><div>+++ b/src/conf/capabilities.c</div><div>@@ -198,6 +198,18 @@ virCapabilitiesClearSecModel(virCapsHostSecModelPtr secmodel)</div><div>}</div><div><br></div><div>static void</div><div>+virCapabilitiesClearCacheBank(virCapsHostCacheBankPtr cachebank)</div><div>+{</div><div>+    size_t i;</div><div>+    for (i = 0; i < cachebank->ncontrol; i++)</div><div>+        VIR_FREE(cachebank->control[i].scope);</div><div>+</div><div>+    VIR_FREE(cachebank->type);</div><div>+    VIR_FREE(cachebank->cpus);</div><div>+}</div><div>+</div><div>+</div><div>+static void</div><div>virCapabilitiesDispose(void *object)</div><div>{</div><div>    virCapsPtr caps = object;</div><div>@@ -221,6 +233,10 @@ virCapabilitiesDispose(void *object)</div><div>        virCapabilitiesClearSecModel(&caps->host.secModels[i]);</div><div>    VIR_FREE(caps->host.secModels);</div><div><br></div><div>+    for (i = 0; i < caps->host.ncachebank; i++)</div><div>+        virCapabilitiesClearCacheBank(caps->host.cachebank[i]);</div><div>+    VIR_FREE(caps->host.cachebank);</div><div>+</div><div>    VIR_FREE(caps->host.netprefix);</div><div>    VIR_FREE(caps->host.pagesSize);</div><div>    virCPUDefFree(caps->host.cpu);</div><div>@@ -844,6 +860,41 @@ virCapabilitiesFormatNUMATopology(virBufferPtr buf,</div><div>    return 0;</div><div>}</div><div><br></div><div>+static int</div><div>+virCapabilitiesFormatCache(virBufferPtr buf,</div><div>+                           size_t ncachebank,</div><div>+                           virCapsHostCacheBankPtr *cachebank)</div><div>+{</div><div>+    size_t i;</div><div>+    size_t j;</div><div>+</div><div>+    virBufferAddLit(buf, "<cache>\n");</div><div>+    virBufferAdjustIndent(buf, 2);</div><div>+</div><div>+    for (i = 0; i < ncachebank; i++) {</div><div>+        virBufferAsprintf(buf,</div><div>+                          "<bank id='%u' type='%s' size='%llu' unit='KiB' cpus='%s'>\n",</div><div>+                          cachebank[i]->id,</div><div>+                          cachebank[i]->type,</div><div>+                          cachebank[i]->size,</div><div>+                          cachebank[i]->cpus);</div><div>+</div><div>+        virBufferAdjustIndent(buf, 2);</div><div>+        for (j = 0; j < cachebank[i]->ncontrol; j++) {</div><div>+            virBufferAsprintf(buf,</div><div>+                              "<control min='%llu' reserved='%llu' unit='KiB' scope='%s'/>\n",</div><div>+                              cachebank[i]->control[j].min,</div><div>+                              cachebank[i]->control[j].reserved,</div><div>+                              cachebank[i]->control[j].scope);</div><div>+        }</div><div>+        virBufferAdjustIndent(buf, -2);</div><div>+        virBufferAddLit(buf, "</bank>\n");</div><div>+    }</div><div>+    virBufferAdjustIndent(buf, -2);</div><div>+    virBufferAddLit(buf, "</cache>\n");</div><div>+    return 0;</div><div>+}</div><div>+</div><div>/**</div><div> * virCapabilitiesFormatXML:</div><div> * @caps: capabilities to format</div><div>@@ -931,6 +982,11 @@ virCapabilitiesFormatXML(virCapsPtr caps)</div><div>        virBufferAddLit(&buf, "</migration_features>\n");</div><div>    }</div><div><br></div><div>+    if (caps->host.ncachebank &&</div><div>+            virCapabilitiesFormatCache(&buf, caps->host.ncachebank,</div><div>+                                       caps->host.cachebank) < 0)</div><div>+        return NULL;</div><div>+</div><div>    if (caps->host.netprefix)</div><div>        virBufferAsprintf(&buf, "<netprefix>%s</netprefix>\n",</div><div>                          caps->host.netprefix);</div><div>diff --git a/src/conf/capabilities.h b/src/conf/capabilities.h</div><div>index cfdc34a..b446de5 100644</div><div>--- a/src/conf/capabilities.h</div><div>+++ b/src/conf/capabilities.h</div><div>@@ -138,6 +138,25 @@ struct _virCapsHostSecModel {</div><div>    virCapsHostSecModelLabelPtr labels;</div><div>};</div><div><br></div><div>+typedef struct _virCapsHostCacheControl virCapsHostCacheControl;</div><div>+typedef virCapsHostCacheControl *virCapsHostCacheControlPtr;</div><div>+struct _virCapsHostCacheControl {</div><div>+    unsigned long long min;</div><div>+    unsigned long long reserved;</div><div>+    char* scope;</div><div>+};</div><div>+</div><div>+typedef struct _virCapsHostCacheBank virCapsHostCacheBank;</div><div>+typedef virCapsHostCacheBank *virCapsHostCacheBankPtr;</div><div>+struct _virCapsHostCacheBank {</div><div>+    unsigned int id;</div><div>+    char* type;</div><div>+    char* cpus;</div><div>+    unsigned long long size;</div><div>+    size_t ncontrol;</div><div>+    virCapsHostCacheControlPtr control;</div><div>+};</div><div>+</div><div>typedef struct _virCapsHost virCapsHost;</div><div>typedef virCapsHost *virCapsHostPtr;</div><div>struct _virCapsHost {</div><div>@@ -160,6 +179,10 @@ struct _virCapsHost {</div><div>    size_t nsecModels;</div><div>    virCapsHostSecModelPtr secModels;</div><div><br></div><div>+    size_t ncachebank;</div><div>+    size_t ncachebank_max;</div><div>+    virCapsHostCacheBankPtr *cachebank;</div><div>+</div><div>    char *netprefix;</div><div>    virCPUDefPtr cpu;</div><div>    int nPagesSize;             /* size of pagesSize array */</div><div>diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms</div><div>index bb7c3ad..b8445ef 100644</div><div>--- a/src/libvirt_private.syms</div><div>+++ b/src/libvirt_private.syms</div><div>@@ -1125,6 +1125,7 @@ virLogManagerNew;</div><div># nodeinfo.h</div><div>nodeCapsInitNUMA;</div><div>nodeGetInfo;</div><div>+virCapsInitCache;</div><div>virHostCPUGetCount;</div><div>virHostCPUGetKVMMaxVCPUs;</div><div>virHostCPUGetMap;</div><div>@@ -2322,8 +2323,10 @@ virRandomInt;</div><div><br></div><div># util/virresctrl.h</div><div>virResCtrlAvailable;</div><div>+virResCtrlGet;</div><div>virResCtrlInit;</div><div><br></div><div>+</div><div># util/virrotatingfile.h</div><div>virRotatingFileReaderConsume;</div><div>virRotatingFileReaderFree;</div><div>diff --git a/src/nodeinfo.c b/src/nodeinfo.c</div><div>index f2ded02..a001cd0 100644</div><div>--- a/src/nodeinfo.c</div><div>+++ b/src/nodeinfo.c</div><div>@@ -48,6 +48,7 @@</div><div>#include "virstring.h"</div><div>#include "virnuma.h"</div><div>#include "virlog.h"</div><div>+#include "virresctrl.h"</div><div><br></div><div>#define VIR_FROM_THIS VIR_FROM_NONE</div><div><br></div><div>@@ -416,3 +417,66 @@ nodeCapsInitNUMA(virCapsPtr caps)</div><div>    VIR_FREE(pageinfo);</div><div>    return ret;</div><div>}</div><div>+</div><div>+int</div><div>+virCapsInitCache(virCapsPtr caps)</div><div>+{</div><div>+    size_t i, j;</div><div>+    virResCtrlPtr resctrl;</div><div>+    virCapsHostCacheBankPtr bank;</div><div>+</div><div>+    for (i = 0; i < VIR_RDT_RESOURCE_LAST; i++) {</div><div>+        /* L3DATA and L3CODE share L3 resources */</div><div>+        if (i == VIR_RDT_RESOURCE_L3CODE)</div><div>+            continue;</div><div>+</div><div>+        resctrl = virResCtrlGet(i);</div><div>+</div><div>+        if (resctrl->enabled) {</div><div>+            for (j = 0; j < resctrl->num_banks; j++) {</div><div>+                if (VIR_RESIZE_N(caps->host.cachebank, caps->host.ncachebank_max,</div><div>+                                caps->host.ncachebank, 1) < 0)</div><div>+                    return -1;</div><div>+</div><div>+                if (VIR_ALLOC(bank) < 0)</div><div>+                    return -1;</div><div>+</div><div>+                bank->id = resctrl->cache_banks[j].host_id;</div><div>+                if (VIR_STRDUP(bank->type, resctrl->cache_level) < 0)</div><div>+                    goto err;</div><div>+                if (VIR_STRDUP(bank->cpus, virBitmapFormat(resctrl->cache_banks[j].cpu_mask)) < 0)</div><div>+                    goto err;</div><div>+                bank->size = resctrl->cache_banks[j].cache_size;</div><div>+                /*L3DATA and L3CODE shares L3 cache resources, so fill them to the control element*/</div><div>+                if (i == VIR_RDT_RESOURCE_L3DATA) {</div><div>+                    if (VIR_EXPAND_N(bank->control, bank->ncontrol, 2) < 0)</div><div>+                        goto err;</div><div>+</div><div>+                    bank->control[0].min = virResCtrlGet(VIR_RDT_RESOURCE_L3DATA)->cache_banks[j].cache_min;</div><div>+                    bank->control[0].reserved = bank->control[0].min * (virResCtrlGet(VIR_RDT_RESOURCE_L3DATA)->min_cbm_bits);</div><div>+                    if (VIR_STRDUP(bank->control[0].scope,</div><div>+                                  virResCtrlGet(VIR_RDT_RESOURCE_L3DATA)->name) < 0)</div><div>+                        goto err;</div><div>+</div><div>+                    bank->control[1].min = virResCtrlGet(VIR_RDT_RESOURCE_L3CODE)->cache_banks[j].cache_min;</div><div>+                    bank->control[1].reserved = bank->control[1].min * (virResCtrlGet(VIR_RDT_RESOURCE_L3CODE)->min_cbm_bits);</div><div>+                    if (VIR_STRDUP(bank->control[1].scope,</div><div>+                                   virResCtrlGet(VIR_RDT_RESOURCE_L3CODE)->name) < 0)</div><div>+                        goto err;</div><div>+                } else {</div><div>+                    if (VIR_EXPAND_N(bank->control, bank->ncontrol, 1) < 0)</div><div>+                        goto err;</div><div>+                    bank->control[0].min = resctrl->cache_banks[j].cache_min;</div><div>+                    bank->control[0].reserved = bank->control[0].min * resctrl->min_cbm_bits;</div><div>+                    if (VIR_STRDUP(bank->control[0].scope, resctrl->name) < 0)</div><div>+                        goto err;</div><div>+                }</div><div>+                caps->host.cachebank[caps->host.ncachebank++] = bank;</div><div>+            }</div><div>+        }</div><div>+    }</div><div>+    return 0;</div><div>+ err:</div><div>+    VIR_FREE(bank);</div><div>+    return -1;</div><div>+}</div><div>diff --git a/src/nodeinfo.h b/src/nodeinfo.h</div><div>index 3c4dc46..5eb0f83 100644</div><div>--- a/src/nodeinfo.h</div><div>+++ b/src/nodeinfo.h</div><div>@@ -28,5 +28,6 @@</div><div><br></div><div>int nodeGetInfo(virNodeInfoPtr nodeinfo);</div><div>int nodeCapsInitNUMA(virCapsPtr caps);</div><div>+int virCapsInitCache(virCapsPtr caps);</div><div><br></div><div>#endif /* __VIR_NODEINFO_H__*/</div><div>diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c</div><div>index 359a0d8..a0d7254 100644</div><div>--- a/src/qemu/qemu_capabilities.c</div><div>+++ b/src/qemu/qemu_capabilities.c</div><div>@@ -1100,6 +1100,11 @@ virQEMUCapsInitCPU(virCapsPtr caps,</div><div>    goto cleanup;</div><div>}</div><div><br></div><div>+static int</div><div>+virQEMUCapsInitCache(virCapsPtr caps)</div><div>+{</div><div>+    return virCapsInitCache(caps);</div><div>+}</div><div><br></div><div>static int</div><div>virQEMUCapsInitPages(virCapsPtr caps)</div><div>@@ -1146,6 +1151,9 @@ virCapsPtr virQEMUCapsInit(virQEMUCapsCachePtr cache)</div><div>    if (virQEMUCapsInitCPU(caps, hostarch) < 0)</div><div>        VIR_WARN("Failed to get host CPU");</div><div><br></div><div>+    if (virQEMUCapsInitCache(caps) < 0)</div><div>+        VIR_WARN("Failed to get host cache");</div><div>+</div><div>    /* Add the power management features of the host */</div><div>    if (virNodeSuspendGetTargetMask(&caps->host.powerMgmt) < 0)</div><div>        VIR_WARN("Failed to get host power management capabilities");</div><div>diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c</div><div>index 77d8175..3bfb4ec 100644</div><div>--- a/src/qemu/qemu_driver.c</div><div>+++ b/src/qemu/qemu_driver.c</div><div>@@ -105,6 +105,7 @@</div><div>#include "vircgroup.h"</div><div>#include "virperf.h"</div><div>#include "virnuma.h"</div><div>+#include "virresctrl.h"</div><div>#include "dirname.h"</div><div>#include "network/bridge_driver.h"</div><div><br></div><div>@@ -849,6 +850,9 @@ qemuStateInitialize(bool privileged,</div><div>        run_gid = cfg->group;</div><div>    }</div><div><br></div><div>+    if (virResCtrlAvailable() && virResCtrlInit() < 0)</div><div>+        VIR_WARN("Faild to initialize resource control.");</div><div>+</div></div></blockquote><div><br></div><div>s/Faild/Failed/</div><div><br></div><div>Also the Available() call seems unnecessary since Init() is graceful to</div><div>unavailability IIRC.</div><div><br></div></div></div></span></blockquote><div>yep, we can remove  virResCtrlAvailable.</div><div><br></div><blockquote type="cite" style="border-left-style:solid;border-width:1px;margin-left:0px;padding-left:10px;"><span><div><div><div></div><div>Anyway if this is to be done once per daemon lifetime, it should be</div><div>wrapped using VIR_ONCE (see VIR_ONCE_GLOBAL_INIT all over the</div><div>codebase).  I believe I mentioned this already in some previous version.</div><div><br></div></div></div></span></blockquote><div>Ops, good to know that, would like to learn how to use VIR_ONCE. </div><div> </div><blockquote type="cite" style="border-left-style:solid;border-width:1px;margin-left:0px;padding-left:10px;"><span><div><div><blockquote type="cite"><div><div>qemu_driver->qemuCapsCache = virQEMUCapsCacheNew(cfg->libDir,</div><div>                                                     cfg->cacheDir,</div><div>                                                     run_uid,</div><div>--</div><div>1.9.1</div><div><br></div><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>
                 
                 
                 
                 
                </blockquote>
                 
                <div>
                    <br>
                </div>