* [Qemu-devel] [PULL 1/5] tap: fix vcpu long time io blocking on tap
2014-12-19 13:18 [Qemu-devel] [PULL 0/5] Net patches Stefan Hajnoczi
@ 2014-12-19 13:18 ` Stefan Hajnoczi
2014-12-19 13:18 ` [Qemu-devel] [PULL 2/5] net: don't use set/get_pointer() in set/get_netdev() Stefan Hajnoczi
` (4 subsequent siblings)
5 siblings, 0 replies; 8+ messages in thread
From: Stefan Hajnoczi @ 2014-12-19 13:18 UTC (permalink / raw)
To: qemu-devel; +Cc: Peter Maydell, Stefan Hajnoczi, Wangkai (Kevin, C)
From: "Wangkai (Kevin,C)" <wangkai86@huawei.com>
[Adjusted doc comment for grammar.
--Stefan]
Signed-off-by: Wangkai <wangkai86@huawei.com>
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
---
net/tap.c | 12 ++++++++++++
1 file changed, 12 insertions(+)
diff --git a/net/tap.c b/net/tap.c
index bde6b58..1fe0edf 100644
--- a/net/tap.c
+++ b/net/tap.c
@@ -189,6 +189,7 @@ static void tap_send(void *opaque)
{
TAPState *s = opaque;
int size;
+ int packets = 0;
while (qemu_can_send_packet(&s->nc)) {
uint8_t *buf = s->buf;
@@ -210,6 +211,17 @@ static void tap_send(void *opaque)
} else if (size < 0) {
break;
}
+
+ /*
+ * When the host keeps receiving more packets while tap_send() is
+ * running we can hog the QEMU global mutex. Limit the number of
+ * packets that are processed per tap_send() callback to prevent
+ * stalling the guest.
+ */
+ packets++;
+ if (packets >= 50) {
+ break;
+ }
}
}
--
2.1.0
^ permalink raw reply related [flat|nested] 8+ messages in thread
* [Qemu-devel] [PULL 2/5] net: don't use set/get_pointer() in set/get_netdev()
2014-12-19 13:18 [Qemu-devel] [PULL 0/5] Net patches Stefan Hajnoczi
2014-12-19 13:18 ` [Qemu-devel] [PULL 1/5] tap: fix vcpu long time io blocking on tap Stefan Hajnoczi
@ 2014-12-19 13:18 ` Stefan Hajnoczi
2014-12-19 13:18 ` [Qemu-devel] [PULL 3/5] net: Fuse g_malloc(); memset() into g_new0() Stefan Hajnoczi
` (3 subsequent siblings)
5 siblings, 0 replies; 8+ messages in thread
From: Stefan Hajnoczi @ 2014-12-19 13:18 UTC (permalink / raw)
To: qemu-devel; +Cc: Peter Maydell, Jason Wang, Markus Armbruster, Stefan Hajnoczi
From: Jason Wang <jasowang@redhat.com>
Commit 1ceef9f27359cbe92ef124bf74de6f792e71f6fb (net: multiqueue
support) tries to use set_pointer() and get_pointer() to set and get
NICPeers which is not a pointer defined in DEFINE_PROP_NETDEV. This
trick works but result a unclean and fragile implementation (e.g
print_netdev and parse_netdev).
This patch solves this issue by not using set/get_pinter() and set and
get netdev directly in set_netdev() and get_netdev(). After this the
parse_netdev() and print_netdev() were no longer used and dropped from
the source.
[Renamed 'err' label to 'out' as suggested by Markus Armbruster.
--Stefan]
Cc: Markus Armbruster <armbru@redhat.com>
Cc: Stefan Hajnoczi <stefanha@redhat.com>
Cc: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Jason Wang <jasowang@redhat.com>
Reviewed-by: Markus Armbruster <armbru@redhat.com>
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
---
hw/core/qdev-properties-system.c | 82 +++++++++++++++++++++-------------------
1 file changed, 44 insertions(+), 38 deletions(-)
diff --git a/hw/core/qdev-properties-system.c b/hw/core/qdev-properties-system.c
index 65901ef..a2e44bd 100644
--- a/hw/core/qdev-properties-system.c
+++ b/hw/core/qdev-properties-system.c
@@ -177,42 +177,69 @@ PropertyInfo qdev_prop_chr = {
};
/* --- netdev device --- */
+static void get_netdev(Object *obj, Visitor *v, void *opaque,
+ const char *name, Error **errp)
+{
+ DeviceState *dev = DEVICE(obj);
+ Property *prop = opaque;
+ NICPeers *peers_ptr = qdev_get_prop_ptr(dev, prop);
+ char *p = g_strdup(peers_ptr->ncs[0] ? peers_ptr->ncs[0]->name : "");
-static int parse_netdev(DeviceState *dev, const char *str, void **ptr)
+ visit_type_str(v, &p, name, errp);
+ g_free(p);
+}
+
+static void set_netdev(Object *obj, Visitor *v, void *opaque,
+ const char *name, Error **errp)
{
- NICPeers *peers_ptr = (NICPeers *)ptr;
+ DeviceState *dev = DEVICE(obj);
+ Property *prop = opaque;
+ NICPeers *peers_ptr = qdev_get_prop_ptr(dev, prop);
NetClientState **ncs = peers_ptr->ncs;
NetClientState *peers[MAX_QUEUE_NUM];
- int queues, i = 0;
- int ret;
+ Error *local_err = NULL;
+ int queues, err = 0, i = 0;
+ char *str;
+
+ if (dev->realized) {
+ qdev_prop_set_after_realize(dev, name, errp);
+ return;
+ }
+
+ visit_type_str(v, &str, name, &local_err);
+ if (local_err) {
+ error_propagate(errp, local_err);
+ return;
+ }
queues = qemu_find_net_clients_except(str, peers,
NET_CLIENT_OPTIONS_KIND_NIC,
MAX_QUEUE_NUM);
if (queues == 0) {
- ret = -ENOENT;
- goto err;
+ err = -ENOENT;
+ goto out;
}
if (queues > MAX_QUEUE_NUM) {
- ret = -E2BIG;
- goto err;
+ error_setg(errp, "queues of backend '%s'(%d) exceeds QEMU limitation(%d)",
+ str, queues, MAX_QUEUE_NUM);
+ goto out;
}
for (i = 0; i < queues; i++) {
if (peers[i] == NULL) {
- ret = -ENOENT;
- goto err;
+ err = -ENOENT;
+ goto out;
}
if (peers[i]->peer) {
- ret = -EEXIST;
- goto err;
+ err = -EEXIST;
+ goto out;
}
if (ncs[i]) {
- ret = -EINVAL;
- goto err;
+ err = -EINVAL;
+ goto out;
}
ncs[i] = peers[i];
@@ -221,30 +248,9 @@ static int parse_netdev(DeviceState *dev, const char *str, void **ptr)
peers_ptr->queues = queues;
- return 0;
-
-err:
- return ret;
-}
-
-static char *print_netdev(void *ptr)
-{
- NetClientState *netdev = ptr;
- const char *val = netdev->name ? netdev->name : "";
-
- return g_strdup(val);
-}
-
-static void get_netdev(Object *obj, Visitor *v, void *opaque,
- const char *name, Error **errp)
-{
- get_pointer(obj, v, opaque, print_netdev, name, errp);
-}
-
-static void set_netdev(Object *obj, Visitor *v, void *opaque,
- const char *name, Error **errp)
-{
- set_pointer(obj, v, opaque, parse_netdev, name, errp);
+out:
+ error_set_from_qdev_prop_error(errp, err, dev, prop, str);
+ g_free(str);
}
PropertyInfo qdev_prop_netdev = {
--
2.1.0
^ permalink raw reply related [flat|nested] 8+ messages in thread
* [Qemu-devel] [PULL 3/5] net: Fuse g_malloc(); memset() into g_new0()
2014-12-19 13:18 [Qemu-devel] [PULL 0/5] Net patches Stefan Hajnoczi
2014-12-19 13:18 ` [Qemu-devel] [PULL 1/5] tap: fix vcpu long time io blocking on tap Stefan Hajnoczi
2014-12-19 13:18 ` [Qemu-devel] [PULL 2/5] net: don't use set/get_pointer() in set/get_netdev() Stefan Hajnoczi
@ 2014-12-19 13:18 ` Stefan Hajnoczi
2014-12-19 13:18 ` [Qemu-devel] [PULL 4/5] net: Use g_new() & friends where that makes obvious sense Stefan Hajnoczi
` (2 subsequent siblings)
5 siblings, 0 replies; 8+ messages in thread
From: Stefan Hajnoczi @ 2014-12-19 13:18 UTC (permalink / raw)
To: qemu-devel; +Cc: Peter Maydell, Markus Armbruster, Stefan Hajnoczi
From: Markus Armbruster <armbru@redhat.com>
Signed-off-by: Markus Armbruster <armbru@redhat.com>
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
---
net/l2tpv3.c | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/net/l2tpv3.c b/net/l2tpv3.c
index 3b805a7..6014c43 100644
--- a/net/l2tpv3.c
+++ b/net/l2tpv3.c
@@ -695,8 +695,7 @@ int net_init_l2tpv3(const NetClientOptions *opts,
goto outerr;
}
- s->dgram_dst = g_malloc(sizeof(struct sockaddr_storage));
- memset(s->dgram_dst, '\0' , sizeof(struct sockaddr_storage));
+ s->dgram_dst = g_new0(struct sockaddr_storage, 1);
memcpy(s->dgram_dst, result->ai_addr, result->ai_addrlen);
s->dst_size = result->ai_addrlen;
--
2.1.0
^ permalink raw reply related [flat|nested] 8+ messages in thread
* [Qemu-devel] [PULL 4/5] net: Use g_new() & friends where that makes obvious sense
2014-12-19 13:18 [Qemu-devel] [PULL 0/5] Net patches Stefan Hajnoczi
` (2 preceding siblings ...)
2014-12-19 13:18 ` [Qemu-devel] [PULL 3/5] net: Fuse g_malloc(); memset() into g_new0() Stefan Hajnoczi
@ 2014-12-19 13:18 ` Stefan Hajnoczi
2014-12-19 13:18 ` [Qemu-devel] [PULL 5/5] e1000: defer packets until BM enabled Stefan Hajnoczi
2014-12-21 23:16 ` [Qemu-devel] [PULL 0/5] Net patches Peter Maydell
5 siblings, 0 replies; 8+ messages in thread
From: Stefan Hajnoczi @ 2014-12-19 13:18 UTC (permalink / raw)
To: qemu-devel; +Cc: Peter Maydell, Markus Armbruster, Stefan Hajnoczi
From: Markus Armbruster <armbru@redhat.com>
g_new(T, n) is neater than g_malloc(sizeof(T) * n). It's also safer,
for two reasons. One, it catches multiplication overflowing size_t.
Two, it returns T * rather than void *, which lets the compiler catch
more type errors.
This commit only touches allocations with size arguments of the form
sizeof(T).
Signed-off-by: Markus Armbruster <armbru@redhat.com>
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
---
net/l2tpv3.c | 6 +++---
net/queue.c | 2 +-
net/slirp.c | 2 +-
3 files changed, 5 insertions(+), 5 deletions(-)
diff --git a/net/l2tpv3.c b/net/l2tpv3.c
index 6014c43..8c598b0 100644
--- a/net/l2tpv3.c
+++ b/net/l2tpv3.c
@@ -489,12 +489,12 @@ static struct mmsghdr *build_l2tpv3_vector(NetL2TPV3State *s, int count)
struct iovec *iov;
struct mmsghdr *msgvec, *result;
- msgvec = g_malloc(sizeof(struct mmsghdr) * count);
+ msgvec = g_new(struct mmsghdr, count);
result = msgvec;
for (i = 0; i < count ; i++) {
msgvec->msg_hdr.msg_name = NULL;
msgvec->msg_hdr.msg_namelen = 0;
- iov = g_malloc(sizeof(struct iovec) * IOVSIZE);
+ iov = g_new(struct iovec, IOVSIZE);
msgvec->msg_hdr.msg_iov = iov;
iov->iov_base = g_malloc(s->header_size);
iov->iov_len = s->header_size;
@@ -729,7 +729,7 @@ int net_init_l2tpv3(const NetClientOptions *opts,
}
s->msgvec = build_l2tpv3_vector(s, MAX_L2TPV3_MSGCNT);
- s->vec = g_malloc(sizeof(struct iovec) * MAX_L2TPV3_IOVCNT);
+ s->vec = g_new(struct iovec, MAX_L2TPV3_IOVCNT);
s->header_buf = g_malloc(s->header_size);
qemu_set_nonblock(fd);
diff --git a/net/queue.c b/net/queue.c
index f948318..ebbe2bb 100644
--- a/net/queue.c
+++ b/net/queue.c
@@ -62,7 +62,7 @@ NetQueue *qemu_new_net_queue(void *opaque)
{
NetQueue *queue;
- queue = g_malloc0(sizeof(NetQueue));
+ queue = g_new0(NetQueue, 1);
queue->opaque = opaque;
queue->nq_maxlen = 10000;
diff --git a/net/slirp.c b/net/slirp.c
index 377d7ef..0cbca3c 100644
--- a/net/slirp.c
+++ b/net/slirp.c
@@ -652,7 +652,7 @@ static int slirp_guestfwd(SlirpState *s, const char *config_str,
return -1;
}
} else {
- fwd = g_malloc(sizeof(struct GuestFwd));
+ fwd = g_new(struct GuestFwd, 1);
fwd->hd = qemu_chr_new(buf, p, NULL);
if (!fwd->hd) {
error_report("could not open guest forwarding device '%s'", buf);
--
2.1.0
^ permalink raw reply related [flat|nested] 8+ messages in thread
* [Qemu-devel] [PULL 5/5] e1000: defer packets until BM enabled
2014-12-19 13:18 [Qemu-devel] [PULL 0/5] Net patches Stefan Hajnoczi
` (3 preceding siblings ...)
2014-12-19 13:18 ` [Qemu-devel] [PULL 4/5] net: Use g_new() & friends where that makes obvious sense Stefan Hajnoczi
@ 2014-12-19 13:18 ` Stefan Hajnoczi
2014-12-19 14:21 ` Michael S. Tsirkin
2014-12-21 23:16 ` [Qemu-devel] [PULL 0/5] Net patches Peter Maydell
5 siblings, 1 reply; 8+ messages in thread
From: Stefan Hajnoczi @ 2014-12-19 13:18 UTC (permalink / raw)
To: qemu-devel; +Cc: Peter Maydell, Stefan Hajnoczi, Michael S. Tsirkin
From: "Michael S. Tsirkin" <mst@redhat.com>
Some guests seem to set BM for e1000 after
enabling RX.
If packets arrive in the window, device is wedged.
Probably works by luck on real hardware, work around
this by making can_receive depend on BM.
Tested-by: Gabriel Somlo <somlo@cmu.edu>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Reviewed-by: Jason Wang <jasowang@redhat.com>
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
---
hw/net/e1000.c | 21 ++++++++++++++++++++-
1 file changed, 20 insertions(+), 1 deletion(-)
diff --git a/hw/net/e1000.c b/hw/net/e1000.c
index e33a4da..89c5788 100644
--- a/hw/net/e1000.c
+++ b/hw/net/e1000.c
@@ -33,6 +33,7 @@
#include "sysemu/sysemu.h"
#include "sysemu/dma.h"
#include "qemu/iov.h"
+#include "qemu/range.h"
#include "e1000_regs.h"
@@ -923,7 +924,9 @@ e1000_can_receive(NetClientState *nc)
E1000State *s = qemu_get_nic_opaque(nc);
return (s->mac_reg[STATUS] & E1000_STATUS_LU) &&
- (s->mac_reg[RCTL] & E1000_RCTL_EN) && e1000_has_rxbufs(s, 1);
+ (s->mac_reg[RCTL] & E1000_RCTL_EN) &&
+ (s->parent_obj.config[PCI_COMMAND] & PCI_COMMAND_MASTER) &&
+ e1000_has_rxbufs(s, 1);
}
static uint64_t rx_desc_base(E1000State *s)
@@ -1529,6 +1532,20 @@ static NetClientInfo net_e1000_info = {
.link_status_changed = e1000_set_link_status,
};
+static void e1000_write_config(PCIDevice *pci_dev, uint32_t address,
+ uint32_t val, int len)
+{
+ E1000State *s = E1000(pci_dev);
+
+ pci_default_write_config(pci_dev, address, val, len);
+
+ if (range_covers_byte(address, len, PCI_COMMAND) &&
+ (pci_dev->config[PCI_COMMAND] & PCI_COMMAND_MASTER)) {
+ qemu_flush_queued_packets(qemu_get_queue(s->nic));
+ }
+}
+
+
static int pci_e1000_init(PCIDevice *pci_dev)
{
DeviceState *dev = DEVICE(pci_dev);
@@ -1539,6 +1556,8 @@ static int pci_e1000_init(PCIDevice *pci_dev)
int i;
uint8_t *macaddr;
+ pci_dev->config_write = e1000_write_config;
+
pci_conf = pci_dev->config;
/* TODO: RST# value should be 0, PCI spec 6.2.4 */
--
2.1.0
^ permalink raw reply related [flat|nested] 8+ messages in thread
* Re: [Qemu-devel] [PULL 5/5] e1000: defer packets until BM enabled
2014-12-19 13:18 ` [Qemu-devel] [PULL 5/5] e1000: defer packets until BM enabled Stefan Hajnoczi
@ 2014-12-19 14:21 ` Michael S. Tsirkin
0 siblings, 0 replies; 8+ messages in thread
From: Michael S. Tsirkin @ 2014-12-19 14:21 UTC (permalink / raw)
To: Stefan Hajnoczi; +Cc: Peter Maydell, qemu-devel
On Fri, Dec 19, 2014 at 01:18:24PM +0000, Stefan Hajnoczi wrote:
> From: "Michael S. Tsirkin" <mst@redhat.com>
>
> Some guests seem to set BM for e1000 after
> enabling RX.
> If packets arrive in the window, device is wedged.
> Probably works by luck on real hardware, work around
> this by making can_receive depend on BM.
>
> Tested-by: Gabriel Somlo <somlo@cmu.edu>
> Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
> Reviewed-by: Jason Wang <jasowang@redhat.com>
> Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
Pls defer this.
This does not help windows as I thought it does,
no point in making changes until we have figured
it out.
> ---
> hw/net/e1000.c | 21 ++++++++++++++++++++-
> 1 file changed, 20 insertions(+), 1 deletion(-)
>
> diff --git a/hw/net/e1000.c b/hw/net/e1000.c
> index e33a4da..89c5788 100644
> --- a/hw/net/e1000.c
> +++ b/hw/net/e1000.c
> @@ -33,6 +33,7 @@
> #include "sysemu/sysemu.h"
> #include "sysemu/dma.h"
> #include "qemu/iov.h"
> +#include "qemu/range.h"
>
> #include "e1000_regs.h"
>
> @@ -923,7 +924,9 @@ e1000_can_receive(NetClientState *nc)
> E1000State *s = qemu_get_nic_opaque(nc);
>
> return (s->mac_reg[STATUS] & E1000_STATUS_LU) &&
> - (s->mac_reg[RCTL] & E1000_RCTL_EN) && e1000_has_rxbufs(s, 1);
> + (s->mac_reg[RCTL] & E1000_RCTL_EN) &&
> + (s->parent_obj.config[PCI_COMMAND] & PCI_COMMAND_MASTER) &&
> + e1000_has_rxbufs(s, 1);
> }
>
> static uint64_t rx_desc_base(E1000State *s)
> @@ -1529,6 +1532,20 @@ static NetClientInfo net_e1000_info = {
> .link_status_changed = e1000_set_link_status,
> };
>
> +static void e1000_write_config(PCIDevice *pci_dev, uint32_t address,
> + uint32_t val, int len)
> +{
> + E1000State *s = E1000(pci_dev);
> +
> + pci_default_write_config(pci_dev, address, val, len);
> +
> + if (range_covers_byte(address, len, PCI_COMMAND) &&
> + (pci_dev->config[PCI_COMMAND] & PCI_COMMAND_MASTER)) {
> + qemu_flush_queued_packets(qemu_get_queue(s->nic));
> + }
> +}
> +
> +
> static int pci_e1000_init(PCIDevice *pci_dev)
> {
> DeviceState *dev = DEVICE(pci_dev);
> @@ -1539,6 +1556,8 @@ static int pci_e1000_init(PCIDevice *pci_dev)
> int i;
> uint8_t *macaddr;
>
> + pci_dev->config_write = e1000_write_config;
> +
> pci_conf = pci_dev->config;
>
> /* TODO: RST# value should be 0, PCI spec 6.2.4 */
> --
> 2.1.0
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [Qemu-devel] [PULL 0/5] Net patches
2014-12-19 13:18 [Qemu-devel] [PULL 0/5] Net patches Stefan Hajnoczi
` (4 preceding siblings ...)
2014-12-19 13:18 ` [Qemu-devel] [PULL 5/5] e1000: defer packets until BM enabled Stefan Hajnoczi
@ 2014-12-21 23:16 ` Peter Maydell
5 siblings, 0 replies; 8+ messages in thread
From: Peter Maydell @ 2014-12-21 23:16 UTC (permalink / raw)
To: Stefan Hajnoczi; +Cc: QEMU Developers
On 19 December 2014 at 13:18, Stefan Hajnoczi <stefanha@redhat.com> wrote:
> The following changes since commit 86b182ac0e0b44726d85598cbefb468ed22517fc:
>
> Merge remote-tracking branch 'remotes/xtensa/tags/20141217-xtensa' into staging (2014-12-17 17:31:26 +0000)
>
> are available in the git repository at:
>
> git://github.com/stefanha/qemu.git tags/net-pull-request
>
> for you to fetch changes up to 20302e71a5b654d7b4d0d61c7384e9dd8d112971:
>
> e1000: defer packets until BM enabled (2014-12-19 13:17:06 +0000)
>
> ----------------------------------------------------------------
Applied, thanks.
-- PMM
^ permalink raw reply [flat|nested] 8+ messages in thread