find_ram_offset optimization
The ram_offset allocator searches the smalest gap in the ram_offset address space. This is slow especialy in combination with many allocation (i.e. snapshots). When it is known that there is no gap, this is now optimized.
This commit is contained in:
parent
550265f3c1
commit
e54cf7ee03
|
@ -41,6 +41,7 @@ typedef struct {
|
|||
|
||||
// This struct is originally from qemu/include/exec/ramlist.h
|
||||
typedef struct RAMList {
|
||||
bool freed;
|
||||
RAMBlock *mru_block;
|
||||
QLIST_HEAD(, RAMBlock) blocks;
|
||||
} RAMList;
|
||||
|
|
20
qemu/exec.c
20
qemu/exec.c
|
@ -955,6 +955,21 @@ void flatview_add_to_dispatch(struct uc_struct *uc, FlatView *fv, MemoryRegionSe
|
|||
register_subpage(uc, fv, &remain);
|
||||
}
|
||||
|
||||
static ram_addr_t find_ram_offset_last(struct uc_struct *uc, ram_addr_t size)
|
||||
{
|
||||
RAMBlock *block;
|
||||
ram_addr_t result = 0;
|
||||
|
||||
RAMBLOCK_FOREACH(block) {
|
||||
result = MAX(block->offset + block->max_length, result);
|
||||
}
|
||||
|
||||
if (result + size > RAM_ADDR_MAX) {
|
||||
abort();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/* Allocate space within the ram_addr_t space that governs the
|
||||
* dirty bitmaps.
|
||||
* Called with the ramlist lock held.
|
||||
|
@ -970,6 +985,10 @@ static ram_addr_t find_ram_offset(struct uc_struct *uc, ram_addr_t size)
|
|||
return 0;
|
||||
}
|
||||
|
||||
if (!uc->ram_list.freed) {
|
||||
return find_ram_offset_last(uc, size);
|
||||
}
|
||||
|
||||
RAMBLOCK_FOREACH(block) {
|
||||
ram_addr_t candidate, next = RAM_ADDR_MAX;
|
||||
|
||||
|
@ -1145,6 +1164,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;
|
||||
/* Write list before version */
|
||||
//smp_wmb();
|
||||
// call_rcu(block, reclaim_ramblock, rcu);
|
||||
|
|
Loading…
Reference in New Issue