-
Notifications
You must be signed in to change notification settings - Fork 653
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Tock 2.0 IPC #2434
Tock 2.0 IPC #2434
Conversation
Please do not merge yet, I have not tested properly and have not updated all the documentation. However, I believe it's more or less complete, so worth reviewing. I've separated into two commits, one that changes the IPC driver and one (with a one-line change in a ton of files) that updates references to IPC in all boards using it. I suggest looking primarily at the first commit, which isn't actually that big. |
This increases code size by enough that the kernel no longer fits into flash on Imix (hence the CI failure). Looking at hail, it increased size by 1264 bytes. |
I'll look into it, but that's got to be an alignment thing (e.g., it maybe increased by enough of a margin to just push it over the alignment boundary or something), right? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks mostly good to me, I have a few comments.
Using Phil's size tool, the code size required for functions in the |
This is interesting; fundamentally the idea of this shared memory goes against Rust's ownership model, so does need to be protected by some sort of lock. If we do decide to follow the borrow semantics, though, this becomes message passing (except if it's read-only on both sides)? |
I suspect that the way we use shared memory now would be difficult to use without undefined behavior for a rust userspace? I realize libtock-rs does not currently support IPC. I am not sure what exactly defines "message passing", but it seems that the ability to
is lower overhead than having to pass the entire shared memory region back as a message. Maybe this is more of a semantic difference |
I've been banging up on this a bit with imix. We should do a spring cleaning and see where we could reclaim some space. ADC for example is 6.1k! |
I totally agree, but also I'm not sure how reliable those numbers are at that granularity (the tool is great! don't get me wrong). For example, removing the nrf51 capsule from Hail adds ~1kB to the kernel, and the scheduler module occupies ~10kB on Hail, but only ~5kB on the Nano BLE, and ~8kB on the nrf52840DKs The code changes really shouldn't require adding much code space at all, so I'll debug this enough to figure out what's going on (though again, removing things sometimes increases the size, so it's pretty brittle) and get imix inline. But agree that we should do a deeper more comprehensive dive into this. These modules are all far bigger than they need to be. |
I think this is inlining: modules higher in the call tree can take on code from lower ones. Happens less in the opposite direction. |
kernel/src/ipc.rs
Outdated
process.add_mpu_region( | ||
slice.ptr(), | ||
slice.len(), | ||
slice.len(), | ||
) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We should probably look at #1993 since we are here. What happens if add_mpu_region
fails?
362f7ea
to
7164d50
Compare
Please still don't merge, I'm currently testing with libtock-c and still need to update documentation |
I was playing around with IPC today and I found some issues. #1993 Might not be relevant for this PR but wanted to make a note of it. |
I pushed a commit (which I will squash before we merge) that fixes a bug I had introduced in |
Testing complete. Just going to update documentation, then I think we should be good (modulo squashing the last commit with the first one) |
Documentation updated |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The most recent commit looks correct to me, it seems to match the behavior from when expose_to()
was used, and the updated names are helpful
Squashed |
Mostly a fairly straightforward port, however, I had to change the driver interface in order to handle 2.0's new allow-semantics. Specifically, allow (both readonly and readwrite) can no longer return a value, which is how IPC returned a target descriptor for discovery until now. No matter, the logic is better suited elsewhere anyway. Now, discovery is split into an allow_readonly (which is nice so that large package names can be hardcoded in ROM rather than copied to memory) followed by a command(IPC, 0). allow_readwrite is _only_ used to share buffers between apps. To make this cleaner, I also rejiggerd the arguments to command. Previous, the first argument to command was the target descriptor for a notify, while the second argument differentiated between a service and client notify (the third was unused). Now, the first argument is a command number, differentiating between a discover (0), service notify (1), and client notify (2), the second is the target descriptor and the third is still unused.
bors r+ |
Hurray! |
2434: Tock 2.0 IPC r=alevy a=alevy ### Pull Request Overview This pull request ports the IPC driver to the Tock 2.0 driver interface. This is a mostly fairly straightforward port. However, the old driver API relied on `allow` to return a discovered IPC endpoint upon success, which is no longer possible in the 2.0 driver interface (allow cannot return a value). Recall that IPC works as follows: 1. A client "discovers" an IPC service by supplying the kernel with the service's name (taken from the process's TBF name header) 2. If such a service exists, the kernel supplies the client process with a 32-bit non-zero descriptor to reference the service (implemented as the AppId + 1, but that's not guaranteed). 3. The client can use this descriptor to share memory with the service (using allow) and to `notify` it (using command). For discovery, `allow(IPC, 0)` had been used to both share a buffer containing the service name _and_ request that the kernel perform discovery, returning a descriptor on success. _This is no longer possible_, and it also not canonical driver semantics. With this PR, discovery is split into an `allow_readonly` (which is nice anyway so package names can be hardcoded in ROM rather than copied to memory) followed by a `command(IPC, 1)` to actually perform the discovery and return a descriptor. To make this cleaner, I also rejiggerd the arguments in `command`, which now has to mean more than _just_ notify. Previously, the arguments were: 1. Descriptor (as opposed to the normal command number) 2. Service-or-client-notify (which is actually kind of like a command number) 3. Unused Now, the arguments are: 1. Command number (can be "discover," "service notify," or "client notify") 2. Target descriptor 3. Unused There are a number of other changes I believe _could_ make sense to make to IPC before releasing 2.0, but I think they should be decoupled from this pull request, which merely adapts the interface very little to get it working. These are just ideas, and we should discuss all these _separately_: - Allow both read-only and read-write buffer sharing between client/service - Use borrow semantics for memory ownership - Let client subscribe to be notified when a service is available - Probably more... ### Testing Strategy Tested using the IPC tutorial in libtock-c (examples/tutorial/05-ipc) after applying changes from tock/libtock-c#176 ### TODO or Help Wanted ~~Still need to adapt libtock-c userspace to properly test.~~ (Done in tock/libtock-c#176) Still need to update documentation Please review not only the implementation but the change in interface described above. As I said, there are a variety of changes that might make sense for IPC that go beyond these minimal changes. I ask that we get something in that reliably reproduces the existing high-level semantics for IPC and after (or maybe concurrently) decide whether other changes should happen (either before or after 2.0). ### Documentation Updated - [x] Updated the relevant files in `/docs`, or no updates are required. ### Formatting - [x] Ran `make prepush`. Co-authored-by: Amit Aryeh Levy <amit@amitlevy.com>
Pull Request Overview
This pull request ports the IPC driver to the Tock 2.0 driver interface.
This is a mostly fairly straightforward port. However, the old driver API relied on
allow
to return a discovered IPC endpoint upon success, which is no longer possible in the 2.0 driver interface (allow cannot return a value).Recall that IPC works as follows:
notify
it (using command).For discovery,
allow(IPC, 0)
had been used to both share a buffer containing the service name and request that the kernel perform discovery, returning a descriptor on success.This is no longer possible, and it also not canonical driver semantics.
With this PR, discovery is split into an
allow_readonly
(which is nice anyway sopackage names can be hardcoded in ROM rather than copied to
memory) followed by a
command(IPC, 1)
to actually perform the discovery and return a descriptor.To make this cleaner, I also rejiggerd the arguments in
command
, which now has to mean more than just notify.Previously, the arguments were:
Now, the arguments are:
There are a number of other changes I believe could make sense to make to IPC before releasing 2.0, but I think they should be decoupled from this pull request, which merely adapts the interface very little to get it working. These are just ideas, and we should discuss all these separately:
Testing Strategy
Tested using the IPC tutorial in libtock-c (examples/tutorial/05-ipc) after applying changes from tock/libtock-c#176
TODO or Help Wanted
Still need to adapt libtock-c userspace to properly test.(Done in tock/libtock-c#176)Still need to update documentation
Please review not only the implementation but the change in interface described above. As I said, there are a variety of changes that might make sense for IPC that go beyond these minimal changes. I ask that we get something in that reliably reproduces the existing high-level semantics for IPC and after (or maybe concurrently) decide whether other changes should happen (either before or after 2.0).
Documentation Updated
/docs
, or no updates are required.Formatting
make prepush
.