Skip to content

Commit 8636568

Browse files
danielRepmiguelafsilva5
authored andcommitted
feat(vmpu): add merge of regions to map logic
Signed-off-by: Daniel Oliveira <[email protected]>
1 parent 79daff8 commit 8636568

File tree

1 file changed

+69
-0
lines changed

1 file changed

+69
-0
lines changed

src/core/mpu/mem.c

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
#include <platform_defs.h>
1212
#include <objpool.h>
1313
#include <config.h>
14+
#include <arch/mpu.h>
1415

1516
struct shared_region {
1617
enum AS_TYPE as_type;
@@ -38,6 +39,25 @@ static inline struct mpe* mem_vmpu_get_entry(struct addr_space* as, mpid_t mpid)
3839
return NULL;
3940
}
4041

42+
static int vmpu_node_cmp(node_t* _n1, node_t* _n2)
43+
{
44+
struct mpe* n1 = (struct mpe*)_n1;
45+
struct mpe* n2 = (struct mpe*)_n2;
46+
struct mp_region r1;
47+
struct mp_region r2;
48+
49+
r1 = n1->region;
50+
r2 = n2->region;
51+
52+
if (r1.base > r2.base) {
53+
return 1;
54+
} else if (r1.base < r2.base) {
55+
return -1;
56+
} else {
57+
return 0;
58+
}
59+
}
60+
4161
static void mem_vmpu_set_entry(struct addr_space* as, mpid_t mpid, struct mp_region* mpr)
4262
{
4363
struct mpe* mpe = mem_vmpu_get_entry(as, mpid);
@@ -360,6 +380,51 @@ static mpid_t mem_vmpu_find_overlapping_region(struct addr_space* as, struct mp_
360380
return mpid;
361381
}
362382

383+
void mem_vmpu_coalesce_contiguous(struct addr_space* as, bool broadcast)
384+
{
385+
while (true) {
386+
bool merge = false;
387+
mpid_t cur_mpid = INVALID_MPID;
388+
mpid_t prev_mpid = INVALID_MPID;
389+
struct mpe* prev_reg;
390+
struct mpe* cur_reg;
391+
list_foreach_tail(cpu()->as.vmpu.ordered_list, struct mpe, cur, prev)
392+
{
393+
if (prev == NULL) {
394+
continue;
395+
}
396+
cur_reg = mem_vmpu_get_entry(as, cur->mpid);
397+
prev_reg = mem_vmpu_get_entry(as, prev->mpid);
398+
399+
bool contigous = prev_reg->region.base + prev_reg->region.size == cur_reg->region.base;
400+
bool perms_compatible =
401+
mpu_perms_comptible(prev_reg->region.mem_flags.raw, cur_reg->region.mem_flags.raw);
402+
if (contigous && perms_compatible) {
403+
cur_mpid = cur->mpid;
404+
prev_mpid = prev->mpid;
405+
merge = true;
406+
break;
407+
}
408+
}
409+
410+
if (merge) {
411+
mem_vmpu_remove_region(as, cur_mpid, broadcast);
412+
mem_vmpu_remove_region(as, prev_mpid, broadcast);
413+
struct mp_region merged_reg = {
414+
.base = prev_reg->region.base,
415+
.size = prev_reg->region.size + cur_reg->region.size,
416+
.mem_flags = cur_reg->region.mem_flags,
417+
};
418+
mpid_t mpid = mem_vmpu_allocate_entry(as);
419+
if (mpid != INVALID_MPID) {
420+
mem_vmpu_insert_region(as, mpid, &merged_reg, broadcast);
421+
}
422+
} else {
423+
break;
424+
}
425+
}
426+
}
427+
363428
bool mem_map(struct addr_space* as, struct mp_region* mpr, bool broadcast)
364429
{
365430
bool mapped = false;
@@ -383,6 +448,10 @@ bool mem_map(struct addr_space* as, struct mp_region* mpr, bool broadcast)
383448
}
384449
}
385450

451+
if (mapped) {
452+
mem_vmpu_coalesce_contiguous(as, broadcast);
453+
}
454+
386455
spin_unlock(&as->lock);
387456

388457
return mapped;

0 commit comments

Comments
 (0)