From d4e8754f21ef0b533809ed763fa1dc0068be9e6c Mon Sep 17 00:00:00 2001 From: Max Wash Date: Thu, 2 Feb 2023 21:15:59 +0000 Subject: [PATCH] sandbox: vm: implement vm_cache_free() and kfree() --- sandbox/vm/cache.c | 35 +++++++++++++++++++++++++++++++++++ sandbox/vm/kmalloc.c | 10 ++++++++-- 2 files changed, 43 insertions(+), 2 deletions(-) diff --git a/sandbox/vm/cache.c b/sandbox/vm/cache.c index 38eb24d..2445515 100644 --- a/sandbox/vm/cache.c +++ b/sandbox/vm/cache.c @@ -1,4 +1,6 @@ #include +#include +#include #include #define FREELIST_END ((unsigned int)-1) @@ -178,5 +180,38 @@ void *vm_cache_alloc(vm_cache_t *cache, vm_flags_t flags) void vm_cache_free(vm_cache_t *cache, void *p) { + unsigned long irq_flags; + spin_lock_irqsave(&cache->c_lock, &irq_flags); + phys_addr_t phys = vm_virt_to_phys(p); + vm_page_t *pg = vm_page_get(phys); + + if (!pg || !pg->p_slab) { + spin_unlock_irqrestore(&cache->c_lock, irq_flags); + return; + } + + vm_slab_t *slab = pg->p_slab; + + if (slab->s_cache != cache) { + spin_unlock_irqrestore(&cache->c_lock, irq_flags); + return; + } + + if (slab->s_free == FREELIST_END) { + queue_delete(&cache->c_slabs_full, &slab->s_list); + } else { + queue_delete(&cache->c_slabs_partial, &slab->s_list); + } + + unsigned int slot = pointer_to_slot(slab, p); + slab_free_slot(slab, slot); + + if (slab->s_obj_allocated == 0) { + queue_push_back(&cache->c_slabs_empty, &slab->s_list); + } else { + queue_push_back(&cache->c_slabs_partial, &slab->s_list); + } + + spin_unlock_irqrestore(&cache->c_lock, irq_flags); } diff --git a/sandbox/vm/kmalloc.c b/sandbox/vm/kmalloc.c index 031e14f..8ce78fe 100644 --- a/sandbox/vm/kmalloc.c +++ b/sandbox/vm/kmalloc.c @@ -57,11 +57,17 @@ void *kzalloc(size_t count, vm_flags_t flags) if (p) { memset(p, 0x0, count); } - + return p; } void kfree(void *p) { - /* TODO */ + phys_addr_t phys = vm_virt_to_phys(p); + vm_page_t *pg = vm_page_get(phys); + if (!pg || !pg->p_slab) { + return; + } + + vm_cache_free(pg->p_slab->s_cache, p); }