refactor: vmm_set_map has option to ignore existed mapping.
authorMinep <zelong56@gmail.com>
Sat, 18 Jun 2022 10:16:23 +0000 (11:16 +0100)
committerMinep <zelong56@gmail.com>
Sat, 18 Jun 2022 10:16:23 +0000 (11:16 +0100)
chore: optimize memcpy and memset with x86 feature.

lunaix-os/includes/lunaix/mm/vmm.h
lunaix-os/kernel/k_init.c
lunaix-os/kernel/mm/cow.c
lunaix-os/kernel/mm/dmm.c
lunaix-os/kernel/mm/vmm.c
lunaix-os/kernel/proc0.c
lunaix-os/kernel/process.c
lunaix-os/kernel/sched.c
lunaix-os/libs/klibc/string/mem.c

index 4a22cd7fdfa66ce75d3f29036d91dee44cff652d..5d88f3c75b7f5e45a826de5db480beaa7ab46ad6 100644 (file)
@@ -6,6 +6,9 @@
 #include <stdint.h>
 // Virtual memory manager
 
+#define VMAP_NULL 0
+#define VMAP_IGNORE 1
+
 /**
  * @brief 初始化虚拟内存管理器
  *
@@ -31,7 +34,11 @@ vmm_init_pd();
  * @return int
  */
 int
-vmm_set_mapping(uintptr_t mnt, uintptr_t va, uintptr_t pa, pt_attr attr);
+vmm_set_mapping(uintptr_t mnt,
+                uintptr_t va,
+                uintptr_t pa,
+                pt_attr attr,
+                int options);
 
 /**
  * @brief 删除一个映射
@@ -41,7 +48,7 @@ vmm_set_mapping(uintptr_t mnt, uintptr_t va, uintptr_t pa, pt_attr attr);
  * @param va
  * @return int
  */
