diff options
author | John Levon <john.levon@nutanix.com> | 2022-05-30 09:41:32 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-05-30 09:41:32 +0100 |
commit | e036ac145acea1a5aa77879e978ac2fff909a657 (patch) | |
tree | 1f0837b4c79feb97aa642d4e505e3d64012896d7 /lib/libvfio-user.c | |
parent | 79e83e482d4eb0b7a07cfa207506d33edf05d04b (diff) | |
download | libvfio-user-e036ac145acea1a5aa77879e978ac2fff909a657.zip libvfio-user-e036ac145acea1a5aa77879e978ac2fff909a657.tar.gz libvfio-user-e036ac145acea1a5aa77879e978ac2fff909a657.tar.bz2 |
allow concurrent dirty bitmap get (#677)
Use atomic operations to allow concurrent bitmap updates with
VFIO_IOMMU_DIRTY_PAGES_FLAG_GET_BITMAP operations.
Dirtying clients can race against each other, so we must use atomic or
when marking dirty: we do this byte-by-byte.
When reading the dirty bitmap, we must be careful to not race and lose
any set bits within the same byte. If we miss an update, we'll catch it
the next time around, presuming that before the final pass we'll have
quiesced all I/O.
Signed-off-by: John Levon <john.levon@nutanix.com>
Reviewed-by: Raphael Norwitz <raphael.norwitz@nutanix.com>
Reviewed-by: Thanos Makatos <thanos.makatos@nutanix.com>
Diffstat (limited to 'lib/libvfio-user.c')
-rw-r--r-- | lib/libvfio-user.c | 11 |
1 files changed, 9 insertions, 2 deletions
diff --git a/lib/libvfio-user.c b/lib/libvfio-user.c index 90c4b39..566ece0 100644 --- a/lib/libvfio-user.c +++ b/lib/libvfio-user.c @@ -1310,8 +1310,15 @@ command_needs_quiesce(vfu_ctx_t *vfu_ctx, const vfu_msg_t *msg) case VFIO_USER_DEVICE_RESET: return true; - case VFIO_USER_DIRTY_PAGES: - return true; + case VFIO_USER_DIRTY_PAGES: { + struct vfio_user_dirty_pages *dirty_pages = msg->in.iov.iov_base; + + if (msg->in.iov.iov_len < sizeof(*dirty_pages)) { + return false; + } + + return !(dirty_pages->flags & VFIO_IOMMU_DIRTY_PAGES_FLAG_GET_BITMAP); + } case VFIO_USER_REGION_WRITE: if (msg->in.iov.iov_len < sizeof(*reg)) { |