]> Zhao Yanbai Git Server - kernel.git/commitdiff
fix slub system
authoracevest <zhaoyanbai@126.com>
Sun, 14 Nov 2021 10:55:38 +0000 (18:55 +0800)
committeracevest <zhaoyanbai@126.com>
Sun, 14 Nov 2021 10:55:38 +0000 (18:55 +0800)
.bochsrc
include/page.h
include/system.h
mm/kmem.c
mm/mm.c
mm/slub.c

index 939539de7c357d0bf83fcd9fc836b83d163dd97f..04ffc271a9a8ffded5c00855958d432dc059a8dc 100644 (file)
--- a/.bochsrc
+++ b/.bochsrc
@@ -1313,4 +1313,4 @@ debug_symbols: file="kernel.sym"
 #megs: 64
 #megs: 32
 #megs: 16
-megs: 8
+megs: 32
index e8c8406c5f29e91bda4027968331c8ad8b5385c9..daa3dfeb3f04f9ae2efe46d3655cc41b115e426c 100644 (file)
@@ -128,42 +128,31 @@ void free_pages(unsigned long addr);
 struct kmem_cache {
     const char *name;
 
+    // 预期分配的大小
     unsigned long objsize;
+
+    // 实际分配的大小
     unsigned long size;
+
+    // 对齐
     unsigned long align;
+
+    // 从buddy system批发的页的幂数
     unsigned long order;
+
+    //
     unsigned long objects;
 
+    // 没有完全分配的页的链表及数量
     unsigned int partial_cnt;
     list_head_t partial;
 
+    // 正在分配的页
     page_t *page;
 
     list_head_t list;
 };
 
-// TODO Remove
-typedef struct page_ {
-    // struct page *prev, *next;
-    ListHead list;
-    unsigned int order;
-    unsigned int mapNR;
-    unsigned int count;
-} Page, *pPage;
-
-typedef struct free_area_ {
-    // struct page *prev, *next;
-    ListHead freeList;
-    unsigned char *map;
-    unsigned int mapSize;
-    unsigned int count;
-} FreeArea, *pFreeArea;
-
-pPage old_alloc_pages(unsigned int order);
-void old_free_pages(pPage page);
-// void    free_pages(pPage page, unsigned int order);
-void disp_free_area();
-
 #endif  // ASM
 
 #endif  //_PAGE_H
