Re: [RFC v3 3/5] virtio_ring: add packed ring support

From: Jason Wang
Date: Thu May 10 2018 - 05:49:40 EST




On 2018å05æ10æ 16:56, Tiwei Bie wrote:
On Thu, May 10, 2018 at 03:34:50PM +0800, Jason Wang wrote:
On 2018å05æ10æ 15:32, Jason Wang wrote:
On 2018å04æ25æ 13:15, Tiwei Bie wrote:
+ÂÂÂ /* We're using some buffers from the free list. */
+ÂÂÂ vq->vq.num_free -= descs_used;
+
+ÂÂÂ /* Update free pointer */
+ÂÂÂ if (indirect) {
+ÂÂÂÂÂÂÂ n = head + 1;
+ÂÂÂÂÂÂÂ if (n >= vq->vring_packed.num) {
+ÂÂÂÂÂÂÂÂÂÂÂ n = 0;
+ÂÂÂÂÂÂÂÂÂÂÂ vq->wrap_counter ^= 1;
+ÂÂÂÂÂÂÂ }
+ÂÂÂÂÂÂÂ vq->next_avail_idx = n;
+ÂÂÂ } else
+ÂÂÂÂÂÂÂ vq->next_avail_idx = i;
During testing zerocopy (out of order completion), I found driver may
submit two identical buffer id to vhost. So the above code may not work
well.

Consider the case that driver adds 3 buffer and virtqueue size is 8.

a) id = 0,count = 2,next_avail = 2

b) id = 2,count = 4,next_avail = 2
next_avail should be 6 here.

c) id = 4,count = 2,next_avail = 0

id should be 6 here.

Thanks

if packet b is done before packet a, driver may think buffer id 0 is
available and try to use it if even if the real buffer 0 was not done.

Thanks
Nice catch! Thanks a lot!
I'll implement an ID allocator.

Best regards,
Tiwei Bie

Sounds good.

Another similar issue is detac_buf_packed(). It did:

ÂÂÂÂÂÂÂ for (j = 0; j < vq->desc_state[head].num; j++) {
ÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂ desc = &vq->vring_packed.desc[i];
ÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂ vring_unmap_one_packed(vq, desc);
ÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂ i++;
ÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂ if (i >= vq->vring_packed.num)
ÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂ i = 0;
ÂÂÂÂÂÂÂ }

This probably won't work for out of order too and according to the spec:

"""
Driver needs to keep track of the size of the list corresponding to each
buffer ID, to be able to skip to where the next used descriptor is written by the device.
"""

Looks like we should not depend on the descriptor ring.

Thanks