ram_blocks: Convert to a QLIST
PATCH v2 1/1 ram_blocks: Convert to a QLIST
This makes the RAM block list easier to manipulate. Also incorporate relevant variables into the RAMList struct.
Signed-off-by Alex Williamson <[email protected]>
Acked-by Chris Wright <[email protected]>
---
v2: For qemu.git this time
arch_init.c | 14 +++++------ cpu-all.h | 28 +++++++++++++++------ exec.c | 78 ++++++++++++++++++++--------------------------------------- 3 files changed, 54 insertions(+), 66 deletions(-)
arch_init.c +7 -7
@@ -110,7 +110,7 @@ static int ram_save_block(QEMUFile *f)ram_addr_t addr =0 ;int bytes_sent =0 ; -while (addr < last_ram_offset) { +while (addr < ram_list.last_offset) {if (cpu_physical_memory_get_dirty (current_addr,MIGRATION_DIRTY_FLAG )) {uint8_t *p;
@@ -133,7 +133,7 @@ static int ram_save_block(QEMUFile *f)break ; } addr +=TARGET_PAGE_SIZE ; - current_addr = (saved_addr + addr) % last_ram_offset; + current_addr = (saved_addr + addr) % ram_list.last_offset; }return bytes_sent;
@@ -146,7 +146,7 @@ static ram_addr_t ram_save_remaining(void)ram_addr_t addr;ram_addr_t count =0 ; -for (addr =0 ; addr < last_ram_offset; addr +=TARGET_PAGE_SIZE ) { +for (addr =0 ; addr < ram_list.last_offset; addr +=TARGET_PAGE_SIZE ) {if (cpu_physical_memory_get_dirty (addr,MIGRATION_DIRTY_FLAG )) { count++; }
@@ -167,7 +167,7 @@ uint64_t ram_bytes_transferred(void)uint64_t ram_bytes_total (void ) { -return last_ram_offset; +return ram_list.last_offset; }int ram_save_live (Monitor *mon,QEMUFile *f,int stage,void *opaque)
@@ -191,7 +191,7 @@ int ram_save_live(Monitor *mon, QEMUFile *f, int stage, void *opaque) bytes_transferred =0 ;/* Make sure all dirty bits are set */ -for (addr =0 ; addr < last_ram_offset; addr +=TARGET_PAGE_SIZE ) { +for (addr =0 ; addr < ram_list.last_offset; addr +=TARGET_PAGE_SIZE ) {if (!cpu_physical_memory_get_dirty (addr,MIGRATION_DIRTY_FLAG )) {cpu_physical_memory_set_dirty (addr); }
@@ -200,7 +200,7 @@ int ram_save_live(Monitor *mon, QEMUFile *f, int stage, void *opaque)/* Enable dirty memory tracking */ cpu_physical_memory_set_dirty_tracking (1 ); -qemu_put_be64 (f, last_ram_offset |RAM_SAVE_FLAG_MEM_SIZE ); +qemu_put_be64 (f, ram_list.last_offset |RAM_SAVE_FLAG_MEM_SIZE ); } bytes_transferred_last = bytes_transferred;
@@ -259,7 +259,7 @@ int ram_load(QEMUFile *f, void *opaque, int version_id) addr &=TARGET_PAGE_MASK ;if (flags &RAM_SAVE_FLAG_MEM_SIZE ) { -if (addr != last_ram_offset) { +if (addr != ram_list.last_offset) {return -EINVAL ; } }
cpu-all.h +20 -8
@@ -859,9 +859,21 @@ target_phys_addr_t cpu_get_phys_page_debug(CPUState *env, target_ulong addr);/* memory API */ extern int phys_ram_fd; -extern uint8_t *phys_ram_dirty;extern ram_addr_t ram_size; -extern ram_addr_t last_ram_offset; + +typedef struct RAMBlock { +uint8_t *host; +ram_addr_t offset; +ram_addr_t length; +QLIST_ENTRY (RAMBlock) next; +}RAMBlock ; + +typedef struct RAMList { +uint8_t *phys_dirty; +ram_addr_t last_offset; + QLIST_HEAD(ram, RAMBlock) blocks; +}RAMList ; +extern RAMList ram_list;extern const char *mem_path;extern int mem_prealloc;
@@ -891,29 +903,29 @@ extern int mem_prealloc;/* read dirty bit (return 0 or 1) */ static inline int cpu_physical_memory_is_dirty (ram_addr_t addr) { -return phys_ram_dirty[addr >>TARGET_PAGE_BITS ] ==0xff ; +return ram_list.phys_dirty[addr >>TARGET_PAGE_BITS ] ==0xff ; }static inline int cpu_physical_memory_get_dirty_flags (ram_addr_t addr) { -return phys_ram_dirty[addr >>TARGET_PAGE_BITS ]; +return ram_list.phys_dirty[addr >>TARGET_PAGE_BITS ]; }static inline int cpu_physical_memory_get_dirty (ram_addr_t addr,int dirty_flags) { -return phys_ram_dirty[addr >>TARGET_PAGE_BITS ] & dirty_flags; +return ram_list.phys_dirty[addr >>TARGET_PAGE_BITS ] & dirty_flags; }static inline void cpu_physical_memory_set_dirty (ram_addr_t addr) { - phys_ram_dirty[addr >>TARGET_PAGE_BITS ] =0xff ; + ram_list.phys_dirty[addr >>TARGET_PAGE_BITS ] =0xff ; }static inline int cpu_physical_memory_set_dirty_flags (ram_addr_t addr,int dirty_flags) { -return phys_ram_dirty[addr >>TARGET_PAGE_BITS ] |= dirty_flags; +return ram_list.phys_dirty[addr >>TARGET_PAGE_BITS ] |= dirty_flags; } static inline void cpu_physical_memory_mask_dirty_range(ram_addr_t start,
@@ -925,7 +937,7 @@ static inline void cpu_physical_memory_mask_dirty_range(ram_addr_t start, len = length >>TARGET_PAGE_BITS ; mask = ~dirty_flags; - p = phys_ram_dirty + (start >>TARGET_PAGE_BITS ); + p = ram_list.phys_dirty + (start >>TARGET_PAGE_BITS );for (i =0 ; i < len; i++) { p[i] &= mask; }
exec.c +27 -51
113 lines not on this page · raw message
Anthony Liguori
AppliedQuoted 6 lines · Alex Williamson
This makes the RAM block list easier to manipulate. Also incorporate relevant variables into the RAMList struct.
Signed-off-by Alex Williamson<[email protected]>Acked-by Chris Wright<[email protected]>
Applied. Thanks.
Regards,
Anthony Liguori
Quoted 273 lines
---
v2: For qemu.git this time
arch_init.c | 14 +++++------ cpu-all.h | 28 +++++++++++++++------ exec.c | 78 ++++++++++++++++++++--------------------------------------- 3 files changed, 54 insertions(+), 66 deletions(-)arch_init.c +7
-7@@ -110,7 +110,7 @@ static int ram_save_block(QEMUFile *f)ram_addr_t addr =0 ;int bytes_sent =0 ; -while (addr< last_ram_offset) { +while (addr< ram_list.last_offset) {if (cpu_physical_memory_get_dirty (current_addr,MIGRATION_DIRTY_FLAG )) {uint8_t *p;@@ -133,7 +133,7 @@ static int ram_save_block(QEMUFile *f)break ; } addr +=TARGET_PAGE_SIZE ; - current_addr = (saved_addr + addr) % last_ram_offset; + current_addr = (saved_addr + addr) % ram_list.last_offset; }return bytes_sent;@@ -146,7 +146,7 @@ static ram_addr_t ram_save_remaining(void)ram_addr_t addr;ram_addr_t count =0 ; -for (addr =0 ; addr< last_ram_offset; addr +=TARGET_PAGE_SIZE ) { +for (addr =0 ; addr< ram_list.last_offset; addr +=TARGET_PAGE_SIZE ) {if (cpu_physical_memory_get_dirty (addr,MIGRATION_DIRTY_FLAG )) { count++; }@@ -167,7 +167,7 @@ uint64_t ram_bytes_transferred(void)uint64_t ram_bytes_total (void ) { -return last_ram_offset; +return ram_list.last_offset; }int ram_save_live (Monitor *mon,QEMUFile *f,int stage,void *opaque)@@ -191,7 +191,7 @@ int ram_save_live(Monitor *mon, QEMUFile *f, int stage, void *opaque) bytes_transferred =0 ;/* Make sure all dirty bits are set */ -for (addr =0 ; addr< last_ram_offset; addr +=TARGET_PAGE_SIZE ) { +for (addr =0 ; addr< ram_list.last_offset; addr +=TARGET_PAGE_SIZE ) {if (!cpu_physical_memory_get_dirty (addr,MIGRATION_DIRTY_FLAG )) {cpu_physical_memory_set_dirty (addr); }@@ -200,7 +200,7 @@ int ram_save_live(Monitor *mon, QEMUFile *f, int stage, void *opaque)/* Enable dirty memory tracking */ cpu_physical_memory_set_dirty_tracking (1 ); -qemu_put_be64 (f, last_ram_offset |RAM_SAVE_FLAG_MEM_SIZE ); +qemu_put_be64 (f, ram_list.last_offset |RAM_SAVE_FLAG_MEM_SIZE ); } bytes_transferred_last = bytes_transferred;@@ -259,7 +259,7 @@ int ram_load(QEMUFile *f, void *opaque, int version_id) addr&=TARGET_PAGE_MASK ;if (flags&RAM_SAVE_FLAG_MEM_SIZE ) { -if (addr != last_ram_offset) { +if (addr != ram_list.last_offset) {return -EINVAL ; } }cpu-all.h +20
-8@@ -859,9 +859,21 @@ target_phys_addr_t cpu_get_phys_page_debug(CPUState *env, target_ulong addr);/* memory API */ extern int phys_ram_fd; -extern uint8_t *phys_ram_dirty;extern ram_addr_t ram_size; -extern ram_addr_t last_ram_offset; + +typedef struct RAMBlock { +uint8_t *host; +ram_addr_t offset; +ram_addr_t length; +QLIST_ENTRY (RAMBlock) next; +}RAMBlock ; + +typedef struct RAMList { +uint8_t *phys_dirty; +ram_addr_t last_offset; + QLIST_HEAD(ram, RAMBlock) blocks; +}RAMList ; +extern RAMList ram_list;extern const char *mem_path;extern int mem_prealloc;@@ -891,29 +903,29 @@ extern int mem_prealloc;/* read dirty bit (return 0 or 1) */ static inline int cpu_physical_memory_is_dirty (ram_addr_t addr) { -return phys_ram_dirty[addr>>TARGET_PAGE_BITS ] ==0xff ; +return ram_list.phys_dirty[addr>>TARGET_PAGE_BITS ] ==0xff ; }static inline int cpu_physical_memory_get_dirty_flags (ram_addr_t addr) { -return phys_ram_dirty[addr>>TARGET_PAGE_BITS ]; +return ram_list.phys_dirty[addr>>TARGET_PAGE_BITS ]; }static inline int cpu_physical_memory_get_dirty (ram_addr_t addr,int dirty_flags) { -return phys_ram_dirty[addr>>TARGET_PAGE_BITS ]& dirty_flags; +return ram_list.phys_dirty[addr>>TARGET_PAGE_BITS ]& dirty_flags; }static inline void cpu_physical_memory_set_dirty (ram_addr_t addr) { - phys_ram_dirty[addr>>TARGET_PAGE_BITS ] =0xff ; + ram_list.phys_dirty[addr>>TARGET_PAGE_BITS ] =0xff ; }static inline int cpu_physical_memory_set_dirty_flags (ram_addr_t addr,int dirty_flags) { -return phys_ram_dirty[addr>>TARGET_PAGE_BITS ] |= dirty_flags; +return ram_list.phys_dirty[addr>>TARGET_PAGE_BITS ] |= dirty_flags; } static inline void cpu_physical_memory_mask_dirty_range(ram_addr_t start,@@ -925,7 +937,7 @@ static inline void cpu_physical_memory_mask_dirty_range(ram_addr_t start, len = length>>TARGET_PAGE_BITS ; mask = ~dirty_flags; - p = phys_ram_dirty + (start>>TARGET_PAGE_BITS ); + p = ram_list.phys_dirty + (start>>TARGET_PAGE_BITS );for (i =0 ; i< len; i++) { p[i]&= mask; }exec.c +27
-51@@ -110,21 +110,9 @@ uint8_t *code_gen_ptr;#if !defined(CONFIG_USER_ONLY )int phys_ram_fd; -uint8_t *phys_ram_dirty;static int in_migration; -typedef struct RAMBlock { -uint8_t *host; -ram_addr_t offset; -ram_addr_t length; -struct RAMBlock *next; -}RAMBlock ; - -static RAMBlock *ram_blocks; -/* TODO: When we implement (and use) ram deallocation (e.g. for hotplug) -then we can no longer assume contiguous ram offsets, and external uses -of this variable will break. */ -ram_addr_t last_ram_offset; +RAMList ram_list = { .blocks =QLIST_HEAD_INITIALIZER (ram_list) };#endif CPUState *first_cpu;@@ -2810,18 +2798,17 @@ ram_addr_t qemu_ram_alloc(ram_addr_t size)madvise (new_block->host, size,MADV_MERGEABLE );#endif } - new_block->offset = last_ram_offset; + new_block->offset = ram_list.last_offset; new_block->length = size; - new_block->next = ram_blocks; - ram_blocks = new_block; +QLIST_INSERT_HEAD (&ram_list.blocks, new_block, next); - phys_ram_dirty =qemu_realloc (phys_ram_dirty, - (last_ram_offset + size)>>TARGET_PAGE_BITS ); -memset (phys_ram_dirty + (last_ram_offset>>TARGET_PAGE_BITS ), + ram_list.phys_dirty =qemu_realloc (ram_list.phys_dirty, + (ram_list.last_offset + size)>>TARGET_PAGE_BITS ); +memset (ram_list.phys_dirty + (ram_list.last_offset>>TARGET_PAGE_BITS ),0xff , size>>TARGET_PAGE_BITS ); - last_ram_offset += size; + ram_list.last_offset += size;if (kvm_enabled ())kvm_setup_guest_memory (new_block->host, size);@@ -2844,31 +2831,20 @@ void qemu_ram_free(ram_addr_t addr)*/ void *qemu_get_ram_ptr (ram_addr_t addr) { -RAMBlock *prev; -RAMBlock **prevp;RAMBlock *block; - prev =NULL ; - prevp =&ram_blocks; - block = ram_blocks; -while (block&& (block->offset> addr - || block->offset + block->length<= addr)) { -if (prev) - prevp =&prev->next; - prev = block; - block = block->next; - } -if (!block) { -fprintf (stderr,"Bad ram offset %" PRIx64"\n" , (uint64_t )addr); -abort (); - } -/* Move this entry to to start of the list. */ -if (prev) { - prev->next = block->next; - block->next = *prevp; - *prevp = block; + QLIST_FOREACH(block,&ram_list.blocks, next) { +if (addr - block->offset< block->length) { +QLIST_REMOVE (block, next); +QLIST_INSERT_HEAD (&ram_list.blocks, block, next); +return block->host + (addr - block->offset); + } } -return block->host + (addr - block->offset); + +fprintf (stderr,"Bad ram offset %" PRIx64"\n" , (uint64_t )addr); +abort (); + +return NULL ; }/* Some of the softmmu routines need to translate from a host pointer @@ -2878,16 +2854,16 @@ ram_addr_t qemu_ram_addr_from_host(void *ptr)RAMBlock *block;uint8_t *host = ptr; - block = ram_blocks; -while (block&& (block->host> host - || block->host + block->length<= host)) { - block = block->next; - } -if (!block) { -fprintf (stderr,"Bad ram pointer %p\n" , ptr); -abort (); + QLIST_FOREACH(block,&ram_list.blocks, next) { +if (host - block->host< block->length) { +return block->offset + (host - block->host); + } } -return block->offset + (host - block->host); + +fprintf (stderr,"Bad ram pointer %p\n" , ptr); +abort (); + +return 0 ; }static uint32_t unassigned_mem_readb (void *opaque,target_phys_addr_t addr)