69 lines
3.8 KiB
ReStructuredText
Executable File
69 lines
3.8 KiB
ReStructuredText
Executable File
.. SPDX-License-Identifier: GPL-2.0
|
|
|
|
Message Queues
|
|
==============
|
|
Message queue is a simple low-capacity IPC channel between two virtual machines.
|
|
It is intended for sending small control and configuration messages. Each
|
|
message queue is unidirectional and buffered in the hypervisor. A full-duplex
|
|
IPC channel requires a pair of queues.
|
|
|
|
The size of the queue and the maximum size of the message that can be passed is
|
|
fixed at creation of the message queue. Resource manager is presently the only
|
|
use case for message queues, and creates messages queues between itself and VMs
|
|
with a fixed maximum message size of 240 bytes. Longer messages require a
|
|
further protocol on top of the message queue messages themselves. For instance,
|
|
communication with the resource manager adds a header field for sending longer
|
|
messages which are split into smaller fragments.
|
|
|
|
The diagram below shows how message queue works. A typical configuration
|
|
involves 2 message queues. Message queue 1 allows VM_A to send messages to VM_B.
|
|
Message queue 2 allows VM_B to send messages to VM_A.
|
|
|
|
1. VM_A sends a message of up to 240 bytes in length. It makes a hypercall
|
|
with the message to request the hypervisor to add the message to
|
|
message queue 1's queue. The hypervisor copies memory into the internal
|
|
message queue buffer; the memory doesn't need to be shared between
|
|
VM_A and VM_B.
|
|
|
|
2. Gunyah raises the corresponding interrupt for VM_B (Rx vIRQ) when any of
|
|
these happens:
|
|
|
|
a. gunyah_msgq_send() has PUSH flag. This is a typical case when the message
|
|
queue is being used to implement an RPC-like interface.
|
|
b. Explicitly with gunyah_msgq_push hypercall from VM_A.
|
|
c. Message queue has reached a threshold depth. Typically, this threshold
|
|
depth is the size of the queue (in other words: when queue is full, Rx
|
|
vIRQ is raised).
|
|
|
|
3. VM_B calls gunyah_msgq_recv() and Gunyah copies message to requested buffer.
|
|
|
|
4. Gunyah raises the corresponding interrupt for VM_A (Tx vIRQ) when the message
|
|
queue falls below a watermark depth. Typically, this is when the queue is
|
|
drained. Note the watermark depth and the threshold depth for the Rx vIRQ are
|
|
independent values. Coincidentally, this signal is conceptually similar to
|
|
Clear-to-Send.
|
|
|
|
For VM_B to send a message to VM_A, the process is identical, except that
|
|
hypercalls reference message queue 2's capability ID. The IRQ will be different
|
|
for the second message queue.
|
|
|
|
::
|
|
|
|
+-------------------+ +-----------------+ +-------------------+
|
|
| VM_A | |Gunyah hypervisor| | VM_B |
|
|
| | | | | |
|
|
| | | | | |
|
|
| | Tx | | | |
|
|
| |-------->| | Rx vIRQ | |
|
|
|gunyah_msgq_send() | Tx vIRQ |Message queue 1 |-------->|gunyah_msgq_recv() |
|
|
| |<------- | | | |
|
|
| | | | | |
|
|
| | | | | |
|
|
| | | | Tx | |
|
|
| | Rx vIRQ | |<--------| |
|
|
|gunyah_msgq_recv() |<--------|Message queue 2 | Tx vIRQ |gunyah_msgq_send() |
|
|
| | | |-------->| |
|
|
| | | | | |
|
|
| | | | | |
|
|
+-------------------+ +-----------------+ +---------------+
|