summaryrefslogtreecommitdiff
path: root/net.h
diff options
context:
space:
mode:
authorMark McLoughlin <markmc@redhat.com>2009-04-29 12:15:26 +0100
committerMark McLoughlin <markmc@redhat.com>2009-06-09 11:38:50 +0100
commitf3b6c7fcf8fca857b3c3ba0aa5b3a06d7ce0ac37 (patch)
tree87a74f9c688e73c0552962b333917c58d3c54a35 /net.h
parente94667b91ccfdb70164ae320b1c4ded6b5b8a3ec (diff)
downloadqemu-f3b6c7fcf8fca857b3c3ba0aa5b3a06d7ce0ac37.tar.gz
net: add qemu_send_packet_async()
Add a qemu_send_packet() variant which will queue up the packet if it cannot be sent when all client queues are full. It later invokes the supplied callback when the packet has been sent. If qemu_send_packet_async() returns zero, the caller is expected to not send any more packets until the queued packet has been sent. Packets are queued iff a receive() handler returns zero (indicating queue full) and the caller has provided a sent notification callback (indicating it will stop and start its own queue). We need the packet sending API to support queueing because: - a sending client should process all available packets in one go (e.g. virtio-net emptying its tx ring) - a receiving client may not be able to handle the packet (e.g. -EAGAIN from write() to tapfd) - the sending client could detect this condition in advance (e.g. by select() for writable on tapfd) - that's too much overhead (e.g. a select() call per packet) - therefore the sending client must handle the condition by dropping the packet or queueing it - dropping packets is poor form; we should queue. However, we don't want queueing to be completely transparent. We want the sending client to stop sending packets as soon as a packet is queued. This allows the sending client to be throttled by the receiver. Signed-off-by: Mark McLoughlin <markmc@redhat.com>
Diffstat (limited to 'net.h')
-rw-r--r--net.h8
1 files changed, 8 insertions, 0 deletions
diff --git a/net.h b/net.h
index f1cedf4d17..89e7706be4 100644
--- a/net.h
+++ b/net.h
@@ -32,10 +32,13 @@ struct VLANClientState {
typedef struct VLANPacket VLANPacket;
+typedef void (NetPacketSent) (VLANClientState *);
+
struct VLANPacket {
struct VLANPacket *next;
VLANClientState *sender;
int size;
+ NetPacketSent *sent_cb;
uint8_t data[0];
};
@@ -62,7 +65,12 @@ VLANClientState *qemu_find_vlan_client(VLANState *vlan, void *opaque);
int qemu_can_send_packet(VLANClientState *vc);
ssize_t qemu_sendv_packet(VLANClientState *vc, const struct iovec *iov,
int iovcnt);
+ssize_t qemu_sendv_packet_async(VLANClientState *vc, const struct iovec *iov,
+ int iovcnt, NetPacketSent *sent_cb);
void qemu_send_packet(VLANClientState *vc, const uint8_t *buf, int size);
+ssize_t qemu_send_packet_async(VLANClientState *vc, const uint8_t *buf,
+ int size, NetPacketSent *sent_cb);
+void qemu_flush_queued_packets(VLANClientState *vc);
void qemu_format_nic_info_str(VLANClientState *vc, uint8_t macaddr[6]);
void qemu_check_nic_model(NICInfo *nd, const char *model);
void qemu_check_nic_model_list(NICInfo *nd, const char * const *models,