feat: alignment option of cake allocator for dma buffer
authorMinep <zelong56@gmail.com>
Sun, 3 Jul 2022 15:29:09 +0000 (16:29 +0100)
committerMinep <zelong56@gmail.com>
Sun, 3 Jul 2022 15:34:59 +0000 (16:34 +0100)
fix: ensure a minimium dword alignment
chore: adjust comments, code clean up

lunaix-os/includes/lunaix/mm/cake.h
lunaix-os/includes/lunaix/mm/valloc.h
lunaix-os/kernel/mm/cake.c
lunaix-os/kernel/mm/valloc.c
lunaix-os/kernel/proc0.c

index 8e971d82d3401961b2d26f18b8eabb5a1751c5cc..0312c45d381ac7854a802cb248eb792ac496cbf6 100644 (file)
@@ -1,16 +1,19 @@
-#ifndef __LUNAIX_SLAB_H
-#define __LUNAIX_SLAB_H
+#ifndef __LUNAIX_CAKE_H
+#define __LUNAIX_CAKE_H
 
 #include <lunaix/ds/llist.h>
 
 #define PILE_NAME_MAXLEN 20
 
+#define PILE_CACHELINE 1
+
 struct cake_pile
 {
     struct llist_header piles;
     struct llist_header full;
     struct llist_header partial;
     struct llist_header free;
+    unsigned int offset;
     unsigned int piece_size;
     unsigned int cakes_count;
     unsigned int alloced_pieces;
@@ -33,15 +36,18 @@ struct cake_s
 };
 
 /**
- * @brief 创建一个堆
+ * @brief 创建一个蛋糕
  *
  * @param name 堆名称
- * @param piece_size 每个蛋糕上可以被切分的大小
+ * @param piece_size 每个蛋糕切块儿的大小
  * @param pg_per_cake 每个蛋糕所占据的页数
  * @return struct cake_pile*
  */
 struct cake_pile*
