feat: lru eviction policy on page caches
authorMinep <zelong56@gmail.com>
Sun, 14 Aug 2022 00:14:07 +0000 (01:14 +0100)
committerMinep <zelong56@gmail.com>
Sun, 14 Aug 2022 00:16:03 +0000 (01:16 +0100)
refactor: interface to file operations operats on inode only, not v_file itself
enhance: enforce more strict compiler options for code quality
chore: tweaks that make compiler happy

33 files changed:
lunaix-os/config/make-cc
lunaix-os/hal/acpi/acpi.c
lunaix-os/hal/acpi/parser/madt_parser.c
lunaix-os/hal/ahci/ahci.c
lunaix-os/hal/ahci/ata.c
lunaix-os/hal/ahci/atapi.c
lunaix-os/hal/ahci/utils.c
lunaix-os/hal/pci.c
lunaix-os/includes/arch/x86/interrupts.h
lunaix-os/includes/hal/ahci/scsi.h
lunaix-os/includes/hal/pci.h
lunaix-os/includes/lib/hash.h
lunaix-os/includes/lunaix/common.h
lunaix-os/includes/lunaix/device.h
lunaix-os/includes/lunaix/ds/llist.h
lunaix-os/includes/lunaix/ds/lru.h [new file with mode: 0644]
lunaix-os/includes/lunaix/fs.h
lunaix-os/includes/lunaix/fs/twifs.h
lunaix-os/includes/lunaix/status.h
lunaix-os/kernel/block.c
lunaix-os/kernel/device.c
lunaix-os/kernel/ds/btrie.c
lunaix-os/kernel/ds/lru.c [new file with mode: 0644]
lunaix-os/kernel/fs/pcache.c
lunaix-os/kernel/fs/twifs/twifs.c
lunaix-os/kernel/fs/vfs.c
lunaix-os/kernel/mm/cake.c
lunaix-os/kernel/mm/valloc.c
lunaix-os/kernel/sched.c
lunaix-os/kernel/syscall.c
lunaix-os/kernel/time/timer.c
lunaix-os/libs/hash.c
lunaix-os/makefile

index 643b4eee1dbefc44c9c9e0f86d9f0c4534b62f8a..7a1899c327622e7abe2fdb86482ceb0b42dc3176 100644 (file)
@@ -4,6 +4,12 @@ AS := i686-elf-as
 
 ARCH_OPT := -D__ARCH_IA32
 O := -O2
-W := -Wall -Wextra -Wno-unknown-pragmas
+W := -Wall -Wextra -Wno-unknown-pragmas \
+               -Wno-unused-function \
+               -Wno-unused-but-set-variable \
+               -Wno-unused-parameter \
+               -Wno-unused-variable\
+               -Werror=incompatible-pointer-types
+               
 CFLAGS := -std=gnu99 -ffreestanding $(O) $(W) $(ARCH_OPT)
 LDFLAGS := -ffreestanding $(O) -nostdlib -lgcc
