On 21/12/2016 17:19, Fam Zheng wrote: > It's clever! It'd be a bit more complicated than that, though. Things like > queues etc in block/nvme.c have to be preserved, and if we already ensure > that, > ram blocks can be preserved similarly, but indeed bounce buffers can be > handled > that way. I still need to think about how to make sure none of the invalidated > IOVA addresses are in use by other requests.
Hmm, that's true. As you said, we'll probably want to split the IOVA space in two, with a relatively small part for "volatile" addresses. You can add two counters that track how many requests are using volatile space. When it's time to do the VFIO_IOMMU_UNMAP_DMA, you do something like: if (vfio->next_phase == vfio->current_phase) { vfio->next_phase = !vfio->current_phase; while (vfio->request_counter[vfio->current_phase] != 0) { wait on CoQueue } ioctl(VFIO_IOMMU_UNMAP_DMA) vfio->current_phase = vfio->next_phase; wake up everyone on CoQueue } else { /* wait for the unmap to happen */ while (vfio->next_phase != vfio->current_phase) { wait on CoQueue } } As an optimization, incrementing/decrementing request_counter can be delayed until you find an item of the QEMUIOVector that needs a volatile IOVA. Then it should never be incremented in practice during guest execution. Paolo > Also I wonder how expensive the huge VFIO_IOMMU_UNMAP_DMA is. In the worst > case > the "throwaway" IOVAs can be limited to a small range.