-cake_new_pile(char* name, unsigned int piece_size, unsigned int pg_per_cake);
+cake_new_pile(char* name,
+              unsigned int piece_size,
+              unsigned int pg_per_cake,
+              int options);
 
 /**
  * @brief 拿一块儿蛋糕
index ee646e5f66505cd7e23c0afdb6a38601c12a5df9..076503f70fa762d647f808de7de9860deff70d15 100644 (file)
@@ -7,6 +7,12 @@ valloc(unsigned int size);
 void
 vfree(void* ptr);
 
+void*
+valloc_dma(unsigned int size);
+
+void
+vfree_dma(void* ptr);
+
 void
 valloc_init();
 
index 21172865ceaf498509cfde033f0b89e949f56cbd..fad5bc2525efa8117dc6d2e169fea3861770850d 100644 (file)
@@ -19,7 +19,7 @@
 
 LOG_MODULE("CAKE")
 
-#define SLAB_SIZE PG_SIZE
+#define CACHE_LINE_SIZE 128
 
 struct cake_pile master_pile;
 
@@ -39,8 +39,7 @@ __new_cake(struct cake_pile* pile)
 
     int max_piece = pile->pieces_per_cake;
 
-    cake->first_piece =
-      (void*)((uintptr_t)(cake + 1) + max_piece * sizeof(piece_index_t));
+    cake->first_piece = (void*)((uintptr_t)cake + pile->offset);
     cake->next_free = 0;
 
     piece_index_t* free_list = &cake->free_list;
@@ -58,8 +57,18 @@ void
 __init_pile(struct cake_pile* pile,
             char* name,
             unsigned int piece_size,
-            unsigned int pg_per_cake)
+            unsigned int pg_per_cake,
+            int options)
 {
+    unsigned int offset = sizeof(long);
+
+    // 默认每块儿蛋糕对齐到地址总线宽度
+    if ((options & PILE_CACHELINE)) {
+        // 对齐到128字节缓存行大小,主要用于DMA
+        offset = CACHE_LINE_SIZE;
+    }
+
+    piece_size = ROUNDUP(piece_size, offset);
     *pile = (struct cake_pile){ .piece_size = piece_size,
                                 .cakes_count = 1,
                                 .pieces_per_cake =
@@ -67,6 +76,11 @@ __init_pile(struct cake_pile* pile,
                                   (piece_size + sizeof(piece_index_t)),
                                 .pg_per_cake = pg_per_cake };
 
+    unsigned int overhead_size =
+      sizeof(struct cake_s) + pile->pieces_per_cake * sizeof(piece_index_t);
+
+    pile->offset = ROUNDUP(overhead_size, offset);
+
     strncpy(&pile->pile_name, name, PILE_NAME_MAXLEN);
 
     llist_init_head(&pile->free);
@@ -78,15 +92,18 @@ __init_pile(struct cake_pile* pile,
 void
 cake_init()
 {
-    __init_pile(&master_pile, "master", sizeof(master_pile), 1);
+    __init_pile(&master_pile, "pinkamina", sizeof(master_pile), 1, 0);
 }
 
 struct cake_pile*
-cake_new_pile(char* name, unsigned int piece_size, unsigned int pg_per_cake)
+cake_new_pile(char* name,
+              unsigned int piece_size,
+              unsigned int pg_per_cake,
+              int options)
 {
     struct cake_pile* pile = (struct cake_pile*)cake_grab(&master_pile);
 
-    __init_pile(pile, name, piece_size, pg_per_cake);
+    __init_pile(pile, name, piece_size, pg_per_cake, options);
 
     return pile;
 }
index 44295625f3adb8f6bfe239618e565219a0829657..0c4d4d4020e2167cf85c7a5d304812f80abc144a 100644 (file)
@@ -3,27 +3,40 @@
 #define MAX_CLASS 6
 
 static char piles_names[MAX_CLASS][PILE_NAME_MAXLEN] = {
-    "valloc_128", "valloc_256", "valloc_512",
-    "valloc_1k",  "valloc_2k",  "valloc_4k"
+    "valloc_16",  "valloc_32",  "valloc_64",
+    "valloc_128", "valloc_256", "valloc_512"
+};
+
+static char piles_names_dma[MAX_CLASS][PILE_NAME_MAXLEN] = {
+    "valloc_dma_128", "valloc_dma_512", "valloc_dma_512",
+    "valloc_dma_1k",  "valloc_dma_2k",  "valloc_dma_4k"
 };
 
 static struct cake_pile* piles[MAX_CLASS];
+static struct cake_pile* piles_dma[MAX_CLASS];
 
 void
 valloc_init()
 {
+    for (size_t i = 0; i < MAX_CLASS; i++) {
+        int size = 1 << (i + 4);
+        piles[i] = cake_new_pile(&piles_names[i], size, 1, 0);
+    }
+
+    // DMA 内存保证128字节对齐
     for (size_t i = 0; i < MAX_CLASS; i++) {
         int size = 1 << (i + 7);
-        piles[i] = cake_new_pile(&piles_names[i], size, size > 1024 ? 8 : 1);
+        piles_dma[i] = cake_new_pile(
+          &piles_names_dma[i], size, size > 1024 ? 8 : 1, PILE_CACHELINE);
     }
 }
 
 void*
-valloc(unsigned int size)
+__valloc(unsigned int size, struct cake_pile** segregate_list)
 {
     size_t i = 0;
     for (; i < MAX_CLASS; i++) {
-        if (piles[i]->piece_size > size) {
+        if (segregate_list[i]->piece_size >= size) {
             goto found_class;
         }
     }
@@ -31,16 +44,40 @@ valloc(unsigned int size)
     return NULL;
 
 found_class:
-    return cake_grab(piles[i]);
+    return cake_grab(segregate_list[i]);
 }
 
 void
-vfree(void* ptr)
+__vfree(void* ptr, struct cake_pile** segregate_list)
 {
     size_t i = 0;
     for (; i < MAX_CLASS; i++) {
-        if (cake_release(piles[i], ptr)) {
+        if (cake_release(segregate_list[i], ptr)) {
             return;
         }
     }
+}
+
+void*
+valloc(unsigned int size)
+{
+    return __valloc(size, &piles);
+}
+
+void
+vfree(void* ptr)
+{
+    __vfree(ptr, &piles);
+}
+
+void*
+valloc_dma(unsigned int size)
+{
+    return __valloc(size, &piles_dma);
+}
+
+void
+vfree_dma(void* ptr)
+{
+    __vfree(ptr, &piles_dma);
 }
\ No newline at end of file
index bef7bb7316f896afa4cc8e77c90cdcada4ec672d..e94397492c06d7a272d4d63e6ba4b0fcb6003983 100644 (file)
@@ -128,7 +128,6 @@ init_platform()
     ps2_kbd_init();
     pci_init();
     ahci_init();
-    pci_print_device();
     ahci_list_device();
 
     cake_stats();