\ No newline at end of file
index 55c27aea4994876ef99d7232e16f94bb45e8a709..c6a566e47b713849f320920f74eeecd696bc0fdf 100644 (file)
@@ -36,7 +36,8 @@ acpi_init(multiboot_info_t* mb_info)
 
     size_t entry_n = (rsdt->header.length - sizeof(acpi_sdthdr_t)) >> 2;
     for (size_t i = 0; i < entry_n; i++) {
-        acpi_sdthdr_t* sdthdr = ((acpi_apic_t**)&(rsdt->entry))[i];
+        acpi_sdthdr_t* sdthdr =
+          (acpi_sdthdr_t*)((acpi_apic_t**)&(rsdt->entry))[i];
         switch (sdthdr->signature) {
             case ACPI_MADT_SIG:
                 madt_parse((acpi_madt_t*)sdthdr, ctx);
index 8456b57ce9ee2efa54341f31a08aa0f9f3b72fdd..5e9aeb4badf00cc952c66367e1fb65ff77b605e5 100644 (file)
@@ -12,7 +12,8 @@ madt_parse(acpi_madt_t* madt, acpi_context* toc)
 
     // Cosidering only one IOAPIC present (max 24 pins)
     // FIXME: use hash table instead
-    toc->madt.irq_exception = (acpi_intso_t*)vcalloc(24, sizeof(acpi_intso_t*));
+    toc->madt.irq_exception =
+      (acpi_intso_t**)vcalloc(24, sizeof(acpi_intso_t*));
 
     size_t so_idx = 0;
     while (ics_start < ics_end) {
index 0551ee547fe9283bf4c063895bc61db89806d4fd..a04bca7e2551661566e04bc3ca188e73f1dbee33 100644 (file)
@@ -34,7 +34,7 @@ LOG_MODULE("AHCI")
 static struct ahci_hba hba;
 
 void
-__ahci_hba_isr(isr_param param);
+__ahci_hba_isr(const isr_param* param);
 
 int
 ahci_init_device(struct hba_port* port);
@@ -185,7 +185,7 @@ char sata_ifs[][20] = { "Not detected",
                         "SATA III (6.0Gbps)" };
 
 void
-__ahci_hba_isr(isr_param param)
+__ahci_hba_isr(const isr_param* param)
 {
     // TODO: clear the interrupt status
     // TODO: I/O-operation scheduler should be here
@@ -424,11 +424,11 @@ fail:
 }
 
 int
-ahci_identify_device(struct hba_port* port)
+ahci_identify_device(struct hba_device* device)
 {
     // 用于重新识别设备(比如在热插拔的情况下)
-    vfree(port->device);
-    return ahci_init_device(port);
+    vfree(device);
+    return ahci_init_device(device->port);
 }
 
 void
index a2f10ba769bfa49c24e7440baae63b7e98231c65..a77e03b4a87535ee0929911e2a57a5b7485a8a18 100644 (file)
@@ -5,6 +5,14 @@
 #include <lunaix/mm/vmm.h>
 #include <lunaix/spike.h>
 
+void
+sata_read_error(struct hba_port* port)
+{
+    uint32_t tfd = port->regs[HBA_RPxTFD];
+    port->device->last_error = (tfd >> 8) & 0xff;
+    port->device->last_status = tfd & 0xff;
+}
+
 int
 __sata_buffer_io(struct hba_device* dev,
                  uint64_t lba,
@@ -28,7 +36,7 @@ __sata_buffer_io(struct hba_device* dev,
     header->options |= HBA_CMDH_WRITE * (write == 1);
 
     uint16_t count = ICEIL(size, port->device->block_size);
-    struct sata_reg_fis* fis = table->command_fis;
+    struct sata_reg_fis* fis = (struct sata_reg_fis*)table->command_fis;
 
     if ((port->device->flags & HBA_DEV_FEXTLBA)) {
         // 如果该设备支持48位LBA寻址
@@ -87,11 +95,3 @@ sata_write_buffer(struct hba_device* dev,
 {
     return __sata_buffer_io(dev, lba, buffer, size, 1);
 }
-
-void
-sata_read_error(struct hba_port* port)
-{
-    uint32_t tfd = port->regs[HBA_RPxTFD];
-    port->device->last_error = (tfd >> 8) & 0xff;
-    port->device->last_status = tfd & 0xff;
-}
\ No newline at end of file
index 0ef5099404b3bfa5a0f5a1211858743620662835..85c3bab056291fc0542a4b871d3a27e6708427b5 100644 (file)
@@ -41,7 +41,7 @@ scsi_parse_capacity(struct hba_device* device, uint32_t* parameter)
     device->block_size = SCSI_FLIP(*(parameter + 2));
 }
 
-void
+int
 __scsi_buffer_io(struct hba_device* dev,
                  uint64_t lba,
                  void* buffer,
@@ -65,7 +65,7 @@ __scsi_buffer_io(struct hba_device* dev,
 
     uint32_t count = ICEIL(size, port->device->block_size);
 
-    struct sata_reg_fis* fis = table->command_fis;
+    struct sata_reg_fis* fis = (struct sata_reg_fis*)table->command_fis;
     void* cdb = table->atapi_cmd;
     sata_create_fis(fis, ATA_PACKET, (size << 8), 0);
     fis->feature = 1 | ((!write) << 2);
@@ -107,20 +107,20 @@ fail:
     return 0;
 }
 
-void
+int
 scsi_read_buffer(struct hba_device* dev,
                  uint64_t lba,
                  void* buffer,
                  uint32_t size)
 {
-    __scsi_buffer_io(dev, lba, buffer, size, 0);
+    return __scsi_buffer_io(dev, lba, buffer, size, 0);
 }
 
-void
+int
 scsi_write_buffer(struct hba_device* dev,
                   uint64_t lba,
                   void* buffer,
                   uint32_t size)
 {
-    __scsi_buffer_io(dev, lba, buffer, size, 1);
+    return __scsi_buffer_io(dev, lba, buffer, size, 1);
 }
\ No newline at end of file
index e101efdd42d300c11f504bb5f7beff4f6de70abc..664488dbe3f0a1b5969516533b2c598ef36242b0 100644 (file)
@@ -33,8 +33,8 @@ ahci_parse_dev_info(struct hba_device* dev_info, uint16_t* data)
         dev_info->flags |= HBA_DEV_FEXTLBA;
     }
 
-    ahci_parsestr(&dev_info->serial_num, data + IDDEV_OFFSERIALNUM, 10);
-    ahci_parsestr(&dev_info->model, data + IDDEV_OFFMODELNUM, 20);
+    ahci_parsestr(dev_info->serial_num, data + IDDEV_OFFSERIALNUM, 10);
+    ahci_parsestr(dev_info->model, data + IDDEV_OFFMODELNUM, 20);
 }
 
 void
index d6267682475ff74fafdffc7e23eb0796c5caad6b..3d6accfafaacf31dc9d026c44b4a60e471a11191 100644 (file)
@@ -126,7 +126,7 @@ pci_print_device()
                 PCI_INTR_IRQ(pos->intr_info),
                 PCI_INTR_PIN(pos->intr_info));
 #ifdef PCI_PRINT_BAR_LISTING
-        pci_reg_t bar;
+        uint32_t bar;
         for (size_t i = 1; i <= 6; i++) {
             size_t size = pci_bar_sizing(pos, &bar, i);
             if (!bar)
index 94c15e1e7396544f439c457d28f596b096c0f7b4..3643a9ef668a92f2ae4b8f1b81d4a15ba431f67b 100644 (file)
@@ -32,7 +32,7 @@ typedef struct
     unsigned int ss;
 } __attribute__((packed)) isr_param;
 
-typedef void (*int_subscriber)(isr_param*);
+typedef void (*int_subscriber)(const isr_param*);
 
 #pragma region ISR_DECLARATION
 
index 6ba0fc2596df2b6eacdf349a2139bb7ad00f7ccf..0635614abec7d7bfd696a929e5ee980a1aaa7076 100644 (file)
@@ -47,13 +47,13 @@ scsi_create_packet16(struct scsi_cdb16* cdb,
                      uint64_t lba,
                      uint32_t alloc_size);
 
-void
+int
 scsi_read_buffer(struct hba_device* dev,
                  uint64_t lba,
                  void* buffer,
                  uint32_t size);
 
-void
+int
 scsi_write_buffer(struct hba_device* dev,
                   uint64_t lba,
                   void* buffer,
index d622acbfe32a6ddd8438a0c0fd0b1ff34eb096e6..57c04ca6d4661a9b19cc87cf754065482532a5ec 100644 (file)
@@ -69,14 +69,14 @@ struct pci_device
 // PCI Configuration Space (C-Space) r/w:
 //      Refer to "PCI Local Bus Specification, Rev.3, Section 3.2.2.3.2"
 
-inline pci_reg_t
+static inline pci_reg_t
 pci_read_cspace(uint32_t base, int offset)
 {
     io_outl(PCI_CONFIG_ADDR, base | (offset & ~0x3));
     return io_inl(PCI_CONFIG_DATA);
 }
 
-inline void
+static inline void
 pci_write_cspace(uint32_t base, int offset, pci_reg_t data)
 {
     io_outl(PCI_CONFIG_ADDR, base | (offset & ~0x3));
index ad5e98b9772d8d910a1bba6c7981295497b754ad..22998f78ac7c0804142b613bc307b6ea4a3dc7b8 100644 (file)
@@ -6,7 +6,7 @@
 #define HASH_SIZE_BITS 32
 
 uint32_t
-strhash_32(unsigned char* str, uint32_t truncate_to);
+strhash_32(char* str, uint32_t truncate_to);
 
 /**
  * @brief Simple generic hash function
index d341daa341120feca19b36510b7987d657cbcf46..4c8c794f8a1026851d5583c232eb1cf0491b6acd 100644 (file)
@@ -32,8 +32,6 @@
 #define USTACK_END (0x9fffffff - USTACK_SIZE + 1)
 #define UMMAP_AREA 0x4D000000
 
-#define SYS_TIMER_FREQUENCY_HZ 2048
-
 #ifndef __ASM__
 #include <stddef.h>
 // From Linux kernel v2.6.0 <kernel.h:194>
index 08d25c4a2776ee399e450951ce82efd582823485..14558a7ce840ccb3458ef58355ba056f427ea42b 100644 (file)
@@ -14,14 +14,8 @@ struct device
     char name_val[DEVICE_NAME_SIZE];
     void* underlay;
     void* fs_node;
-    int (*read)(struct device* dev,
-                void* buf,
-                unsigned int offset,
-                unsigned int len);
-    int (*write)(struct device* dev,
-                 void* buf,
-                 unsigned int offset,
-                 unsigned int len);
+    int (*read)(struct device* dev, void* buf, size_t offset, size_t len);
+    int (*write)(struct device* dev, void* buf, size_t offset, size_t len);
 };
 
 void
index 9af9dd1fba4ebe90fe86090e3e72438492cea95e..6129ca05a83bd015b20058c8c9ac1bd68276e69c 100644 (file)
@@ -41,13 +41,13 @@ llist_init_head(struct llist_header* head)
 static inline void
 llist_append(struct llist_header* head, struct llist_header* elem)
 {
-    __llist_add(elem, head, head->next);
+    __llist_add(elem, head->prev, head);
 }
 
 static inline void
 llist_prepend(struct llist_header* head, struct llist_header* elem)
 {
-    __llist_add(elem, head->prev, head);
+    __llist_add(elem, head, head->next);
 }
 
 static inline void
diff --git a/lunaix-os/includes/lunaix/ds/lru.h b/lunaix-os/includes/lunaix/ds/lru.h
new file mode 100644 (file)
index 0000000..5ae607d
--- /dev/null
@@ -0,0 +1,29 @@
+#ifndef __LUNAIX_LRU_H
+#define __LUNAIX_LRU_H
+
+#include <lunaix/ds/llist.h>
+
+struct lru_zone
+{
+    struct llist_header lead_node;
+    struct llist_header zones;
+};
+
+struct lru_node
+{
+    struct llist_header lru_nodes;
+};
+
+struct lru_zone*
+lru_new_zone();
+
+void
+lru_use_one(struct lru_zone* zone, struct lru_node* node);
+
+struct lru_node*
+lru_evict_one(struct lru_zone* zone);
+
+void
+lru_remove(struct lru_node* node);
+
+#endif /* __LUNAIX_LRU_H */
index fd09e965537d47b1519074c018815c9aabfeea46..d0d59d10a0d83b01a9286b098439b90b5d5bb462 100644 (file)
@@ -8,6 +8,7 @@
 #include <lunaix/ds/hashtable.h>
 #include <lunaix/ds/hstr.h>
 #include <lunaix/ds/llist.h>
+#include <lunaix/ds/lru.h>
 #include <lunaix/status.h>
 
 #define VFS_NAME_MAXLEN 128
 #define FSTYPE_ROFS 0x1
 
 #define VFS_VALID_CHAR(chr)                                                    \
-    ('A' <= (chr) && (chr) <= 'Z' || 'a' <= (chr) && (chr) <= 'z' ||           \
-     '0' <= (chr) && (chr) <= '9' || (chr) == '.' || (chr) == '_' ||           \
+    (('A' <= (chr) && (chr) <= 'Z') || ('a' <= (chr) && (chr) <= 'z') ||       \
+     ('0' <= (chr) && (chr) <= '9') || (chr) == '.' || (chr) == '_' ||         \
      (chr) == '-')
 
 extern struct hstr vfs_ddot;
 extern struct hstr vfs_dot;
 
 struct v_dnode;
+struct v_inode;
+struct v_superblock;
+struct v_file;
+struct v_fd;
 struct pcache;
 
 struct filesystem
@@ -73,13 +78,13 @@ struct dir_context
 
 struct v_file_ops
 {
-    int (*write)(struct v_file* file, void* buffer, size_t len, size_t fpos);
-    int (*read)(struct v_file* file, void* buffer, size_t len, size_t fpos);
-    int (*readdir)(struct v_file* file, struct dir_context* dctx);
-    int (*seek)(struct v_file* file, size_t offset);
-    int (*rename)(struct v_file* file, char* new_name);
+    int (*write)(struct v_inode* inode, void* buffer, size_t len, size_t fpos);
+    int (*read)(struct v_inode* inode, void* buffer, size_t len, size_t fpos);
+    int (*readdir)(struct v_inode* inode, struct dir_context* dctx);
+    int (*seek)(struct v_inode* inode, size_t offset);
+    int (*rename)(struct v_inode* inode, char* new_name);
     int (*close)(struct v_file* file);
-    int (*sync)(struct v_file* file);
+    int (*sync)(struct v_inode* inode);
 };
 
 struct v_file
@@ -89,7 +94,6 @@ struct v_file
     struct llist_header* f_list;
     uint32_t f_pos;
     uint32_t ref_count;
-    void* data; // 允许底层FS绑定他的一些专有数据
     struct v_file_ops ops;
 };
 
@@ -153,6 +157,7 @@ struct pcache_pg
 {
     struct llist_header pg_list;
     struct llist_header dirty_list;
+    struct lru_node lru;
     void* pg;
     uint32_t flags;
     uint32_t fpos;
@@ -160,6 +165,7 @@ struct pcache_pg
 
 struct pcache
 {
+    struct v_inode* master;
     struct btrie tree;
     struct llist_header pages;
     struct llist_header dirty;
@@ -257,20 +263,20 @@ pcache_get_page(struct pcache* pcache,
                 struct pcache_pg** page);
 
 int
-pcache_write(struct v_file* file, void* data, uint32_t len, uint32_t fpos);
+pcache_write(struct v_inode* inode, void* data, uint32_t len, uint32_t fpos);
 
 int
-pcache_read(struct v_file* file, void* data, uint32_t len, uint32_t fpos);
+pcache_read(struct v_inode* inode, void* data, uint32_t len, uint32_t fpos);
 
 void
 pcache_release(struct pcache* pcache);
 
 int
-pcache_commit(struct v_file* file, struct pcache_pg* page);
+pcache_commit(struct v_inode* inode, struct pcache_pg* page);
 
 void
-pcache_invalidate(struct v_file* file, struct pcache_pg* page);
+pcache_commit_all(struct v_inode* inode);
 
 void
-pcache_commit_all(struct v_file* file);
+pcache_invalidate(struct pcache* pcache, struct pcache_pg* page);
 #endif /* __LUNAIX_VFS_H */
index f2d6b15bf2197eae356b7165c81f93bbb1e30bc9..22028f3c8880ac0462fd6cb4e0fd9e7ba6cecc02 100644 (file)
@@ -13,11 +13,14 @@ struct twifs_node
     struct llist_header siblings;
     struct
     {
-        int (*write)(struct v_file* file,
+        int (*write)(struct v_inode* inode,
                      void* buffer,
                      size_t len,
                      size_t fpos);
-        int (*read)(struct v_file* file, void* buffer, size_t len, size_t fpos);
+        int (*read)(struct v_inode* inode,
+                    void* buffer,
+                    size_t len,
+                    size_t fpos);
     } ops;
 };
 
index 9bb6b4bd45107008797e95e5482dd01b81d4c243..3d300f20f89fcaaf83b2bf85fb1abdc69500d9f0 100644 (file)
@@ -27,5 +27,6 @@
 #define ELOOP -22
 #define ENODEV -23
 #define ERANGE -24
+#define ENOMEM LXOUTOFMEM
 
 #endif /* __LUNAIX_CODE_H */
index 97e9bd69d83d286e2705a943d3366109414d250c..b855910ffc18fc12a1506e105540dda74fc62964 100644 (file)
@@ -39,10 +39,7 @@ block_init()
 }
 
 int
-__block_read(struct device* dev,
-             void* buf,
-             unsigned int offset,
-             unsigned int len)
+__block_read(struct device* dev, void* buf, size_t offset, size_t len)
 {
     int errno;
     struct block_dev* bdev = (struct block_dev*)dev->underlay;
@@ -72,10 +69,7 @@ error:
 }
 
 int
-__block_write(struct device* dev,
-              void* buf,
-              unsigned int offset,
-              unsigned int len)
+__block_write(struct device* dev, void* buf, size_t offset, size_t len)
 {
     int errno;
     struct block_dev* bdev = (struct block_dev*)dev->underlay;
index 2471a9cc8aac18d3cb897f5ecb3678033d5d086d..017f3b331114c5da0984a90b3632cb14f5f8565d 100644 (file)
@@ -8,10 +8,10 @@ struct llist_header dev_list;
 static struct twifs_node* dev_root;
 
 int
-__dev_read(struct v_file* file, void* buffer, size_t len, size_t fpos);
+__dev_read(struct v_inode* inode, void* buffer, size_t len, size_t fpos);
 
 int
-__dev_write(struct v_file* file, void* buffer, size_t len, size_t fpos);
+__dev_write(struct v_inode* inode, void* buffer, size_t len, size_t fpos);
 
 void
 device_init()
@@ -78,9 +78,9 @@ device_addvol(struct device* parent, void* underlay, char* name_fmt, ...)
 }
 
 int
-__dev_read(struct v_file* file, void* buffer, size_t len, size_t fpos)
+__dev_read(struct v_inode* inode, void* buffer, size_t len, size_t fpos)
 {
-    struct twifs_node* dev_node = (struct twifs_node*)file->inode->data;
+    struct twifs_node* dev_node = (struct twifs_node*)inode->data;
     struct device* dev = (struct device*)dev_node->data;
 
     if (!dev->read) {
@@ -90,9 +90,9 @@ __dev_read(struct v_file* file, void* buffer, size_t len, size_t fpos)
 }
 
 int
-__dev_write(struct v_file* file, void* buffer, size_t len, size_t fpos)
+__dev_write(struct v_inode* inode, void* buffer, size_t len, size_t fpos)
 {
-    struct twifs_node* dev_node = (struct twifs_node*)file->inode->data;
+    struct twifs_node* dev_node = (struct twifs_node*)inode->data;
     struct device* dev = (struct device*)dev_node->data;
 
     if (!dev->write) {
index fd173b9455c701b99ff60b12ed9ae7a3acb7b01c..8a4380e4c19da2320979f8462a71c5ee367c9b1b 100644 (file)
@@ -83,15 +83,16 @@ btrie_set(struct btrie* root, uint32_t index, void* data)
 }
 
 void
-__btrie_remove(struct btrie_node* node)
+__btrie_rm_recursive(struct btrie_node* node)
 {
     struct btrie_node* parent = node->parent;
+
     if (parent) {
         llist_delete(&node->siblings);
         llist_delete(&node->nodes);
         vfree(node);
-        if (llist_empty(&parent->children)) {
-            __btrie_remove(parent);
+        if (llist_empty(&parent->children) && !parent->data) {
+            __btrie_rm_recursive(parent);
         }
     }
 }
@@ -104,7 +105,11 @@ btrie_remove(struct btrie* root, uint32_t index)
         return 0;
     }
     void* data = node->data;
-    __btrie_remove(node);
+    if (!llist_empty(&node->children)) {
+        node->data = NULL;
+    } else {
+        __btrie_rm_recursive(node);
+    }
     return data;
 }
 
diff --git a/lunaix-os/kernel/ds/lru.c b/lunaix-os/kernel/ds/lru.c
new file mode 100644 (file)
index 0000000..ebabeef
--- /dev/null
@@ -0,0 +1,49 @@
+#include <lunaix/ds/lru.h>
+#include <lunaix/mm/valloc.h>
+
+struct llist_header zone_lead = { .next = &zone_lead, .prev = &zone_lead };
+
+struct lru_zone*
+lru_new_zone()
+{
+    struct lru_zone* zone = valloc(sizeof(struct lru_zone));
+    if (!zone) {
+        return NULL;
+    }
+
+    llist_init_head(&zone->lead_node);
+    llist_append(&zone_lead, &zone->zones);
+
+    return zone;
+}
+
+void
+lru_use_one(struct lru_zone* zone, struct lru_node* node)
+{
+    if (node->lru_nodes.next && node->lru_nodes.prev) {
+        llist_delete(&node->lru_nodes);
+    }
+
+    llist_prepend(&zone->lead_node, &node->lru_nodes);
+}
+
+struct lru_node*
+lru_evict_one(struct lru_zone* zone)
+{
+    struct llist_header* tail = zone->lead_node.prev;
+    if (tail == &zone->lead_node) {
+        return;
+    }
+
+    llist_delete(tail);
+
+    return container_of(tail, struct lru_node, lru_nodes);
+}
+
+void
+lru_remove(struct lru_node* node)
+{
+    if (node->lru_nodes.next && node->lru_nodes.prev) {
+        llist_delete(&node->lru_nodes);
+    }
+}
\ No newline at end of file
index 3db75718592896c96b0968c73c70b84dd2760240..03f7502072d9acab6c98fd688b0ecb4e708bb1e2 100644 (file)
@@ -9,19 +9,21 @@
 
 #define PCACHE_DIRTY 0x1
 
+static struct lru_zone* pcache_zone;
+
 void
 pcache_init(struct pcache* pcache)
 {
     btrie_init(&pcache->tree, PG_SIZE_BITS);
     llist_init_head(&pcache->dirty);
     llist_init_head(&pcache->pages);
+    pcache_zone = lru_new_zone();
 }
 
 void
 pcache_release_page(struct pcache* pcache, struct pcache_pg* page)
 {
-    pmm_free_page(KERNEL_PID, page->pg);
-    vmm_del_mapping(PD_REFERENCED, page->pg);
+    vfree(page->pg);
 
     llist_delete(&page->pg_list);
 
@@ -30,13 +32,36 @@ pcache_release_page(struct pcache* pcache, struct pcache_pg* page)
     pcache->n_pages--;
 }
 
+void
+pcache_evict(struct pcache* pcache)
+{
+    struct pcache_pg* page =
+      container_of(lru_evict_one(pcache_zone), struct pcache_pg, lru);
+
+    if (!page)
+        return;
+
+    pcache_invalidate(pcache, page);
+}
+
 struct pcache_pg*
 pcache_new_page(struct pcache* pcache, uint32_t index)
 {
-    void* pg = pmm_alloc_page(KERNEL_PID, 0);
-    void* pg_v = vmm_vmap(pg, PG_SIZE, PG_PREM_URW);
     struct pcache_pg* ppg = vzalloc(sizeof(struct pcache_pg));
-    ppg->pg = pg_v;
+    void* pg = valloc(PG_SIZE);
+
+    if (!ppg || !pg) {
+        pcache_evict(pcache);
+        if (!ppg && !(ppg = vzalloc(sizeof(struct pcache_pg)))) {
+            return NULL;
+        }
+
+        if (!pg && !(pg = valloc(PG_SIZE))) {
+            return NULL;
+        }
+    }
+
+    ppg->pg = pg;
 
     llist_append(&pcache->pages, &ppg->pg_list);
     btrie_set(&pcache->tree, index, ppg);
@@ -63,25 +88,30 @@ pcache_get_page(struct pcache* pcache,
     struct pcache_pg* pg = btrie_get(&pcache->tree, index);
     int is_new = 0;
     *offset = index & ((1 << pcache->tree.truncated) - 1);
-    if (!pg) {
-        pg = pcache_new_page(pcache, index);
+    if (!pg && (pg = pcache_new_page(pcache, index))) {
         pg->fpos = index - *offset;
         pcache->n_pages++;
         is_new = 1;
     }
+    if (pg)
+        lru_use_one(pcache_zone, &pg->lru);
     *page = pg;
     return is_new;
 }
 
 int
-pcache_write(struct v_file* file, void* data, uint32_t len, uint32_t fpos)
+pcache_write(struct v_inode* inode, void* data, uint32_t len, uint32_t fpos)
 {
     uint32_t pg_off, buf_off = 0;
-    struct pcache* pcache = file->inode->pg_cache;
+    struct pcache* pcache = inode->pg_cache;
     struct pcache_pg* pg;
 
     while (buf_off < len) {
         pcache_get_page(pcache, fpos, &pg_off, &pg);
+        if (!pg) {
+            return ENOMEM;
+        }
+
         uint32_t wr_bytes = MIN(PG_SIZE - pg_off, len - buf_off);
         memcpy(pg->pg + pg_off, (data + buf_off), wr_bytes);
 
@@ -95,18 +125,22 @@ pcache_write(struct v_file* file, void* data, uint32_t len, uint32_t fpos)
 }
 
 int
-pcache_read(struct v_file* file, void* data, uint32_t len, uint32_t fpos)
+pcache_read(struct v_inode* inode, void* data, uint32_t len, uint32_t fpos)
 {
     uint32_t pg_off, buf_off = 0, new_pg = 0;
     int errno = 0;
-    struct pcache* pcache = file->inode->pg_cache;
+    struct pcache* pcache = inode->pg_cache;
     struct pcache_pg* pg;
-    struct v_inode* inode = file->inode;
 
     while (buf_off < len) {
         if (pcache_get_page(pcache, fpos, &pg_off, &pg)) {
+
+            if (!pg) {
+                return ENOMEM;
+            }
+
             // Filling up the page
-            errno = inode->default_fops.read(file, pg->pg, PG_SIZE, pg->fpos);
+            errno = inode->default_fops.read(inode, pg->pg, PG_SIZE, pg->fpos);
             if (errno >= 0 && errno < PG_SIZE) {
                 // EOF
                 len = buf_off + errno;
@@ -130,6 +164,7 @@ pcache_release(struct pcache* pcache)
     struct pcache_pg *pos, *n;
     llist_for_each(pos, n, &pcache->pages, pg_list)
     {
+        lru_remove(&pos->lru);
         vfree(pos);
     }
 
@@ -137,38 +172,38 @@ pcache_release(struct pcache* pcache)
 }
 
 int
-pcache_commit(struct v_file* file, struct pcache_pg* page)
+pcache_commit(struct v_inode* inode, struct pcache_pg* page)
 {
     if (!(page->flags & PCACHE_DIRTY)) {
         return;
     }
 
-    struct v_inode* inode = file->inode;
-    int errno = inode->default_fops.write(file, page->pg, PG_SIZE, page->fpos);
+    int errno = inode->default_fops.write(inode, page->pg, PG_SIZE, page->fpos);
 
     if (!errno) {
         page->flags &= ~PCACHE_DIRTY;
         llist_delete(&page->dirty_list);
-        file->inode->pg_cache->n_dirty--;
+        inode->pg_cache->n_dirty--;
     }
 
     return errno;
 }
 
 void
-pcache_commit_all(struct v_file* file)
+pcache_commit_all(struct v_inode* inode)
 {
-    struct pcache* cache = file->inode->pg_cache;
+    struct pcache* cache = inode->pg_cache;
     struct pcache_pg *pos, *n;
+
     llist_for_each(pos, n, &cache->dirty, dirty_list)
     {
-        pcache_commit(file, pos);
+        pcache_commit(inode, pos);
     }
 }
 
 void
-pcache_invalidate(struct v_file* file, struct pcache_pg* page)
+pcache_invalidate(struct pcache* pcache, struct pcache_pg* page)
 {
-    pcache_commit(file, page);
-    pcache_release_page(&file->inode->pg_cache, page);
+    pcache_commit(pcache->master, page);
+    pcache_release_page(pcache, page);
 }
\ No newline at end of file
index f53508418ed4bea89d23c2cafac0bf793e53438e..ec2707fb6f96ed3388966c60587e20c085da5433 100644 (file)
@@ -32,7 +32,7 @@ struct v_inode*
 __twifs_create_inode(struct twifs_node* twi_node);
 
 int
-__twifs_iterate_dir(struct v_file* file, struct dir_context* dctx);
+__twifs_iterate_dir(struct v_inode* inode, struct dir_context* dctx);
 
 int
 __twifs_mount(struct v_superblock* vsb, struct v_dnode* mount_point);
@@ -44,10 +44,10 @@ int
 __twifs_rmstuff(struct v_inode* inode);
 
 int
-__twifs_fwrite(struct v_file* file, void* buffer, size_t len, size_t fpos);
+__twifs_fwrite(struct v_inode* inode, void* buffer, size_t len, size_t fpos);
 
 int
-__twifs_fread(struct v_file* file, void* buffer, size_t len, size_t fpos);
+__twifs_fread(struct v_inode* inode, void* buffer, size_t len, size_t fpos);
 
 void
 twifs_init()
@@ -186,23 +186,23 @@ __twifs_create_inode(struct twifs_node* twi_node)
 }
 
 int
-__twifs_fwrite(struct v_file* file, void* buffer, size_t len, size_t fpos)
+__twifs_fwrite(struct v_inode* inode, void* buffer, size_t len, size_t fpos)
 {
-    struct twifs_node* twi_node = (struct twifs_node*)file->inode->data;
+    struct twifs_node* twi_node = (struct twifs_node*)inode->data;
     if (!twi_node || !twi_node->ops.write) {
         return ENOTSUP;
     }
-    return twi_node->ops.write(file, buffer, len, fpos);
+    return twi_node->ops.write(inode, buffer, len, fpos);
 }
 
 int
-__twifs_fread(struct v_file* file, void* buffer, size_t len, size_t fpos)
+__twifs_fread(struct v_inode* inode, void* buffer, size_t len, size_t fpos)
 {
-    struct twifs_node* twi_node = (struct twifs_node*)file->inode->data;
+    struct twifs_node* twi_node = (struct twifs_node*)inode->data;
     if (!twi_node || !twi_node->ops.read) {
         return ENOTSUP;
     }
-    return twi_node->ops.read(file, buffer, len, fpos);
+    return twi_node->ops.read(inode, buffer, len, fpos);
 }
 
 struct twifs_node*
@@ -246,9 +246,9 @@ __twifs_dirlookup(struct v_inode* inode, struct v_dnode* dnode)
 }
 
 int
-__twifs_iterate_dir(struct v_file* file, struct dir_context* dctx)
+__twifs_iterate_dir(struct v_inode* inode, struct dir_context* dctx)
 {
-    struct twifs_node* twi_node = (struct twifs_node*)(file->inode->data);
+    struct twifs_node* twi_node = (struct twifs_node*)(inode->data);
     int counter = 0;
     struct twifs_node *pos, *n;
 
index ad9fd709ea501893b4b58657820fae1290c6bd3e..68a8d5fbe2b7aa87b09b4442448f4bbcfc65e133 100644 (file)
@@ -229,7 +229,7 @@ vfs_walk(struct v_dnode* start,
          int options)
 {
     struct v_dnode* interim;
-    char* pathname = path;
+    const char* pathname = path;
     int errno = __vfs_walk(start, path, &interim, component, options);
     int counter = 0;
 
@@ -340,6 +340,7 @@ vfs_open(struct v_dnode* dnode, struct v_file** file)
     if ((inode->itype & VFS_IFFILE) && !inode->pg_cache) {
         struct pcache* pcache = vzalloc(sizeof(struct pcache));
         pcache_init(pcache);
+        pcache->master = inode;
         inode->pg_cache = pcache;
     }
 
@@ -378,7 +379,7 @@ vfs_close(struct v_file* file)
     if (!file->ops.close || !(errno = file->ops.close(file))) {
         file->dnode->ref_count--;
         file->inode->open_count--;
-        pcache_commit_all(file);
+        pcache_commit_all(file->inode);
         cake_release(file_pile, file);
     }
     return errno;
@@ -388,12 +389,9 @@ int
 vfs_fsync(struct v_file* file)
 {
     int errno = ENOTSUP;
-    pcache_commit_all(file);
+    pcache_commit_all(file->inode);
     if (file->ops.sync) {
-        errno = file->ops.sync(file);
-    }
-    if (!errno && file->inode->ops.sync) {
-        return file->inode->ops.sync(file->inode);
+        errno = file->ops.sync(file->inode);
     }
     return errno;
 }
@@ -606,7 +604,7 @@ __DEFINE_LXSYSCALL2(int, readdir, int, fd, struct dirent*, dent)
             __vfs_readdir_callback(&dctx, vfs_ddot.value, vfs_ddot.len, 0);
         } else {
             dctx.index -= 2;
-            if ((errno = fd_s->file->ops.readdir(fd_s->file, &dctx))) {
+            if ((errno = fd_s->file->ops.readdir(fd_s->file->inode, &dctx))) {
                 goto done;
             }
         }
@@ -664,7 +662,7 @@ __DEFINE_LXSYSCALL3(int, read, int, fd, void*, buf, size_t, count)
     }
 
     __SYSCALL_INTERRUPTIBLE(
-      { errno = file->ops.read(file, buf, count, file->f_pos); })
+      { errno = file->ops.read(file->inode, buf, count, file->f_pos); })
 
     if (errno > 0) {
         file->f_pos += errno;
@@ -690,7 +688,7 @@ __DEFINE_LXSYSCALL3(int, write, int, fd, void*, buf, size_t, count)
     }
 
     __SYSCALL_INTERRUPTIBLE(
-      { errno = file->ops.write(file, buf, count, file->f_pos); })
+      { errno = file->ops.write(file->inode, buf, count, file->f_pos); })
 
     if (errno > 0) {
         file->f_pos += errno;
@@ -722,7 +720,7 @@ __DEFINE_LXSYSCALL3(int, lseek, int, fd, int, offset, int, options)
             fpos = offset;
             break;
     }
-    if (!file->ops.seek || !(errno = file->ops.seek(file, fpos))) {
+    if (!file->ops.seek || !(errno = file->ops.seek(file->inode, fpos))) {
         file->f_pos = fpos;
     }
 
@@ -761,7 +759,7 @@ vfs_get_path(struct v_dnode* dnode, char* buf, size_t size, int depth)
 int
 vfs_readlink(struct v_dnode* dnode, char* buf, size_t size)
 {
-    char* link;
+    const char* link;
     if (dnode->inode->ops.read_symlink) {
         int errno = dnode->inode->ops.read_symlink(dnode->inode, &link);
         strncpy(buf, link, size);
@@ -979,7 +977,7 @@ vfs_dup2(int oldfd, int newfd)
     }
 
     newfd_s = __current->fdtable->fds[newfd];
-    if (newfd_s && (errno = vfs_close(newfd_s))) {
+    if (newfd_s && (errno = vfs_close(newfd_s->file))) {
         goto done;
     }
 
index a64b3ea6acf40f02098c3536076325e3dcfe120d..c3cee83d7153b23a7df3f96ff9ce213ce489f126 100644 (file)
@@ -29,6 +29,9 @@ void*
 __alloc_cake(unsigned int cake_pg)
 {
     uintptr_t pa = pmm_alloc_cpage(KERNEL_PID, cake_pg, 0);
+    if (!pa) {
+        return NULL;
+    }
     return vmm_vmap(pa, cake_pg * PG_SIZE, PG_PREM_RW);
 }
 
@@ -37,12 +40,16 @@ __new_cake(struct cake_pile* pile)
 {
     struct cake_s* cake = __alloc_cake(pile->pg_per_cake);
 
+    if (!cake) {
+        return NULL;
+    }
+
     int max_piece = pile->pieces_per_cake;
 
     cake->first_piece = (void*)((uintptr_t)cake + pile->offset);
     cake->next_free = 0;
 
-    piece_index_t* free_list = &cake->free_list;
+    piece_index_t* free_list = cake->free_list;
     for (size_t i = 0; i < max_piece - 1; i++) {
         free_list[i] = i + 1;
     }
@@ -60,6 +67,10 @@ __init_pile(struct cake_pile* pile,
             unsigned int pg_per_cake,
             int options)
 {
+    if (!pile) {
+        return;
+    }
+
     unsigned int offset = sizeof(long);
 
     // 默认每块儿蛋糕对齐到地址总线宽度
@@ -81,7 +92,7 @@ __init_pile(struct cake_pile* pile,
     pile->offset = ROUNDUP(sizeof(struct cake_s) + free_list_size, offset);
     pile->pieces_per_cake -= ICEIL((pile->offset - free_list_size), piece_size);
 
-    strncpy(&pile->pile_name, name, PILE_NAME_MAXLEN);
+    strncpy(pile->pile_name, name, PILE_NAME_MAXLEN);
 
     llist_init_head(&pile->free);
     llist_init_head(&pile->full);
@@ -120,6 +131,9 @@ cake_grab(struct cake_pile* pile)
         pos = list_entry(pile->free.next, typeof(*pos), cakes);
     }
 
+    if (!pos)
+        return NULL;
+
     piece_index_t found_index = pos->next_free;
     pos->next_free = pos->free_list[found_index];
     pos->used_pieces++;
@@ -165,7 +179,7 @@ found:
     pos->used_pieces--;
     pile->alloced_pieces--;
 
-    llist_delete(pos);
+    llist_delete(&pos->cakes);
     if (!pos->used_pieces) {
         llist_append(&pile->free, &pos->cakes);
     } else {
index 04379e1dcf047ea3f6bf1e63a2c658ef7aba4487..a744ed1aeb091ac94f0f7562eb02cb27925fbc07 100644 (file)
@@ -24,14 +24,14 @@ valloc_init()
 {
     for (size_t i = 0; i < CLASS_LEN(piles_names); i++) {
         int size = 1 << (i + 3);
-        piles[i] = cake_new_pile(&piles_names[i], size, size > 1024 ? 8 : 1, 0);
+        piles[i] = cake_new_pile(piles_names[i], size, size > 1024 ? 8 : 1, 0);
     }
 
     // DMA 内存保证128字节对齐
     for (size_t i = 0; i < CLASS_LEN(piles_names_dma); i++) {
         int size = 1 << (i + 7);
         piles_dma[i] = cake_new_pile(
-          &piles_names_dma[i], size, size > 1024 ? 4 : 1, PILE_CACHELINE);
+          piles_names_dma[i], size, size > 1024 ? 4 : 1, PILE_CACHELINE);
     }
 }
 
@@ -65,13 +65,13 @@ __vfree(void* ptr, struct cake_pile** segregate_list, size_t len)
 void*
 valloc(unsigned int size)
 {
-    return __valloc(size, &piles, CLASS_LEN(piles_names), 3);
+    return __valloc(size, piles, CLASS_LEN(piles_names), 3);
 }
 
 void*
 vzalloc(unsigned int size)
 {
-    void* ptr = __valloc(size, &piles, CLASS_LEN(piles_names), 3);
+    void* ptr = __valloc(size, piles, CLASS_LEN(piles_names), 3);
     memset(ptr, 0, size);
     return ptr;
 }
@@ -84,7 +84,7 @@ vcalloc(unsigned int size, unsigned int count)
         return 0;
     }
 
-    void* ptr = __valloc(alloc_size, &piles, CLASS_LEN(piles_names), 3);
+    void* ptr = __valloc(alloc_size, piles, CLASS_LEN(piles_names), 3);
     memset(ptr, 0, alloc_size);
     return ptr;
 }
@@ -92,19 +92,19 @@ vcalloc(unsigned int size, unsigned int count)
 void
 vfree(void* ptr)
 {
-    __vfree(ptr, &piles, CLASS_LEN(piles_names));
+    __vfree(ptr, piles, CLASS_LEN(piles_names));
 }
 
 void*
 valloc_dma(unsigned int size)
 {
-    return __valloc(size, &piles_dma, CLASS_LEN(piles_names_dma), 7);
+    return __valloc(size, piles_dma, CLASS_LEN(piles_names_dma), 7);
 }
 
 void*
 vzalloc_dma(unsigned int size)
 {
-    void* ptr = __valloc(size, &piles_dma, CLASS_LEN(piles_names_dma), 7);
+    void* ptr = __valloc(size, piles_dma, CLASS_LEN(piles_names_dma), 7);
     memset(ptr, 0, size);
     return ptr;
 }
@@ -112,5 +112,5 @@ vzalloc_dma(unsigned int size)
 void
 vfree_dma(void* ptr)
 {
-    __vfree(ptr, &piles_dma, CLASS_LEN(piles_names_dma));
+    __vfree(ptr, piles_dma, CLASS_LEN(piles_names_dma));
 }
\ No newline at end of file
index 4a0e254151799fdc6fc32674a36172c890be16c7..f8f00d40a094d62c31976cd4d54ef577673ba6de 100644 (file)
@@ -279,7 +279,7 @@ alloc_process()
     proc->pgid = proc->pid;
     proc->fdtable = vzalloc(sizeof(struct v_fdtable));
 
-    llist_init_head(&proc->mm.regions);
+    llist_init_head(&proc->mm.regions.head);
     llist_init_head(&proc->children);
     llist_init_head(&proc->grp_member);
     llist_init_head(&proc->sleep.sleepers);
index ce0f2a794813dcc1a405c6d288fbdc85c2518b32..5cee205f8fc0bd7e621e8a0f9b6839cb54687855 100644 (file)
@@ -7,7 +7,7 @@
 LOG_MODULE("SYSCALL")
 
 extern void
-syscall_hndlr(isr_param* param);
+syscall_hndlr(const isr_param* param);
 
 void
 syscall_install()
index 51c2c7fd11f942e1df888185b21d160060f9010b..7d9a391ee3624f1f2f3227d361ed745aed5b10b7 100644 (file)
@@ -57,7 +57,7 @@ timer_init_context()
     assert_msg(timer_ctx, "Fail to initialize timer contex");
 
     timer_ctx->active_timers = (struct lx_timer*)cake_grab(timer_pile);
-    llist_init_head(timer_ctx->active_timers);
+    llist_init_head(&timer_ctx->active_timers->link);
 }
 
 void
@@ -178,7 +178,7 @@ timer_run(ticks_t ticks, void (*callback)(void*), void* payload, uint8_t flags)
     timer->payload = payload;
     timer->flags = flags;
 
-    llist_append(timer_ctx->active_timers, &timer->link);
+    llist_append(&timer_ctx->active_timers->link, &timer->link);
 
     return timer;
 }
index c1580edda5a51074ea9237abe709eeaddac55cb3..277efb32eaf8370fc8f265ef8038ce4d1960004f 100644 (file)
@@ -9,7 +9,7 @@
  * @return unsigned int
  */
 uint32_t
-strhash_32(unsigned char* str, uint32_t truncate_to)
+strhash_32(char* str, uint32_t truncate_to)
 {
     if (!str)
         return 0;
index b997ccc3165f09c456215f6a0f57791060e67bd6..879304b38d92c155836316dccd879d81bc14f4b5 100644 (file)
@@ -48,7 +48,7 @@ all-debug: clean $(BUILD_DIR)/$(OS_ISO)
 
 clean:
        @rm -rf $(BUILD_DIR) || exit 1
-       @sleep 2
+       @sleep 1
 
 run: $(BUILD_DIR)/$(OS_ISO)
        @qemu-system-i386 -cdrom $(BUILD_DIR)/$(OS_ISO) $(QEMU_OPTIONS)