On Tue, Oct 16, 2018 at 11:01:31AM +0200, Jens Freimann wrote: [...] > +void > +vq_ring_free_chain_packed(struct virtqueue *vq, uint16_t desc_idx) > +{ > + struct vring_desc_packed *dp; > + struct vq_desc_extra *dxp = NULL, *dxp_tail = NULL; > + uint16_t desc_idx_last = desc_idx; > + > + dp = &vq->vq_ring.desc_packed[desc_idx]; > + dxp = &vq->vq_descx[desc_idx];
In the out-of-order case, we can't assume the desc and desc_extra have the same index. > + vq->vq_free_cnt = (uint16_t)(vq->vq_free_cnt + dxp->ndescs); > + if ((dp->flags & VRING_DESC_F_INDIRECT) == 0) { > + while (dp->flags & VRING_DESC_F_NEXT) { https://github.com/oasis-tcs/virtio-spec/blob/89dd55f5e606/packed-ring.tex#L222-L226 The device only writes out a single used descriptor for the whole list. It then skips forward according to the number of descriptors in the list. The 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. IOW, we can't use the VRING_DESC_F_NEXT here. > + desc_idx_last = dxp->next; > + dp = &vq->vq_ring.desc_packed[dxp->next]; > + dxp = &vq->vq_descx[dxp->next]; > + } > + }