vmm: use mutexes

This commit is contained in:
Matheus
2023-07-26 21:39:06 -03:00
parent 49eef0e04c
commit f5c5b01d85
2 changed files with 19 additions and 18 deletions
+2 -2
View File
@@ -43,7 +43,7 @@ typedef struct vmmrange_t{
} vmmrange_t; } vmmrange_t;
typedef struct { typedef struct {
spinlock_t lock; mutex_t lock;
struct vmmcache_t *next; struct vmmcache_t *next;
size_t freecount; size_t freecount;
uintmax_t firstfree; uintmax_t firstfree;
@@ -57,7 +57,7 @@ typedef struct vmmcache_t {
} vmmcache_t; } vmmcache_t;
typedef struct { typedef struct {
spinlock_t lock; mutex_t lock;
vmmrange_t *ranges; vmmrange_t *ranges;
void *start; void *start;
void *end; void *end;
+17 -16
View File
@@ -17,7 +17,7 @@ static vmmcache_t *newcache() {
ptr->header.freecount = VMM_RANGES_PER_CACHE; ptr->header.freecount = VMM_RANGES_PER_CACHE;
ptr->header.firstfree = 0; ptr->header.firstfree = 0;
ptr->header.next = NULL; ptr->header.next = NULL;
SPINLOCK_INIT(ptr->header.lock); MUTEX_INIT(&ptr->header.lock);
for (uintmax_t i = 0; i < VMM_RANGES_PER_CACHE; ++i) { for (uintmax_t i = 0; i < VMM_RANGES_PER_CACHE; ++i) {
ptr->ranges[i].size = 0; ptr->ranges[i].size = 0;
@@ -43,20 +43,20 @@ static vmmrange_t *allocrange() {
vmmcache_t *cache = cachelist; vmmcache_t *cache = cachelist;
vmmrange_t *range = NULL; vmmrange_t *range = NULL;
while (cache) { while (cache) {
spinlock_acquire(&cache->header.lock); MUTEX_ACQUIRE(&cache->header.lock, false);
if (cache->header.freecount > 0) { if (cache->header.freecount > 0) {
--cache->header.freecount; --cache->header.freecount;
uintmax_t r = getentrynumber(cache); uintmax_t r = getentrynumber(cache);
cache->header.firstfree = r + 1; cache->header.firstfree = r + 1;
range = &cache->ranges[r]; range = &cache->ranges[r];
range->size = -1; // set as allocated temporarily range->size = -1; // set as allocated temporarily
spinlock_release(&cache->header.lock); MUTEX_RELEASE(&cache->header.lock);
break; break;
} else if (cache->header.next == NULL) } else if (cache->header.next == NULL)
cache->header.next = newcache(); cache->header.next = newcache();
vmmcache_t *next = cache->header.next; vmmcache_t *next = cache->header.next;
spinlock_release(&cache->header.lock); MUTEX_RELEASE(&cache->header.lock);
cache = next; cache = next;
} }
@@ -65,7 +65,7 @@ static vmmrange_t *allocrange() {
static void freerange(vmmrange_t *range) { static void freerange(vmmrange_t *range) {
vmmcache_t *cache = (vmmcache_t *)ROUND_DOWN((uintptr_t)range, PAGE_SIZE); vmmcache_t *cache = (vmmcache_t *)ROUND_DOWN((uintptr_t)range, PAGE_SIZE);
spinlock_acquire(&cache->header.lock); MUTEX_ACQUIRE(&cache->header.lock, false);
int rangeoffset = ((uintptr_t)range - (uintptr_t)cache->ranges) / sizeof(vmmrange_t); int rangeoffset = ((uintptr_t)range - (uintptr_t)cache->ranges) / sizeof(vmmrange_t);
range->size = 0; range->size = 0;
@@ -73,7 +73,7 @@ static void freerange(vmmrange_t *range) {
if (cache->header.firstfree > rangeoffset) if (cache->header.firstfree > rangeoffset)
cache->header.firstfree = rangeoffset; cache->header.firstfree = rangeoffset;
spinlock_release(&cache->header.lock); MUTEX_RELEASE(&cache->header.lock);
} }
// ranges are separated into kernel and user. the kernel has a temporary user context // ranges are separated into kernel and user. the kernel has a temporary user context
@@ -297,7 +297,7 @@ bool vmm_pagefault(void *addr, bool user, int actions) {
if (space == NULL || (space == &kernelspace && user)) if (space == NULL || (space == &kernelspace && user))
return false; return false;
spinlock_acquire(&space->lock); MUTEX_ACQUIRE(&space->lock, false);
vmmrange_t *range = getrange(space, addr); vmmrange_t *range = getrange(space, addr);
bool status = false; bool status = false;
@@ -339,7 +339,7 @@ bool vmm_pagefault(void *addr, bool user, int actions) {
} }
cleanup: cleanup:
spinlock_release(&space->lock); MUTEX_RELEASE(&space->lock);
return status; return status;
} }
@@ -360,7 +360,7 @@ void *vmm_map(void *addr, volatile size_t size, int flags, mmuflags_t mmuflags,
if (space == NULL) if (space == NULL)
return NULL; return NULL;
spinlock_acquire(&space->lock); MUTEX_ACQUIRE(&space->lock, false);
vmmrange_t *range = NULL; vmmrange_t *range = NULL;
void *start = getfreerange(space, addr, size); void *start = getfreerange(space, addr, size);
@@ -431,7 +431,7 @@ void *vmm_map(void *addr, volatile size_t size, int flags, mmuflags_t mmuflags,
if (start == NULL && range) if (start == NULL && range)
freerange(range); freerange(range);
spinlock_release(&space->lock); MUTEX_RELEASE(&space->lock);
return retaddr; return retaddr;
} }
@@ -449,10 +449,10 @@ void vmm_unmap(void *addr, size_t size, int flags) {
if (space == NULL) if (space == NULL)
return; return;
spinlock_acquire(&space->lock); MUTEX_ACQUIRE(&space->lock, false);
unmap(space, addr, size); unmap(space, addr, size);
spinlock_release(&space->lock); MUTEX_RELEASE(&space->lock);
} }
static scache_t *ctxcache; static scache_t *ctxcache;
@@ -461,7 +461,7 @@ static void ctxctor(scache_t *cache, void *obj) {
vmmcontext_t *ctx = obj; vmmcontext_t *ctx = obj;
ctx->space.start = USERSPACE_START; ctx->space.start = USERSPACE_START;
ctx->space.end = USERSPACE_END; ctx->space.end = USERSPACE_END;
SPINLOCK_INIT(ctx->space.lock); MUTEX_INIT(&ctx->space.lock);
ctx->space.ranges = NULL; ctx->space.ranges = NULL;
} }
@@ -499,7 +499,7 @@ vmmcontext_t *vmm_fork(vmmcontext_t *oldcontext) {
if (newcontext == NULL) if (newcontext == NULL)
return NULL; return NULL;
spinlock_acquire(&oldcontext->space.lock); MUTEX_ACQUIRE(&oldcontext->space.lock, false);
vmmrange_t *range = oldcontext->space.ranges; vmmrange_t *range = oldcontext->space.ranges;
@@ -536,10 +536,10 @@ vmmcontext_t *vmm_fork(vmmcontext_t *oldcontext) {
range = range->next; range = range->next;
} }
spinlock_release(&oldcontext->space.lock); MUTEX_RELEASE(&oldcontext->space.lock);
return newcontext; return newcontext;
error: error:
spinlock_release(&oldcontext->space.lock); MUTEX_RELEASE(&oldcontext->space.lock);
vmm_destroycontext(newcontext); vmm_destroycontext(newcontext);
return NULL; return NULL;
} }
@@ -571,6 +571,7 @@ extern volatile struct limine_memmap_request pmm_liminemap;
void vmm_init() { void vmm_init() {
__assert(sizeof(vmmcache_t) <= PAGE_SIZE); __assert(sizeof(vmmcache_t) <= PAGE_SIZE);
MUTEX_INIT(&kernelspace.lock);
cachelist = newcache(); cachelist = newcache();
vmm_kernelctx.pagetable = arch_mmu_newtable(); vmm_kernelctx.pagetable = arch_mmu_newtable();