[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PATCH 009/156] tap: avoid deadlocking rx
From: |
Michael Roth |
Subject: |
[Qemu-devel] [PATCH 009/156] tap: avoid deadlocking rx |
Date: |
Tue, 8 Jul 2014 12:16:40 -0500 |
From: Stefan Hajnoczi <address@hidden>
The net subsystem has a control flow mechanism so peer NetClientStates
can tell each other to stop sending packets. This is used to stop
monitoring the tap file descriptor for incoming packets if the guest rx
ring has no spare buffers.
There is a corner case when tap_can_send() is true at the beginning of
an event loop iteration but becomes false before the tap_send() fd
handler is invoked.
tap_send() will read the packet from the tap file descriptor and attempt
to send it. The net queue will hold on to the packet and return 0,
indicating that further I/O is not possible. tap then stops monitoring
the file descriptor for reads.
This is unlike the normal case where tap_can_send() is the same before
and during the event loop iteration. The event loop would simply not
monitor the file descriptor if tap_can_send() returns true. Upon next
iteration it would check tap_can_send() again and begin monitoring if we
can send.
The deadlock happens because tap_send() explicitly disabled read_poll.
This is done with the expectation that the peer will call
qemu_net_queue_flush(). But hw/net/virtio-net.c does not monitor
vm_running transitions and issue the flush. Hence we're left with a
broken tap device.
Cc: address@hidden
Reported-by: Neil Skrypuch <address@hidden>
Tested-by: Neil Skrypuch <address@hidden>
Signed-off-by: Stefan Hajnoczi <address@hidden>
(cherry picked from commit 68e5ec64009812dbaa03ed9cfded9344986f5304)
Signed-off-by: Michael Roth <address@hidden>
---
net/tap.c | 7 +++++--
1 file changed, 5 insertions(+), 2 deletions(-)
diff --git a/net/tap.c b/net/tap.c
index 39c1cda..6b87a73 100644
--- a/net/tap.c
+++ b/net/tap.c
@@ -190,7 +190,7 @@ static void tap_send(void *opaque)
TAPState *s = opaque;
int size;
- do {
+ while (qemu_can_send_packet(&s->nc)) {
uint8_t *buf = s->buf;
size = tap_read_packet(s->fd, s->buf, sizeof(s->buf));
@@ -206,8 +206,11 @@ static void tap_send(void *opaque)
size = qemu_send_packet_async(&s->nc, buf, size, tap_send_completed);
if (size == 0) {
tap_read_poll(s, false);
+ break;
+ } else if (size < 0) {
+ break;
}
- } while (size > 0 && qemu_can_send_packet(&s->nc));
+ }
}
bool tap_has_ufo(NetClientState *nc)
--
1.9.1
- [Qemu-devel] [PATCH 043/156] Fix vmstate_info_int32_le comparison/assign, (continued)
- [Qemu-devel] [PATCH 043/156] Fix vmstate_info_int32_le comparison/assign, Michael Roth, 2014/07/08
- [Qemu-devel] [PATCH 014/156] virtio-net: Do not filter VLANs without F_CTRL_VLAN, Michael Roth, 2014/07/08
- [Qemu-devel] [PATCH 101/156] qcow2: Fix new L1 table size check (CVE-2014-0143), Michael Roth, 2014/07/08
- [Qemu-devel] [PATCH 103/156] dmg: prevent out-of-bounds array access on terminator, Michael Roth, 2014/07/08
- [Qemu-devel] [PATCH 082/156] vpc/vhd: add bounds check for max_table_entries and block_size (CVE-2014-0144), Michael Roth, 2014/07/08
- [Qemu-devel] [PATCH 152/156] qapi: zero-initialize all QMP command parameters, Michael Roth, 2014/07/08
- [Qemu-devel] [PATCH 023/156] block: Use BDRV_O_NO_BACKING where appropriate, Michael Roth, 2014/07/08
- [Qemu-devel] [PATCH 140/156] scsi-disk: fix bug in scsi_block_new_request() introduced by commit 137745c, Michael Roth, 2014/07/08
- [Qemu-devel] [PATCH 067/156] migration: remove duplicate code, Michael Roth, 2014/07/08
- [Qemu-devel] [PATCH 092/156] qcow2: Validate active L1 table offset and size (CVE-2014-0144), Michael Roth, 2014/07/08
- [Qemu-devel] [PATCH 009/156] tap: avoid deadlocking rx,
Michael Roth <=
- [Qemu-devel] [PATCH 008/156] qom: Avoid leaking str and bool properties on failure, Michael Roth, 2014/07/08
- [Qemu-devel] [PATCH 011/156] configure: Don't use __int128_t for clang versions before 3.2, Michael Roth, 2014/07/08
- [Qemu-devel] [PATCH 114/156] parallels: Fix catalog size integer overflow (CVE-2014-0143), Michael Roth, 2014/07/08
- [Qemu-devel] [PATCH 015/156] hw/net/stellaris_enet: Restructure tx_fifo code to avoid buffer overrun, Michael Roth, 2014/07/08
- [Qemu-devel] [PATCH 119/156] qcow1: Validate image size (CVE-2014-0223), Michael Roth, 2014/07/08
- [Qemu-devel] [PATCH 118/156] qcow1: Validate L2 table size (CVE-2014-0222), Michael Roth, 2014/07/08
- [Qemu-devel] [PATCH 090/156] qcow2: Validate refcount table offset, Michael Roth, 2014/07/09
- [Qemu-devel] [PATCH 138/156] qga: Fix handle fd leak in acquire_privilege(), Michael Roth, 2014/07/09
- [Qemu-devel] [PATCH 121/156] virtio-scsi: Plug memory leak on virtio_scsi_push_event() error path, Michael Roth, 2014/07/09
- [Qemu-devel] [PATCH 044/156] vmstate: fix buffer overflow in target-arm/machine.c, Michael Roth, 2014/07/09