diff options
author | dzwdz | 2024-07-12 00:12:06 +0200 |
---|---|---|
committer | dzwdz | 2024-07-12 00:12:06 +0200 |
commit | ded843efbdad1ed048fe42c50c8fb68d50bafa51 (patch) | |
tree | de6b59e3a8e62af367d91f35d2e70d9d54d51975 | |
parent | ed8ff1ff9c4c0f847ffc2ab4624bd999539a0890 (diff) |
kernel: don't reuse VfsReq allocations for a single process
To use the same testing methodology as when I've introduced request slots:
before:
/ $ iostress 1 1000000 0 > /dev/vtty
run 0: 2585203
1000000 calls, 0 bytes. avg 2585203
after:
/ $ iostress 1 1000000 0 > /dev/vtty
run 0: 2783171
1000000 calls, 0 bytes. avg 2783171
This is around a 7.7% slowdown - that I hope to fix with a better malloc.
While this doesn't really make the code that much simpler, it doesn't feel
like the right approach in the first place
-rw-r--r-- | src/kernel/proc.c | 4 | ||||
-rw-r--r-- | src/kernel/proc.h | 2 | ||||
-rw-r--r-- | src/kernel/vfs/request.c | 22 |
3 files changed, 9 insertions, 19 deletions
diff --git a/src/kernel/proc.c b/src/kernel/proc.c index fcb51c6..9a9a84f 100644 --- a/src/kernel/proc.c +++ b/src/kernel/proc.c @@ -223,10 +223,8 @@ void proc_kill(Proc *p, int ret) { if (p->state == PS_WAITS4FS) { assert(p->reqslot); - p->reqslot->caller = NULL; /* transfer ownership */ + p->reqslot->caller = NULL; p->reqslot = NULL; - } else if (p->reqslot) { - kfree(p->reqslot); } if (p->state == PS_WAITS4PIPE) { diff --git a/src/kernel/proc.h b/src/kernel/proc.h index f4b6b97..99eac94 100644 --- a/src/kernel/proc.h +++ b/src/kernel/proc.h @@ -80,7 +80,7 @@ struct Proc { uint32_t localid; uint32_t nextlid; - /* allocated once, the requests from WAITS4FS get stored here */ + /* stores a request during WAITS4FS, NULL otherwise */ VfsReq *reqslot; /* vfs_backend controlled (not exclusively) by this process */ diff --git a/src/kernel/vfs/request.c b/src/kernel/vfs/request.c index 4489f5a..d4ea16c 100644 --- a/src/kernel/vfs/request.c +++ b/src/kernel/vfs/request.c @@ -33,19 +33,7 @@ vfsreq_dispatchcopy(VfsReq tmpl) VfsBackend *backend; /* allocate memory for the request and move it there */ - if (tmpl.caller) { - // TODO: ensure we aren't overriding an existing request - // TODO: wouldn't it be better to just optimize malloc? - // see commit afa28cfc7069f7649632f7b33daac47ee56d3819 - proc_setstate(tmpl.caller, PS_WAITS4FS); - if (!tmpl.caller->reqslot) - tmpl.caller->reqslot = kmalloc(sizeof *req, "reqslot"); - req = tmpl.caller->reqslot; - /* (re)using a single allocation for all request a process makes */ - } else { - req = kmalloc(sizeof *req, "reqanon"); - } - + req = kmalloc(sizeof *req, "VfsReq"); memcpy(req, &tmpl, sizeof *req); backend = req->backend; if (backend) { @@ -53,6 +41,11 @@ vfsreq_dispatchcopy(VfsReq tmpl) backend->usehcnt++; } + if (req->caller) { + proc_setstate(req->caller, PS_WAITS4FS); + req->caller->reqslot = req; + } + /* Check request validity. Doing this after the memcpy means that it * doesn't need to be special cased in vfsreq_finish. */ if (!vfsreq_isvalid(req)) { @@ -125,9 +118,8 @@ vfsreq_finish(VfsReq *req, char __user *stored, long ret, int flags, Proc *handl assert(req->caller->state == PS_WAITS4FS); regs_savereturn(&req->caller->regs, ret); proc_setstate(req->caller, PS_RUNNING); - } else { - kfree(req); } + kfree(req); } void |