From b62706c9f2ceed65394457ae9b131996a2b29463 Mon Sep 17 00:00:00 2001 From: Brett Weiland Date: Fri, 24 Sep 2021 14:20:20 -0500 Subject: palloc/pfree found smp safe --- src/kernel/page.c | 37 +++++++++++++++++++++++++++---------- 1 file changed, 27 insertions(+), 10 deletions(-) (limited to 'src/kernel/page.c') diff --git a/src/kernel/page.c b/src/kernel/page.c index 0b286a4..c79b1fa 100644 --- a/src/kernel/page.c +++ b/src/kernel/page.c @@ -100,7 +100,6 @@ void fix_stack() { :"r"(PA_OFFSET)); while(frame->next != 0) { - printf("%p\n", frame->function_base); frame->next = PHYS_TO_VIRT((void *)frame->next); frame = frame->next; } @@ -171,14 +170,13 @@ void debug_pmap() { } } -//TODO I know you don't want to, but you need to thoroughly check this. void pfree(void *addr, size_t size) { int blevel = 0; uint64_t *onbyte; uint64_t page_bitloc; int bbitlen; int lshift; - pmap_t *pmap = first_pmap; + pmap_t *pmap; /* note: there's no security check to see if the page is actually allocated, * or if we are freeing the table itself. @@ -192,10 +190,13 @@ void pfree(void *addr, size_t size) { return; } size /= 0x1000; - for(; pmap != 0; pmap = pmap->next) { + for(pmap = first_pmap; pmap; pmap = pmap->next) { page_bitloc = (addr - (void *)pmap) / 0x1000; onbyte = pmap->buddy[0] + (page_bitloc / 64); - if((addr >= (void *)pmap) && onbyte < pmap->buddy[1]) break; + if((addr >= (void *)pmap) && onbyte < pmap->buddy[1]) { + lock(&pmap->mutex); + break; + } } while(blevel < MAX_BUDDY_ORDER) { @@ -241,6 +242,7 @@ void pfree(void *addr, size_t size) { blevel++; } } + unlock(&pmap->mutex); } @@ -276,13 +278,10 @@ void *palloc(size_t size) { self_alloc = false; min_blevel = 63 - __builtin_clzl(size); if(size & (size - 1)) min_blevel++; - if(min_blevel > MAX_BUDDY_ORDER - 1) return 0; + if(min_blevel > MAX_BUDDY_ORDER - 1) PANIC(KERNEL_PANIC_PALLOC_TOO_LARGE); } for(blevel = min_blevel; blevel < MAX_BUDDY_ORDER; blevel++) { - //for(pmap = first_pmap; pmap != 0; pmap = pmap->next) { - //while(!unlocked_pmaps_searched || - // is_empty(waiting_pmaps[core_id], sizeof(&pmap) * pmap_count)) { pmap = first_pmap; while(pmap) { @@ -329,12 +328,13 @@ void *palloc(size_t size) { return ret; } } -get_next_pmap: pmap->mutex = 0; +get_next_pmap: if(unlocked_pmaps_searched) { pmap = 0; for(searchingp_i = waitingp_i + 1; searchingp_i < pmap_count; searchingp_i++) { if(waiting_pmaps[waitlist_i(searchingp_i)]) { + waitingp_i = searchingp_i; pmap = waiting_pmaps[waitlist_i(searchingp_i)]; break; } @@ -342,6 +342,7 @@ get_next_pmap: if(!pmap) { for(searchingp_i = 0; searchingp_i <= waitingp_i; searchingp_i++) { if(waiting_pmaps[waitlist_i(searchingp_i)]) { + waitingp_i = searchingp_i; pmap = waiting_pmaps[waitlist_i(searchingp_i)]; break; } @@ -350,6 +351,7 @@ get_next_pmap: } else { if(!pmap->next) { + waitingp_i = 0; pmap = waiting_pmaps ? waiting_pmaps[waitlist_i(0)] : 0; unlocked_pmaps_searched = true; } @@ -515,3 +517,18 @@ void *init_pmap(size_t pagetable_size) { } return pmap; } + +void lock_all_maps() { + pmap_t *pmap; + for(pmap = first_pmap; pmap; pmap = pmap->next) pmap->mutex = 1; + pmap = first_pmap; + pmap_count++; + for(pmap = first_pmap;;pmap = pmap->next) { + if(!pmap->next) { + pmap->next = malloc(sizeof(pmap_t)); + pmap->next->mutex = 1; + break; + } + } + first_pmap->mutex = 0; +} -- cgit v1.2.3