diff options
| author | Kimplul <kimi.h.kuparinen@gmail.com> | 2024-11-01 10:12:02 +0200 |
|---|---|---|
| committer | Kimplul <kimi.h.kuparinen@gmail.com> | 2024-11-01 10:28:16 +0200 |
| commit | 8100eef0826e7fb182434979a9b139716b3637e1 (patch) | |
| tree | 991324108d849a9bc825528fbba38fb4a887cd11 | |
| parent | 9914b44878ca52cc615d2f4e47fec400dd55ab76 (diff) | |
| download | kmi-8100eef0826e7fb182434979a9b139716b3637e1.tar.gz kmi-8100eef0826e7fb182434979a9b139716b3637e1.zip | |
speed up creating threads quite a bit
| -rw-r--r-- | TODO | 4 | ||||
| -rw-r--r-- | arch/riscv64/kernel/vmem.c | 43 | ||||
| -rw-r--r-- | src/tcb.c | 2 | ||||
| -rw-r--r-- | tests/create-exhaustion/init.c | 3 |
4 files changed, 27 insertions, 25 deletions
@@ -51,7 +51,6 @@ associated program. Easy. (started) + Start working on proper context swaps and RPC swaps. (which thread ID should be visible from cur_tcb() when in an RPC? should I use some kind of effective tid instead of cur_tcb()?) -+ Export VM flags to userspace, separate header or something? + Get core count? It's technically speaking available from the fdt but could be limited by the NR_CPUS macro, so it might be a good idea to export as a CONF_* + The node subsystem might benefit from larger-than-base-page sizes, for example @@ -62,6 +61,9 @@ limited by the NR_CPUS macro, so it might be a good idea to export as a CONF_* just check if the last message is OK, and we only really need more complex checking if we need to calculate like memory leaks etc. ++ grow_rpc() shouldn't exceed limits ++ handle_pagefault() should kill processes that have no good reason to pagefault + !!! FUTURE: + Cache locality? + When mapping some other address space into your own, I could keep a maximum diff --git a/arch/riscv64/kernel/vmem.c b/arch/riscv64/kernel/vmem.c index 4986c1f..bd7906b 100644 --- a/arch/riscv64/kernel/vmem.c +++ b/arch/riscv64/kernel/vmem.c @@ -297,6 +297,9 @@ stat_t map_vpage(struct vmem *branch, pm_t paddr, vm_t vaddr, vmflags_t flags, while (top != order) { size_t idx = vm_to_index(vaddr, top); + /* what if we create one high-level page and a low-level page + * doesn't have enough memory? I think that situation would fail + * the unit tests I currently have */ if (__unused((pm_t)branch->leaf[idx])) { struct vmem *leaf = __create_leaf(); if (!leaf) @@ -602,25 +605,28 @@ stat_t setup_rpc_stack(struct tcb *t) vmflags_t flags = VM_V | VM_R | VM_W; /* note how VM_U is missing, userspace messing about will be done later */ - for (size_t i = 0; i < rpc_pages; ++i) { - pm_t page = alloc_page(BASE_PAGE); - if (!page) - return ERR_OOMEM; + pm_t page = alloc_page(MM_O1); + if (!page) + return ERR_OOMEM; - if (map_vpage(t->rpc.vmem, page, - RPC_STACK_BASE + BASE_PAGE_SIZE * i, - flags, BASE_PAGE)) - return ERR_OOMEM; + if (map_vpage(t->rpc.vmem, page, RPC_STACK_BASE, flags, BASE_PAGE)) { + free_page(MM_O1, page); + return ERR_OOMEM; } - /* we allocated a second order page for rpc stack usage */ - t->rpc_stack = RPC_STACK_BASE + order_size(MM_O1); - - /* slightly hacky maybe but we know the first pte is at RPC_STACK_BASE, - * which means that it must also be the leaf */ t->arch.rpc_leaf = (struct vmem *)__find_vmem(t->rpc.vmem, RPC_STACK_BASE, NULL); + + for (size_t i = 0; i < rpc_pages; ++i) { + t->arch.rpc_leaf->leaf[i] = (struct vmem *)to_pte( + (pm_t)__pa(page + i * BASE_PAGE_SIZE), + vp_flags(flags) + ); + } + + t->rpc_stack = RPC_STACK_BASE + order_size(MM_O1); + /* we count downward in base pages, the top page is *always* reserved */ t->arch.rpc_idx = rpc_pages - 1; /** @todo we could mark the first stack page accessible here already */ @@ -632,14 +638,9 @@ stat_t setup_rpc_stack(struct tcb *t) void destroy_rpc_stack(struct tcb *t) { - for (size_t i = 0; i < rpc_pages; ++i) { - pm_t page = 0; enum mm_order order = BASE_PAGE; - if (stat_vpage(t->rpc.vmem, RPC_STACK_BASE + BASE_PAGE_SIZE * i, - &page, &order, NULL)) - return; - - free_page(order, page); - } + pm_t *pte = (pm_t *)t->arch.rpc_leaf; + pm_t page = (pm_t)pte_addr(*pte); + free_page(MM_O1, page); } void reset_rpc_stack(struct tcb *t) @@ -113,7 +113,6 @@ static stat_t __init_free_thread(struct tcb *t) } if (setup_rpc_stack(t)) { - destroy_rpc_stack(t); destroy_rpcmem(t->rpc.vmem); destroy_vmem(t->proc.vmem); return ERR_OOMEM; @@ -147,7 +146,6 @@ static stat_t __init_owned_thread(struct tcb *p, struct tcb *t) return NULL; if (setup_rpc_stack(t)) { - destroy_rpc_stack(t); destroy_rpcmem(t->rpc.vmem); return ERR_OOMEM; } diff --git a/tests/create-exhaustion/init.c b/tests/create-exhaustion/init.c index d5ac20a..8fc9b1f 100644 --- a/tests/create-exhaustion/init.c +++ b/tests/create-exhaustion/init.c @@ -10,8 +10,9 @@ START(pid, tid, d0, d1, d2, d3) UNUSED(d3); size_t old_ram = 0; + int count = 0; while (1) { - printf("creating new thread\n"); + printf("creating new thread %d\n", count++); id_t new_thread = sys_create((uintptr_t)_start, 1, 2, 3, 4); if (new_thread < 0) break; |
