From: Andrey Smirnov <andrew.smirnov@gmail.com>
To: qemu-arm@nongnu.org
Cc: "Andrey Smirnov" <andrew.smirnov@gmail.com>,
"Peter Maydell" <peter.maydell@linaro.org>,
"Jason Wang" <jasowang@redhat.com>,
"Philippe Mathieu-Daudé" <f4bug@amsat.org>,
qemu-devel@nongnu.org, yurovsky@gmail.com
Subject: [Qemu-devel] [PATCH 03/13] imx_fec: Change queue flushing heuristics
Date: Mon, 11 Dec 2017 13:29:57 -0800 [thread overview]
Message-ID: <20171211213007.7353-4-andrew.smirnov@gmail.com> (raw)
In-Reply-To: <20171211213007.7353-1-andrew.smirnov@gmail.com>
In current implementation, packet queue flushing logic seem to suffer
from a deadlock like scenario if a packet is received by the interface
before before Rx ring is initialized by Guest's driver. Consider the
following sequence of events:
1. A QEMU instance is started against a TAP device on Linux
host, running Linux guest, e. g., something to the effect
of:
qemu-system-arm \
-net nic,model=imx.fec,netdev=lan0 \
netdev tap,id=lan0,ifname=tap0,script=no,downscript=no \
... rest of the arguments ...
2. Once QEMU starts, but before guest reaches the point where
FEC deriver is done initializing the HW, Guest, via TAP
interface, receives a number of multicast MDNS packets from
Host (not necessarily true for every OS, but it happens at
least on Fedora 25)
3. Recieving a packet in such a state results in
imx_eth_can_receive() returning '0', which in turn causes
tap_send() to disable corresponding event (tap.c:203)
4. Once Guest's driver reaches the point where it is ready to
recieve packets it prepares Rx ring descriptors and writes
ENET_RDAR_RDAR to ENET_RDAR register to indicate to HW that
more descriptors are ready. And at this points emulation
layer does this:
s->regs[index] = ENET_RDAR_RDAR;
imx_eth_enable_rx(s);
which, combined with:
if (!s->regs[ENET_RDAR]) {
qemu_flush_queued_packets(qemu_get_queue(s->nic));
}
results in Rx queue never being flushed and corresponding
I/O event beign disabled.
To prevent the problem, change the code to always flush packet queue
when ENET_RDAR transitions 0 -> ENET_RDAR_RDAR.
Cc: Peter Maydell <peter.maydell@linaro.org>
Cc: Jason Wang <jasowang@redhat.com>
Cc: Philippe Mathieu-Daudé <f4bug@amsat.org>
Cc: qemu-devel@nongnu.org
Cc: qemu-arm@nongnu.org
Cc: yurovsky@gmail.com
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Andrey Smirnov <andrew.smirnov@gmail.com>
---
hw/net/imx_fec.c | 12 ++++++------
1 file changed, 6 insertions(+), 6 deletions(-)
diff --git a/hw/net/imx_fec.c b/hw/net/imx_fec.c
index 8b2e4b8ffe..eb034ffd0c 100644
--- a/hw/net/imx_fec.c
+++ b/hw/net/imx_fec.c
@@ -533,7 +533,7 @@ static void imx_eth_do_tx(IMXFECState *s)
}
}
-static void imx_eth_enable_rx(IMXFECState *s)
+static void imx_eth_enable_rx(IMXFECState *s, bool flush)
{
IMXFECBufDesc bd;
bool rx_ring_full;
@@ -544,7 +544,7 @@ static void imx_eth_enable_rx(IMXFECState *s)
if (rx_ring_full) {
FEC_PRINTF("RX buffer full\n");
- } else if (!s->regs[ENET_RDAR]) {
+ } else if (flush) {
qemu_flush_queued_packets(qemu_get_queue(s->nic));
}
@@ -807,7 +807,7 @@ static void imx_eth_write(void *opaque, hwaddr offset, uint64_t value,
if (s->regs[ENET_ECR] & ENET_ECR_ETHEREN) {
if (!s->regs[index]) {
s->regs[index] = ENET_RDAR_RDAR;
- imx_eth_enable_rx(s);
+ imx_eth_enable_rx(s, true);
}
} else {
s->regs[index] = 0;
@@ -930,7 +930,7 @@ static int imx_eth_can_receive(NetClientState *nc)
FEC_PRINTF("\n");
- return s->regs[ENET_RDAR] ? 1 : 0;
+ return !!s->regs[ENET_RDAR];
}
static ssize_t imx_fec_receive(NetClientState *nc, const uint8_t *buf,
@@ -1020,7 +1020,7 @@ static ssize_t imx_fec_receive(NetClientState *nc, const uint8_t *buf,
}
}
s->rx_descriptor = addr;
- imx_eth_enable_rx(s);
+ imx_eth_enable_rx(s, false);
imx_eth_update(s);
return len;
}
@@ -1116,7 +1116,7 @@ static ssize_t imx_enet_receive(NetClientState *nc, const uint8_t *buf,
}
}
s->rx_descriptor = addr;
- imx_eth_enable_rx(s);
+ imx_eth_enable_rx(s, false);
imx_eth_update(s);
return len;
}
--
2.14.3
next prev parent reply other threads:[~2017-12-11 21:30 UTC|newest]
Thread overview: 24+ messages / expand[flat|nested] mbox.gz Atom feed top
2017-12-11 21:29 [Qemu-devel] [PATCH 00/13] i.MX FEC and SD changes Andrey Smirnov
2017-12-11 21:29 ` [Qemu-devel] [PATCH 01/13] imx_fec: Do not link to netdev Andrey Smirnov
2017-12-11 21:29 ` [Qemu-devel] [PATCH 02/13] imx_fec: Refactor imx_eth_enable_rx() Andrey Smirnov
2017-12-11 21:29 ` Andrey Smirnov [this message]
2017-12-11 21:29 ` [Qemu-devel] [PATCH 05/13] imx_fec: Use ENET_FTRL to determine truncation length Andrey Smirnov
2017-12-11 21:30 ` [Qemu-devel] [PATCH 06/13] imx_fec: Use MIN instead of explicit ternary operator Andrey Smirnov
2017-12-11 21:30 ` [Qemu-devel] [PATCH 07/13] imx_fec: Emulate SHIFT16 in ENETx_RACC Andrey Smirnov
2017-12-11 21:30 ` [Qemu-devel] [PATCH 08/13] imx_fec: Add support for multiple Tx DMA rings Andrey Smirnov
2017-12-11 21:30 ` [Qemu-devel] [PATCH 09/13] imx_fec: Use correct length for packet size Andrey Smirnov
2017-12-11 21:30 ` [Qemu-devel] [PATCH 10/13] imx_fec: Fix a typo in imx_enet_receive() Andrey Smirnov
2017-12-12 17:32 ` Peter Maydell
2017-12-11 21:30 ` [Qemu-devel] [PATCH 11/13] imx_fec: Reserve full FSL_IMX25_FEC_SIZE page for the register file Andrey Smirnov
2017-12-12 17:32 ` Peter Maydell
2017-12-11 21:30 ` [Qemu-devel] [PATCH 12/13] sdhci: Add i.MX specific subtype of SDHCI Andrey Smirnov
2017-12-12 17:52 ` Peter Maydell
2017-12-14 14:03 ` Andrey Smirnov
2017-12-14 15:32 ` Philippe Mathieu-Daudé
2017-12-14 16:05 ` Andrey Smirnov
2017-12-14 16:17 ` Philippe Mathieu-Daudé
2017-12-11 21:30 ` [Qemu-devel] [PATCH 13/13] sdhci: Implement write method of ACMD12ERRSTS register Andrey Smirnov
2017-12-12 17:40 ` [Qemu-devel] [PATCH 00/13] i.MX FEC and SD changes Peter Maydell
2017-12-14 2:09 ` Philippe Mathieu-Daudé
2017-12-14 14:11 ` Andrey Smirnov
2017-12-14 14:09 ` Andrey Smirnov
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20171211213007.7353-4-andrew.smirnov@gmail.com \
--to=andrew.smirnov@gmail.com \
--cc=f4bug@amsat.org \
--cc=jasowang@redhat.com \
--cc=peter.maydell@linaro.org \
--cc=qemu-arm@nongnu.org \
--cc=qemu-devel@nongnu.org \
--cc=yurovsky@gmail.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).