Skip to content

Commit

Permalink
VIRTIO_F_NOTIFICATION_DATA: extra data to devices
Browse files Browse the repository at this point in the history
Some devices benefit from ability to find out the number of available
descriptors in the ring: for efficiency or as a debugging aid.

To help with these optimizations, add a new feature:
VIRTIO_F_NOTIFICATION_DATA. When negotiated, driver notifications to the
device include this extra information.

Signed-off-by: Michael S. Tsirkin <[email protected]>
  • Loading branch information
mstsirkin committed Mar 27, 2018
1 parent 91d9850 commit 396b195
Show file tree
Hide file tree
Showing 3 changed files with 113 additions and 6 deletions.
109 changes: 103 additions & 6 deletions content.tex
Original file line number Diff line number Diff line change
Expand Up @@ -283,9 +283,49 @@ \section{Virtqueues}\label{sec:Basic Facilities of a Virtio Device / Virtqueues}
Every driver and device supports either the Packed or the Split
Virtqueue format, or both.

\subsection{Driver notifications} \label{sec:Virtqueues / Driver notifications}
The driver is sometimes required to notify the device after
making changes to the virtqueue.

When VIRTIO_F_NOTIFICATION_DATA has not been negotiated,
this notification involves sending the
virtqueue number to the device (method depending on the transport).

However, some devices benefit from the ability to find out the number of
available descriptors in the ring without accessing the virtqueue in memory:
for efficiency or as a debugging aid.

To help with these optimizations, when VIRTIO_F_NOTIFICATION_DATA
has been negotiated, driver notifications to the device include
the following information:

\begin{description}
\item [VQ number]
\item [Offset]
Within the ring where the next available ring entry
will be written.
Without VIRTIO_F_RING_PACKED this refers to the
15 least significant bits of the available index.
With VIRTIO_F_RING_PACKED this refers to the offset
(in units of descriptor entries)
within the descriptor ring where the next available
descriptor will be written.
\item [Wrap Counter]
With VIRTIO_F_RING_PACKED this is the wrap counter
referring to the next available descriptor.
Without VIRTIO_F_RING_PACKED this is the most significant bit
of the available index.
\end{description}

Note that the driver can trigger multiple notifications even without
making any more changes to the ring. When VIRTIO_F_NOTIFICATION_DATA
has been negotiated, these notifications would then have
identical \field{Offset} and \field{Wrap Counter} values.

\input{split-ring.tex}

\input{packed-ring.tex}

\chapter{General Initialization And Device Operation}\label{sec:General Initialization And Device Operation}

