summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authordzwdz2024-03-13 22:33:38 +0100
committerdzwdz2024-03-13 22:46:47 +0100
commit72f55421fb61b750512f324d284b30e3e67e36e0 (patch)
tree8933dc013580a2440730644807a03606c6805547 /src
parente47412d940db4e9be2d05608272e30f560a275d0 (diff)
kernel/malloc: slight rework (it's still bad), store more metadata
Diffstat (limited to 'src')
-rw-r--r--src/kernel/arch/amd64/boot.c2
-rw-r--r--src/kernel/arch/amd64/driver/fsroot.c2
-rw-r--r--src/kernel/handle.c2
-rw-r--r--src/kernel/malloc.c142
-rw-r--r--src/kernel/malloc.h9
-rw-r--r--src/kernel/proc.c12
-rw-r--r--src/kernel/syscalls.c10
-rw-r--r--src/kernel/vfs/mount.c4
-rw-r--r--src/kernel/vfs/procfs.c4
-rw-r--r--src/kernel/vfs/request.c4
10 files changed, 119 insertions, 72 deletions
diff --git a/src/kernel/arch/amd64/boot.c b/src/kernel/arch/amd64/boot.c
index 76bc864..19f249a 100644
--- a/src/kernel/arch/amd64/boot.c
+++ b/src/kernel/arch/amd64/boot.c
@@ -86,7 +86,7 @@ void kmain_early(void *mbi) {
}
void shutdown(void) {
- kprintf("shutting off\n");
+ kprintf("[kern] shutting off\n");
mem_debugprint();
cpu_shutdown();
}
diff --git a/src/kernel/arch/amd64/driver/fsroot.c b/src/kernel/arch/amd64/driver/fsroot.c
index 2684b72..228232e 100644
--- a/src/kernel/arch/amd64/driver/fsroot.c
+++ b/src/kernel/arch/amd64/driver/fsroot.c
@@ -53,7 +53,7 @@ handle(VfsReq *req)
case Hdev:
if (!dev) {
dev_len = get_dev(NULL);
- dev = kmalloc(dev_len);
+ dev = kmalloc(dev_len, "/ cache");
get_dev(dev);
}
lst = dev;
diff --git a/src/kernel/handle.c b/src/kernel/handle.c
index 51a95be..ca4c4c4 100644
--- a/src/kernel/handle.c
+++ b/src/kernel/handle.c
@@ -7,7 +7,7 @@
#include <shared/mem.h>
Handle *handle_init(enum handle_type type) {
- Handle *h = kzalloc(sizeof *h);
+ Handle *h = kzalloc(sizeof *h, "handle");
h->type = type;
h->refcount = 1;
return h;
diff --git a/src/kernel/malloc.c b/src/kernel/malloc.c
index 7efd5a5..8ba00dc 100644
--- a/src/kernel/malloc.c
+++ b/src/kernel/malloc.c
@@ -6,23 +6,28 @@
#include <stdbool.h>
#include <stdint.h>
-#define MALLOC_MAGIC 0xA770C666
-
-struct malloc_hdr {
- uint32_t magic;
- uint32_t page_amt;
- struct malloc_hdr *next, *prev;
+#define MALLOC_MAGIC 0x616c6c6f63686472
+#define DESCLEN 8
+
+typedef struct Allocation Allocation;
+struct Allocation {
+ uint64_t magic;
+ uint64_t len;
+ Allocation *next, *prev;
void *stacktrace[4];
+ char desc[DESCLEN];
};
-struct malloc_hdr *malloc_last = NULL;
+Allocation *malloc_last = NULL;
extern uint8_t pbitmap[]; /* linker.ld */
static size_t pbitmap_len; /* in bytes */
static size_t pbitmap_firstfree = 0;
-static bool bitmap_get(long i) {
+static
+bool bitmap_get(long i)
+{
assert(i >= 0);
size_t b = i / 8;
uint8_t m = 1 << (i&7);
@@ -30,7 +35,9 @@ static bool bitmap_get(long i) {
return (pbitmap[b]&m) != 0;
}
-static bool bitmap_set(long i, bool v) {
+static
+bool bitmap_set(long i, bool v)
+{
assert(i >= 0);
size_t b = i / 8;
uint8_t m = 1 << (i&7);
@@ -41,18 +48,30 @@ static bool bitmap_set(long i, bool v) {
return prev;
}
-static long toindex(void *p) {
+static
+long toindex(void *p)
+{
return ((long)p - (long)pbitmap) / PAGE_SIZE;
}
-void mem_init(void *memtop) {
+static
+size_t page_amt(size_t bytes)
+{
+ return (bytes + PAGE_SIZE - 1) / PAGE_SIZE;
+}
+
+void
+mem_init(void *memtop)
+{
kprintf("memory %8x -> %8x\n", &_bss_end, memtop);
pbitmap_len = toindex(memtop) / 8;
memset(pbitmap, 0, pbitmap_len);
mem_reserve(pbitmap, pbitmap_len);
}
-void mem_reserve(void *addr, size_t len) {
+void
+mem_reserve(void *addr, size_t len)
+{
kprintf("reserved %8x -> %8x\n", addr, addr + len);
/* align to the previous page */
@@ -67,21 +86,36 @@ void mem_reserve(void *addr, size_t len) {
}
}
-void mem_debugprint(void) {
- size_t total = 0;
- kprintf("current kmallocs:\n");
- kprintf("addr pages\n");
- for (struct malloc_hdr *iter = malloc_last; iter; iter = iter->prev) {
- kprintf("%08x %05x", iter, iter->page_amt);
- for (size_t i = 0; i < 4; i++)
- kprintf(" k/%08x", iter->stacktrace[i]);
- kprintf("\n peek 0x%x\n", *(uint32_t*)(&iter[1]));
- total++;
+void
+mem_debugprint(void)
+{
+ size_t count = 0, bytes = 0, pages = 0;
+ kprintf("[kern] current allocations:\n");
+ for (Allocation *iter = malloc_last; iter; iter = iter->prev) {
+ kprintf(
+ "%08p %6dB %.8s ",
+ ((void*)iter) + sizeof(Allocation),
+ iter->len - sizeof(Allocation),
+ iter->desc
+ );
+ for (size_t i = 0; i < 4; i++) {
+ kprintf(" k/%08x", iter->stacktrace[i]);
+ }
+ kprintf("\n");
+
+ count++;
+ bytes += iter->len;
+ pages += page_amt(iter->len);
}
- kprintf(" total 0x%x\n", total);
+ kprintf(
+ "%d in total, %d bytes, %d pages = %dB used\n",
+ count, bytes, pages, pages*PAGE_SIZE
+ );
}
-void *page_alloc(size_t pages) {
+void
+*page_alloc(size_t pages)
+{
/* i do realize how painfully slow this is */
size_t streak = 0;
for (size_t i = pbitmap_firstfree; i < pbitmap_len * 8; i++) {
@@ -102,14 +136,18 @@ void *page_alloc(size_t pages) {
panic_unimplemented();
}
-void *page_zalloc(size_t pages) {
+void
+*page_zalloc(size_t pages)
+{
void *p = page_alloc(pages);
memset(p, 0, pages * PAGE_SIZE);
return p;
}
-// frees `pages` consecutive pages starting from *first
-void page_free(void *addr, size_t pages) {
+/* frees `pages` consecutive pages starting from *first */
+void
+page_free(void *addr, size_t pages)
+{
assert(addr >= (void*)pbitmap);
size_t first = toindex(addr);
for (size_t i = 0; i < pages; i++) {
@@ -122,27 +160,35 @@ void page_free(void *addr, size_t pages) {
}
}
-void kmalloc_sanity(const void *addr) {
+void
+kmalloc_sanity(const void *addr)
+{
assert(addr);
- const struct malloc_hdr *hdr = addr - sizeof(struct malloc_hdr);
+ const Allocation *hdr = addr - sizeof(Allocation);
assert(hdr->magic == MALLOC_MAGIC);
if (hdr->next) assert(hdr->next->prev == hdr);
if (hdr->prev) assert(hdr->prev->next == hdr);
}
-void *kmalloc(size_t len) {
- // TODO better kmalloc
-
- struct malloc_hdr *hdr;
+// TODO better kmalloc
+void
+*kmalloc(size_t len, const char *desc)
+{
+ Allocation *hdr;
void *addr;
- uint32_t pages;
-
- len += sizeof(struct malloc_hdr);
- pages = len / PAGE_SIZE + 1;
- hdr = page_alloc(pages);
+ len += sizeof(Allocation);
+ hdr = page_alloc(page_amt(len));
hdr->magic = MALLOC_MAGIC;
- hdr->page_amt = pages;
+ hdr->len = len;
+
+ memset(hdr->desc, ' ', DESCLEN);
+ if (desc) {
+ for (int i = 0; i < DESCLEN; i++) {
+ if (desc[i] == '\0') break;
+ hdr->desc[i] = desc[i];
+ }
+ }
hdr->next = NULL;
hdr->prev = malloc_last;
@@ -156,7 +202,7 @@ void *kmalloc(size_t len) {
malloc_last = hdr;
- addr = (void*)hdr + sizeof(struct malloc_hdr);
+ addr = (void*)hdr + sizeof(Allocation);
#ifndef NDEBUG
memset(addr, 0xCC, len);
#endif
@@ -164,13 +210,16 @@ void *kmalloc(size_t len) {
return addr;
}
-void kfree(void *ptr) {
- struct malloc_hdr *hdr;
- uint32_t page_amt;
+void
+kfree(void *ptr)
+{
+ Allocation *hdr;
+ size_t pages;
if (ptr == NULL) return;
- hdr = ptr - sizeof(struct malloc_hdr);
+ hdr = ptr - sizeof(Allocation);
kmalloc_sanity(ptr);
+ pages = page_amt(hdr->len);
hdr->magic = ~MALLOC_MAGIC; // (hopefully) detect double frees
if (hdr->next)
@@ -179,9 +228,8 @@ void kfree(void *ptr) {
hdr->prev->next = hdr->next;
if (malloc_last == hdr)
malloc_last = hdr->prev;
- page_amt = hdr->page_amt;
#ifndef NDEBUG
- memset(hdr, 0xC0, page_amt * PAGE_SIZE);
+ memset(hdr, 0xC0, pages * PAGE_SIZE);
#endif
- page_free(hdr, page_amt);
+ page_free(hdr, pages);
}
diff --git a/src/kernel/malloc.h b/src/kernel/malloc.h
index 671a468..03934de 100644
--- a/src/kernel/malloc.h
+++ b/src/kernel/malloc.h
@@ -3,8 +3,6 @@
#include <shared/mem.h>
#include <stddef.h>
-extern struct malloc_hdr *malloc_last;
-
void mem_init(void *memtop);
void mem_reserve(void *addr, size_t len);
void mem_debugprint(void);
@@ -19,11 +17,12 @@ void *page_zalloc(size_t pages);
void page_free(void *first, size_t pages);
void kmalloc_sanity(const void *addr);
-void *kmalloc(size_t len);
+void *kmalloc(size_t len, const char *desc);
void kfree(void *ptr);
-static inline void *kzalloc(size_t len) {
- void *b = kmalloc(len);
+// TODO calloc
+static inline void *kzalloc(size_t len, const char *desc) {
+ void *b = kmalloc(len, desc);
memset(b, 0, len);
return b;
}
diff --git a/src/kernel/proc.c b/src/kernel/proc.c
index 26b9e3a..8182a54 100644
--- a/src/kernel/proc.c
+++ b/src/kernel/proc.c
@@ -19,12 +19,12 @@ static void proc_prune_leaves(void);
Proc *proc_seed(void *data, size_t datalen) {
assert(!proc_first);
- proc_first = kzalloc(sizeof *proc_first);
+ proc_first = kzalloc(sizeof *proc_first, "init");
proc_first->state = PS_RUNNING;
proc_first->pages = pagedir_new();
proc_first->mount = vfs_mount_seed();
proc_first->globalid = next_pid++;
- proc_first->_handles = kzalloc(sizeof(Handle) * HANDLE_MAX);
+ proc_first->_handles = kzalloc(sizeof(Handle) * HANDLE_MAX, "init fds");
proc_first->pns = proc_first;
proc_first->localid = 1;
@@ -47,11 +47,11 @@ Proc *proc_seed(void *data, size_t datalen) {
}
Proc *proc_fork(Proc *parent, int flags) {
- Proc *child = kzalloc(sizeof *child);
+ Proc *child = kzalloc(sizeof *child, "proc");
if (flags & FORK_SHAREMEM) {
if (!parent->pages_refcount) {
- parent->pages_refcount = kmalloc(sizeof *parent->pages_refcount);
+ parent->pages_refcount = kmalloc(sizeof *parent->pages_refcount, "pagerefs");
*parent->pages_refcount = 1;
}
*parent->pages_refcount += 1;
@@ -96,14 +96,14 @@ Proc *proc_fork(Proc *parent, int flags) {
if (flags & FORK_SHAREHANDLE) {
if (!parent->handles_refcount) {
- parent->handles_refcount = kmalloc(sizeof *parent->handles_refcount);
+ parent->handles_refcount = kmalloc(sizeof *parent->handles_refcount, "fd refs");
*parent->handles_refcount = 1;
}
*parent->handles_refcount += 1;
child->handles_refcount = parent->handles_refcount;
child->_handles = parent->_handles;
} else {
- child->_handles = kzalloc(sizeof(Handle) * HANDLE_MAX);
+ child->_handles = kzalloc(sizeof(Handle) * HANDLE_MAX, "handles");
for (hid_t h = 0; h < HANDLE_MAX; h++) {
child->_handles[h] = parent->_handles[h];
if (child->_handles[h])
diff --git a/src/kernel/syscalls.c b/src/kernel/syscalls.c
index 5cec6c4..2a9a7b5 100644
--- a/src/kernel/syscalls.c
+++ b/src/kernel/syscalls.c
@@ -38,7 +38,7 @@ long _sys_fork(int flags, hid_t __user *fs_front) {
SYSCALL_RETURN(-EMFILE);
}
- h->backend = kzalloc(sizeof *h->backend);
+ h->backend = kzalloc(sizeof *h->backend, "user fs");
h->backend->is_user = true;
h->backend->provhcnt = 1; /* child */
h->backend->usehcnt = 1; /* handle */
@@ -67,7 +67,7 @@ hid_t _sys_open(const char __user *path, long len, int flags) {
/* Doesn't check for free handles. Another thread could use up all
* handles in the meantime anyways, or free some up. */
- path_buf = kmalloc(len);
+ path_buf = kmalloc(len, "path opn");
if (pcpy_from(proc_cur, path_buf, path, len) < (size_t)len) {
goto fail;
}
@@ -110,7 +110,7 @@ long _sys_mount(hid_t hid, const char __user *path, long len) {
if (PATH_MAX < len)
SYSCALL_RETURN(-1);
- path_buf = kmalloc(len);
+ path_buf = kmalloc(len, "path mnt");
if (pcpy_from(proc_cur, path_buf, path, len) < (size_t)len) {
goto fail;
}
@@ -135,7 +135,7 @@ long _sys_mount(hid_t hid, const char __user *path, long len) {
// append to mount list
// TODO move to kernel/vfs/mount.c
- mount = kmalloc(sizeof *mount);
+ mount = kmalloc(sizeof *mount, "user mnt");
mount->prev = proc_cur->mount;
mount->prefix = path_buf;
mount->prefix_owned = true;
@@ -458,7 +458,7 @@ long _sys_execbuf(void __user *ubuf, size_t len) {
SYSCALL_RETURN(-1);
// TODO consider supporting nesting execbufs
- char *kbuf = kmalloc(len);
+ char *kbuf = kmalloc(len, "execbuf");
if (pcpy_from(proc_cur, kbuf, ubuf, len) < len) {
kfree(kbuf);
SYSCALL_RETURN(-1);
diff --git a/src/kernel/vfs/mount.c b/src/kernel/vfs/mount.c
index c153c69..adf9b8c 100644
--- a/src/kernel/vfs/mount.c
+++ b/src/kernel/vfs/mount.c
@@ -10,8 +10,8 @@ VfsMount *vfs_mount_seed(void) {
}
void vfs_root_register(const char *path, void (*accept)(VfsReq *)) {
- VfsBackend *backend = kmalloc(sizeof *backend);
- VfsMount *mount = kmalloc(sizeof *mount);
+ VfsBackend *backend = kmalloc(sizeof *backend, "root bck");
+ VfsMount *mount = kmalloc(sizeof *mount, "root mnt");
*backend = (VfsBackend) {
.is_user = false,
.usehcnt = 1,
diff --git a/src/kernel/vfs/procfs.c b/src/kernel/vfs/procfs.c
index 4bacaf7..79dfdc0 100644
--- a/src/kernel/vfs/procfs.c
+++ b/src/kernel/vfs/procfs.c
@@ -73,7 +73,7 @@ openpath(const char *path, size_t len, Proc *root)
return NULL;
}
- h = kmalloc(sizeof *h);
+ h = kmalloc(sizeof *h, "proc fd");
h->gid = gid;
h->type = type;
return h;
@@ -182,7 +182,7 @@ isdigit(int c) {
VfsBackend *
procfs_backend(Proc *proc)
{
- VfsBackend *be = kzalloc(sizeof(VfsBackend));
+ VfsBackend *be = kzalloc(sizeof(VfsBackend), "kern fs");
*be = (VfsBackend) {
.is_user = false,
.provhcnt = 1,
diff --git a/src/kernel/vfs/request.c b/src/kernel/vfs/request.c
index 3a42c2a..21eecb8 100644
--- a/src/kernel/vfs/request.c
+++ b/src/kernel/vfs/request.c
@@ -13,11 +13,11 @@ void vfsreq_create(VfsReq req_) {
if (req_.caller) {
proc_setstate(req_.caller, PS_WAITS4FS);
if (!req_.caller->reqslot)
- req_.caller->reqslot = kmalloc(sizeof *req);
+ req_.caller->reqslot = kmalloc(sizeof *req, "reqslot");
req = req_.caller->reqslot;
/* (re)using a single allocation for all request a process makes */
} else {
- req = kmalloc(sizeof *req);
+ req = kmalloc(sizeof *req, "reqanon");
}
memcpy(req, &req_, sizeof *req);
if (req->backend) {