1 |
commit: ff7aef9e665a0417a66e5c92cc5bf1ba7f4c22d3 |
2 |
Author: Bo Yang <boyang <AT> suse <DOT> com> |
3 |
AuthorDate: Wed Aug 29 11:26:11 2012 +0000 |
4 |
Commit: Doug Goldstein <cardoe <AT> gentoo <DOT> org> |
5 |
CommitDate: Wed Oct 24 07:05:04 2012 +0000 |
6 |
URL: http://git.overlays.gentoo.org/gitweb/?p=proj/qemu-kvm.git;a=commit;h=ff7aef9e |
7 |
|
8 |
eepro100: Fix network hang when rx buffers run out |
9 |
|
10 |
This is reported by QA. When installing os with pxe, after the initial |
11 |
kernel and initrd are loaded, the procedure tries to copy files from install |
12 |
server to local harddisk, the network becomes stall because of running out of |
13 |
receive descriptor. |
14 |
|
15 |
[Whitespace fixes and removed qemu_notify_event() because Paolo's |
16 |
earlier net patches have moved it into qemu_flush_queued_packets(). |
17 |
|
18 |
Additional info: |
19 |
|
20 |
I can reproduce the network hang with a tap device doing a iPXE HTTP |
21 |
boot as follows: |
22 |
|
23 |
$ qemu -enable-kvm -m 1024 \ |
24 |
-netdev tap,id=netdev0,script=no,downscript=no \ |
25 |
-device i82559er,netdev=netdev0,romfile=80861209.rom \ |
26 |
-drive if=virtio,cache=none,file=test.img |
27 |
iPXE> ifopen net0 |
28 |
iPXE> config # set static network configuration |
29 |
iPXE> kernel http://mirror.bytemark.co.uk/fedora/linux/releases/17/Fedora/x86_64/os/images/pxeboot/vmlinuz |
30 |
|
31 |
I needed a vanilla iPXE ROM to get to the iPXE prompt. I think the boot |
32 |
prompt has been disabled in the ROMs that ship with QEMU to reduce boot |
33 |
time. |
34 |
|
35 |
During the vmlinuz HTTP download there is a network hang. hw/eepro100.c |
36 |
has reached the end of the rx descriptor list. When the iPXE driver |
37 |
replenishes the rx descriptor list we don't kick the QEMU net subsystem |
38 |
and event loop, thereby leaving the tap netdev without its file |
39 |
descriptor in select(2). |
40 |
|
41 |
Stefan Hajnoczi <stefanha <AT> gmail.com>] |
42 |
|
43 |
Signed-off-by: Bo Yang <boyang <AT> suse.com> |
44 |
Signed-off-by: Stefan Hajnoczi <stefanha <AT> gmail.com> |
45 |
(cherry picked from commit 1069985fb132cd4324fc02d371f1e61492a1823f) |
46 |
|
47 |
--- |
48 |
hw/eepro100.c | 4 +++- |
49 |
1 files changed, 3 insertions(+), 1 deletions(-) |
50 |
|
51 |
diff --git a/hw/eepro100.c b/hw/eepro100.c |
52 |
index 6279ae3..5b62196 100644 |
53 |
--- a/hw/eepro100.c |
54 |
+++ b/hw/eepro100.c |
55 |
@@ -1036,6 +1036,7 @@ static void eepro100_ru_command(EEPRO100State * s, uint8_t val) |
56 |
} |
57 |
set_ru_state(s, ru_ready); |
58 |
s->ru_offset = e100_read_reg4(s, SCBPointer); |
59 |
+ qemu_flush_queued_packets(&s->nic->nc); |
60 |
TRACE(OTHER, logout("val=0x%02x (rx start)\n", val)); |
61 |
break; |
62 |
case RX_RESUME: |
63 |
@@ -1763,7 +1764,8 @@ static ssize_t nic_receive(VLANClientState *nc, const uint8_t * buf, size_t size |
64 |
if (rfd_command & COMMAND_EL) { |
65 |
/* EL bit is set, so this was the last frame. */ |
66 |
logout("receive: Running out of frames\n"); |
67 |
- set_ru_state(s, ru_suspended); |
68 |
+ set_ru_state(s, ru_no_resources); |
69 |
+ eepro100_rnr_interrupt(s); |
70 |
} |
71 |
if (rfd_command & COMMAND_S) { |
72 |
/* S bit is set. */ |