Commit fc5b81d1f6df7342f0963120b2cf3e919d6fc08a

Authored by Mark McLoughlin
Committed by Anthony Liguori
1 parent df7a607b

net: set a default value for sndbuf=

On reflection, perhaps it does make sense to set a default value for
the sndbuf= tap parameter.

For best effect, sndbuf= should be set to just below the capacity of
the physical NIC.

Setting it higher will cause packets to be dropped before the limit
is hit. Setting it much lower will not cause any problems unless
you set it low enough such that the guest cannot queue up new packets
before the NIC has emptied its queue.

In Linux, txqueuelen=1000 by default for ethernet NICs. Given a 1500
byte MTU, 1Mb is a good choice for sndbuf.

If it turns out that txqueuelen is actually much lower than this, then
sndbuf is essentially disabled. In the event that txqueuelen is much
higher, it's unlikely that the NIC will be able to empty a 1Mb queue.

Thanks to Herbert Xu for this logic.

Signed-off-by: Mark McLoughlin <markmc@redhat.com>
Cc: Herbert Xu <herbert.xu@redhat.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
Showing 2 changed files with 31 additions and 6 deletions
@@ -1396,17 +1396,39 @@ static void tap_send(void *opaque) @@ -1396,17 +1396,39 @@ static void tap_send(void *opaque)
1396 } while (size > 0); 1396 } while (size > 0);
1397 } 1397 }
1398 1398
1399 -static void tap_set_sndbuf(TAPState *s, int sndbuf, Monitor *mon)  
1400 -{  
1401 #ifdef TUNSETSNDBUF 1399 #ifdef TUNSETSNDBUF
  1400 +/* sndbuf should be set to a value lower than the tx queue
  1401 + * capacity of any destination network interface.
  1402 + * Ethernet NICs generally have txqueuelen=1000, so 1Mb is
  1403 + * a good default, given a 1500 byte MTU.
  1404 + */
  1405 +#define TAP_DEFAULT_SNDBUF 1024*1024
  1406 +
  1407 +static void tap_set_sndbuf(TAPState *s, const char *sndbuf_str, Monitor *mon)
  1408 +{
  1409 + int sndbuf = TAP_DEFAULT_SNDBUF;
  1410 +
  1411 + if (sndbuf_str) {
  1412 + sndbuf = atoi(sndbuf_str);
  1413 + }
  1414 +
  1415 + if (!sndbuf) {
  1416 + sndbuf = INT_MAX;
  1417 + }
  1418 +
1402 if (ioctl(s->fd, TUNSETSNDBUF, &sndbuf) == -1) { 1419 if (ioctl(s->fd, TUNSETSNDBUF, &sndbuf) == -1) {
1403 config_error(mon, "TUNSETSNDBUF ioctl failed: %s\n", 1420 config_error(mon, "TUNSETSNDBUF ioctl failed: %s\n",
1404 strerror(errno)); 1421 strerror(errno));
1405 } 1422 }
  1423 +}
1406 #else 1424 #else
1407 - config_error(mon, "No '-net tap,sndbuf=<nbytes>' support available\n");  
1408 -#endif 1425 +static void tap_set_sndbuf(TAPState *s, const char *sndbuf_str, Monitor *mon)
  1426 +{
  1427 + if (sndbuf_str) {
  1428 + config_error(mon, "No '-net tap,sndbuf=<nbytes>' support available\n");
  1429 + }
1409 } 1430 }
  1431 +#endif /* TUNSETSNDBUF */
1410 1432
1411 static void tap_cleanup(VLANClientState *vc) 1433 static void tap_cleanup(VLANClientState *vc)
1412 { 1434 {
@@ -2654,9 +2676,11 @@ int net_client_init(Monitor *mon, const char *device, const char *p) @@ -2654,9 +2676,11 @@ int net_client_init(Monitor *mon, const char *device, const char *p)
2654 s = net_tap_init(vlan, device, name, ifname, setup_script, down_script); 2676 s = net_tap_init(vlan, device, name, ifname, setup_script, down_script);
2655 } 2677 }
2656 if (s != NULL) { 2678 if (s != NULL) {
  2679 + const char *sndbuf_str = NULL;
2657 if (get_param_value(buf, sizeof(buf), "sndbuf", p)) { 2680 if (get_param_value(buf, sizeof(buf), "sndbuf", p)) {
2658 - tap_set_sndbuf(s, atoi(buf), mon); 2681 + sndbuf_str = buf;
2659 } 2682 }
  2683 + tap_set_sndbuf(s, sndbuf_str, mon);
2660 ret = 0; 2684 ret = 0;
2661 } else { 2685 } else {
2662 ret = -1; 2686 ret = -1;
qemu-options.hx
@@ -778,7 +778,8 @@ DEF(&quot;net&quot;, HAS_ARG, QEMU_OPTION_net, @@ -778,7 +778,8 @@ DEF(&quot;net&quot;, HAS_ARG, QEMU_OPTION_net,
778 " use '[down]script=no' to disable script execution;\n" 778 " use '[down]script=no' to disable script execution;\n"
779 " use 'fd=h' to connect to an already opened TAP interface\n" 779 " use 'fd=h' to connect to an already opened TAP interface\n"
780 #ifdef TUNSETSNDBUF 780 #ifdef TUNSETSNDBUF
781 - " use 'sndbuf=nbytes' to limit the size of the send buffer\n" 781 + " use 'sndbuf=nbytes' to limit the size of the send buffer; the\n"
  782 + " default of 'sndbuf=1048576' can be disabled using 'sndbuf=0'\n"
782 #endif 783 #endif
783 #endif 784 #endif
784 "-net socket[,vlan=n][,name=str][,fd=h][,listen=[host]:port][,connect=host:port]\n" 785 "-net socket[,vlan=n][,name=str][,fd=h][,listen=[host]:port][,connect=host:port]\n"