RSoC: improving drivers and kernel - part 1 (largely io_uring)

By 4lDO2 on

Introduction

This week has been quite productive for the most part. I continued updating the RFC, with some newer ideas that I came up while working on the implementation, most imporantly how the kernel is going to be involved in io_uring operation.

I also came up with a set of standard opcodes, that schemes are meant to use when using io_uring, unless in some special scenarios (like general-purpose IPC between processes). The opcodes at this point in time, can be found here.

The three attachment modes

The most notable change that I made, is that instead of always attaching an io_uring between two userspace processes, there can be attachments directly from the userspace to the kernel (and vice versa), which is much more similar to how io_uring on Linux works, except that Redox has two additional “attachment modes”. The three of them are:

Updating rustc

This was probably the least fun part of this week. Not that it is required for io_urings to function properly, but async/await could really help in some situtations, for example when storing pending submissions to handle. While async/await has been there since stable 1.39, only recently has it worked in #![no_std]. It turned out that the nightly version that Redox used for everything, was nigthly-2019-11-25, and so I decided to use the latest version (also for the newer asm! macro). Somehow the master branch from the official rust repository was capable of compiling all of Redox (there may be some parts that require patching anyways, but I could run the system out-of-the-box, just like with the older compiler). I hope that it won’t be too hard to correctly submit the patches to every repo with the llvm_asm change, and get it to integrate with the cookbook. Anyways, hooray!

TODO

Currently only a few opcodes are implemented by the kernel, and my next goal is to implement a superset of the scheme syscalls, and allow most of the regular syscalls to be bypassed as an io_uring submission, but completely non-blocking. Additionally, I’m trying to get an asynchronous executor to work with the API, which would be really nice to have for nearly every usecase (both nvmed and xhcid already use async, but it’d be nicer not having to write your own executor for every driver).

With this executor, I’m going to try getting usbscsid to be completely async and talk to xhcid uring io_uring, and let xhcid mask MSI interrupts by talking to pcid with io_uring as well.

I’ll also see whether at some point in the future, it could be possible to be compatible with the Linux io_uring API; perhaps it won’t have to be syscall compatible (even if that would work), but porting liburing would certainly benefit.

I’d really appreciate any kind of feedback if possible.