diff --git a/docs/formatdomain.html.in b/docs/formatdomain.html.in index b1e38f00e42370e4daed12863eede72a493be028..5469fc37268e355930c585634a5b595b355989b6 100644 --- a/docs/formatdomain.html.in +++ b/docs/formatdomain.html.in @@ -5405,6 +5405,33 @@ qemu-kvm -net nic,model=? /dev/null Since 3.1.0

+
Coalesce settings
+
+...
+<devices>
+  <interface type='network'>
+    <source network='default'/>
+    <target dev='vnet0'/>
+    <coalesce>
+      <rx>
+        <frames max='7'/>
+      </rx>
+    </coalesce>
+  </interface>
+</devices>
+...
+ +

+ This element provides means of setting coalesce settings for + some interface devices (currently only type network + and bridge. Currently there is just one attribute, + max, to tweak, in element frames for + the rx group, which accepts a non-negative integer + that specifies the maximum number of packets that will be + received before an interrupt. + Since 3.3.0 +

+
IP configuration
 ...
diff --git a/docs/schemas/domaincommon.rng b/docs/schemas/domaincommon.rng
index edc225fe50c5295740722a9e4f51429bc7f1c179..eb4b0f7437babbc7f06c80f93effb57218c2e7d1 100644
--- a/docs/schemas/domaincommon.rng
+++ b/docs/schemas/domaincommon.rng
@@ -2508,6 +2508,9 @@
       
         
       
+      
+        
+      
       
         
           
@@ -5743,4 +5746,132 @@
       
     
   
+
+  
+    
+      
+        
+          
+            
+              
+                
+                  
+                    
+                  
+                
+                
+              
+            
+            
+          
+        
+        
+      
+    
+  
+
 
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index 705deb39a1bfff28b91e8185c2b7f7dec5c42f06..cbeebdc568803ecf084c414efd1e82715b291ce1 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -6772,6 +6772,77 @@ virDomainNetIPInfoParseXML(const char *source,
     return ret;
 }
 
+
+static virNetDevCoalescePtr
+virDomainNetDefCoalesceParseXML(xmlNodePtr node,
+                                xmlXPathContextPtr ctxt)
+{
+    virNetDevCoalescePtr ret = NULL;
+    xmlNodePtr save = NULL;
+    char *str = NULL;
+    unsigned long long tmp = 0;
+
+    save = ctxt->node;
+    ctxt->node = node;
+
+    str = virXPathString("string(./rx/frames/@max)", ctxt);
+    if (!str)
+        goto cleanup;
+
+    if (!ret && VIR_ALLOC(ret) < 0)
+        goto cleanup;
+
+    if (virStrToLong_ullp(str, NULL, 10, &tmp) < 0) {
+        virReportError(VIR_ERR_XML_DETAIL,
+                       _("cannot parse value '%s' for coalesce parameter"),
+                       str);
+        VIR_FREE(str);
+        goto error;
+    }
+    VIR_FREE(str);
+
+    if (tmp > UINT32_MAX) {
+        virReportError(VIR_ERR_OVERFLOW,
+                       _("value '%llu' is too big for coalesce "
+                         "parameter, maximum is '%lu'"),
+                       tmp, (unsigned long) UINT32_MAX);
+        goto error;
+    }
+    ret->rx_max_coalesced_frames = tmp;
+
+ cleanup:
+    ctxt->node = save;
+    return ret;
+
+ error:
+    VIR_FREE(ret);
+    goto cleanup;
+}
+
+static void
+virDomainNetDefCoalesceFormatXML(virBufferPtr buf,
+                                 virNetDevCoalescePtr coalesce)
+{
+    if (!coalesce || !coalesce->rx_max_coalesced_frames)
+        return;
+
+    virBufferAddLit(buf, "\n");
+    virBufferAdjustIndent(buf, 2);
+
+    virBufferAddLit(buf, "\n");
+    virBufferAdjustIndent(buf, 2);
+
+    virBufferAsprintf(buf, "\n",
+                      coalesce->rx_max_coalesced_frames);
+
+    virBufferAdjustIndent(buf, -2);
+    virBufferAddLit(buf, "\n");
+
+    virBufferAdjustIndent(buf, -2);
+    virBufferAddLit(buf, "\n");
+}
+
+
 static int
 virDomainHostdevDefParseXMLCaps(xmlNodePtr node ATTRIBUTE_UNUSED,
                                 xmlXPathContextPtr ctxt,
@@ -10255,6 +10326,13 @@ virDomainNetDefParseXML(virDomainXMLOptionPtr xmlopt,
         goto error;
     }
 
+    node = virXPathNode("./coalesce", ctxt);
+    if (node) {
+        def->coalesce = virDomainNetDefCoalesceParseXML(node, ctxt);
+        if (!def->coalesce)
+            goto error;
+    }
+
  cleanup:
     ctxt->node = oldnode;
     VIR_FREE(macaddr);
@@ -22147,6 +22225,8 @@ virDomainNetDefFormat(virBufferPtr buf,
     if (def->mtu)
         virBufferAsprintf(buf, "\n", def->mtu);
 
+    virDomainNetDefCoalesceFormatXML(buf, def->coalesce);
+
     if (virDomainDeviceInfoFormat(buf, &def->info,
                                   flags | VIR_DOMAIN_DEF_FORMAT_ALLOW_BOOT
                                   | VIR_DOMAIN_DEF_FORMAT_ALLOW_ROM) < 0)
diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h
index 7da554f8ee28eca0eed88ba4c91209d5041d93f4..3b6b1745161843ab2102e459feab6f142c232395 100644
--- a/src/conf/domain_conf.h
+++ b/src/conf/domain_conf.h
@@ -41,6 +41,7 @@
 # include "numa_conf.h"
 # include "virnetdevmacvlan.h"
 # include "virsysinfo.h"
+# include "virnetdev.h"
 # include "virnetdevip.h"
 # include "virnetdevvportprofile.h"
 # include "virnetdevbandwidth.h"
@@ -1036,6 +1037,7 @@ struct _virDomainNetDef {
     int trustGuestRxFilters; /* enum virTristateBool */
     int linkstate;
     unsigned int mtu;
+    virNetDevCoalescePtr coalesce;
 };
 
 /* Used for prefix of ifname of any network name generated dynamically
diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c
index b3e1573c690d95b1e144c222c5504626a63b7aeb..d906fe6fdd4f7ca74f5261b46af14a10fedd4421 100644
--- a/src/qemu/qemu_domain.c
+++ b/src/qemu/qemu_domain.c
@@ -2984,6 +2984,30 @@ qemuDomainDefValidate(const virDomainDef *def,
 }
 
 
+static bool
+qemuDomainNetSupportsCoalesce(virDomainNetType type)
+{
+    switch (type) {
+    case VIR_DOMAIN_NET_TYPE_NETWORK:
+    case VIR_DOMAIN_NET_TYPE_BRIDGE:
+        return true;
+    case VIR_DOMAIN_NET_TYPE_VHOSTUSER:
+    case VIR_DOMAIN_NET_TYPE_ETHERNET:
+    case VIR_DOMAIN_NET_TYPE_DIRECT:
+    case VIR_DOMAIN_NET_TYPE_HOSTDEV:
+    case VIR_DOMAIN_NET_TYPE_USER:
+    case VIR_DOMAIN_NET_TYPE_SERVER:
+    case VIR_DOMAIN_NET_TYPE_CLIENT:
+    case VIR_DOMAIN_NET_TYPE_MCAST:
+    case VIR_DOMAIN_NET_TYPE_INTERNAL:
+    case VIR_DOMAIN_NET_TYPE_UDP:
+    case VIR_DOMAIN_NET_TYPE_LAST:
+        break;
+    }
+    return false;
+}
+
+
 static int
 qemuDomainDeviceDefValidate(const virDomainDeviceDef *dev,
                             const virDomainDef *def ATTRIBUTE_UNUSED,
@@ -3018,6 +3042,13 @@ qemuDomainDeviceDefValidate(const virDomainDeviceDef *dev,
                            virDomainNetTypeToString(net->type));
             goto cleanup;
         }
+
+        if (net->coalesce && !qemuDomainNetSupportsCoalesce(net->type)) {
+            virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
+                           _("coalesce settings on interface type %s are not supported"),
+                           virDomainNetTypeToString(net->type));
+            goto cleanup;
+        }
     }
 
     ret = 0;
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-net-coalesce.xml b/tests/qemuxml2argvdata/qemuxml2argv-net-coalesce.xml
new file mode 100644
index 0000000000000000000000000000000000000000..b510324427d3272522b3fa3a29a59146d9dbe2e5
--- /dev/null
+++ b/tests/qemuxml2argvdata/qemuxml2argv-net-coalesce.xml
@@ -0,0 +1,68 @@
+
+  test
+  15d091de-0181-456b-9554-e4382dc1f1ab
+  1048576
+  1048576
+  1
+  
+    hvm
+    
+    
+    
+  
+  
+  destroy
+  restart
+  restart
+  
+    /usr/bin/qemu-system-x86_64
+    
+      
+      
+      
+      
+ + + + + + +
+ + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/tests/qemuxml2xmloutdata/qemuxml2xmlout-net-coalesce.xml b/tests/qemuxml2xmloutdata/qemuxml2xmlout-net-coalesce.xml new file mode 100644 index 0000000000000000000000000000000000000000..fd5fdbece52817f31b9beb9025cfc094f487446a --- /dev/null +++ b/tests/qemuxml2xmloutdata/qemuxml2xmlout-net-coalesce.xml @@ -0,0 +1,71 @@ + + test + 15d091de-0181-456b-9554-e4382dc1f1ab + 1048576 + 1048576 + 1 + + hvm + + + + + + destroy + restart + restart + + /usr/bin/qemu-system-x86_64 + + + + +
+ + + + + + +
+ + +
+ + +
+ + +
+ + + + + + + + + + + +
+ + + + + +
+ + + + + + + + + + +
+ + + diff --git a/tests/qemuxml2xmltest.c b/tests/qemuxml2xmltest.c index e4b510fd31ee5b10a1fe65ce62b5d1d10ff40076..2dccde746ef186e1ff2d7be1787ebc5939e4bb7c 100644 --- a/tests/qemuxml2xmltest.c +++ b/tests/qemuxml2xmltest.c @@ -528,6 +528,7 @@ mymain(void) DO_TEST("net-bandwidth", NONE); DO_TEST("net-bandwidth2", NONE); DO_TEST("net-mtu", NONE); + DO_TEST("net-coalesce", NONE); DO_TEST("serial-vc", NONE); DO_TEST("serial-pty", NONE);