diff options
author | Jason Wang <jasowang@redhat.com> | 2013-09-02 04:40:57 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2013-09-03 22:46:57 -0400 |
commit | c92112aed3f0b14fdd2dbd9f192cce1af22c0e1c (patch) | |
tree | ee7b35d59a5ab61b295e33087862b381481ed292 /drivers/vhost | |
parent | 094afe7d556428a2ce2df0f6a4b333f7ba4d74d5 (diff) |
vhost_net: use vhost_add_used_and_signal_n() in vhost_zerocopy_signal_used()
We tend to batch the used adding and signaling in vhost_zerocopy_callback()
which may result more than 100 used buffers to be updated in
vhost_zerocopy_signal_used() in some cases. So switch to use
vhost_add_used_and_signal_n() to avoid multiple calls to
vhost_add_used_and_signal(). Which means much less times of used index
updating and memory barriers.
2% performance improvement were seen on netperf TCP_RR test.
Signed-off-by: Jason Wang <jasowang@redhat.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/vhost')
-rw-r--r-- | drivers/vhost/net.c | 13 |
1 files changed, 8 insertions, 5 deletions
diff --git a/drivers/vhost/net.c b/drivers/vhost/net.c index 280ee66ae552..8a6dd0d5667c 100644 --- a/drivers/vhost/net.c +++ b/drivers/vhost/net.c | |||
@@ -281,7 +281,7 @@ static void vhost_zerocopy_signal_used(struct vhost_net *net, | |||
281 | { | 281 | { |
282 | struct vhost_net_virtqueue *nvq = | 282 | struct vhost_net_virtqueue *nvq = |
283 | container_of(vq, struct vhost_net_virtqueue, vq); | 283 | container_of(vq, struct vhost_net_virtqueue, vq); |
284 | int i; | 284 | int i, add; |
285 | int j = 0; | 285 | int j = 0; |
286 | 286 | ||
287 | for (i = nvq->done_idx; i != nvq->upend_idx; i = (i + 1) % UIO_MAXIOV) { | 287 | for (i = nvq->done_idx; i != nvq->upend_idx; i = (i + 1) % UIO_MAXIOV) { |
@@ -289,14 +289,17 @@ static void vhost_zerocopy_signal_used(struct vhost_net *net, | |||
289 | vhost_net_tx_err(net); | 289 | vhost_net_tx_err(net); |
290 | if (VHOST_DMA_IS_DONE(vq->heads[i].len)) { | 290 | if (VHOST_DMA_IS_DONE(vq->heads[i].len)) { |
291 | vq->heads[i].len = VHOST_DMA_CLEAR_LEN; | 291 | vq->heads[i].len = VHOST_DMA_CLEAR_LEN; |
292 | vhost_add_used_and_signal(vq->dev, vq, | ||
293 | vq->heads[i].id, 0); | ||
294 | ++j; | 292 | ++j; |
295 | } else | 293 | } else |
296 | break; | 294 | break; |
297 | } | 295 | } |
298 | if (j) | 296 | while (j) { |
299 | nvq->done_idx = i; | 297 | add = min(UIO_MAXIOV - nvq->done_idx, j); |
298 | vhost_add_used_and_signal_n(vq->dev, vq, | ||
299 | &vq->heads[nvq->done_idx], add); | ||
300 | nvq->done_idx = (nvq->done_idx + add) % UIO_MAXIOV; | ||
301 | j -= add; | ||
302 | } | ||
300 | } | 303 | } |
301 | 304 | ||
302 | static void vhost_zerocopy_callback(struct ubuf_info *ubuf, bool success) | 305 | static void vhost_zerocopy_callback(struct ubuf_info *ubuf, bool success) |