1 #ifndef RAMLIST_H 2 #define RAMLIST_H 3 4 #include "qemu/queue.h" 5 #include "qemu/thread.h" 6 #include "qemu/rcu.h" 7 #include "qemu/rcu_queue.h" 8 9 typedef struct RAMBlockNotifier RAMBlockNotifier; 10 11 #define DIRTY_MEMORY_VGA 0 12 #define DIRTY_MEMORY_CODE 1 13 #define DIRTY_MEMORY_MIGRATION 2 14 #define DIRTY_MEMORY_NUM 3 /* num of dirty bits */ 15 16 /* The dirty memory bitmap is split into fixed-size blocks to allow growth 17 * under RCU. The bitmap for a block can be accessed as follows: 18 * 19 * rcu_read_lock(); 20 * 21 * DirtyMemoryBlocks *blocks = 22 * qatomic_rcu_read(&ram_list.dirty_memory[DIRTY_MEMORY_MIGRATION]); 23 * 24 * ram_addr_t idx = (addr >> TARGET_PAGE_BITS) / DIRTY_MEMORY_BLOCK_SIZE; 25 * unsigned long *block = blocks.blocks[idx]; 26 * ...access block bitmap... 27 * 28 * rcu_read_unlock(); 29 * 30 * Remember to check for the end of the block when accessing a range of 31 * addresses. Move on to the next block if you reach the end. 32 * 33 * Organization into blocks allows dirty memory to grow (but not shrink) under 34 * RCU. When adding new RAMBlocks requires the dirty memory to grow, a new 35 * DirtyMemoryBlocks array is allocated with pointers to existing blocks kept 36 * the same. Other threads can safely access existing blocks while dirty 37 * memory is being grown. When no threads are using the old DirtyMemoryBlocks 38 * anymore it is freed by RCU (but the underlying blocks stay because they are 39 * pointed to from the new DirtyMemoryBlocks). 40 */ 41 #define DIRTY_MEMORY_BLOCK_SIZE ((ram_addr_t)256 * 1024 * 8) 42 typedef struct { 43 struct rcu_head rcu; 44 unsigned long *blocks[]; 45 } DirtyMemoryBlocks; 46 47 typedef struct RAMList { 48 QemuMutex mutex; 49 RAMBlock *mru_block; 50 /* RCU-enabled, writes protected by the ramlist lock. */ 51 QLIST_HEAD(, RAMBlock) blocks; 52 DirtyMemoryBlocks *dirty_memory[DIRTY_MEMORY_NUM]; 53 unsigned int num_dirty_blocks; 54 uint32_t version; 55 QLIST_HEAD(, RAMBlockNotifier) ramblock_notifiers; 56 } RAMList; 57 extern RAMList ram_list; 58 59 /* Should be holding either ram_list.mutex, or the RCU lock. */ 60 #define INTERNAL_RAMBLOCK_FOREACH(block) \ 61 QLIST_FOREACH_RCU(block, &ram_list.blocks, next) 62 /* Never use the INTERNAL_ version except for defining other macros */ 63 #define RAMBLOCK_FOREACH(block) INTERNAL_RAMBLOCK_FOREACH(block) 64 65 void qemu_mutex_lock_ramlist(void); 66 void qemu_mutex_unlock_ramlist(void); 67 68 struct RAMBlockNotifier { 69 void (*ram_block_added)(RAMBlockNotifier *n, void *host, size_t size, 70 size_t max_size); 71 void (*ram_block_removed)(RAMBlockNotifier *n, void *host, size_t size, 72 size_t max_size); 73 void (*ram_block_resized)(RAMBlockNotifier *n, void *host, size_t old_size, 74 size_t new_size); 75 QLIST_ENTRY(RAMBlockNotifier) next; 76 }; 77 78 void ram_block_notifier_add(RAMBlockNotifier *n); 79 void ram_block_notifier_remove(RAMBlockNotifier *n); 80 void ram_block_notify_add(void *host, size_t size, size_t max_size); 81 void ram_block_notify_remove(void *host, size_t size, size_t max_size); 82 void ram_block_notify_resize(void *host, size_t old_size, size_t new_size); 83 84 GString *ram_block_format(void); 85 86 #endif /* RAMLIST_H */ 87