We start with an overview of device initialization, then expand on the
Expand Down Expand Up @@ -862,7 +902,9 @@ \subsubsection{Notification structure layout}\label{sec:Virtio Transport Options
\devicenormative{\paragraph}{Notification capability}{Virtio Transport Options / Virtio Over PCI Bus / PCI Device Layout / Notification capability}
The device MUST present at least one notification capability.

The \field{cap.offset} MUST be 2-byte aligned.
For devices not offering VIRTIO_F_NOTIFICATION_DATA:

The \field{cap.offset} MUST be 2-byte aligned.

The device MUST either present \field{notify_off_multiplier} as an even power of 2,
or present \field{notify_off_multiplier} as 0.
Expand All @@ -876,6 +918,23 @@ \subsubsection{Notification structure layout}\label{sec:Virtio Transport Options
cap.length >= queue_notify_off * notify_off_multiplier + 2
\end{lstlisting}

For devices offering VIRTIO_F_NOTIFICATION_DATA:

The device MUST either present \field{notify_off_multiplier} as a
number that is a power of 2 that is also a multiple 4,
or present \field{notify_off_multiplier} as 0.

The \field{cap.offset} MUST be 4-byte aligned.

The value \field{cap.length} presented by the device MUST be at least 4
and MUST be large enough to support queue notification offsets
for all supported queues in all possible configurations.

For all queues, the value \field{cap.length} presented by the device MUST satisfy:
\begin{lstlisting}
cap.length >= queue_notify_off * notify_off_multiplier + 4
\end{lstlisting}

\subsubsection{ISR status capability}\label{sec:Virtio Transport Options / Virtio Over PCI Bus / PCI Device Layout / ISR status capability}

The VIRTIO_PCI_CAP_ISR_CFG capability
Expand Down Expand Up @@ -1268,8 +1327,21 @@ \subsubsection{Device Initialization}\label{sec:Virtio Transport Options / Virti

\subsubsection{Notifying The Device}\label{sec:Virtio Transport Options / Virtio Over PCI Bus / PCI-specific Initialization And Device Operation / Notifying The Device}

The driver notifies the device by writing the 16-bit virtqueue index
of this virtqueue to the Queue Notify address. See \ref{sec:Virtio Transport Options / Virtio Over PCI Bus / PCI Device Layout / Notification capability} for how to calculate this address.
When VIRTIO_F_NOTIFICATION_DATA has not been negotiated,
the driver notifies the device by writing the 16-bit virtqueue index
of this virtqueue (in little-endian byte order format)
to the Queue Notify address.

When VIRTIO_F_NOTIFICATION_DATA has been negotiated,
the driver notifies the device by writing the following
32-bit value to the Queue Notify address:
\lstinputlisting{notifications-le.c}

See \ref{sec:Virtqueues / Driver notifications}~\nameref{sec:Virtqueues / Driver notifications}
for the definition of the components.

See \ref{sec:Virtio Transport Options / Virtio Over PCI Bus / PCI Device Layout / Notification capability} for how to calculate the
Queue Notify address.

\subsubsection{Virtqueue Interrupts From The Device}\label{sec:Virtio Transport Options / Virtio Over PCI Bus / PCI-specific Initialization And Device Operation / Virtqueue Interrupts From The Device}

Expand Down Expand Up @@ -1500,8 +1572,19 @@ \subsection{MMIO Device Register Layout}\label{sec:Virtio Transport Options / Vi
}
\hline
\mmioreg{QueueNotify}{Queue notifier}{0x050}{W}{%
Writing a queue index to this register notifies the device that
there are new buffers to process in the queue.
Writing a value this register notifies the device that
there are new buffers to process in a queue.

When VIRTIO_F_NOTIFICATION_DATA has not been negotiated,
the value written is the queue index.

When VIRTIO_F_NOTIFICATION_DATA has been negotiated,
the value has the following format:

\lstinputlisting{notifications-le.c}

See \ref{sec:Virtqueues / Driver notifications}~\nameref{sec:Virtqueues / Driver notifications}
for the definition of the components.
}
\hline
\mmioreg{InterruptStatus}{Interrupt status}{0x60}{R}{%
Expand Down Expand Up @@ -2340,12 +2423,22 @@ \subsubsection{Guest->Host Notification}\label{sec:Virtio Transport Options / Vi
\hline
2 & Subchannel ID & Host Cookie \\
\hline
3 & Virtqueue number & \\
3 & Notification data & \\
\hline
4 & Host Cookie & \\
\hline
\end{tabular}

When VIRTIO_F_NOTIFICATION_DATA has not been negotiated,
the \field{Notification data} contains the Virtqueue number.

When VIRTIO_F_NOTIFICATION_DATA has been negotiated,
the value has the following format:
\lstinputlisting{notifications-be.c}

See \ref{sec:Virtqueues / Driver notifications}~\nameref{sec:Virtqueues / Driver notifications}
for the definition of the components.

\devicenormative{\paragraph}{Guest->Host Notification}{Virtio Transport Options / Virtio over channel I/O / Device Operation / Guest->Host Notification}
The device MUST ignore bits 0-31 (counting from the left) of GPR2.
This aligns passing the subchannel ID with the way it is passed
Expand Down Expand Up @@ -5348,6 +5441,10 @@ \chapter{Reserved Feature Bits}\label{sec:Reserved Feature Bits}
\item[VIRTIO_F_IN_ORDER(35)] This feature indicates
that all buffers are used by the device in the same
order in which they have been made available.
\item[VIRTIO_F_NOTIFICATION_DATA(36)] This feature indicates
that drivers pass extra data (besides identifying the Virtqueue)
in their device notifications.
See \ref{sec:Virtqueues / Driver notifications}~\nameref{sec:Virtqueues / Driver notifications}.
\end{description}

\drivernormative{\section}{Reserved Feature Bits}{Reserved Feature Bits}
Expand Down
5 changes: 5 additions & 0 deletions notifications-be.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
be32 {
vqn : 16;
next_off : 15;
next_wrap : 1;
};
5 changes: 5 additions & 0 deletions notifications-le.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
le32 {
vqn : 16;
next_off : 15;
next_wrap : 1;
};

0 comments on commit 396b195

Please sign in to comment.