index 4c477c95dbd2d84cd59d0c8eb827c85b8e1b3a95..5726b370614ab0d052085922cbcb7e8c33fb5b10 100644 (file)
@@ -147,7 +147,7 @@ typedef struct system {
     u64 mm_size;   // Byte
 
     u32 page_count;
-    pPage page_map;
+
     u32 page_bitmap;
 
     u32 *page_dir;
index bc19bd64219c3b074a070bab9efa41fd2ec11ef7..756aebeace3ddd3d63d1650361010319c96c4be6 100644 (file)
--- a/mm/kmem.c
+++ b/mm/kmem.c
@@ -20,34 +20,37 @@ 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;
+    cache->align = align;
 
-    // calculate order
-    unsigned long order;
-    for (order = 1; order < MAX_ORDER; ++order) {
+    // 允许从buddy system最小分配一页
+    unsigned long order = ~0UL;
+    for (order = 0; 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");
+    // 如果没有找到合适的从buddy system分配的大小则失败
+    if (~0UL == cache->order) {
+        panic("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));
 
@@ -78,14 +81,31 @@ void kmem_cache_free(kmem_cache_t *cache, void *addr) {
     slub_free(cache, page, addr);
 }
 
+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;
+    }
+
+    kmem_cache_init(cache, name, size, align);
+
+    unsigned long flags;
+    irq_save(flags);
+
+    list_add(&(cache->list), &slub_caches);
+
+    irq_restore(flags);
+
+    return cache;
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////////
+
 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) {
@@ -94,56 +114,31 @@ void *kmalloc(size_t size, gfp_t gfpflags) {
         }
     }
 
-    // 如果没找到支持的cache则分配失败
-    if (0 == cache) {
-        goto err;
+    if (0 != cache) {
+        addr = kmem_cache_alloc(cache, gfpflags);
     }
 
-    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() {
+void init_kmem_caches() {
     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/mm.c b/mm/mm.c
index 40cf447d5fd2c5561e04ef56ea81574965c410d0..0e7c1f2c0a2107cc8054a8063a6da3faaf9b7ec4 100644 (file)
--- a/mm/mm.c
+++ b/mm/mm.c
@@ -24,9 +24,6 @@
 #include <types.h>
 
 extern char etext, edata, end;
-extern void init_buddy_system();
-extern void init_slub_system();
-extern void init_bootmem();
 
 pde_t __initdata init_pgd[PDECNT_PER_PAGE] __attribute__((__aligned__(PAGE_SIZE)));
 pte_t __initdata init_pgt[PTECNT_PER_PAGE * BOOT_INIT_PAGETBL_CNT] __attribute__((__aligned__(PAGE_SIZE)));
@@ -124,15 +121,17 @@ void init_paging() {
 
 void init_mm() {
     printk("init bootmem alloc...\n");
+    extern void init_bootmem();
     init_bootmem();
     printk("init global paging...\n");
-
     init_paging();
 
     printk("init buddy system...\n");
+    extern void init_buddy_system();
     init_buddy_system();
 
-    printk("init slub system...\n");
-    init_slub_system();
+    printk("init kmem caches...\n");
+    extern void init_kmem_caches();
+    init_kmem_caches();
     printk("memory init finished...\n");
 }
index 393bf504266f1803997eed2d222bedce16d48afd..d700130ced85fb8c31c2236b0d38764488931a02 100644 (file)
--- a/mm/slub.c
+++ b/mm/slub.c
@@ -26,24 +26,44 @@ page_t *get_partial(kmem_cache_t *cache, gfp_t gfpflags) {
     return page;
 }
 
+// 从伙伴系统批发页,并将之初始化成一个链表
 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;
+
+    // 找到该页的管理结构
     page_t *page = va2page(bgn);
 
-    if (0 == page) return 0;
+    //
+    if (0 == page) {
+        return 0;
+    }
 
     end = bgn + cache->objects * cache->size;
 
+#if 1
     unsigned long last = bgn;
     unsigned long addr;
+
+    // 第一遍会将 bgn[0]的地址赋值给bgn[0],也就是 bgn[0] = bgn + 0
+    // 第二遍开始就是 bgn[n-1] = bgn + n
     for (addr = bgn; addr < end; addr += cache->size) {
         *((void **)last) = (void *)addr;
         last = addr;
     }
 
+    // 最后一个赋值为0
     *((void **)last) = 0;
+#else
+    unsigned long addr;
+    for (addr = bgn; addr < end; addr += cache->size) {
+        *(unsigned long *)addr = addr + cache->size;
+    }
+
+    addr = end - cache->size;
+    *(unsigned long *)addr = 0;
+#endif
 
     page->freelist = (void **)bgn;
     page->inuse = 0;
@@ -58,28 +78,26 @@ void *__slub_alloc(kmem_cache_t *cache, gfp_t gfpflags) {
 
     if (cache->page == 0) {
         page = get_partial(cache, gfpflags);
+        // 如果partial为空,则上伙伴系统申请
+        // 否则直接从partial上直接拿一个页来用
         if (page == 0) {
-            page = new_slub(cache, gfpflags);
-            if (page != 0) {
-                cache->page = page;
-            }
+            cache->page = new_slub(cache, gfpflags);
         } else {
             cache->page = page;
         }
     }
 
+    // 从partial和伙伴系统里没申请到页
     if (cache->page == 0) {
         return 0;
     }
 
     object = cache->page->freelist;
 
-    if (object == 0) {
-        cache->page = 0;
-    } else {
-        cache->page->freelist = object[0];
-        cache->page->inuse++;
-    }
+    assert(0 != object);
+
+    cache->page->freelist = object[0];
+    cache->page->inuse++;
 
     return object;
 }
@@ -87,15 +105,21 @@ 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;
+    if (cache == 0) {
+        return 0;
+    }
 
     unsigned long flags;
     irq_save(flags);
 
     if (cache->page == 0 || cache->page->freelist == 0) {
+        // 如果cache还没上buddy system批发页
+        // 或者批发的页已经分配完了
+        // 则需要换新的页: 1. 如果partial里有,就用partial的;2. 如果partial为空则上buddy system批发
         cache->page = 0;
         object = __slub_alloc(cache, gfpflags);
     } else {
+        // 否则分配一个
         object = cache->page->freelist;
         cache->page->freelist = object[0];
         cache->page->inuse++;
@@ -116,10 +140,10 @@ void __slub_free(kmem_cache_t *cache, page_t *page, void *addr) {
     if (page->inuse == 0) {
         list_del(&page->lru);
         free_pages((unsigned long)page2va(page));
-    }
-
-    if (prior == 0) {
-        list_add(&page->lru, &cache->partial);
+    } else {
+        if (prior == 0) {
+            list_add(&page->lru, &cache->partial);
+        }
     }
 }