Skip to content

Latest commit

 

History

History
69 lines (56 loc) · 3.72 KB

message-queue.rst

File metadata and controls

69 lines (56 loc) · 3.72 KB

Message Queues

Message queue is a simple low-capacity IPC channel between two VMs. It is intended for sending small control and configuration messages. Each message queue is unidirectional, so a full-duplex IPC channel requires a pair of queues.

Messages can be up to 240 bytes in length. 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 via multiple message 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 raises a hypercall with the message to inform the hypervisor to add the message to message queue 1's queue.
  2. Gunyah raises the corresponding interrupt for VM_B (Rx vIRQ) when any of these happens:
    1. gh_msgq_send has PUSH flag. Queue is immediately flushed. This is the typical case.
    2. Explicility with gh_msgq_push command from VM_A.
    3. Message queue has reached a threshold depth.
  3. VM_B calls gh_msgq_recv and Gunyah copies message to requested buffer.
  4. Gunyah buffers messages in the queue. If the queue became full when VM_A added a message, the return values for gh_msgq_send() include a flag that indicates the queue is full. Once VM_B receives the message and, thus, there is space in the queue, Gunyah will raise the Tx vIRQ on VM_A to indicate it can continue sending messages.

For VM_B to send a message to VM_A, the process is identical, except that hypercalls reference message queue 2's capability ID. Each message queue has its own independent vIRQ: two TX message queues will have two vIRQs (and two capability IDs).

+---------------+         +-----------------+         +---------------+
|      VM_A     |         |Gunyah hypervisor|         |      VM_B     |
|               |         |                 |         |               |
|               |         |                 |         |               |
|               |   Tx    |                 |         |               |
|               |-------->|                 | Rx vIRQ |               |
|gh_msgq_send() | Tx vIRQ |Message queue 1  |-------->|gh_msgq_recv() |
|               |<------- |                 |         |               |
|               |         |                 |         |               |
| Message Queue |         |                 |         | Message Queue |
| driver        |         |                 |         | driver        |
|               |         |                 |         |               |
|               |         |                 |         |               |
|               |         |                 |   Tx    |               |
|               | Rx vIRQ |                 |<--------|               |
|gh_msgq_recv() |<--------|Message queue 2  | Tx vIRQ |gh_msgq_send() |
|               |         |                 |-------->|               |
|               |         |                 |         |               |
|               |         |                 |         |               |
+---------------+         +-----------------+         +---------------+

Gunyah message queues are exposed as mailboxes. To create the mailbox, create a mbox_client and call gh_msgq_init. On receipt of the RX_READY interrupt, all messages in the RX message queue are read and pushed via the rx_callback of the registered mbox_client.

.. kernel-doc:: drivers/mailbox/gunyah-msgq.c
   :identifiers: gh_msgq_init