diff options
author | Gerd Hoffmann <kraxel@redhat.com> | 2017-04-21 11:16:25 +0200 |
---|---|---|
committer | Gerd Hoffmann <kraxel@redhat.com> | 2017-04-24 10:12:28 +0200 |
commit | 8deaf12ca1a7c89867df739dc9056080509628bd (patch) | |
tree | f7bae444ae09a9ed1fe4374c7d91b614529bcb13 /include | |
parent | d6eb1413920affb7be3df9982682dd183a805dd7 (diff) | |
download | qemu-8deaf12ca1a7c89867df739dc9056080509628bd.zip qemu-8deaf12ca1a7c89867df739dc9056080509628bd.tar.gz qemu-8deaf12ca1a7c89867df739dc9056080509628bd.tar.bz2 |
memory: add support getting and using a dirty bitmap copy.
This patch adds support for getting and using a local copy of the dirty
bitmap.
memory_region_snapshot_and_clear_dirty() will create a snapshot of the
dirty bitmap for the specified range, clear the dirty bitmap and return
the copy. The returned bitmap can be a bit larger than requested, the
range is expanded so the code can copy unsigned longs from the bitmap
and avoid atomic bit update operations.
memory_region_snapshot_get_dirty() will return the dirty status of
pages, pretty much like memory_region_get_dirty(), but using the copy
returned by memory_region_copy_and_clear_dirty().
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
Message-id: 20170421091632.30900-3-kraxel@redhat.com
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
Diffstat (limited to 'include')
-rw-r--r-- | include/exec/memory.h | 47 | ||||
-rw-r--r-- | include/exec/ram_addr.h | 7 | ||||
-rw-r--r-- | include/qemu/typedefs.h | 1 |
3 files changed, 55 insertions, 0 deletions
diff --git a/include/exec/memory.h b/include/exec/memory.h index c4fc94d..99e0f54 100644 --- a/include/exec/memory.h +++ b/include/exec/memory.h @@ -918,6 +918,53 @@ void memory_region_set_dirty(MemoryRegion *mr, hwaddr addr, */ bool memory_region_test_and_clear_dirty(MemoryRegion *mr, hwaddr addr, hwaddr size, unsigned client); + +/** + * memory_region_snapshot_and_clear_dirty: Get a snapshot of the dirty + * bitmap and clear it. + * + * Creates a snapshot of the dirty bitmap, clears the dirty bitmap and + * returns the snapshot. The snapshot can then be used to query dirty + * status, using memory_region_snapshot_get_dirty. Unlike + * memory_region_test_and_clear_dirty this allows to query the same + * page multiple times, which is especially useful for display updates + * where the scanlines often are not page aligned. + * + * The dirty bitmap region which gets copyed into the snapshot (and + * cleared afterwards) can be larger than requested. The boundaries + * are rounded up/down so complete bitmap longs (covering 64 pages on + * 64bit hosts) can be copied over into the bitmap snapshot. Which + * isn't a problem for display updates as the extra pages are outside + * the visible area, and in case the visible area changes a full + * display redraw is due anyway. Should other use cases for this + * function emerge we might have to revisit this implementation + * detail. + * + * Use g_free to release DirtyBitmapSnapshot. + * + * @mr: the memory region being queried. + * @addr: the address (relative to the start of the region) being queried. + * @size: the size of the range being queried. + * @client: the user of the logging information; typically %DIRTY_MEMORY_VGA. + */ +DirtyBitmapSnapshot *memory_region_snapshot_and_clear_dirty(MemoryRegion *mr, + hwaddr addr, + hwaddr size, + unsigned client); + +/** + * memory_region_snapshot_get_dirty: Check whether a range of bytes is dirty + * in the specified dirty bitmap snapshot. + * + * @mr: the memory region being queried. + * @snap: the dirty bitmap snapshot + * @addr: the address (relative to the start of the region) being queried. + * @size: the size of the range being queried. + */ +bool memory_region_snapshot_get_dirty(MemoryRegion *mr, + DirtyBitmapSnapshot *snap, + hwaddr addr, hwaddr size); + /** * memory_region_sync_dirty_bitmap: Synchronize a region's dirty bitmap with * any external TLBs (e.g. kvm) diff --git a/include/exec/ram_addr.h b/include/exec/ram_addr.h index c9ddcd0..6436a41 100644 --- a/include/exec/ram_addr.h +++ b/include/exec/ram_addr.h @@ -343,6 +343,13 @@ bool cpu_physical_memory_test_and_clear_dirty(ram_addr_t start, ram_addr_t length, unsigned client); +DirtyBitmapSnapshot *cpu_physical_memory_snapshot_and_clear_dirty + (ram_addr_t start, ram_addr_t length, unsigned client); + +bool cpu_physical_memory_snapshot_get_dirty(DirtyBitmapSnapshot *snap, + ram_addr_t start, + ram_addr_t length); + static inline void cpu_physical_memory_clear_dirty_range(ram_addr_t start, ram_addr_t length) { diff --git a/include/qemu/typedefs.h b/include/qemu/typedefs.h index e95f28c..f08d327 100644 --- a/include/qemu/typedefs.h +++ b/include/qemu/typedefs.h @@ -23,6 +23,7 @@ typedef struct CPUAddressSpace CPUAddressSpace; typedef struct CPUState CPUState; typedef struct DeviceListener DeviceListener; typedef struct DeviceState DeviceState; +typedef struct DirtyBitmapSnapshot DirtyBitmapSnapshot; typedef struct DisplayChangeListener DisplayChangeListener; typedef struct DisplayState DisplayState; typedef struct DisplaySurface DisplaySurface; |