-int
+uintptr_t
 vmm_del_mapping(uintptr_t mnt, uintptr_t va);
 
 /**
index 971464c9f705a722d4243a8060d142a1f5ab7894..7600caf21e07d348c8e9556a1f23ba12e48aca62 100644 (file)
@@ -83,8 +83,11 @@ _kernel_init()
     // 为内核创建一个专属栈空间。
     for (size_t i = 0; i < (KSTACK_SIZE >> PG_SIZE_BITS); i++) {
         uintptr_t pa = pmm_alloc_page(KERNEL_PID, 0);
-        vmm_set_mapping(
-          PD_REFERENCED, KSTACK_START + (i << PG_SIZE_BITS), pa, PG_PREM_RW);
+        vmm_set_mapping(PD_REFERENCED,
+                        KSTACK_START + (i << PG_SIZE_BITS),
+                        pa,
+                        PG_PREM_RW,
+                        VMAP_NULL);
     }
     kprintf(KINFO "[MM] Allocated %d pages for stack start at %p\n",
             KSTACK_SIZE >> PG_SIZE_BITS,
@@ -207,7 +210,8 @@ setup_memory(multiboot_memory_map_t* map, size_t map_size)
         vmm_set_mapping(PD_REFERENCED,
                         VGA_BUFFER_VADDR + (i << PG_SIZE_BITS),
                         VGA_BUFFER_PADDR + (i << PG_SIZE_BITS),
-                        PG_PREM_URW);
+                        PG_PREM_URW,
+                        VMAP_NULL);
     }
 
     // 更新VGA缓冲区位置至虚拟地址
index 5f35e9b24ae27c48ec874edab57adf680f2dcf5a..81e064892cb480cbdcaf8a602e4922f7485966ad 100644 (file)
@@ -4,8 +4,8 @@ void*
 vmm_dup_page(pid_t pid, void* pa)
 {
     void* new_ppg = pmm_alloc_page(pid, 0);
-    vmm_set_mapping(PD_REFERENCED, PG_MOUNT_3, new_ppg, PG_PREM_RW);
-    vmm_set_mapping(PD_REFERENCED, PG_MOUNT_4, pa, PG_PREM_RW);
+    vmm_set_mapping(PD_REFERENCED, PG_MOUNT_3, new_ppg, PG_PREM_RW, VMAP_NULL);
+    vmm_set_mapping(PD_REFERENCED, PG_MOUNT_4, pa, PG_PREM_RW, VMAP_NULL);
 
     asm volatile("movl %1, %%edi\n"
                  "movl %2, %%esi\n"
index cb87202e82c33c18a373dcffb5f7def06bbca515..44f0f9e897d2d176a65c260f38744fb3aa3a4c6a 100644 (file)
@@ -57,8 +57,8 @@ dmm_init(heap_context_t* heap)
         perm = 0;
     }
 
-    return vmm_set_mapping(PD_REFERENCED, heap->brk, 0, PG_WRITE | perm) !=
-           NULL;
+    return vmm_set_mapping(
+             PD_REFERENCED, heap->brk, 0, PG_WRITE | perm, VMAP_NULL) != NULL;
 }
 
 int
@@ -93,7 +93,8 @@ lxsbrk(heap_context_t* heap, size_t size, int user)
             vmm_set_mapping(PD_REFERENCED,
                             PG_ALIGN(current_brk) + PG_SIZE + i,
                             0,
-                            PG_WRITE | user);
+                            PG_WRITE | user,
+                            VMAP_NULL);
         }
     }
 
index 55fe52ba22e1509b58997f6d9fa5de6810aa58cb..1453c89e65b10d505f9f380e19c284538aee5180 100644 (file)
@@ -4,8 +4,6 @@
 #include <lunaix/mm/vmm.h>
 #include <lunaix/spike.h>
 
-#include <stdbool.h>
-
 void
 vmm_init()
 {
@@ -28,7 +26,11 @@ vmm_init_pd()
 }
 
 int
-vmm_set_mapping(uintptr_t mnt, uintptr_t va, uintptr_t pa, pt_attr attr)
+vmm_set_mapping(uintptr_t mnt,
+                uintptr_t va,
+                uintptr_t pa,
+                pt_attr attr,
+                int options)
 {
     assert((uintptr_t)va % PG_SIZE == 0);
 
@@ -51,6 +53,11 @@ vmm_set_mapping(uintptr_t mnt, uintptr_t va, uintptr_t pa, pt_attr attr)
         // This must be writable
         l1pt->entry[l1_inx] = NEW_L1_ENTRY(attr | PG_WRITE, new_l1pt_pa);
         memset((void*)l2pt, 0, PG_SIZE);
+    } else {
+        x86_pte_t pte = l2pt->entry[l2_inx];
+        if (pte && (options & VMAP_IGNORE)) {
+            return 1;
+        }
     }
 
     if (mnt == PD_REFERENCED) {
@@ -61,7 +68,7 @@ vmm_set_mapping(uintptr_t mnt, uintptr_t va, uintptr_t pa, pt_attr attr)
     return 1;
 }
 
-int
+uintptr_t
 vmm_del_mapping(uintptr_t mnt, uintptr_t va)
 {
     assert(((uintptr_t)va & 0xFFFU) == 0);
@@ -84,14 +91,16 @@ vmm_del_mapping(uintptr_t mnt, uintptr_t va)
 
         cpu_invplg(va);
         l2pt->entry[l2_index] = PTE_NULL;
+
+        return PG_ENTRY_ADDR(l2pte);
     }
+
+    return 0;
 }
 
 int
 vmm_lookup(uintptr_t va, v_mapping* mapping)
 {
-    // va = va & ~0xfff;
-
     uint32_t l1_index = L1_INDEX(va);
     uint32_t l2_index = L2_INDEX(va);
 
index 2331c9fc8381aef3803d9cdc0f6c977448a43603..542ef1c72469439f247f4bb60d7a3d8560a7022c 100644 (file)
@@ -93,8 +93,9 @@ init_platform()
     pmm_mark_page_occupied(KERNEL_PID, FLOOR(ioapic_addr, PG_SIZE_BITS), 0);
 
     vmm_set_mapping(
-      PD_REFERENCED, APIC_BASE_VADDR, __APIC_BASE_PADDR, PG_PREM_RW);
-    vmm_set_mapping(PD_REFERENCED, IOAPIC_BASE_VADDR, ioapic_addr, PG_PREM_RW);
+      PD_REFERENCED, APIC_BASE_VADDR, __APIC_BASE_PADDR, PG_PREM_RW, VMAP_NULL);
+    vmm_set_mapping(
+      PD_REFERENCED, IOAPIC_BASE_VADDR, ioapic_addr, PG_PREM_RW, VMAP_NULL);
 
     apic_init();
     ioapic_init();
@@ -115,7 +116,7 @@ lock_reserved_memory()
     multiboot_memory_map_t* mmaps = _k_init_mb_info->mmap_addr;
     size_t map_size =
       _k_init_mb_info->mmap_length / sizeof(multiboot_memory_map_t);
-    v_mapping mapping;
+    // v_mapping mapping;
     for (unsigned int i = 0; i < map_size; i++) {
         multiboot_memory_map_t mmap = mmaps[i];
         if (mmap.type == MULTIBOOT_MEMORY_AVAILABLE) {
@@ -125,10 +126,10 @@ lock_reserved_memory()
         size_t pg_num = CEIL(mmap.len_low, PG_SIZE_BITS);
         for (size_t j = 0; j < pg_num; j++) {
             uintptr_t _pa = pa + (j << PG_SIZE_BITS);
-            if (vmm_lookup(_pa, &mapping) && *mapping.pte) {
-                continue;
-            }
-            vmm_set_mapping(PD_REFERENCED, _pa, _pa, PG_PREM_R);
+            // if (vmm_lookup(_pa, &mapping) && *mapping.pte) {
+            //     continue;
+            // }
+            vmm_set_mapping(PD_REFERENCED, _pa, _pa, PG_PREM_R, VMAP_IGNORE);
             pmm_mark_page_occupied(KERNEL_PID, _pa >> 12, 0);
         }
     }
index 2e3e356685be91b5b183760becc7c72379241c36..c4e348f19b9dc96844f5cd71d33bd92136dbb2c0 100644 (file)
@@ -16,7 +16,7 @@ void*
 __dup_pagetable(pid_t pid, uintptr_t mount_point)
 {
     void* ptd_pp = pmm_alloc_page(pid, PP_FGPERSIST);
-    vmm_set_mapping(PD_REFERENCED, PG_MOUNT_1, ptd_pp, PG_PREM_RW);
+    vmm_set_mapping(PD_REFERENCED, PG_MOUNT_1, ptd_pp, PG_PREM_RW, VMAP_NULL);
 
     x86_page_table* ptd = PG_MOUNT_1;
     x86_page_table* pptd = (x86_page_table*)(mount_point | (0x3FF << 12));
@@ -29,7 +29,8 @@ __dup_pagetable(pid_t pid, uintptr_t mount_point)
         }
 
         void* pt_pp = pmm_alloc_page(pid, PP_FGPERSIST);
-        vmm_set_mapping(PD_REFERENCED, PG_MOUNT_2, pt_pp, PG_PREM_RW);
+        vmm_set_mapping(
+          PD_REFERENCED, PG_MOUNT_2, pt_pp, PG_PREM_RW, VMAP_NULL);
 
         x86_page_table* ppt = (x86_page_table*)(mount_point | (i << 12));
         x86_page_table* pt = PG_MOUNT_2;
index a93c9bb5e37a87802df17a761039793bca0cb607..ab04e66a05290977a923c0d96d61285394728bb1 100644 (file)
@@ -34,7 +34,8 @@ sched_init()
 
     for (size_t i = 0; i <= pg_size; i += 4096) {
         uintptr_t pa = pmm_alloc_page(KERNEL_PID, PP_FGPERSIST);
-        vmm_set_mapping(PD_REFERENCED, &__proc_table + i, pa, PG_PREM_RW);
+        vmm_set_mapping(
+          PD_REFERENCED, &__proc_table + i, pa, PG_PREM_RW, VMAP_NULL);
     }
 
     sched_ctx = (struct scheduler){ ._procs = (struct proc_info*)&__proc_table,
index 0b93a7d065f198ba18cba0c471e2b09990a61c7a..aeaca009510283b7b8b393d31c92deeaa3c551f2 100755 (executable)
@@ -1,14 +1,14 @@
-#include <stdint.h>
 #include <klibc/string.h>
+#include <stdint.h>
 
 void*
 memcpy(void* dest, const void* src, size_t num)
 {
-    uint8_t* dest_ptr = (uint8_t*)dest;
-    const uint8_t* src_ptr = (const uint8_t*)src;
-    for (size_t i = 0; i < num; i++) {
-        *(dest_ptr + i) = *(src_ptr + i);
-    }
+    asm volatile("movl %1, %%edi\n"
+                 "rep movsb\n" ::"S"(src),
+                 "r"(dest),
+                 "c"(num)
+                 : "edi", "memory");
     return dest;
 }
 
@@ -32,10 +32,11 @@ memmove(void* dest, const void* src, size_t num)
 void*
 memset(void* ptr, int value, size_t num)
 {
-    uint8_t* c_ptr = (uint8_t*)ptr;
-    for (size_t i = 0; i < num; i++) {
-        *(c_ptr + i) = (uint8_t)value;
-    }
+    asm volatile("movl %1, %%edi\n"
+                 "rep stosb\n" ::"c"(num),
+                 "r"(ptr),
+                 "a"(value)
+                 : "edi", "memory");
     return ptr;
 }