Skip to content

Commit eff7ceb

Browse files
danielRepmiguelafsilva5
authored andcommitted
feat(mem/mpu): merge adjacent vmpu regions
This reduces the number of vMPU/MPU entries. Signed-off-by: Daniel Oliveira <[email protected]> Signed-off-by: Miguel Silva <[email protected]>
1 parent 6e8b2a7 commit eff7ceb

File tree

1 file changed

+47
-0
lines changed

1 file changed

+47
-0
lines changed

src/core/mpu/mem.c

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -452,6 +452,49 @@ static mpid_t mem_vmpu_find_overlapping_region(struct addr_space* as, struct mp_
452452
return mpid;
453453
}
454454

455+
static void mem_vmpu_coalesce_contiguous(struct addr_space* as, bool broadcast)
456+
{
457+
while (true) {
458+
bool merge = false;
459+
mpid_t cur_mpid = INVALID_MPID;
460+
mpid_t prev_mpid = INVALID_MPID;
461+
struct mpe* prev_reg;
462+
struct mpe* cur_reg;
463+
list_foreach_tail(as->vmpu.ordered_list, struct mpe, cur, prev)
464+
{
465+
if (prev == NULL) {
466+
continue;
467+
}
468+
cur_reg = mem_vmpu_get_entry(as, cur->mpid);
469+
prev_reg = mem_vmpu_get_entry(as, prev->mpid);
470+
471+
bool contiguous = prev_reg->region.base + prev_reg->region.size == cur_reg->region.base;
472+
bool perms_compatible =
473+
mpu_perms_compatible(prev_reg->region.mem_flags.raw, cur_reg->region.mem_flags.raw);
474+
bool lock_compatible = !prev_reg->lock && !cur_reg->lock;
475+
if (contiguous && perms_compatible && lock_compatible) {
476+
cur_mpid = cur->mpid;
477+
prev_mpid = prev->mpid;
478+
merge = true;
479+
break;
480+
}
481+
}
482+
483+
if (merge) {
484+
struct mp_region merged_reg = {
485+
.base = prev_reg->region.base,
486+
.size = prev_reg->region.size + cur_reg->region.size,
487+
.mem_flags = cur_reg->region.mem_flags,
488+
};
489+
if (mem_vmpu_update_region(as, prev_mpid, merged_reg, broadcast, prev_reg->lock)) {
490+
mem_vmpu_remove_region(as, cur_mpid, broadcast);
491+
}
492+
} else {
493+
break;
494+
}
495+
}
496+
}
497+
455498
bool mem_map(struct addr_space* as, struct mp_region* mpr, bool broadcast, bool locked)
456499
{
457500
bool mapped = false;
@@ -474,6 +517,10 @@ bool mem_map(struct addr_space* as, struct mp_region* mpr, bool broadcast, bool
474517
}
475518
}
476519

520+
if (mapped && !locked) {
521+
mem_vmpu_coalesce_contiguous(as, broadcast);
522+
}
523+
477524
spin_unlock(&as->lock);
478525

479526
return mapped;

0 commit comments

Comments
 (0)