exec: replace leaf with skip
In preparation for dynamic radix tree depth support, rename is_leaf field to skip, telling us how many bits to skip to next level. Set to 0 for leaf. Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
This commit is contained in:
parent
03f4995781
commit
9736e55b78
17
exec.c
17
exec.c
@ -83,8 +83,9 @@ int use_icount;
|
|||||||
typedef struct PhysPageEntry PhysPageEntry;
|
typedef struct PhysPageEntry PhysPageEntry;
|
||||||
|
|
||||||
struct PhysPageEntry {
|
struct PhysPageEntry {
|
||||||
uint16_t is_leaf : 1;
|
/* How many bits skip to next level (in units of L2_SIZE). 0 for a leaf. */
|
||||||
/* index into phys_sections (is_leaf) or phys_map_nodes (!is_leaf) */
|
uint16_t skip : 1;
|
||||||
|
/* index into phys_sections (!skip) or phys_map_nodes (skip) */
|
||||||
uint16_t ptr : 15;
|
uint16_t ptr : 15;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -164,7 +165,7 @@ static uint16_t phys_map_node_alloc(void)
|
|||||||
assert(ret != PHYS_MAP_NODE_NIL);
|
assert(ret != PHYS_MAP_NODE_NIL);
|
||||||
assert(ret != next_map.nodes_nb_alloc);
|
assert(ret != next_map.nodes_nb_alloc);
|
||||||
for (i = 0; i < P_L2_SIZE; ++i) {
|
for (i = 0; i < P_L2_SIZE; ++i) {
|
||||||
next_map.nodes[ret][i].is_leaf = 0;
|
next_map.nodes[ret][i].skip = 1;
|
||||||
next_map.nodes[ret][i].ptr = PHYS_MAP_NODE_NIL;
|
next_map.nodes[ret][i].ptr = PHYS_MAP_NODE_NIL;
|
||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
@ -178,12 +179,12 @@ static void phys_page_set_level(PhysPageEntry *lp, hwaddr *index,
|
|||||||
int i;
|
int i;
|
||||||
hwaddr step = (hwaddr)1 << (level * P_L2_BITS);
|
hwaddr step = (hwaddr)1 << (level * P_L2_BITS);
|
||||||
|
|
||||||
if (!lp->is_leaf && lp->ptr == PHYS_MAP_NODE_NIL) {
|
if (lp->skip && lp->ptr == PHYS_MAP_NODE_NIL) {
|
||||||
lp->ptr = phys_map_node_alloc();
|
lp->ptr = phys_map_node_alloc();
|
||||||
p = next_map.nodes[lp->ptr];
|
p = next_map.nodes[lp->ptr];
|
||||||
if (level == 0) {
|
if (level == 0) {
|
||||||
for (i = 0; i < P_L2_SIZE; i++) {
|
for (i = 0; i < P_L2_SIZE; i++) {
|
||||||
p[i].is_leaf = 1;
|
p[i].skip = 0;
|
||||||
p[i].ptr = PHYS_SECTION_UNASSIGNED;
|
p[i].ptr = PHYS_SECTION_UNASSIGNED;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -194,7 +195,7 @@ static void phys_page_set_level(PhysPageEntry *lp, hwaddr *index,
|
|||||||
|
|
||||||
while (*nb && lp < &p[P_L2_SIZE]) {
|
while (*nb && lp < &p[P_L2_SIZE]) {
|
||||||
if ((*index & (step - 1)) == 0 && *nb >= step) {
|
if ((*index & (step - 1)) == 0 && *nb >= step) {
|
||||||
lp->is_leaf = true;
|
lp->skip = 0;
|
||||||
lp->ptr = leaf;
|
lp->ptr = leaf;
|
||||||
*index += step;
|
*index += step;
|
||||||
*nb -= step;
|
*nb -= step;
|
||||||
@ -221,7 +222,7 @@ static MemoryRegionSection *phys_page_find(PhysPageEntry lp, hwaddr index,
|
|||||||
PhysPageEntry *p;
|
PhysPageEntry *p;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
for (i = P_L2_LEVELS - 1; i >= 0 && !lp.is_leaf; i--) {
|
for (i = P_L2_LEVELS; lp.skip && (i -= lp.skip) >= 0;) {
|
||||||
if (lp.ptr == PHYS_MAP_NODE_NIL) {
|
if (lp.ptr == PHYS_MAP_NODE_NIL) {
|
||||||
return §ions[PHYS_SECTION_UNASSIGNED];
|
return §ions[PHYS_SECTION_UNASSIGNED];
|
||||||
}
|
}
|
||||||
@ -1681,7 +1682,7 @@ static void mem_begin(MemoryListener *listener)
|
|||||||
AddressSpace *as = container_of(listener, AddressSpace, dispatch_listener);
|
AddressSpace *as = container_of(listener, AddressSpace, dispatch_listener);
|
||||||
AddressSpaceDispatch *d = g_new(AddressSpaceDispatch, 1);
|
AddressSpaceDispatch *d = g_new(AddressSpaceDispatch, 1);
|
||||||
|
|
||||||
d->phys_map = (PhysPageEntry) { .ptr = PHYS_MAP_NODE_NIL, .is_leaf = 0 };
|
d->phys_map = (PhysPageEntry) { .ptr = PHYS_MAP_NODE_NIL, .skip = 1 };
|
||||||
d->as = as;
|
d->as = as;
|
||||||
as->next_dispatch = d;
|
as->next_dispatch = d;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user