virtio — archive
[Date Prev]
| [Thread Prev]
| [Thread Next]
| [Date Next]
— [Date Index]
| [Thread Index]
| [Month Index]
| [List Home]
[PATCH] VIRTIO-60: avoid vring and VIRTIO_RING.
These are never introduced, so use simpler names: virtq* for structures and VIRTIO_ for features. NOTE: This needs notes about legacy names! But MST is adding legacy sections soon anyway, so fix after that. Signed-off-by: Rusty Russell <[email protected]> diff --git a/content.tex b/content.tex index 3a9c849..9f4cdf1 100644 --- a/content.tex +++ b/content.tex @@ -265,10 +265,10 @@ required for the virtqueue according to the following formula:
egin{lstlisting} #define ALIGN(x) (((x) + PAGE_SIZE) & ~PAGE_SIZE) -static inline unsigned vring_size(unsigned int qsz) +static inline unsigned virtq_size(unsigned int qsz) { -
return ALIGN(sizeof(struct vring_desc)*qsz + sizeof(u16)*(3 + qsz)) -
+ ALIGN(sizeof(u16)*3 + sizeof(struct vring_used_elem)*qsz); +
return ALIGN(sizeof(struct virtq_desc)*qsz + sizeof(u16)*(3 + qsz)) +
+ ALIGN(sizeof(u16)*3 + sizeof(struct virtq_used_elem)*qsz); } end{lstlisting}
@@ -276,18 +276,18 @@ This wastes some space with padding. The legacy virtqueue layout structure therefore looks like this:
egin{lstlisting} -struct vring { +struct virtq {
// The actual descriptors (16 bytes each) -
struct vring_desc desc[ Queue Size ]; +
struct virtq_desc desc[ Queue Size ];
// A ring of available descriptor heads with free-running index. -
struct vring_avail avail; +
struct virtq_avail avail;
// Padding to the next PAGE_SIZE boundary.
u8 pad[ Padding ];
// A ring of used descriptor heads with free-running index. -
struct vring_used used; +
struct virtq_used used; }; end{lstlisting}
@@ -350,18 +350,18 @@ it with a status tailer for the device to write.
egin{lstlisting} /* Note: LEGACY version was not little endian! */ -struct vring_desc { +struct virtq_desc {
/* Address (guest-physical). */
le64 addr;
/* Length. */
le32 len;
/* This marks a buffer as continuing via the next field. */ -#define VRING_DESC_F_NEXT
1 +#define VIRTQ_DESC_F_NEXT
1 /* This marks a buffer as device write-only (otherwise device read-only). */ -#define VRING_DESC_F_WRITE
2 +#define VIRTQ_DESC_F_WRITE
2 /* This means the buffer contains a list of buffer descriptors. */ -#define VRING_DESC_F_INDIRECT
4 +#define VIRTQ_DESC_F_INDIRECT
4
/* The flags as indicated above. */
le16 flags;
/* Next field if flags & NEXT */ @@ -384,10 +384,10 @@ this implies that loops in the descriptor chain are forbidden! subsubsection{Indirect Descriptors}label{sec:Basic Facilities of a Virtio Device / Virtqueues / The Virtqueue Descriptor Table / Indirect Descriptors}
Some devices benefit by concurrently dispatching a large number -of large requests. The VIRTIO_RING_F_INDIRECT_DESC feature allows this (see
ef{sec:virtio-ring.h}~
ameref{sec:virtio-ring.h}). To increase +of large requests. The VIRTIO_F_INDIRECT_DESC feature allows this (see
ef{sec:virtio-ring.h}~
ameref{sec:virtio-ring.h}). To increase ring capacity the driver can store a table of indirect descriptors anywhere in memory, and insert a descriptor in main -virtqueue (with field{flags}&VRING_DESC_F_INDIRECT on) that refers to memory buffer +virtqueue (with field{flags}&VIRTQ_DESC_F_INDIRECT on) that refers to memory buffer containing this indirect descriptor table; field{addr} and field{len} refer to the indirect table address and length in bytes, respectively. @@ -399,36 +399,36 @@ which is a variable, so this code won't compile): egin{lstlisting} struct indirect_descriptor_table {
/* The actual descriptors (16 bytes each) */ -
struct vring_desc desc[len / 16]; +
struct virtq_desc desc[len / 16]; }; end{lstlisting}
The first indirect descriptor is located at start of the indirect descriptor table (index 0), additional indirect descriptors are chained by field{next}. An indirect descriptor without a valid field{next} -(with field{flags}&VRING_DESC_F_NEXT off) signals the end of the descriptor. +(with field{flags}&VIRTQ_DESC_F_NEXT off) signals the end of the descriptor. A single indirect descriptor table can include both device-readable and device-writable descriptors.
drivernormative{paragraph}{Indirect Descriptors}{Basic Facilities of a Virtio Device / Virtqueues / The Virtqueue Descriptor Table / Indirect Descriptors} -The driver MUST NOT set the VRING_DESC_F_INDIRECT flag unless the -VIRTIO_RING_F_INDIRECT_DESC feature was negotiated.
The driver MUST NOT -set the VRING_DESC_F_INDIRECT flag within an indirect descriptor (ie. only +The driver MUST NOT set the VIRTQ_DESC_F_INDIRECT flag unless the +VIRTIO_F_INDIRECT_DESC feature was negotiated.
The driver MUST NOT +set the VIRTQ_DESC_F_INDIRECT flag within an indirect descriptor (ie. only one table per descriptor).
devicenormative{paragraph}{Indirect Descriptors}{Basic Facilities of a Virtio Device / Virtqueues / The Virtqueue Descriptor Table / Indirect Descriptors} -The device MUST ignore the write-only flag (field{flags}&VRING_DESC_F_WRITE) in the descriptor that refers to an indirect table. +The device MUST ignore the write-only flag (field{flags}&VIRTQ_DESC_F_WRITE) in the descriptor that refers to an indirect table.
subsection{The Virtqueue Available Ring}label{sec:Basic Facilities of a Virtio Device / Virtqueues / The Virtqueue Available Ring}
egin{lstlisting} /* Note: LEGACY version was not little endian! */ -struct vring_avail { -#define VRING_AVAIL_F_NO_INTERRUPT
1 +struct virtq_avail { +#define VIRTQ_AVAIL_F_NO_INTERRUPT
1
le16 flags;
le16 idx;
le16 ring[ /* Queue Size */ ]; -
le16 used_event; /* Only if VIRTIO_RING_F_EVENT_IDX */ +
le16 used_event; /* Only if VIRTIO_F_EVENT_IDX */ }; end{lstlisting}
@@ -441,7 +441,7 @@ entry in the ring (modulo the queue size). This starts at 0, and increases.
subsection{Virtqueue Interrupt Suppression}label{sec:Basic Facilities of a Virtio Device / Virtqueues / Virtqueue Interrupt Suppression}
-If the VIRTIO_RING_F_EVENT_IDX feature bit is not negotiated, +If the VIRTIO_F_EVENT_IDX feature bit is not negotiated, the field{flags} field in the available ring offers a crude mechanism for the driver to inform the device that it doesn't want interrupts when buffers are used. Otherwise field{used_event} is a more performant alterative where the driver @@ -452,14 +452,14 @@ are not explicitly synchronized with the device, but they serve as useful optimizations.
drivernormative{subsubsection}{Virtqueue Interrupt Suppression}{Basic Facilities of a Virtio Device / Virtqueues / Virtqueue Interrupt Suppression} -If the VIRTIO_RING_F_EVENT_IDX feature bit is not negotiated: +If the VIRTIO_F_EVENT_IDX feature bit is not negotiated: egin{itemize} item The driver MUST set field{flags} to 0 or 1. item The driver MAY set field{flags} to 1 to advise the device that interrupts are not required. end{itemize}
-Otherwise, if the VIRTIO_RING_F_EVENT_IDX feature bit is negotiated: +Otherwise, if the VIRTIO_F_EVENT_IDX feature bit is negotiated: egin{itemize} item The driver MUST set field{flags} to 0. item The driver MAY use field{used_event} to advise the device that interrupts are not required until the device writes entry with an index specified by field{used_event} into the used ring (equivalently, until field{idx} in the @@ -470,7 +470,7 @@ The driver MUST handle spurious interrupts from the device.
devicenormative{subsubsection}{Virtqueue Interrupt Suppression}{Basic Facilities of a Virtio Device / Virtqueues / Virtqueue Interrupt Suppression}
-If the VIRTIO_RING_F_EVENT_IDX feature bit is not negotiated: +If the VIRTIO_F_EVENT_IDX feature bit is not negotiated: egin{itemize} item The device MUST ignore the field{used_event} value. item After the device writes a descriptor index into the used ring: @@ -480,7 +480,7 @@ If the VIRTIO_RING_F_EVENT_IDX feature bit is not negotiated:
end{itemize} end{itemize}
-Otherwise, if the VIRTIO_RING_F_EVENT_IDX feature bit is negotiated: +Otherwise, if the VIRTIO_F_EVENT_IDX feature bit is negotiated: egin{itemize} item The device MUST ignore the lower bit of field{flags}. item After the device writes a descriptor index into the used ring: @@ -494,7 +494,7 @@ Otherwise, if the VIRTIO_RING_F_EVENT_IDX feature bit is negotiated:
egin{note} For example, if field{used_event} is 0, then a device using - VIRTIO_RING_F_EVENT_IDX would interrupt after the first buffer is + VIRTIO_F_EVENT_IDX would interrupt after the first buffer is
used (and again after the 65536th buffer, etc). end{note}
@@ -502,17 +502,17 @@ For example, if field{used_event} is 0, then a device using
egin{lstlisting} /* Note: LEGACY version was not little endian! */ -struct vring_used { -#define VRING_USED_F_NO_NOTIFY 1 +struct virtq_used { +#define VIRTQ_USED_F_NO_NOTIFY 1
le16 flags;
le16 idx; -
struct vring_used_elem ring[ /* Queue Size */]; -
le16 avail_event; /* Only if VIRTIO_RING_F_EVENT_IDX */ +
struct virtq_used_elem ring[ /* Queue Size */]; +
le16 avail_event; /* Only if VIRTIO_F_EVENT_IDX */ };
/* Note: LEGACY version was not little endian! */ /* le32 is used here for ids for padding reasons. */ -struct vring_used_elem { +struct virtq_used_elem {
/* Index of start of used descriptor chain. */
le32 id;
/* Total length of the descriptor chain which was used (written to) */ @@ -543,7 +543,7 @@ same way the driver manipulates field{flags} or field{used_event} in the avail The driver MUST initialize field{flags} in the used ring to 0 when allocating the used ring.
-If the VIRTIO_RING_F_EVENT_IDX feature bit is not negotiated: +If the VIRTIO_F_EVENT_IDX feature bit is not negotiated: egin{itemize} item The driver MUST ignore the field{avail_event} value. item After the driver writes a descriptor index into the available ring: @@ -553,7 +553,7 @@ If the VIRTIO_RING_F_EVENT_IDX feature bit is not negotiated:
end{itemize} end{itemize}
-Otherwise, if the VIRTIO_RING_F_EVENT_IDX feature bit is negotiated: +Otherwise, if the VIRTIO_F_EVENT_IDX feature bit is negotiated: egin{itemize} item The driver MUST ignore the lower bit of field{flags}. item After the driver writes a descriptor index into the available ring: @@ -566,14 +566,14 @@ Otherwise, if the VIRTIO_RING_F_EVENT_IDX feature bit is negotiated: end{itemize}
devicenormative{subsubsection}{Virtqueue Notification Suppression}{Basic Facilities of a Virtio Device / Virtqueues / Virtqueue Notification Suppression} -If the VIRTIO_RING_F_EVENT_IDX feature bit is not negotiated: +If the VIRTIO_F_EVENT_IDX feature bit is not negotiated: egin{itemize} item The device MUST set field{flags} to 0 or 1. item The device MAY set field{flags} to 1 to advise the driver that notifications are not required. end{itemize}
-Otherwise, if the VIRTIO_RING_F_EVENT_IDX feature bit is negotiated: +Otherwise, if the VIRTIO_F_EVENT_IDX feature bit is negotiated: egin{itemize} item The device MUST set field{flags} to 0. item The device MAY use field{avail_event} to advise the driver that notifications are not required until the driver writes entry with an index specified by field{avail_event} into the available ring (equivalently, until field{idx} in the @@ -714,13 +714,13 @@ for each buffer element, b: item Get the next free descriptor table entry, d item Set field{d.addr} to the physical address of the start of b item Set field{d.len} to the length of b. -item If b is device-writable, set field{d.flags} to VRING_DESC_F_WRITE, +item If b is device-writable, set field{d.flags} to VIRTQ_DESC_F_WRITE,
otherwise 0. item If there is a buffer element after this:
egin{enumerate}
item Set field{d.next} to the index of the next free descriptor
element. -
item Set the VRING_DESC_F_NEXT bit in field{d.flags}. +
item Set the VIRTQ_DESC_F_NEXT bit in field{d.flags}.
end{enumerate} end{enumerate}
@@ -791,20 +791,20 @@ emptying the ring and reenabling interrupts. This is usually handled by re-checking for more used buffers after interrups are re-enabled:
egin{lstlisting} -vring_disable_interrupts(vq); +virtq_disable_interrupts(vq);
for (;;) { -
if (vq->last_seen_used != le16_to_cpu(vring->used.idx)) { -
vring_enable_interrupts(vq); +
if (vq->last_seen_used != le16_to_cpu(virtq->used.idx)) { +
virtq_enable_interrupts(vq);
mb();
-
if (vq->last_seen_used != le16_to_cpu(vring->used.idx)) +
if (vq->last_seen_used != le16_to_cpu(virtq->used.idx))
break;
-
vring_disable_interrupts(vq); +
virtq_disable_interrupts(vq);
}
-
struct vring_used_elem *e = vring.used->ring[vq->last_seen_used%vsz]; +
struct virtq_used_elem *e = virtq.used->ring[vq->last_seen_used%vsz];
process_buffer(e);
vq->last_seen_used++; } @@ -2389,11 +2389,11 @@ The calculation for total size is as follows:
egin{lstlisting} #define ALIGN(x) (((x) + align) & ~align) -static inline unsigned vring_size(unsigned int num) +static inline unsigned virtq_size(unsigned int num) { -
return ALIGN(sizeof(struct vring_desc)*num +
return ALIGN(sizeof(struct virtq_desc)*num
+ sizeof(u16)*(3 + num)) -
+ ALIGN(sizeof(u16)*3 + sizeof(struct vring_used_elem)*num); +
+ ALIGN(sizeof(u16)*3 + sizeof(struct virtq_used_elem)*num); } end{lstlisting}
@@ -3036,7 +3036,7 @@ which case it MUST set the VIRTIO_NET_HDR_GSO_ECN bit in field{gso_type}. paragraph{Packet Transmission Interrupt}label{sec:Device Types / Network Device / Device Operation / Packet Transmission / Packet Transmission Interrupt}
Often a driver will suppress transmission interrupts using the -VRING_AVAIL_F_NO_INTERRUPT flag +VIRTQ_AVAIL_F_NO_INTERRUPT flag
(see
ef{sec:General Initialization And Device Operation / Device Operation / Receiving Used Buffers From The Device}~
ameref{sec:General Initialization And Device Operation / Device Operation / Receiving Used Buffers From The Device}) and check for used packets in the transmit path of following packets. @@ -4719,7 +4719,7 @@ Currently there are three device-independent feature bits defined:
egin{description}
item[VIRTIO_F_RING_INDIRECT_DESC (28)] Negotiating this feature indicates - that the driver can use descriptors with the VRING_DESC_F_INDIRECT + that the driver can use descriptors with the VIRTQ_DESC_F_INDIRECT
flag set, as described in
ef{sec:Basic Facilities of a Virtio Device / Virtqueues / The Virtqueue Descriptor Table / Indirect Descriptors}~
ameref{sec:Basic Facilities of a Virtio Device / Virtqueues / The Virtqueue Descriptor Table / Indirect Descriptors}.
item[VIRTIO_F_RING_EVENT_IDX(29)] This feature enables the field{used_event} @@ -4747,7 +4747,7 @@ Legacy or transitional devices may offer the following: item[VIRTIO_F_NOTIFY_ON_EMPTY (24)] Negotiating this feature
indicates that the driver wants an interrupt if the device runs
out of available descriptors on a virtqueue, even though - interrupts are suppressed using the VRING_AVAIL_F_NO_INTERRUPT + interrupts are suppressed using the VIRTQ_AVAIL_F_NO_INTERRUPT
flag or the field{used_event} field. egin{note}
An example of this is the
[Date Prev]
| [Thread Prev]
| [Thread Next]
| [Date Next]
— [Date Index]
| [Thread Index]
| [Month Index]
| [List Home]