From af8e873ae38b72a56a89485c62bb5ccd22a9f8a7 Mon Sep 17 00:00:00 2001 From: Minep Date: Sun, 14 Aug 2022 01:14:07 +0100 Subject: [PATCH] feat: lru eviction policy on page caches 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 --- lunaix-os/config/make-cc | 8 ++- lunaix-os/hal/acpi/acpi.c | 3 +- lunaix-os/hal/acpi/parser/madt_parser.c | 3 +- lunaix-os/hal/ahci/ahci.c | 10 +-- lunaix-os/hal/ahci/ata.c | 18 +++--- lunaix-os/hal/ahci/atapi.c | 12 ++-- lunaix-os/hal/ahci/utils.c | 4 +- lunaix-os/hal/pci.c | 2 +- lunaix-os/includes/arch/x86/interrupts.h | 2 +- lunaix-os/includes/hal/ahci/scsi.h | 4 +- lunaix-os/includes/hal/pci.h | 4 +- lunaix-os/includes/lib/hash.h | 2 +- lunaix-os/includes/lunaix/common.h | 2 - lunaix-os/includes/lunaix/device.h | 10 +-- lunaix-os/includes/lunaix/ds/llist.h | 4 +- lunaix-os/includes/lunaix/ds/lru.h | 29 +++++++++ lunaix-os/includes/lunaix/fs.h | 34 ++++++---- lunaix-os/includes/lunaix/fs/twifs.h | 7 +- lunaix-os/includes/lunaix/status.h | 1 + lunaix-os/kernel/block.c | 10 +-- lunaix-os/kernel/device.c | 12 ++-- lunaix-os/kernel/ds/btrie.c | 13 ++-- lunaix-os/kernel/ds/lru.c | 49 ++++++++++++++ lunaix-os/kernel/fs/pcache.c | 81 +++++++++++++++++------- lunaix-os/kernel/fs/twifs/twifs.c | 22 +++---- lunaix-os/kernel/fs/vfs.c | 24 ++++--- lunaix-os/kernel/mm/cake.c | 20 +++++- lunaix-os/kernel/mm/valloc.c | 18 +++--- lunaix-os/kernel/sched.c | 2 +- lunaix-os/kernel/syscall.c | 2 +- lunaix-os/kernel/time/timer.c | 4 +- lunaix-os/libs/hash.c | 2 +- lunaix-os/makefile | 2 +- 33 files changed, 277 insertions(+), 143 deletions(-) create mode 100644 lunaix-os/includes/lunaix/ds/lru.h create mode 100644 lunaix-os/kernel/ds/lru.c diff --git a/lunaix-os/config/make-cc b/lunaix-os/config/make-cc index 643b4ee..7a1899c 100644 --- a/lunaix-os/config/make-cc +++ b/lunaix-os/config/make-cc @@ -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 diff --git a/lunaix-os/hal/acpi/acpi.c b/lunaix-os/hal/acpi/acpi.c index 55c27ae..c6a566e 100644 --- a/lunaix-os/hal/acpi/acpi.c +++ b/lunaix-os/hal/acpi/acpi.c @@ -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); diff --git a/lunaix-os/hal/acpi/parser/madt_parser.c b/lunaix-os/hal/acpi/parser/madt_parser.c index 8456b57..5e9aeb4 100644 --- a/lunaix-os/hal/acpi/parser/madt_parser.c +++ b/lunaix-os/hal/acpi/parser/madt_parser.c @@ -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) { diff --git a/lunaix-os/hal/ahci/ahci.c b/lunaix-os/hal/ahci/ahci.c index 0551ee5..a04bca7 100644 --- a/lunaix-os/hal/ahci/ahci.c +++ b/lunaix-os/hal/ahci/ahci.c @@ -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 diff --git a/lunaix-os/hal/ahci/ata.c b/lunaix-os/hal/ahci/ata.c index a2f10ba..a77e03b 100644 --- a/lunaix-os/hal/ahci/ata.c +++ b/lunaix-os/hal/ahci/ata.c @@ -5,6 +5,14 @@ #include #include +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 diff --git a/lunaix-os/hal/ahci/atapi.c b/lunaix-os/hal/ahci/atapi.c index 0ef5099..85c3bab 100644 --- a/lunaix-os/hal/ahci/atapi.c +++ b/lunaix-os/hal/ahci/atapi.c @@ -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 diff --git a/lunaix-os/hal/ahci/utils.c b/lunaix-os/hal/ahci/utils.c index e101efd..664488d 100644 --- a/lunaix-os/hal/ahci/utils.c +++ b/lunaix-os/hal/ahci/utils.c @@ -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 diff --git a/lunaix-os/hal/pci.c b/lunaix-os/hal/pci.c index d626768..3d6accf 100644 --- a/lunaix-os/hal/pci.c +++ b/lunaix-os/hal/pci.c @@ -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) diff --git a/lunaix-os/includes/arch/x86/interrupts.h b/lunaix-os/includes/arch/x86/interrupts.h index 94c15e1..3643a9e 100644 --- a/lunaix-os/includes/arch/x86/interrupts.h +++ b/lunaix-os/includes/arch/x86/interrupts.h @@ -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 diff --git a/lunaix-os/includes/hal/ahci/scsi.h b/lunaix-os/includes/hal/ahci/scsi.h index 6ba0fc2..0635614 100644 --- a/lunaix-os/includes/hal/ahci/scsi.h +++ b/lunaix-os/includes/hal/ahci/scsi.h @@ -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, diff --git a/lunaix-os/includes/hal/pci.h b/lunaix-os/includes/hal/pci.h index d622acb..57c04ca 100644 --- a/lunaix-os/includes/hal/pci.h +++ b/lunaix-os/includes/hal/pci.h @@ -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)); diff --git a/lunaix-os/includes/lib/hash.h b/lunaix-os/includes/lib/hash.h index ad5e98b..22998f7 100644 --- a/lunaix-os/includes/lib/hash.h +++ b/lunaix-os/includes/lib/hash.h @@ -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 diff --git a/lunaix-os/includes/lunaix/common.h b/lunaix-os/includes/lunaix/common.h index d341daa..4c8c794 100644 --- a/lunaix-os/includes/lunaix/common.h +++ b/lunaix-os/includes/lunaix/common.h @@ -32,8 +32,6 @@ #define USTACK_END (0x9fffffff - USTACK_SIZE + 1) #define UMMAP_AREA 0x4D000000 -#define SYS_TIMER_FREQUENCY_HZ 2048 - #ifndef __ASM__ #include // From Linux kernel v2.6.0 diff --git a/lunaix-os/includes/lunaix/device.h b/lunaix-os/includes/lunaix/device.h index 08d25c4..14558a7 100644 --- a/lunaix-os/includes/lunaix/device.h +++ b/lunaix-os/includes/lunaix/device.h @@ -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 diff --git a/lunaix-os/includes/lunaix/ds/llist.h b/lunaix-os/includes/lunaix/ds/llist.h index 9af9dd1..6129ca0 100644 --- a/lunaix-os/includes/lunaix/ds/llist.h +++ b/lunaix-os/includes/lunaix/ds/llist.h @@ -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 index 0000000..5ae607d --- /dev/null +++ b/lunaix-os/includes/lunaix/ds/lru.h @@ -0,0 +1,29 @@ +#ifndef __LUNAIX_LRU_H +#define __LUNAIX_LRU_H + +#include + +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 */ diff --git a/lunaix-os/includes/lunaix/fs.h b/lunaix-os/includes/lunaix/fs.h index fd09e96..d0d59d1 100644 --- a/lunaix-os/includes/lunaix/fs.h +++ b/lunaix-os/includes/lunaix/fs.h @@ -8,6 +8,7 @@ #include #include #include +#include #include #define VFS_NAME_MAXLEN 128 @@ -27,14 +28,18 @@ #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 */ diff --git a/lunaix-os/includes/lunaix/fs/twifs.h b/lunaix-os/includes/lunaix/fs/twifs.h index f2d6b15..22028f3 100644 --- a/lunaix-os/includes/lunaix/fs/twifs.h +++ b/lunaix-os/includes/lunaix/fs/twifs.h @@ -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; }; diff --git a/lunaix-os/includes/lunaix/status.h b/lunaix-os/includes/lunaix/status.h index 9bb6b4b..3d300f2 100644 --- a/lunaix-os/includes/lunaix/status.h +++ b/lunaix-os/includes/lunaix/status.h @@ -27,5 +27,6 @@ #define ELOOP -22 #define ENODEV -23 #define ERANGE -24 +#define ENOMEM LXOUTOFMEM #endif /* __LUNAIX_CODE_H */ diff --git a/lunaix-os/kernel/block.c b/lunaix-os/kernel/block.c index 97e9bd6..b855910 100644 --- a/lunaix-os/kernel/block.c +++ b/lunaix-os/kernel/block.c @@ -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; diff --git a/lunaix-os/kernel/device.c b/lunaix-os/kernel/device.c index 2471a9c..017f3b3 100644 --- a/lunaix-os/kernel/device.c +++ b/lunaix-os/kernel/device.c @@ -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) { diff --git a/lunaix-os/kernel/ds/btrie.c b/lunaix-os/kernel/ds/btrie.c index fd173b9..8a4380e 100644 --- a/lunaix-os/kernel/ds/btrie.c +++ b/lunaix-os/kernel/ds/btrie.c @@ -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 index 0000000..ebabeef --- /dev/null +++ b/lunaix-os/kernel/ds/lru.c @@ -0,0 +1,49 @@ +#include +#include + +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 diff --git a/lunaix-os/kernel/fs/pcache.c b/lunaix-os/kernel/fs/pcache.c index 3db7571..03f7502 100644 --- a/lunaix-os/kernel/fs/pcache.c +++ b/lunaix-os/kernel/fs/pcache.c @@ -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 diff --git a/lunaix-os/kernel/fs/twifs/twifs.c b/lunaix-os/kernel/fs/twifs/twifs.c index f535084..ec2707f 100644 --- a/lunaix-os/kernel/fs/twifs/twifs.c +++ b/lunaix-os/kernel/fs/twifs/twifs.c @@ -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; diff --git a/lunaix-os/kernel/fs/vfs.c b/lunaix-os/kernel/fs/vfs.c index ad9fd70..68a8d5f 100644 --- a/lunaix-os/kernel/fs/vfs.c +++ b/lunaix-os/kernel/fs/vfs.c @@ -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; } diff --git a/lunaix-os/kernel/mm/cake.c b/lunaix-os/kernel/mm/cake.c index a64b3ea..c3cee83 100644 --- a/lunaix-os/kernel/mm/cake.c +++ b/lunaix-os/kernel/mm/cake.c @@ -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 { diff --git a/lunaix-os/kernel/mm/valloc.c b/lunaix-os/kernel/mm/valloc.c index 04379e1..a744ed1 100644 --- a/lunaix-os/kernel/mm/valloc.c +++ b/lunaix-os/kernel/mm/valloc.c @@ -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 diff --git a/lunaix-os/kernel/sched.c b/lunaix-os/kernel/sched.c index 4a0e254..f8f00d4 100644 --- a/lunaix-os/kernel/sched.c +++ b/lunaix-os/kernel/sched.c @@ -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); diff --git a/lunaix-os/kernel/syscall.c b/lunaix-os/kernel/syscall.c index ce0f2a7..5cee205 100644 --- a/lunaix-os/kernel/syscall.c +++ b/lunaix-os/kernel/syscall.c @@ -7,7 +7,7 @@ LOG_MODULE("SYSCALL") extern void -syscall_hndlr(isr_param* param); +syscall_hndlr(const isr_param* param); void syscall_install() diff --git a/lunaix-os/kernel/time/timer.c b/lunaix-os/kernel/time/timer.c index 51c2c7f..7d9a391 100644 --- a/lunaix-os/kernel/time/timer.c +++ b/lunaix-os/kernel/time/timer.c @@ -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; } diff --git a/lunaix-os/libs/hash.c b/lunaix-os/libs/hash.c index c1580ed..277efb3 100644 --- a/lunaix-os/libs/hash.c +++ b/lunaix-os/libs/hash.c @@ -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; diff --git a/lunaix-os/makefile b/lunaix-os/makefile index b997ccc..879304b 100644 --- a/lunaix-os/makefile +++ b/lunaix-os/makefile @@ -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) -- 2.27.0