diff --git a/0006-rtl8139-flush-queued-packets-when-RxBufPtr-is-writte.patch b/0006-rtl8139-flush-queued-packets-when-RxBufPtr-is-writte.patch new file mode 100644 index 0000000..9b9fb4a --- /dev/null +++ b/0006-rtl8139-flush-queued-packets-when-RxBufPtr-is-writte.patch @@ -0,0 +1,47 @@ +From 4044e0670486ad089367952843f17351c4f6faa0 Mon Sep 17 00:00:00 2001 +From: Stefan Hajnoczi +Date: Wed, 22 May 2013 14:50:18 +0200 +Subject: [PATCH] rtl8139: flush queued packets when RxBufPtr is written + +Net queues support efficient "receive disable". For example, tap's file +descriptor will not be polled while its peer has receive disabled. This +saves CPU cycles for needlessly copying and then dropping packets which +the peer cannot receive. + +rtl8139 is missing the qemu_flush_queued_packets() call that wakes the +queue up when receive becomes possible again. + +As a result, the Windows 7 guest driver reaches a state where the +rtl8139 cannot receive packets. The driver has actually refilled the +receive buffer but we never resume reception. + +The bug can be reproduced by running a large FTP 'get' inside a Windows +7 guest: + + $ qemu -netdev tap,id=tap0,... + -device rtl8139,netdev=tap0 + +The Linux guest driver does not trigger the bug, probably due to a +different buffer management strategy. + +Reported-by: Oliver Francke +Signed-off-by: Stefan Hajnoczi +(cherry picked from commit 00b7ade807b5ce6779ddd86ce29c5521ec5c529a) +--- + hw/net/rtl8139.c | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/hw/net/rtl8139.c b/hw/net/rtl8139.c +index 9369507..7993f9f 100644 +--- a/hw/net/rtl8139.c ++++ b/hw/net/rtl8139.c +@@ -2575,6 +2575,9 @@ static void rtl8139_RxBufPtr_write(RTL8139State *s, uint32_t val) + /* this value is off by 16 */ + s->RxBufPtr = MOD2(val + 0x10, s->RxBufferSize); + ++ /* more buffer space may be available so try to receive */ ++ qemu_flush_queued_packets(qemu_get_queue(s->nic)); ++ + DPRINTF(" CAPR write: rx buffer length %d head 0x%04x read 0x%04x\n", + s->RxBufferSize, s->RxBufAddr, s->RxBufPtr); + }