OT: I always felt the synchronous system call model is very dated. All high performance systems I know of (say, GPUs, NVMe, NFSv4, etc) all use a similar async command list model. Each exchange package up as much as possible and more work is done per context switch. Instead in Linux we just get an ever growing list of compound system calls (like pwritev, pwrite64, renameat). There's some hope with io_uring and ebpf, but it really should just be general mechanism. There's no need for a context switch outside of exceptions (like page fault) or blocking on completions for commands.