Commit 440a2294 authored by Paolo Abeni's avatar Paolo Abeni Committed by Khalid Elmously

vhost_net: use packet weight for rx handler, too

Similar to commit a2ac9990 ("vhost-net: set packet weight of
tx polling to 2 * vq size"), we need a packet-based limit for
handler_rx, too - elsewhere, under rx flood with small packets,
tx can be delayed for a very long time, even without busypolling.

The pkt limit applied to handle_rx must be the same applied by
handle_tx, or we will get unfair scheduling between rx and tx.
Tying such limit to the queue length makes it less effective for
large queue length values and can introduce large process
scheduler latencies, so a constant valued is used - likewise
the existing bytes limit.

The selected limit has been validated with PVP[1] performance
test with different queue sizes:

queue size		256	512	1024

baseline		366	354	362
weight 128		715	723	670
weight 256		740	745	733
weight 512		600	460	583
weight 1024		423	427	418

A packet weight of 256 gives peek performances in under all the
tested scenarios.

No measurable regression in unidirectional performance tests has
been detected.

[1] https://developers.redhat.com/blog/2017/06/05/measuring-and-comparing-open-vswitch-performance/Signed-off-by: default avatarPaolo Abeni <pabeni@redhat.com>
Acked-by: default avatarJason Wang <jasowang@redhat.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>

CVE-2019-3900

(backported from commit db688c24)
[tyhicks: Backport to Xenial:
 - Context adjustment in call to mutex_lock_nested() in hunk #3 due to missing
   and unneeded commit aaa3149b ("vhost_net: add missing lock nesting
   notation")
 - Context adjustment in call to vhost_log_write() in hunk #4 due to missing
   and unneeded commit cc5e7107 ("vhost: log dirty page correctly")
 - Context adjustment in hunk #4 due to using break instead of goto out]
Signed-off-by: default avatarTyler Hicks <tyhicks@canonical.com>
Acked-by: default avatarStefan Bader <stefan.bader@canonical.com>
Acked-by: default avatarConnor Kuehl <connor.kuehl@canonical.com>
Signed-off-by: default avatarKhalid Elmously <khalid.elmously@canonical.com>
parent 054d27bf
...@@ -40,8 +40,10 @@ MODULE_PARM_DESC(experimental_zcopytx, "Enable Zero Copy TX;" ...@@ -40,8 +40,10 @@ MODULE_PARM_DESC(experimental_zcopytx, "Enable Zero Copy TX;"
#define VHOST_NET_WEIGHT 0x80000 #define VHOST_NET_WEIGHT 0x80000
/* Max number of packets transferred before requeueing the job. /* Max number of packets transferred before requeueing the job.
* Using this limit prevents one virtqueue from starving rx. */ * Using this limit prevents one virtqueue from starving others with small
#define VHOST_NET_PKT_WEIGHT(vq) ((vq)->num * 2) * pkts.
*/
#define VHOST_NET_PKT_WEIGHT 256
/* MAX number of TX used buffers for outstanding zerocopy */ /* MAX number of TX used buffers for outstanding zerocopy */
#define VHOST_MAX_PEND 128 #define VHOST_MAX_PEND 128
...@@ -425,7 +427,7 @@ static void handle_tx(struct vhost_net *net) ...@@ -425,7 +427,7 @@ static void handle_tx(struct vhost_net *net)
vhost_zerocopy_signal_used(net, vq); vhost_zerocopy_signal_used(net, vq);
vhost_net_tx_packet(net); vhost_net_tx_packet(net);
if (unlikely(total_len >= VHOST_NET_WEIGHT) || if (unlikely(total_len >= VHOST_NET_WEIGHT) ||
unlikely(++sent_pkts >= VHOST_NET_PKT_WEIGHT(vq))) { unlikely(++sent_pkts >= VHOST_NET_PKT_WEIGHT)) {
vhost_poll_queue(&vq->poll); vhost_poll_queue(&vq->poll);
break; break;
} }
...@@ -556,6 +558,7 @@ static void handle_rx(struct vhost_net *net) ...@@ -556,6 +558,7 @@ static void handle_rx(struct vhost_net *net)
struct socket *sock; struct socket *sock;
struct iov_iter fixup; struct iov_iter fixup;
__virtio16 num_buffers; __virtio16 num_buffers;
int recv_pkts = 0;
mutex_lock(&vq->mutex); mutex_lock(&vq->mutex);
sock = vq->private_data; sock = vq->private_data;
...@@ -648,7 +651,8 @@ static void handle_rx(struct vhost_net *net) ...@@ -648,7 +651,8 @@ static void handle_rx(struct vhost_net *net)
if (unlikely(vq_log)) if (unlikely(vq_log))
vhost_log_write(vq, vq_log, log, vhost_len); vhost_log_write(vq, vq_log, log, vhost_len);
total_len += vhost_len; total_len += vhost_len;
if (unlikely(total_len >= VHOST_NET_WEIGHT)) { if (unlikely(total_len >= VHOST_NET_WEIGHT) ||
unlikely(++recv_pkts >= VHOST_NET_PKT_WEIGHT)) {
vhost_poll_queue(&vq->poll); vhost_poll_queue(&vq->poll);
break; break;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment