<feed xmlns='http://www.w3.org/2005/Atom'>
<title>passt/udp_vu.c, branch 2026_05_26.038c51e</title>
<subtitle>Plug A Simple Socket Transport</subtitle>
<link rel='alternate' type='text/html' href='https://passt.top/passt/'/>
<entry>
<title>vhost_user: Offer VIRTIO_NET_F_GUEST_CSUM</title>
<updated>2026-05-26T16:24:31+00:00</updated>
<author>
<name>Laurent Vivier</name>
<email>lvivier@redhat.com</email>
</author>
<published>2026-04-16T16:21:39+00:00</published>
<link rel='alternate' type='text/html' href='https://passt.top/passt/commit/?id=038c51e324695b65c154bc0eee30bd19a7423ad2'/>
<id>038c51e324695b65c154bc0eee30bd19a7423ad2</id>
<content type='text'>
According to the virtio-net specification, when the VIRTIO_NET_F_GUEST_CSUM
is negotiated, the device can set VIRTIO_NET_HDR_F_DATA_VALID in the
virtio-net header to indicate that packet checksums have been validated,
allowing the guest to skip verification. Without this feature, the device
must provide fully checksummed packets.

The vhost-user TCP and UDP paths were unconditionally skipping checksum
computation, regardless of whether GUEST_CSUM was negotiated. This
went undetected with Linux guests because Linux's virtio-net driver
honours VIRTIO_NET_HDR_F_DATA_VALID regardless of whether
VIRTIO_NET_F_GUEST_CSUM was negotiated, marking such packets as
CHECKSUM_UNNECESSARY and skipping verification.

iPXE, however, does not negotiate GUEST_CSUM, ignores the DATA_VALID
flag entirely, and always verifies checksums. This caused TCP
connections to fail: the SYN-ACK had a zero TCP checksum, iPXE rejected
it, and the connection timed out in SYN_RCVD.

Adding --pcap happened to mask the bug, because the pcap code path
forces checksum computation to ensure correct captures.

Offer VIRTIO_NET_F_GUEST_CSUM in the device features, and only skip
checksum computation when the guest has actually negotiated it. When
GUEST_CSUM is not negotiated, always compute valid checksums as required
by the specification.

We keep setting VIRTIO_NET_HDR_F_DATA_VALID unconditionally in
VU_HEADER: when GUEST_CSUM is negotiated, the flag lets the guest skip
checksum verification; when it is not, the spec says the guest should
ignore the flags field, so setting it is harmless.

Signed-off-by: Laurent Vivier &lt;lvivier@redhat.com&gt;
Reviewed-by: David Gibson &lt;david@gibson.dropbear.id.au&gt;
[sbrivio: Resolved conflicts, in particular with commit dec66c02b5e4
 ("udp: Pass iov_tail to udp_update_hdr4()/udp_update_hdr6()")]
Signed-off-by: Stefano Brivio &lt;sbrivio@redhat.com&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
According to the virtio-net specification, when the VIRTIO_NET_F_GUEST_CSUM
is negotiated, the device can set VIRTIO_NET_HDR_F_DATA_VALID in the
virtio-net header to indicate that packet checksums have been validated,
allowing the guest to skip verification. Without this feature, the device
must provide fully checksummed packets.

The vhost-user TCP and UDP paths were unconditionally skipping checksum
computation, regardless of whether GUEST_CSUM was negotiated. This
went undetected with Linux guests because Linux's virtio-net driver
honours VIRTIO_NET_HDR_F_DATA_VALID regardless of whether
VIRTIO_NET_F_GUEST_CSUM was negotiated, marking such packets as
CHECKSUM_UNNECESSARY and skipping verification.

iPXE, however, does not negotiate GUEST_CSUM, ignores the DATA_VALID
flag entirely, and always verifies checksums. This caused TCP
connections to fail: the SYN-ACK had a zero TCP checksum, iPXE rejected
it, and the connection timed out in SYN_RCVD.

Adding --pcap happened to mask the bug, because the pcap code path
forces checksum computation to ensure correct captures.

Offer VIRTIO_NET_F_GUEST_CSUM in the device features, and only skip
checksum computation when the guest has actually negotiated it. When
GUEST_CSUM is not negotiated, always compute valid checksums as required
by the specification.

We keep setting VIRTIO_NET_HDR_F_DATA_VALID unconditionally in
VU_HEADER: when GUEST_CSUM is negotiated, the flag lets the guest skip
checksum verification; when it is not, the spec says the guest should
ignore the flags field, so setting it is harmless.

Signed-off-by: Laurent Vivier &lt;lvivier@redhat.com&gt;
Reviewed-by: David Gibson &lt;david@gibson.dropbear.id.au&gt;
[sbrivio: Resolved conflicts, in particular with commit dec66c02b5e4
 ("udp: Pass iov_tail to udp_update_hdr4()/udp_update_hdr6()")]
Signed-off-by: Stefano Brivio &lt;sbrivio@redhat.com&gt;
</pre>
</div>
</content>
</entry>
<entry>
<title>udp: Pass iov_tail to udp_update_hdr4()/udp_update_hdr6()</title>
<updated>2026-05-26T10:17:07+00:00</updated>
<author>
<name>Laurent Vivier</name>
<email>lvivier@redhat.com</email>
</author>
<published>2026-05-20T09:55:26+00:00</published>
<link rel='alternate' type='text/html' href='https://passt.top/passt/commit/?id=dec66c02b5e43e0ef809afa47e1008e143a01250'/>
<id>dec66c02b5e43e0ef809afa47e1008e143a01250</id>
<content type='text'>
Change udp_update_hdr4() and udp_update_hdr6() to take an iov_tail
pointing at the UDP frame instead of a contiguous udp_payload_t buffer
and explicit data length.  This lets vhost-user pass scatter-gather
virtqueue buffers directly without an intermediate copy.

The UDP header is built into a local struct udphdr and written back with
IOV_PUSH_HEADER().  On the tap side, udp_tap_prepare() wraps the
existing udp_payload_t in a two-element iov to match the new interface.

Signed-off-by: Laurent Vivier &lt;lvivier@redhat.com&gt;
Reviewed-by: David Gibson &lt;david@gibson.dropbear.id.au&gt;
Signed-off-by: Stefano Brivio &lt;sbrivio@redhat.com&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
Change udp_update_hdr4() and udp_update_hdr6() to take an iov_tail
pointing at the UDP frame instead of a contiguous udp_payload_t buffer
and explicit data length.  This lets vhost-user pass scatter-gather
virtqueue buffers directly without an intermediate copy.

The UDP header is built into a local struct udphdr and written back with
IOV_PUSH_HEADER().  On the tap side, udp_tap_prepare() wraps the
existing udp_payload_t in a two-element iov to match the new interface.

Signed-off-by: Laurent Vivier &lt;lvivier@redhat.com&gt;
Reviewed-by: David Gibson &lt;david@gibson.dropbear.id.au&gt;
Signed-off-by: Stefano Brivio &lt;sbrivio@redhat.com&gt;
</pre>
</div>
</content>
</entry>
<entry>
<title>udp_vu: Allow virtqueue elements with multiple iovec entries</title>
<updated>2026-05-26T10:16:03+00:00</updated>
<author>
<name>Laurent Vivier</name>
<email>lvivier@redhat.com</email>
</author>
<published>2026-05-20T09:55:24+00:00</published>
<link rel='alternate' type='text/html' href='https://passt.top/passt/commit/?id=28ee143d92df5fd779a3f16b3f2717ab478584da'/>
<id>28ee143d92df5fd779a3f16b3f2717ab478584da</id>
<content type='text'>
The previous code assumed a 1:1 mapping between virtqueue elements and
iovec entries (enforced by an assert).  Drop that assumption to allow
elements that span multiple iovecs: track elem_used separately by
walking the element list against the iov count returned after padding.
This also fixes vu_queue_rewind() and vu_flush() to use the element
count rather than the iov count.

Use iov_tail_clone() in udp_vu_sock_recv() to handle header offset,
replacing the manual base/len adjustment and restore pattern.

Signed-off-by: Laurent Vivier &lt;lvivier@redhat.com&gt;
Reviewed-by: David Gibson &lt;david@gibson.dropbear.id.au&gt;
Reviewed-by: Jon Maloy &lt;jmaloy@redhat.com&gt;
Signed-off-by: Stefano Brivio &lt;sbrivio@redhat.com&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
The previous code assumed a 1:1 mapping between virtqueue elements and
iovec entries (enforced by an assert).  Drop that assumption to allow
elements that span multiple iovecs: track elem_used separately by
walking the element list against the iov count returned after padding.
This also fixes vu_queue_rewind() and vu_flush() to use the element
count rather than the iov count.

Use iov_tail_clone() in udp_vu_sock_recv() to handle header offset,
replacing the manual base/len adjustment and restore pattern.

Signed-off-by: Laurent Vivier &lt;lvivier@redhat.com&gt;
Reviewed-by: David Gibson &lt;david@gibson.dropbear.id.au&gt;
Reviewed-by: Jon Maloy &lt;jmaloy@redhat.com&gt;
Signed-off-by: Stefano Brivio &lt;sbrivio@redhat.com&gt;
</pre>
</div>
</content>
</entry>
<entry>
<title>vhost-user: Centralise Ethernet frame padding in vu_collect() and vu_pad()</title>
<updated>2026-05-19T23:21:55+00:00</updated>
<author>
<name>Laurent Vivier</name>
<email>lvivier@redhat.com</email>
</author>
<published>2026-05-13T11:52:18+00:00</published>
<link rel='alternate' type='text/html' href='https://passt.top/passt/commit/?id=db798fc60f4c5869cb53168354e068fb4dabd91a'/>
<id>db798fc60f4c5869cb53168354e068fb4dabd91a</id>
<content type='text'>
The previous per-protocol padding done by vu_pad() in tcp_vu.c and
udp_vu.c was only correct for single-buffer frames: it assumed the
padding area always fell within the first iov, writing past its end
with a plain memset().

It also required each caller to compute MAX(..., ETH_ZLEN + VNET_HLEN)
for vu_collect() and to call vu_pad() at the right point, duplicating
the minimum-size logic across protocols.

Move the Ethernet minimum size enforcement into vu_collect() itself, so
that enough buffer space is always reserved for padding regardless of
the requested frame size.

Rewrite vu_pad() to take a full iovec array and use iov_memset(),
making it safe for multi-buffer (mergeable rx buffer) frames.

In tcp_vu_sock_recv(), replace iov_truncate() with iov_skip_bytes():
now that all consumers receive explicit data lengths, truncating the
iovecs is no longer needed.  In tcp_vu_data_from_sock(), cap each
frame's data length against the remaining bytes actually received from
the socket, so that the last partial frame gets correct headers and
sequence number advancement.

Signed-off-by: Laurent Vivier &lt;lvivier@redhat.com&gt;
Reviewed-by: Jon Maloy &lt;jmaloy@redhat.com&gt;
Reviewed-by: David Gibson &lt;david@gibson.dropbear.id.au&gt;
Signed-off-by: Stefano Brivio &lt;sbrivio@redhat.com&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
The previous per-protocol padding done by vu_pad() in tcp_vu.c and
udp_vu.c was only correct for single-buffer frames: it assumed the
padding area always fell within the first iov, writing past its end
with a plain memset().

It also required each caller to compute MAX(..., ETH_ZLEN + VNET_HLEN)
for vu_collect() and to call vu_pad() at the right point, duplicating
the minimum-size logic across protocols.

Move the Ethernet minimum size enforcement into vu_collect() itself, so
that enough buffer space is always reserved for padding regardless of
the requested frame size.

Rewrite vu_pad() to take a full iovec array and use iov_memset(),
making it safe for multi-buffer (mergeable rx buffer) frames.

In tcp_vu_sock_recv(), replace iov_truncate() with iov_skip_bytes():
now that all consumers receive explicit data lengths, truncating the
iovecs is no longer needed.  In tcp_vu_data_from_sock(), cap each
frame's data length against the remaining bytes actually received from
the socket, so that the last partial frame gets correct headers and
sequence number advancement.

Signed-off-by: Laurent Vivier &lt;lvivier@redhat.com&gt;
Reviewed-by: Jon Maloy &lt;jmaloy@redhat.com&gt;
Reviewed-by: David Gibson &lt;david@gibson.dropbear.id.au&gt;
Signed-off-by: Stefano Brivio &lt;sbrivio@redhat.com&gt;
</pre>
</div>
</content>
</entry>
<entry>
<title>vu_common: Pass explicit frame length to vu_flush()</title>
<updated>2026-05-19T23:21:47+00:00</updated>
<author>
<name>Laurent Vivier</name>
<email>lvivier@redhat.com</email>
</author>
<published>2026-05-13T11:52:16+00:00</published>
<link rel='alternate' type='text/html' href='https://passt.top/passt/commit/?id=d83470f8b149c1108d884648d58fcdacd9ed781c'/>
<id>d83470f8b149c1108d884648d58fcdacd9ed781c</id>
<content type='text'>
Currently vu_flush() derives the frame size from the iov, but in
preparation for iov arrays that may be larger than the actual frame,
pass the total length (including vnet header) explicitly so that only
the relevant portion is reported to the virtqueue.

Ensure a minimum frame size of ETH_ZLEN + VNET_HLEN to handle short
frames. All elements are still flushed to avoid descriptor leaks,
but trailing elements beyond frame_len will report a zero length.

Signed-off-by: Laurent Vivier &lt;lvivier@redhat.com&gt;
Reviewed-by: David Gibson &lt;david@gibson.dropbear.id.au&gt;
Reviewed-by: Jon Maloy &lt;jmaloy@redhat.com&gt;
Signed-off-by: Stefano Brivio &lt;sbrivio@redhat.com&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
Currently vu_flush() derives the frame size from the iov, but in
preparation for iov arrays that may be larger than the actual frame,
pass the total length (including vnet header) explicitly so that only
the relevant portion is reported to the virtqueue.

Ensure a minimum frame size of ETH_ZLEN + VNET_HLEN to handle short
frames. All elements are still flushed to avoid descriptor leaks,
but trailing elements beyond frame_len will report a zero length.

Signed-off-by: Laurent Vivier &lt;lvivier@redhat.com&gt;
Reviewed-by: David Gibson &lt;david@gibson.dropbear.id.au&gt;
Reviewed-by: Jon Maloy &lt;jmaloy@redhat.com&gt;
Signed-off-by: Stefano Brivio &lt;sbrivio@redhat.com&gt;
</pre>
</div>
</content>
</entry>
<entry>
<title>pcap: Pass explicit L2 length to pcap_iov()</title>
<updated>2026-05-19T23:21:42+00:00</updated>
<author>
<name>Laurent Vivier</name>
<email>lvivier@redhat.com</email>
</author>
<published>2026-05-13T11:52:15+00:00</published>
<link rel='alternate' type='text/html' href='https://passt.top/passt/commit/?id=533ef11ecb4edd98c7adad3b51c40fdcc2f0671d'/>
<id>533ef11ecb4edd98c7adad3b51c40fdcc2f0671d</id>
<content type='text'>
With vhost-user multibuffer frames, the iov can be larger than the
actual L2 frame. The previous approach of computing L2 length as
iov_size() - offset would overcount and write extra bytes into the
pcap file.

Pass the L2 frame length explicitly to pcap_frame() and pcap_iov(),
and write exactly that many bytes instead of the full iov remainder.

Signed-off-by: Laurent Vivier &lt;lvivier@redhat.com&gt;
Reviewed-by: Jon Maloy &lt;jmaloy@redhat.com&gt;
Reviewed-by: David Gibson &lt;david@gibson.dropbear.id.au&gt;
Signed-off-by: Stefano Brivio &lt;sbrivio@redhat.com&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
With vhost-user multibuffer frames, the iov can be larger than the
actual L2 frame. The previous approach of computing L2 length as
iov_size() - offset would overcount and write extra bytes into the
pcap file.

Pass the L2 frame length explicitly to pcap_frame() and pcap_iov(),
and write exactly that many bytes instead of the full iov remainder.

Signed-off-by: Laurent Vivier &lt;lvivier@redhat.com&gt;
Reviewed-by: Jon Maloy &lt;jmaloy@redhat.com&gt;
Reviewed-by: David Gibson &lt;david@gibson.dropbear.id.au&gt;
Signed-off-by: Stefano Brivio &lt;sbrivio@redhat.com&gt;
</pre>
</div>
</content>
</entry>
<entry>
<title>checksum: Pass explicit L4 length to checksum functions</title>
<updated>2026-05-19T23:21:38+00:00</updated>
<author>
<name>Laurent Vivier</name>
<email>lvivier@redhat.com</email>
</author>
<published>2026-05-13T11:52:14+00:00</published>
<link rel='alternate' type='text/html' href='https://passt.top/passt/commit/?id=aa78f63c3c9491a9cad9f3c805a59748bd8c1ae2'/>
<id>aa78f63c3c9491a9cad9f3c805a59748bd8c1ae2</id>
<content type='text'>
The iov_tail passed to csum_iov_tail() may contain padding or trailing
data beyond the actual L4 payload.  Rather than relying on
iov_tail_size() to determine how many bytes to checksum, pass the
length explicitly so that only the relevant payload bytes are included
in the checksum computation.

Signed-off-by: Laurent Vivier &lt;lvivier@redhat.com&gt;
Reviewed-by: David Gibson &lt;david@gibson.dropbear.id.au&gt;
Reviewed-by: Jon Maloy &lt;jmaloy@redhat.com&gt;
Signed-off-by: Stefano Brivio &lt;sbrivio@redhat.com&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
The iov_tail passed to csum_iov_tail() may contain padding or trailing
data beyond the actual L4 payload.  Rather than relying on
iov_tail_size() to determine how many bytes to checksum, pass the
length explicitly so that only the relevant payload bytes are included
in the checksum computation.

Signed-off-by: Laurent Vivier &lt;lvivier@redhat.com&gt;
Reviewed-by: David Gibson &lt;david@gibson.dropbear.id.au&gt;
Reviewed-by: Jon Maloy &lt;jmaloy@redhat.com&gt;
Signed-off-by: Stefano Brivio &lt;sbrivio@redhat.com&gt;
</pre>
</div>
</content>
</entry>
<entry>
<title>udp_vu: Pass iov explicitly to helpers instead of using file-scoped array</title>
<updated>2026-05-19T23:21:29+00:00</updated>
<author>
<name>Laurent Vivier</name>
<email>lvivier@redhat.com</email>
</author>
<published>2026-05-13T11:52:13+00:00</published>
<link rel='alternate' type='text/html' href='https://passt.top/passt/commit/?id=7cd5afbed58d05cae84e7c00c5c160e8f24f714d'/>
<id>7cd5afbed58d05cae84e7c00c5c160e8f24f714d</id>
<content type='text'>
udp_vu_sock_recv(), udp_vu_prepare(), and udp_vu_csum() all operated on
the file-scoped iov_vu[] array directly.  Pass iov and count as explicit
parameters instead, and move iov_vu[] and elem[] to function-local
statics in udp_vu_sock_to_tap(), the only function that needs them.

Signed-off-by: Laurent Vivier &lt;lvivier@redhat.com&gt;
Reviewed-by: David Gibson &lt;david@gibson.dropbear.id.au&gt;
Reviewed-by: Jon Maloy &lt;jmaloy@redhat.com&gt;
Signed-off-by: Stefano Brivio &lt;sbrivio@redhat.com&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
udp_vu_sock_recv(), udp_vu_prepare(), and udp_vu_csum() all operated on
the file-scoped iov_vu[] array directly.  Pass iov and count as explicit
parameters instead, and move iov_vu[] and elem[] to function-local
statics in udp_vu_sock_to_tap(), the only function that needs them.

Signed-off-by: Laurent Vivier &lt;lvivier@redhat.com&gt;
Reviewed-by: David Gibson &lt;david@gibson.dropbear.id.au&gt;
Reviewed-by: Jon Maloy &lt;jmaloy@redhat.com&gt;
Signed-off-by: Stefano Brivio &lt;sbrivio@redhat.com&gt;
</pre>
</div>
</content>
</entry>
<entry>
<title>udp_vu: Move virtqueue management from udp_vu_sock_recv() to its caller</title>
<updated>2026-05-19T23:21:24+00:00</updated>
<author>
<name>Laurent Vivier</name>
<email>lvivier@redhat.com</email>
</author>
<published>2026-05-13T11:52:12+00:00</published>
<link rel='alternate' type='text/html' href='https://passt.top/passt/commit/?id=ee0ba3f5db89904afc5cbedd9f8dd934eca3d738'/>
<id>ee0ba3f5db89904afc5cbedd9f8dd934eca3d738</id>
<content type='text'>
udp_vu_sock_recv() currently mixes two concerns: receiving data from the
socket and managing virtqueue buffers (collecting, rewinding, releasing).
This makes the function harder to reason about and couples socket I/O
with virtqueue state.

Move all virtqueue operations, vu_collect(), vu_init_elem(),
vu_queue_rewind(), vu_set_vnethdr(), and the queue-readiness check, into
udp_vu_sock_to_tap(), which is the only caller.  This turns
udp_vu_sock_recv() into a pure socket receive function that simply reads
into the provided iov array and adjusts its length.

Signed-off-by: Laurent Vivier &lt;lvivier@redhat.com&gt;
Reviewed-by: David Gibson &lt;david@gibson.dropbear.id.au&gt;
Reviewed-by: Jon Maloy &lt;jmaloy@redhat.com&gt;
Signed-off-by: Stefano Brivio &lt;sbrivio@redhat.com&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
udp_vu_sock_recv() currently mixes two concerns: receiving data from the
socket and managing virtqueue buffers (collecting, rewinding, releasing).
This makes the function harder to reason about and couples socket I/O
with virtqueue state.

Move all virtqueue operations, vu_collect(), vu_init_elem(),
vu_queue_rewind(), vu_set_vnethdr(), and the queue-readiness check, into
udp_vu_sock_to_tap(), which is the only caller.  This turns
udp_vu_sock_recv() into a pure socket receive function that simply reads
into the provided iov array and adjusts its length.

Signed-off-by: Laurent Vivier &lt;lvivier@redhat.com&gt;
Reviewed-by: David Gibson &lt;david@gibson.dropbear.id.au&gt;
Reviewed-by: Jon Maloy &lt;jmaloy@redhat.com&gt;
Signed-off-by: Stefano Brivio &lt;sbrivio@redhat.com&gt;
</pre>
</div>
</content>
</entry>
<entry>
<title>vu_common: Move vnethdr setup into vu_flush()</title>
<updated>2026-05-19T23:21:19+00:00</updated>
<author>
<name>Laurent Vivier</name>
<email>lvivier@redhat.com</email>
</author>
<published>2026-05-13T11:52:11+00:00</published>
<link rel='alternate' type='text/html' href='https://passt.top/passt/commit/?id=d3a486858be2aa3e318047929e963cb4c02aa997'/>
<id>d3a486858be2aa3e318047929e963cb4c02aa997</id>
<content type='text'>
Every caller of vu_flush() was calling vu_set_vnethdr() beforehand with
the same pattern.  Move it into vu_flush().

Remove vu_queue_notify() from vu_flush() and let callers invoke it
explicitly.  This allows paths that perform multiple flushes, such as
tcp_vu_send_flag() and tcp_vu_data_from_sock(), to issue a single guest
notification at the end.

Signed-off-by: Laurent Vivier &lt;lvivier@redhat.com&gt;
Reviewed-by: David Gibson &lt;david@gibson.dropbear.id.au&gt;
Reviewed-by: Jon Maloy &lt;jmaloy@redhat.com&gt;
Signed-off-by: Stefano Brivio &lt;sbrivio@redhat.com&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
Every caller of vu_flush() was calling vu_set_vnethdr() beforehand with
the same pattern.  Move it into vu_flush().

Remove vu_queue_notify() from vu_flush() and let callers invoke it
explicitly.  This allows paths that perform multiple flushes, such as
tcp_vu_send_flag() and tcp_vu_data_from_sock(), to issue a single guest
notification at the end.

Signed-off-by: Laurent Vivier &lt;lvivier@redhat.com&gt;
Reviewed-by: David Gibson &lt;david@gibson.dropbear.id.au&gt;
Reviewed-by: Jon Maloy &lt;jmaloy@redhat.com&gt;
Signed-off-by: Stefano Brivio &lt;sbrivio@redhat.com&gt;
</pre>
</div>
</content>
</entry>
</feed>
