Commit bb1d5041 authored by Alice Ryhl's avatar Alice Ryhl
Browse files

ANDROID: rust_binder: add oneway transactions

Add support for sending oneway transactions using the binder driver.

Oneway transactions have a special requirement that they need to be
serialized. That is, the driver should not deliver an oneway transaction
when another one is already being handled. This is to avoid the case
where oneway transactions appear to arrive in the wrong order to
userspace. However, this patch does not implement serialization of
oneway transactions. Therefore, this patch does not actually make it
possible to send oneway transactions - it just defines them and adds a
TODO for making it possible to send them. It will be made possible to
send them in a later patch that makes them serialized.

To receive transactions, the process must first use mmap to create a
memory region for holding the contents of incoming transactions. The
driver will manage the resulting memory using two files: `allocation.rs`
and `range_alloc.rs`.

The `allocation.rs` file is responsible for actually managing the
mmap'ed region of memory and has methods for writing to it.

The `range_alloc.rs` file contains a data structure for tracking where
in the mmap we are storing different things. It doesn't actually touch
the mmap itself. Basically, it's a data structure that stores a set of
non-overlapping intervals (the allocations) and it is able to find the
smallest offset where the next X bytes are free and allocate that
region.

Other than that, this patch introduces a `Transaction` struct that
stores the information related to a transaction, and adds the necessary
infrastructure to send and receive them. This uses the work lists
introduced by a previous patch to deliver incoming transactions.

There are several different possible implementations of the range
allocator, and we have implemented several of them. The simplest
possible implementation is to use a linked list to store the allocations
and free regions sorted by address. Another possibility is to store the
same thing using a red-black tree. The red-black tree is preferable to
the linked list because its accesses are logarithmic rather than linear.

This RFC implements the range allocator using a red-black tree.

We have also looked into replacing the red-black tree with an XArray.
However, this is challenging because it doesn't have a good way to look
up the smallest free region whose size is at least some lower bound. You
can use `xa_find`, but there could be many free regions of the same
size, which makes it a challenge to maintain this information correctly.
We also run into issues with having to allocate while holding a lock.
Finally, the XArray is not optimized for this use-case: all of the
indices are going to have gaps between them.

Link: https://lore.kernel.org/rust-for-linux/20231101-rust-binder-v1-6-08ba9197f637@google.com/


Change-Id: I47177f93b40bd62cefa04010c4158908e7d9c95b
Co-developed-by: default avatarWedson Almeida Filho <wedsonaf@gmail.com>
Co-developed-by: default avatarMatt Gilbride <mattgilbride@google.com>
Signed-off-by: default avatarWedson Almeida Filho <wedsonaf@gmail.com>
Signed-off-by: default avatarMatt Gilbride <mattgilbride@google.com>
Signed-off-by: default avatarAlice Ryhl <aliceryhl@google.com>
Bug: 278052745
parent 0ccb57c7
Loading
Loading
Loading
Loading
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please to comment