On Fri, Jun 09, 2017 at 06:41:41PM +0800, Wei Wang wrote: > - if (!virtqueue_indirect_desc_table_add(vq, desc, num)) { > + if (!virtqueue_indirect_desc_table_add(vq, desc, *num)) { > virtqueue_kick(vq); > - wait_event(vb->acked, virtqueue_get_buf(vq, &len)); > - vb->balloon_page_chunk.chunk_num = 0; > + if (busy_wait) > + while (!virtqueue_get_buf(vq, &len) && > + !virtqueue_is_broken(vq)) > + cpu_relax(); > + else > + wait_event(vb->acked, virtqueue_get_buf(vq, &len)); This is something I didn't previously notice. As you always keep a single buffer in flight, you do not really need indirect at all. Just add all descriptors in the ring directly, then kick. E.g. virtqueue_add_first virtqueue_add_next virtqueue_add_last ? You also want a flag to avoid allocations but there's no need to do it per descriptor, set it on vq. -- MST