From da51a335aa61ec0e45879d80f3c5e2ee4f87cd2f Mon Sep 17 00:00:00 2001 From: Jason Wang Date: Fri, 29 May 2015 14:15:24 +0800 Subject: virtio-net: adding all queues in .realize() Instead of adding queues for multiqueue during feature set. This patch did this in .realize(), this will help the following patches that count the number of virtqueues used in .device_plugged() callback. Signed-off-by: Jason Wang Reviewed-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin --- hw/net/virtio-net.c | 59 +++++++++++++++-------------------------------------- 1 file changed, 17 insertions(+), 42 deletions(-) (limited to 'hw/net/virtio-net.c') diff --git a/hw/net/virtio-net.c b/hw/net/virtio-net.c index 3af6faf..3edb1c4 100644 --- a/hw/net/virtio-net.c +++ b/hw/net/virtio-net.c @@ -1301,39 +1301,8 @@ static void virtio_net_tx_bh(void *opaque) static void virtio_net_set_multiqueue(VirtIONet *n, int multiqueue) { - VirtIODevice *vdev = VIRTIO_DEVICE(n); - int i, max = multiqueue ? n->max_queues : 1; - n->multiqueue = multiqueue; - for (i = 2; i < n->max_queues * 2 + 1; i++) { - virtio_del_queue(vdev, i); - } - - for (i = 1; i < max; i++) { - n->vqs[i].rx_vq = virtio_add_queue(vdev, 256, virtio_net_handle_rx); - if (n->vqs[i].tx_timer) { - n->vqs[i].tx_vq = - virtio_add_queue(vdev, 256, virtio_net_handle_tx_timer); - n->vqs[i].tx_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, - virtio_net_tx_timer, - &n->vqs[i]); - } else { - n->vqs[i].tx_vq = - virtio_add_queue(vdev, 256, virtio_net_handle_tx_bh); - n->vqs[i].tx_bh = qemu_bh_new(virtio_net_tx_bh, &n->vqs[i]); - } - - n->vqs[i].tx_waiting = 0; - n->vqs[i].n = n; - } - - /* Note: Minux Guests (version 3.2.1) use ctrl vq but don't ack - * VIRTIO_NET_F_CTRL_VQ. Create ctrl vq unconditionally to avoid - * breaking them. - */ - n->ctrl_vq = virtio_add_queue(vdev, 64, virtio_net_handle_ctrl); - virtio_net_set_queues(n); } @@ -1594,9 +1563,7 @@ static void virtio_net_device_realize(DeviceState *dev, Error **errp) return; } n->vqs = g_malloc0(sizeof(VirtIONetQueue) * n->max_queues); - n->vqs[0].rx_vq = virtio_add_queue(vdev, 256, virtio_net_handle_rx); n->curr_queues = 1; - n->vqs[0].n = n; n->tx_timeout = n->net_conf.txtimer; if (n->net_conf.tx && strcmp(n->net_conf.tx, "timer") @@ -1607,16 +1574,24 @@ static void virtio_net_device_realize(DeviceState *dev, Error **errp) error_report("Defaulting to \"bh\""); } - if (n->net_conf.tx && !strcmp(n->net_conf.tx, "timer")) { - n->vqs[0].tx_vq = virtio_add_queue(vdev, 256, - virtio_net_handle_tx_timer); - n->vqs[0].tx_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, virtio_net_tx_timer, - &n->vqs[0]); - } else { - n->vqs[0].tx_vq = virtio_add_queue(vdev, 256, - virtio_net_handle_tx_bh); - n->vqs[0].tx_bh = qemu_bh_new(virtio_net_tx_bh, &n->vqs[0]); + for (i = 0; i < n->max_queues; i++) { + n->vqs[i].rx_vq = virtio_add_queue(vdev, 256, virtio_net_handle_rx); + if (n->net_conf.tx && !strcmp(n->net_conf.tx, "timer")) { + n->vqs[i].tx_vq = + virtio_add_queue(vdev, 256, virtio_net_handle_tx_timer); + n->vqs[i].tx_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, + virtio_net_tx_timer, + &n->vqs[i]); + } else { + n->vqs[i].tx_vq = + virtio_add_queue(vdev, 256, virtio_net_handle_tx_bh); + n->vqs[i].tx_bh = qemu_bh_new(virtio_net_tx_bh, &n->vqs[i]); + } + + n->vqs[i].tx_waiting = 0; + n->vqs[i].n = n; } + n->ctrl_vq = virtio_add_queue(vdev, 64, virtio_net_handle_ctrl); qemu_macaddr_default_if_unset(&n->nic_conf.macaddr); memcpy(&n->mac[0], &n->nic_conf.macaddr, sizeof(n->mac)); -- cgit v1.1 From 87b3bd1c858e6cacac4d403da9109ec3a04fe9d0 Mon Sep 17 00:00:00 2001 From: Jason Wang Date: Fri, 29 May 2015 14:15:31 +0800 Subject: virtio: rename VIRTIO_PCI_QUEUE_MAX to VIRTIO_QUEUE_MAX VIRTIO_PCI_QUEUE_MAX is not only used for pci, so rename it be generic. Cc: Amit Shah Cc: Paolo Bonzini Signed-off-by: Jason Wang Reviewed-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin --- hw/net/virtio-net.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'hw/net/virtio-net.c') diff --git a/hw/net/virtio-net.c b/hw/net/virtio-net.c index 3edb1c4..6dca726 100644 --- a/hw/net/virtio-net.c +++ b/hw/net/virtio-net.c @@ -1555,10 +1555,10 @@ static void virtio_net_device_realize(DeviceState *dev, Error **errp) virtio_init(vdev, "virtio-net", VIRTIO_ID_NET, n->config_size); n->max_queues = MAX(n->nic_conf.peers.queues, 1); - if (n->max_queues * 2 + 1 > VIRTIO_PCI_QUEUE_MAX) { + if (n->max_queues * 2 + 1 > VIRTIO_QUEUE_MAX) { error_setg(errp, "Invalid number of queues (= %" PRIu32 "), " "must be a positive integer less than %d.", - n->max_queues, (VIRTIO_PCI_QUEUE_MAX - 1) / 2); + n->max_queues, (VIRTIO_QUEUE_MAX - 1) / 2); virtio_cleanup(vdev); return; } -- cgit v1.1 From 019a3edbb25f1571e876f8af1ce4c55412939e5d Mon Sep 17 00:00:00 2001 From: Gerd Hoffmann Date: Mon, 1 Jun 2015 10:45:40 +0200 Subject: virtio: make features 64bit wide Make features 64bit wide everywhere. On migration a full 64bit guest_features field is sent if one of the high bits is set, in addition to the lower 32bit guest_features field which must stay for compatibility reasons. That way we send the lower 32 feature bits twice, but the code is simpler because we don't have to split and compose the 64bit features into two 32bit fields. Signed-off-by: Gerd Hoffmann Reviewed-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin --- hw/net/virtio-net.c | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) (limited to 'hw/net/virtio-net.c') diff --git a/hw/net/virtio-net.c b/hw/net/virtio-net.c index 6dca726..012ab7f 100644 --- a/hw/net/virtio-net.c +++ b/hw/net/virtio-net.c @@ -435,7 +435,7 @@ static void virtio_net_set_queues(VirtIONet *n) static void virtio_net_set_multiqueue(VirtIONet *n, int multiqueue); -static uint32_t virtio_net_get_features(VirtIODevice *vdev, uint32_t features) +static uint64_t virtio_net_get_features(VirtIODevice *vdev, uint64_t features) { VirtIONet *n = VIRTIO_NET(vdev); NetClientState *nc = qemu_get_queue(n->nic); @@ -468,9 +468,9 @@ static uint32_t virtio_net_get_features(VirtIODevice *vdev, uint32_t features) return vhost_net_get_features(get_vhost_net(nc->peer), features); } -static uint32_t virtio_net_bad_features(VirtIODevice *vdev) +static uint64_t virtio_net_bad_features(VirtIODevice *vdev) { - uint32_t features = 0; + uint64_t features = 0; /* Linux kernel 2.6.25. It understood MAC (as everyone must), * but also these: */ @@ -1032,10 +1032,12 @@ static ssize_t virtio_net_receive(NetClientState *nc, const uint8_t *buf, size_t if (i == 0) return -1; error_report("virtio-net unexpected empty queue: " - "i %zd mergeable %d offset %zd, size %zd, " - "guest hdr len %zd, host hdr len %zd guest features 0x%x", - i, n->mergeable_rx_bufs, offset, size, - n->guest_hdr_len, n->host_hdr_len, vdev->guest_features); + "i %zd mergeable %d offset %zd, size %zd, " + "guest hdr len %zd, host hdr len %zd " + "guest features 0x%" PRIx64, + i, n->mergeable_rx_bufs, offset, size, + n->guest_hdr_len, n->host_hdr_len, + vdev->guest_features); exit(1); } @@ -1518,7 +1520,7 @@ static void virtio_net_guest_notifier_mask(VirtIODevice *vdev, int idx, vdev, idx, mask); } -static void virtio_net_set_config_size(VirtIONet *n, uint32_t host_features) +static void virtio_net_set_config_size(VirtIONet *n, uint64_t host_features) { int i, config_size = 0; virtio_add_feature(&host_features, VIRTIO_NET_F_MAC); -- cgit v1.1