On 2019/8/15 11:01, Jason Wang wrote:
On 2019/8/14 上午10:06, ? jiang wrote:
This change lowers ring buffer reclaim threshold from 1/2*queue to
budget
for better performance. According to our test with qemu + dpdk, packet
dropping happens when the guest is not able to provide free buffer in
avail ring timely with default 1/2*queue. The value in the patch has
been
tested and does show better performance.
Please add your tests setup and result here.
Thanks
Signed-off-by: jiangkidd <jiangkidd@xxxxxxxxxxx>
---
drivers/net/virtio_net.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c
index 0d4115c9e20b..bc08be7925eb 100644
--- a/drivers/net/virtio_net.c
+++ b/drivers/net/virtio_net.c
@@ -1331,7 +1331,7 @@ static int virtnet_receive(struct receive_queue
*rq, int budget,
}
}
- if (rq->vq->num_free > virtqueue_get_vring_size(rq->vq) / 2) {
+ if (rq->vq->num_free > min((unsigned int)budget,
virtqueue_get_vring_size(rq->vq)) / 2) {
if (!try_fill_recv(vi, rq, GFP_ATOMIC))
schedule_delayed_work(&vi->refill, 0);
}
Sure, here are the details:
Data to prove why the patch helps:
----------------------------------------------------
We did have completed several rounds of test with setting the value to
budget (64 as the default value). It does improve a lot with pps is
below 400pps for a single stream. We are confident that it runs out
of free
buffer in avail ring when packet dropping happens with below systemtap:
Just a snippet:
probe module("virtio_ring").function("virtqueue_get_buf")
{
x = (@cast($_vq, "vring_virtqueue")->vring->used->idx)-
(@cast($_vq, "vring_virtqueue")->last_used_idx) ---> we use this one
to verify if the queue is full, which means guest is not able to take
buffer from the queue timely
if (x<0 && (x+65535)<4096)
x = x+65535
if((x==1024) && @cast($_vq, "vring_virtqueue")->vq->callback ==
callback_addr)
netrxcount[x] <<< gettimeofday_s()
}
probe module("virtio_ring").function("virtqueue_add_inbuf")
{
y = (@cast($vq, "vring_virtqueue")->vring->avail->idx)-
(@cast($vq, "vring_virtqueue")->vring->used->idx) ---> we use this one
to verify if we run out of free buffer in avail ring
if (y<0 && (y+65535)<4096)
y = y+65535
if(@2=="debugon")
{
if(y==0 && @cast($vq, "vring_virtqueue")->vq->callback ==
callback_addr)
{
netrxfreecount[y] <<< gettimeofday_s()
printf("no avail ring left seen, printing most recent 5
num free, vq: %lx, current index: %d\n", $vq, recentfreecount)
for(i=recentfreecount; i!=((recentfreecount+4) % 5);
i=((i+1) % 5))
{
printf("index: %d, num free: %d\n", i,
recentfree[$vq,
i])
}
printf("index: %d, num free: %d\n", i, recentfree[$vq,
i])
//exit()
}
}
}
probe
module("virtio_net").statement("virtnet_receive@drivers/net/virtio_net.c:732")
{
recentfreecount++
recentfreecount = recentfreecount % 5
recentfree[$rq->vq, recentfreecount] = $rq->vq->num_free --->
record the num_free for the last 5 calls to virtnet_receive, so we can
see if lowering the bar helps.
}
Here is the result:
no avail ring left seen, printing most recent 5 num free, vq:
ffff9c13c1200000, current index: 1
index: 1, num free: 561
index: 2, num free: 305
index: 3, num free: 369
index: 4, num free: 433
index: 0, num free: 497
no avail ring left seen, printing most recent 5 num free, vq:
ffff9c13c1200000, current index: 1
index: 1, num free: 543
index: 2, num free: 463
index: 3, num free: 469
index: 4, num free: 476
index: 0, num free: 479
no avail ring left seen, printing most recent 5 num free, vq:
ffff9c13c1200000, current index: 2
index: 2, num free: 555
index: 3, num free: 414
index: 4, num free: 420
index: 0, num free: 427
index: 1, num free: 491
We can see in the last 4 calls to virtnet_receive before we run out
of free buffer and start to relaim, num_free is quite high. So if we
can do the reclaim earlier, it will certainly help.
Jiang