aboutsummaryrefslogtreecommitdiff
path: root/lib/libvfio-user.c
diff options
context:
space:
mode:
authorJohn Levon <john.levon@nutanix.com>2022-05-30 09:41:32 +0100
committerGitHub <noreply@github.com>2022-05-30 09:41:32 +0100
commite036ac145acea1a5aa77879e978ac2fff909a657 (patch)
tree1f0837b4c79feb97aa642d4e505e3d64012896d7 /lib/libvfio-user.c
parent79e83e482d4eb0b7a07cfa207506d33edf05d04b (diff)
downloadlibvfio-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.c11
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)) {