The principle of Relay Relay provides a mechanism that allows kernel-space programs to efficiently transfer large amounts of data to user space through user-defined Relay channels (channel). A Relay channel consists of a set of kernel buffers corresponding to CPU one by one. These buffers are also known as Relay buffers (buffer), each of which is represented in the user space by a regular file called the Relay file. Kernel space users can use the API interface provided by Relay to write data, which is automatically written to the current CPU ID corresponding to the Relay buffer, and these buffers from the user space, is a set of ordinary files can be read directly using read (), you can also use the M Map (). Relay does not care about the format and content of the data, which is entirely dependent on the user program using Relay. The purpose of Relay is to provide an interface that is simple enough to make the basic operation as efficient as possible. Relay realizes the separation of the data read and write, so that when the large amount of burst data is written, it does not need to be limited by the relatively slow reading speed of the user space, which greatly improves the efficiency. Relay as a bridge to write and read, which is a program that caches and forwards data written by kernel users to user space. This forwarding mechanism is the origin of the name Relay.
Open (): Allows the user to open a channel buffer that already exists.
Mmap (): Causes the channel buffer to be mapped to the address space of the caller in the user space. It is important to note that we cannot map only local areas. That is, the entire buffer file must be mapped, the size of which is the product of the number of CPUs and the size of a single CPU buffer.
Read (): reads the contents of the channel buffer. Once this data is read out, it means that they are consumed by the user-space program and cannot be seen by the subsequent read operation.
Sendfile (): Transfers data from the channel buffer to an output file descriptor. The possible padding characters are automatically removed and will not be seen by the user.
Poll (): Supports Pollin/pollrdnorm/pollerr signal. Each time a child buffer boundary is crossed, the waiting user space program is notified.
Close (): Reduce the number of references to the channel buffers by 1. When the reference count is reduced to 0 o'clock, it indicates that no process or kernel user needs to open it, so that the channel buffer is freed.
Relay_open (): Creates a relay channel, including creating a relay buffer corresponding to each CPU.
Relay_close (): Closes a relay channel, including releasing all relay buffers, before which Relay_switch () is called to process these relay buffers to ensure that the data that has been read but not full is not lost.
Relay_write (): writes data to the relay buffer corresponding to the current CPU. Because it uses local_irqsave () protection, it can also be used in the context of an interrupt.
Relay_reserve (): A contiguous area is reserved in the relay channel for future write operations. The user is typically used for those who want to write directly to the Relay buffer. For performance or other reasons, these users do not want to write the data to a temporary buffer before writing it through Relay_write ().
Android Deep Exploration and Driver Development (III)