Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Optimize memory handling #1963

Merged
merged 9 commits into from
Oct 16, 2024
Merged
1 change: 1 addition & 0 deletions include/qemu.h
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ typedef struct {
typedef struct RAMList {
bool freed;
RAMBlock *mru_block;
RAMBlock *last_block;
QLIST_HEAD(, RAMBlock) blocks;
} RAMList;

Expand Down
6 changes: 6 additions & 0 deletions include/uc_priv.h
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,8 @@ typedef MemoryRegion *(*uc_memory_mapping_t)(struct uc_struct *, hwaddr addr);

typedef void (*uc_memory_filter_t)(MemoryRegion *, int32_t);

typedef bool (*uc_flatview_copy_t)(struct uc_struct *, FlatView *, FlatView *, bool);

typedef void (*uc_readonly_mem_t)(MemoryRegion *mr, bool readonly);

typedef int (*uc_cpus_init)(struct uc_struct *, const char *);
Expand Down Expand Up @@ -288,6 +290,7 @@ struct uc_struct {
uc_args_uc_ram_size_ptr_t memory_map_ptr;
uc_memory_mapping_t memory_mapping;
uc_memory_filter_t memory_filter_subregions;
uc_flatview_copy_t flatview_copy;
uc_mem_unmap_t memory_unmap;
uc_mem_unmap_t memory_moveout;
uc_mem_unmap_t memory_movein;
Expand Down Expand Up @@ -427,6 +430,9 @@ struct uc_context {
uc_mode mode; // the mode of this context
uc_arch arch; // the arch of this context
int snapshot_level; // the memory snapshot level to restore
bool ramblock_freed; // wheter there was a some ramblock freed
RAMBlock *last_block;// The last element of the ramblock list
FlatView *fv; // The current flatview of the memory
char data[0]; // context
};

Expand Down
10 changes: 10 additions & 0 deletions include/unicorn/unicorn.h
Original file line number Diff line number Diff line change
Expand Up @@ -1018,6 +1018,16 @@ struct uc_tlb_entry {
uc_prot perms;
};

/*
Variables to control which state should be stored in the context.
Defaults to UC_CTL_CONTEXT_CPU. The options are used in a bitfield
so to enable more then one content the binary or of the required
contents can be use.
The UC_CTL_CONTEXT_MEMORY stores some pointers to internal allocated
memory. Therefor it's not possible to use this context with another
unicorn object.
*/

typedef enum uc_context_content {
UC_CTL_CONTEXT_CPU = 1,
UC_CTL_CONTEXT_MEMORY = 2,
Expand Down
2 changes: 2 additions & 0 deletions qemu/aarch64.h
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@
#define vm_start vm_start_aarch64
#define address_space_dispatch_compact address_space_dispatch_compact_aarch64
#define flatview_translate flatview_translate_aarch64
#define flatview_copy flatview_copy_aarch64
#define address_space_translate_for_iotlb address_space_translate_for_iotlb_aarch64
#define qemu_get_cpu qemu_get_cpu_aarch64
#define cpu_address_space_init cpu_address_space_init_aarch64
Expand Down Expand Up @@ -90,6 +91,7 @@
#define iotlb_to_section iotlb_to_section_aarch64
#define address_space_dispatch_new address_space_dispatch_new_aarch64
#define address_space_dispatch_free address_space_dispatch_free_aarch64
#define address_space_dispatch_clear address_space_dispatch_clear_aarch64
#define flatview_read_continue flatview_read_continue_aarch64
#define address_space_read_full address_space_read_full_aarch64
#define address_space_write address_space_write_aarch64
Expand Down
2 changes: 2 additions & 0 deletions qemu/arm.h
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@
#define vm_start vm_start_arm
#define address_space_dispatch_compact address_space_dispatch_compact_arm
#define flatview_translate flatview_translate_arm
#define flatview_copy flatview_copy_arm
#define address_space_translate_for_iotlb address_space_translate_for_iotlb_arm
#define qemu_get_cpu qemu_get_cpu_arm
#define cpu_address_space_init cpu_address_space_init_arm
Expand Down Expand Up @@ -90,6 +91,7 @@
#define iotlb_to_section iotlb_to_section_arm
#define address_space_dispatch_new address_space_dispatch_new_arm
#define address_space_dispatch_free address_space_dispatch_free_arm
#define address_space_dispatch_clear address_space_dispatch_clear_arm
#define flatview_read_continue flatview_read_continue_arm
#define address_space_read_full address_space_read_full_arm
#define address_space_write address_space_write_arm
Expand Down
40 changes: 32 additions & 8 deletions qemu/exec.c
Original file line number Diff line number Diff line change
Expand Up @@ -957,12 +957,10 @@ void flatview_add_to_dispatch(struct uc_struct *uc, FlatView *fv, MemoryRegionSe

static ram_addr_t find_ram_offset_last(struct uc_struct *uc, ram_addr_t size)
{
RAMBlock *block;
ram_addr_t result = 0;
RAMBlock *block = uc->ram_list.last_block;

RAMBLOCK_FOREACH(block) {
result = MAX(block->offset + block->max_length, result);
}
result = block->offset + block->max_length;

if (result + size > RAM_ADDR_MAX) {
abort();
Expand Down Expand Up @@ -1076,18 +1074,26 @@ static void ram_block_add(struct uc_struct *uc, RAMBlock *new_block)
* QLIST (which has an RCU-friendly variant) does not have insertion at
* tail, so save the last element in last_block.
*/
RAMBLOCK_FOREACH(block) {
last_block = block;
if (block->max_length < new_block->max_length) {
break;
if (uc->ram_list.freed || new_block->max_length > uc->target_page_size) {
wtdcode marked this conversation as resolved.
Show resolved Hide resolved
RAMBLOCK_FOREACH(block) {
last_block = block;
if (block->max_length < new_block->max_length) {
break;
}
}
} else {
last_block = uc->ram_list.last_block;
block = NULL;
}

if (block) {
QLIST_INSERT_BEFORE_RCU(block, new_block, next);
} else if (last_block) {
QLIST_INSERT_AFTER_RCU(last_block, new_block, next);
uc->ram_list.last_block = new_block;
} else { /* list is empty */
QLIST_INSERT_HEAD_RCU(&uc->ram_list.blocks, new_block, next);
uc->ram_list.last_block = new_block;
}
uc->ram_list.mru_block = NULL;

Expand Down Expand Up @@ -1165,6 +1171,7 @@ void qemu_ram_free(struct uc_struct *uc, RAMBlock *block)
QLIST_REMOVE_RCU(block, next);
uc->ram_list.mru_block = NULL;
uc->ram_list.freed = true;
uc->ram_list.last_block = NULL;
/* Write list before version */
//smp_wmb();
// call_rcu(block, reclaim_ramblock, rcu);
Expand Down Expand Up @@ -1388,6 +1395,7 @@ static subpage_t *subpage_init(struct uc_struct *uc, FlatView *fv, hwaddr base)
memory_region_init_io(fv->root->uc, &mmio->iomem, &subpage_ops, mmio,
TARGET_PAGE_SIZE);
mmio->iomem.subpage = true;
mmio->iomem.priority = uc->snapshot_level;
#if defined(DEBUG_SUBPAGE)
printf("%s: %p base " TARGET_FMT_plx " len %08x\n", __func__,
mmio, base, TARGET_PAGE_SIZE);
Expand Down Expand Up @@ -1448,6 +1456,22 @@ AddressSpaceDispatch *address_space_dispatch_new(struct uc_struct *uc, FlatView
return d;
}

void address_space_dispatch_clear(AddressSpaceDispatch *d)
{
MemoryRegionSection *section;
struct uc_struct *uc = d->uc;
while (d->map.sections_nb > 0) {
d->map.sections_nb--;
section = &d->map.sections[d->map.sections_nb];
if (section->mr->priority > uc->snapshot_level) {
phys_section_destroy(section->mr);
}
}
g_free(d->map.sections);
g_free(d->map.nodes);
g_free(d);
}

void address_space_dispatch_free(AddressSpaceDispatch *d)
{
phys_sections_free(&d->map);
Expand Down
1 change: 1 addition & 0 deletions qemu/include/exec/memory-internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ void flatview_add_to_dispatch(struct uc_struct *uc, FlatView *fv, MemoryRegionSe
AddressSpaceDispatch *address_space_dispatch_new(struct uc_struct *uc, FlatView *fv);
void address_space_dispatch_compact(AddressSpaceDispatch *d);
void address_space_dispatch_free(AddressSpaceDispatch *d);
void address_space_dispatch_clear(AddressSpaceDispatch *d);

void mtree_print_dispatch(struct AddressSpaceDispatch *d,
MemoryRegion *root);
Expand Down
1 change: 1 addition & 0 deletions qemu/include/exec/memory.h
Original file line number Diff line number Diff line change
Expand Up @@ -1220,5 +1220,6 @@ void memory_unmap(struct uc_struct *uc, MemoryRegion *mr);
void memory_moveout(struct uc_struct *uc, MemoryRegion *mr);
void memory_movein(struct uc_struct *uc, MemoryRegion *mr);
int memory_free(struct uc_struct *uc);
bool flatview_copy(struct uc_struct *uc, FlatView *dst, FlatView *src, bool update_dispatcher);

#endif
2 changes: 2 additions & 0 deletions qemu/m68k.h
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@
#define vm_start vm_start_m68k
#define address_space_dispatch_compact address_space_dispatch_compact_m68k
#define flatview_translate flatview_translate_m68k
#define flatview_copy flatview_copy_m68k
#define address_space_translate_for_iotlb address_space_translate_for_iotlb_m68k
#define qemu_get_cpu qemu_get_cpu_m68k
#define cpu_address_space_init cpu_address_space_init_m68k
Expand Down Expand Up @@ -90,6 +91,7 @@
#define iotlb_to_section iotlb_to_section_m68k
#define address_space_dispatch_new address_space_dispatch_new_m68k
#define address_space_dispatch_free address_space_dispatch_free_m68k
#define address_space_dispatch_clear address_space_dispatch_clear_m68k
#define flatview_read_continue flatview_read_continue_m68k
#define address_space_read_full address_space_read_full_m68k
#define address_space_write address_space_write_m68k
Expand Down
2 changes: 2 additions & 0 deletions qemu/mips.h
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@
#define vm_start vm_start_mips
#define address_space_dispatch_compact address_space_dispatch_compact_mips
#define flatview_translate flatview_translate_mips
#define flatview_copy flatview_copy_mips
#define address_space_translate_for_iotlb address_space_translate_for_iotlb_mips
#define qemu_get_cpu qemu_get_cpu_mips
#define cpu_address_space_init cpu_address_space_init_mips
Expand Down Expand Up @@ -90,6 +91,7 @@
#define iotlb_to_section iotlb_to_section_mips
#define address_space_dispatch_new address_space_dispatch_new_mips
#define address_space_dispatch_free address_space_dispatch_free_mips
#define address_space_dispatch_clear address_space_dispatch_clear_mips
#define flatview_read_continue flatview_read_continue_mips
#define address_space_read_full address_space_read_full_mips
#define address_space_write address_space_write_mips
Expand Down
2 changes: 2 additions & 0 deletions qemu/mips64.h
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@
#define vm_start vm_start_mips64
#define address_space_dispatch_compact address_space_dispatch_compact_mips64
#define flatview_translate flatview_translate_mips64
#define flatview_copy flatview_copy_mips64
#define address_space_translate_for_iotlb address_space_translate_for_iotlb_mips64
#define qemu_get_cpu qemu_get_cpu_mips64
#define cpu_address_space_init cpu_address_space_init_mips64
Expand Down Expand Up @@ -90,6 +91,7 @@
#define iotlb_to_section iotlb_to_section_mips64
#define address_space_dispatch_new address_space_dispatch_new_mips64
#define address_space_dispatch_free address_space_dispatch_free_mips64
#define address_space_dispatch_clear address_space_dispatch_clear_mips64
#define flatview_read_continue flatview_read_continue_mips64
#define address_space_read_full address_space_read_full_mips64
#define address_space_write address_space_write_mips64
Expand Down
2 changes: 2 additions & 0 deletions qemu/mips64el.h
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@
#define vm_start vm_start_mips64el
#define address_space_dispatch_compact address_space_dispatch_compact_mips64el
#define flatview_translate flatview_translate_mips64el
#define flatview_copy flatview_copy_mips64el
#define address_space_translate_for_iotlb address_space_translate_for_iotlb_mips64el
#define qemu_get_cpu qemu_get_cpu_mips64el
#define cpu_address_space_init cpu_address_space_init_mips64el
Expand Down Expand Up @@ -90,6 +91,7 @@
#define iotlb_to_section iotlb_to_section_mips64el
#define address_space_dispatch_new address_space_dispatch_new_mips64el
#define address_space_dispatch_free address_space_dispatch_free_mips64el
#define address_space_dispatch_clear address_space_dispatch_clear_mips64el
#define flatview_read_continue flatview_read_continue_mips64el
#define address_space_read_full address_space_read_full_mips64el
#define address_space_write address_space_write_mips64el
Expand Down
2 changes: 2 additions & 0 deletions qemu/mipsel.h
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@
#define vm_start vm_start_mipsel
#define address_space_dispatch_compact address_space_dispatch_compact_mipsel
#define flatview_translate flatview_translate_mipsel
#define flatview_copy flatview_copy_mipsel
#define address_space_translate_for_iotlb address_space_translate_for_iotlb_mipsel
#define qemu_get_cpu qemu_get_cpu_mipsel
#define cpu_address_space_init cpu_address_space_init_mipsel
Expand Down Expand Up @@ -90,6 +91,7 @@
#define iotlb_to_section iotlb_to_section_mipsel
#define address_space_dispatch_new address_space_dispatch_new_mipsel
#define address_space_dispatch_free address_space_dispatch_free_mipsel
#define address_space_dispatch_clear address_space_dispatch_clear_mipsel
#define flatview_read_continue flatview_read_continue_mipsel
#define address_space_read_full address_space_read_full_mipsel
#define address_space_write address_space_write_mipsel
Expand Down
2 changes: 2 additions & 0 deletions qemu/ppc.h
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@
#define vm_start vm_start_ppc
#define address_space_dispatch_compact address_space_dispatch_compact_ppc
#define flatview_translate flatview_translate_ppc
#define flatview_copy flatview_copy_ppc
#define address_space_translate_for_iotlb address_space_translate_for_iotlb_ppc
#define qemu_get_cpu qemu_get_cpu_ppc
#define cpu_address_space_init cpu_address_space_init_ppc
Expand Down Expand Up @@ -90,6 +91,7 @@
#define iotlb_to_section iotlb_to_section_ppc
#define address_space_dispatch_new address_space_dispatch_new_ppc
#define address_space_dispatch_free address_space_dispatch_free_ppc
#define address_space_dispatch_clear address_space_dispatch_clear_ppc
#define flatview_read_continue flatview_read_continue_ppc
#define address_space_read_full address_space_read_full_ppc
#define address_space_write address_space_write_ppc
Expand Down
2 changes: 2 additions & 0 deletions qemu/ppc64.h
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@
#define vm_start vm_start_ppc64
#define address_space_dispatch_compact address_space_dispatch_compact_ppc64
#define flatview_translate flatview_translate_ppc64
#define flatview_copy flatview_copy_ppc64
#define address_space_translate_for_iotlb address_space_translate_for_iotlb_ppc64
#define qemu_get_cpu qemu_get_cpu_ppc64
#define cpu_address_space_init cpu_address_space_init_ppc64
Expand Down Expand Up @@ -90,6 +91,7 @@
#define iotlb_to_section iotlb_to_section_ppc64
#define address_space_dispatch_new address_space_dispatch_new_ppc64
#define address_space_dispatch_free address_space_dispatch_free_ppc64
#define address_space_dispatch_clear address_space_dispatch_clear_ppc64
#define flatview_read_continue flatview_read_continue_ppc64
#define address_space_read_full address_space_read_full_ppc64
#define address_space_write address_space_write_ppc64
Expand Down
2 changes: 2 additions & 0 deletions qemu/riscv32.h
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@
#define vm_start vm_start_riscv32
#define address_space_dispatch_compact address_space_dispatch_compact_riscv32
#define flatview_translate flatview_translate_riscv32
#define flatview_copy flatview_copy_riscv32
#define address_space_translate_for_iotlb address_space_translate_for_iotlb_riscv32
#define qemu_get_cpu qemu_get_cpu_riscv32
#define cpu_address_space_init cpu_address_space_init_riscv32
Expand Down Expand Up @@ -90,6 +91,7 @@
#define iotlb_to_section iotlb_to_section_riscv32
#define address_space_dispatch_new address_space_dispatch_new_riscv32
#define address_space_dispatch_free address_space_dispatch_free_riscv32
#define address_space_dispatch_clear address_space_dispatch_clear_riscv32
#define flatview_read_continue flatview_read_continue_riscv32
#define address_space_read_full address_space_read_full_riscv32
#define address_space_write address_space_write_riscv32
Expand Down
2 changes: 2 additions & 0 deletions qemu/riscv64.h
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@
#define vm_start vm_start_riscv64
#define address_space_dispatch_compact address_space_dispatch_compact_riscv64
#define flatview_translate flatview_translate_riscv64
#define flatview_copy flatview_copy_riscv64
#define address_space_translate_for_iotlb address_space_translate_for_iotlb_riscv64
#define qemu_get_cpu qemu_get_cpu_riscv64
#define cpu_address_space_init cpu_address_space_init_riscv64
Expand Down Expand Up @@ -90,6 +91,7 @@
#define iotlb_to_section iotlb_to_section_riscv64
#define address_space_dispatch_new address_space_dispatch_new_riscv64
#define address_space_dispatch_free address_space_dispatch_free_riscv64
#define address_space_dispatch_clear address_space_dispatch_clear_riscv64
#define flatview_read_continue flatview_read_continue_riscv64
#define address_space_read_full address_space_read_full_riscv64
#define address_space_write address_space_write_riscv64
Expand Down
2 changes: 2 additions & 0 deletions qemu/s390x.h
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@
#define vm_start vm_start_s390x
#define address_space_dispatch_compact address_space_dispatch_compact_s390x
#define flatview_translate flatview_translate_s390x
#define flatview_copy flatview_copy_s390x
#define address_space_translate_for_iotlb address_space_translate_for_iotlb_s390x
#define qemu_get_cpu qemu_get_cpu_s390x
#define cpu_address_space_init cpu_address_space_init_s390x
Expand Down Expand Up @@ -90,6 +91,7 @@
#define iotlb_to_section iotlb_to_section_s390x
#define address_space_dispatch_new address_space_dispatch_new_s390x
#define address_space_dispatch_free address_space_dispatch_free_s390x
#define address_space_dispatch_clear address_space_dispatch_clear_s390x
#define flatview_read_continue flatview_read_continue_s390x
#define address_space_read_full address_space_read_full_s390x
#define address_space_write address_space_write_s390x
Expand Down
Loading
Loading