From d2dfd97e6d53e2008e7b8a1681744164894a2213 Mon Sep 17 00:00:00 2001 From: acevest Date: Sat, 13 Nov 2021 19:20:22 +0800 Subject: [PATCH] =?utf8?q?=E6=8B=86=E5=88=86slub=E5=92=8Ckmem?= MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit --- Makefile | 2 +- mm/kmem.c | 149 +++++++++++++++++++++++++++++++++++++++++++ mm/slub.c | 187 ++---------------------------------------------------- mm/slub.h | 19 ++++++ 4 files changed, 176 insertions(+), 181 deletions(-) create mode 100644 mm/kmem.c create mode 100644 mm/slub.h diff --git a/Makefile b/Makefile index 3a41967..3ca64e0 100644 --- a/Makefile +++ b/Makefile @@ -11,7 +11,7 @@ KERNELBIN = KERNEL.BIN LINKSCRIPT = scripts/link.ld SRC_DIRS = boot mm lib fs kernel drivers -INC_DIRS = include drivers boot +INC_DIRS = include drivers boot mm CFLAGS += ${INC_DIRS:%=-I%} diff --git a/mm/kmem.c b/mm/kmem.c new file mode 100644 index 0000000..bc19bd6 --- /dev/null +++ b/mm/kmem.c @@ -0,0 +1,149 @@ +/* + * ------------------------------------------------------------------------ + * File Name: kmem.c + * Author: Zhao Yanbai + * 2021-11-13 12:21:11 Saturday CST + * Description: none + * ------------------------------------------------------------------------ + */ + +#include +#include +#include +#include +#include + +static list_head_t slub_caches = LIST_HEAD_INIT(slub_caches); +static kmem_cache_t kmalloc_caches[SLUB_INIT_CACHE_SIZE]; + +bool calculate_params(kmem_cache_t *cache) { + // calculate size + unsigned long size = cache->objsize; + unsigned long align = cache->align; + align = KMALLOC_MIN_ALIGN > align ? KMALLOC_MIN_ALIGN : align; + size = ALIGN(size, align); + size = ALIGN(size, sizeof(void *)); + cache->size = size; + + // calculate order + unsigned long order; + for (order = 1; order < MAX_ORDER; ++order) { + if ((PAGE_SIZE << order) / cache->size >= 4) { + cache->order = order; + break; + } + } + + if (0 == cache->order) { + printk("can not find a valid order\n"); + return false; + } + + cache->objects = (PAGE_SIZE << cache->order) / cache->size; + + if (0 == cache->objects) { + return false; + } + + return true; +} + +bool kmem_cache_init(kmem_cache_t *cache, const char *name, size_t size, size_t align) { + memset(cache, 0, sizeof(kmem_cache_t)); + + cache->name = name; + cache->objsize = size; + cache->align = align; + cache->page = 0; + cache->partial_cnt = 0; + INIT_LIST_HEAD(&(cache->partial)); + + if (!calculate_params(cache)) { + goto err; + } + + return true; +err: + panic("kmem_cache_init can not create cache\n"); + return false; +} + +void *kmem_cache_alloc(kmem_cache_t *cache, gfp_t gfpflags) { return slub_alloc(cache, gfpflags); } + +void kmem_cache_free(kmem_cache_t *cache, void *addr) { + page_t *page = 0; + + page = get_head_page(va2page((unsigned long)addr)); + + slub_free(cache, page, addr); +} + +void *kmalloc(size_t size, gfp_t gfpflags) { + unsigned int i; + kmem_cache_t *cache = 0; + void *addr = 0; + + unsigned long flags; + irq_save(flags); + + for (i = 0; i < SLUB_INIT_CACHE_SIZE; ++i) { + kmem_cache_t *p = kmalloc_caches + i; + if (p->objsize >= size) { + cache = p; + break; + } + } + + // 如果没找到支持的cache则分配失败 + if (0 == cache) { + goto err; + } + + addr = kmem_cache_alloc(cache, gfpflags); + +err: + irq_restore(flags); + + return addr; +} + +void kfree(void *addr) { + unsigned long flags; + irq_save(flags); + + page_t *page = get_head_page(va2page((unsigned long)addr)); + kmem_cache_t *cache = page->cache; + + slub_free(cache, page, addr); + + irq_restore(flags); +} + +kmem_cache_t *kmem_cache_create(const char *name, size_t size, size_t align) { + kmem_cache_t *cache = kmalloc(sizeof(kmem_cache_t), 0); + if (cache == 0) return 0; + + unsigned long flags; + irq_save(flags); + + kmem_cache_init(cache, name, size, align); + + list_add(&(cache->list), &slub_caches); + + irq_restore(flags); + + return cache; +} + +void init_slub_system() { + unsigned int i; + kmem_cache_t *cache; + + for (i = SLUB_MIN_SHIFT; i < SLUB_MAX_SHIFT; ++i) { + cache = kmalloc_caches + i - SLUB_MIN_SHIFT; + kmem_cache_init(cache, "kmalloc", 1UL << i, KMALLOC_MIN_ALIGN); + + list_add(&(cache->list), &slub_caches); + // printk("kmem objsize %d\tsize %d \n", cache->objsize, cache->size); + } +} diff --git a/mm/slub.c b/mm/slub.c index b14bd49..393bf50 100644 --- a/mm/slub.c +++ b/mm/slub.c @@ -9,72 +9,11 @@ #include #include +#include #include #include -list_head_t slub_caches = LIST_HEAD_INIT(slub_caches); - -#define SLUB_MIN_SHIFT 5 -#define SLUB_MAX_SHIFT 16 -#define SLUB_INIT_CACHE_SIZE ((SLUB_MAX_SHIFT) - (SLUB_MIN_SHIFT)) -#define KMALLOC_MIN_SIZE (1UL << (SLUB_MIN_SHIFT)) -#define KMALLOC_MIN_ALIGN (1UL << (SLUB_MIN_SHIFT)) - -static kmem_cache_t kmalloc_caches[SLUB_INIT_CACHE_SIZE]; - -static bool calculate_params(kmem_cache_t *cache) { - // calculate size - unsigned long size = cache->objsize; - unsigned long align = cache->align; - align = KMALLOC_MIN_ALIGN > align ? KMALLOC_MIN_ALIGN : align; - size = ALIGN(size, align); - size = ALIGN(size, sizeof(void *)); - cache->size = size; - - // calculate order - unsigned long order; - for (order = 1; order < MAX_ORDER; ++order) { - if ((PAGE_SIZE << order) / cache->size >= 4) { - cache->order = order; - break; - } - } - - if (0 == cache->order) { - printk("can not find a valid order\n"); - return false; - } - - cache->objects = (PAGE_SIZE << cache->order) / cache->size; - - if (0 == cache->objects) { - return false; - } - - return true; -} - -static bool kmem_cache_init(kmem_cache_t *cache, const char *name, size_t size, size_t align) { - memset(cache, 0, sizeof(kmem_cache_t)); - - cache->name = name; - cache->objsize = size; - cache->align = align; - cache->page = 0; - cache->partial_cnt = 0; - INIT_LIST_HEAD(&(cache->partial)); - - if (!calculate_params(cache)) { - goto err; - } - - return true; -err: - panic("kmem_cache_init can not create cache\n"); - return false; -} - -static page_t *get_partial(kmem_cache_t *cache, gfp_t gfpflags) { +page_t *get_partial(kmem_cache_t *cache, gfp_t gfpflags) { if (list_empty(&cache->partial)) return 0; list_head_t *p = cache->partial.next; @@ -87,7 +26,7 @@ static page_t *get_partial(kmem_cache_t *cache, gfp_t gfpflags) { return page; } -static page_t *new_slub(kmem_cache_t *cache, gfp_t gfpflags) { +page_t *new_slub(kmem_cache_t *cache, gfp_t gfpflags) { // alloc pages from buddy system unsigned long bgn = alloc_pages(gfpflags, cache->order); unsigned long end = 0; @@ -113,7 +52,7 @@ static page_t *new_slub(kmem_cache_t *cache, gfp_t gfpflags) { return page; } -static void *__slub_alloc(kmem_cache_t *cache, gfp_t gfpflags) { +void *__slub_alloc(kmem_cache_t *cache, gfp_t gfpflags) { void **object = 0; page_t *page = 0; @@ -145,7 +84,7 @@ static void *__slub_alloc(kmem_cache_t *cache, gfp_t gfpflags) { return object; } -static void *slub_alloc(kmem_cache_t *cache, gfp_t gfpflags) { +void *slub_alloc(kmem_cache_t *cache, gfp_t gfpflags) { void **object = 0; if (cache == 0) return 0; @@ -167,7 +106,7 @@ static void *slub_alloc(kmem_cache_t *cache, gfp_t gfpflags) { return object; } -static void __slub_free(kmem_cache_t *cache, page_t *page, void *addr) { +void __slub_free(kmem_cache_t *cache, page_t *page, void *addr) { void *prior; void **object = addr; @@ -184,7 +123,7 @@ static void __slub_free(kmem_cache_t *cache, page_t *page, void *addr) { } } -static void slub_free(kmem_cache_t *cache, page_t *page, void *addr) { +void slub_free(kmem_cache_t *cache, page_t *page, void *addr) { unsigned long flags; irq_save(flags); @@ -201,115 +140,3 @@ static void slub_free(kmem_cache_t *cache, page_t *page, void *addr) { irq_restore(flags); } - -void *kmem_cache_alloc(kmem_cache_t *cache, gfp_t gfpflags) { return slub_alloc(cache, gfpflags); } - -void kmem_cache_free(kmem_cache_t *cache, void *addr) { - page_t *page = 0; - - page = get_head_page(va2page((unsigned long)addr)); - - slub_free(cache, page, addr); -} - -void *kmalloc(size_t size, gfp_t gfpflags) { - unsigned int i; - kmem_cache_t *cache = 0; - void *addr = 0; - - unsigned long flags; - irq_save(flags); - - for (i = 0; i < SLUB_INIT_CACHE_SIZE; ++i) { - kmem_cache_t *p = kmalloc_caches + i; - if (p->objsize >= size) { - cache = p; - break; - } - } - - // 如果没找到支持的cache则分配失败 - if (0 == cache) { - goto err; - } - - addr = kmem_cache_alloc(cache, gfpflags); - -err: - irq_restore(flags); - - return addr; -} - -void kfree(void *addr) { - unsigned long flags; - irq_save(flags); - - page_t *page = get_head_page(va2page((unsigned long)addr)); - kmem_cache_t *cache = page->cache; - - slub_free(cache, page, addr); - - irq_restore(flags); -} - -kmem_cache_t *kmem_cache_create(const char *name, size_t size, size_t align) { - kmem_cache_t *cache = kmalloc(sizeof(kmem_cache_t), 0); - if (cache == 0) return 0; - - unsigned long flags; - irq_save(flags); - - kmem_cache_init(cache, name, size, align); - - list_add(&(cache->list), &slub_caches); - - irq_restore(flags); - - return cache; -} - -void init_slub_system() { - unsigned int i; - kmem_cache_t *cache; - - for (i = SLUB_MIN_SHIFT; i < SLUB_MAX_SHIFT; ++i) { - cache = kmalloc_caches + i - SLUB_MIN_SHIFT; - kmem_cache_init(cache, "kmalloc_old", 1UL << i, KMALLOC_MIN_ALIGN); - - list_add(&(cache->list), &slub_caches); - // printk("kmem objsize %d\tsize %d \n", cache->objsize, cache->size); - } - -#if 0 - list_head_t *p; - list_for_each(p, &slub_caches) - { - cache = list_entry(p, kmem_cache_t, list); - printk("cache size %d align %d \n", cache->size, cache->align); - } - -#define SIZE 10000 - void *addrs[SIZE]; - void *addr; - for(i=0; i