From: Gerd Hoffmann <kraxel@redhat.com>
To: qemu-devel@nongnu.org
Cc: Hans de Goede <hdegoede@redhat.com>, Gerd Hoffmann <kraxel@redhat.com>
Subject: [Qemu-devel] [PATCH 09/14] usb-redir: Add an already_in_flight packet-id queue
Date: Thu, 13 Sep 2012 10:39:55 +0200 [thread overview]
Message-ID: <1347525600-28220-10-git-send-email-kraxel@redhat.com> (raw)
In-Reply-To: <1347525600-28220-1-git-send-email-kraxel@redhat.com>
From: Hans de Goede <hdegoede@redhat.com>
After a live migration, the usb-hcd will re-queue all packets by
walking over the schedule in the guest memory again, but requests which
were encountered on the migration source before will already be in flight,
so these should *not* be re-send to the usbredir-host.
This patch adds an already in flight packet ud queue, which will be filled by
the source before migration and then moved over to the migration dest, any
async handled packets are then checked against this queue to avoid sending
the same packet to the usbredir-host twice.
Signed-off-by: Hans de Goede <hdegoede@redhat,com>
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
hw/usb/redirect.c | 43 +++++++++++++++++++++++++++++++++++++++++++
1 files changed, 43 insertions(+), 0 deletions(-)
diff --git a/hw/usb/redirect.c b/hw/usb/redirect.c
index 603262a..f474da8 100644
--- a/hw/usb/redirect.c
+++ b/hw/usb/redirect.c
@@ -98,6 +98,7 @@ struct USBRedirDevice {
struct usbredirparser *parser;
struct endp_data endpoint[MAX_ENDPOINTS];
struct PacketIdQueue cancelled;
+ struct PacketIdQueue already_in_flight;
/* Data for device filtering */
struct usb_redir_device_connect_header device_info;
struct usb_redir_interface_info_header interface_info;
@@ -316,6 +317,34 @@ static int usbredir_is_cancelled(USBRedirDevice *dev, uint64_t id)
return packet_id_queue_remove(&dev->cancelled, id);
}
+static void usbredir_fill_already_in_flight_from_ep(USBRedirDevice *dev,
+ struct USBEndpoint *ep)
+{
+ static USBPacket *p;
+
+ QTAILQ_FOREACH(p, &ep->queue, queue) {
+ packet_id_queue_add(&dev->already_in_flight, p->id);
+ }
+}
+
+static void usbredir_fill_already_in_flight(USBRedirDevice *dev)
+{
+ int ep;
+ struct USBDevice *udev = &dev->dev;
+
+ usbredir_fill_already_in_flight_from_ep(dev, &udev->ep_ctl);
+
+ for (ep = 0; ep < USB_MAX_ENDPOINTS; ep++) {
+ usbredir_fill_already_in_flight_from_ep(dev, &udev->ep_in[ep]);
+ usbredir_fill_already_in_flight_from_ep(dev, &udev->ep_out[ep]);
+ }
+}
+
+static int usbredir_already_in_flight(USBRedirDevice *dev, uint64_t id)
+{
+ return packet_id_queue_remove(&dev->already_in_flight, id);
+}
+
static USBPacket *usbredir_find_packet_by_id(USBRedirDevice *dev,
uint8_t ep, uint64_t id)
{
@@ -531,6 +560,10 @@ static int usbredir_handle_bulk_data(USBRedirDevice *dev, USBPacket *p,
DPRINTF("bulk-out ep %02X len %zd id %"PRIu64"\n", ep, p->iov.size, p->id);
+ if (usbredir_already_in_flight(dev, p->id)) {
+ return USB_RET_ASYNC;
+ }
+
bulk_packet.endpoint = ep;
bulk_packet.length = p->iov.size;
bulk_packet.stream_id = 0;
@@ -611,6 +644,10 @@ static int usbredir_handle_interrupt_data(USBRedirDevice *dev,
DPRINTF("interrupt-out ep %02X len %zd id %"PRIu64"\n", ep,
p->iov.size, p->id);
+ if (usbredir_already_in_flight(dev, p->id)) {
+ return USB_RET_ASYNC;
+ }
+
interrupt_packet.endpoint = ep;
interrupt_packet.length = p->iov.size;
@@ -753,6 +790,10 @@ static int usbredir_handle_control(USBDevice *udev, USBPacket *p,
USBRedirDevice *dev = DO_UPCAST(USBRedirDevice, dev, udev);
struct usb_redir_control_packet_header control_packet;
+ if (usbredir_already_in_flight(dev, p->id)) {
+ return USB_RET_ASYNC;
+ }
+
/* Special cases for certain standard device requests */
switch (request) {
case DeviceOutRequest | USB_REQ_SET_ADDRESS:
@@ -959,6 +1000,7 @@ static int usbredir_initfn(USBDevice *udev)
dev->attach_timer = qemu_new_timer_ms(vm_clock, usbredir_do_attach, dev);
packet_id_queue_init(&dev->cancelled, dev, "cancelled");
+ packet_id_queue_init(&dev->already_in_flight, dev, "already-in-flight");
for (i = 0; i < MAX_ENDPOINTS; i++) {
QTAILQ_INIT(&dev->endpoint[i].bufpq);
}
@@ -980,6 +1022,7 @@ static void usbredir_cleanup_device_queues(USBRedirDevice *dev)
int i;
packet_id_queue_empty(&dev->cancelled);
+ packet_id_queue_empty(&dev->already_in_flight);
for (i = 0; i < MAX_ENDPOINTS; i++) {
usbredir_free_bufpq(dev, I2EP(i));
}
--
1.7.1
next prev parent reply other threads:[~2012-09-13 8:40 UTC|newest]
Thread overview: 19+ messages / expand[flat|nested] mbox.gz Atom feed top
2012-09-13 8:39 [Qemu-devel] [PULL 00/14] usb patch queue Gerd Hoffmann
2012-09-13 8:39 ` [Qemu-devel] [PATCH 01/14] usb-host: allow emulated (non-async) control requests without USBPacket Gerd Hoffmann
2012-09-13 8:39 ` [Qemu-devel] [PATCH 02/14] ehci: switch to new-style memory ops Gerd Hoffmann
2012-09-13 8:39 ` [Qemu-devel] [PATCH 03/14] ehci: Fix interrupts stopping when Interrupt Threshold Control is 8 Gerd Hoffmann
2012-09-13 8:39 ` [Qemu-devel] [PATCH 04/14] ehci: Don't process too much frames in 1 timer tick (v2) Gerd Hoffmann
2012-09-13 8:39 ` [Qemu-devel] [PATCH 05/14] configure: usbredir fixes Gerd Hoffmann
2012-09-13 8:39 ` [Qemu-devel] [PATCH 06/14] ehci: Don't set seen to 0 when removing unseen queue-heads Gerd Hoffmann
2012-09-13 8:39 ` [Qemu-devel] [PATCH 07/14] ehci: Walk async schedule before and after migration Gerd Hoffmann
2012-09-13 8:39 ` [Qemu-devel] [PATCH 08/14] usb-redir: Change cancelled packet code into a generic packet-id queue Gerd Hoffmann
2012-09-13 8:39 ` Gerd Hoffmann [this message]
2012-09-13 8:39 ` [Qemu-devel] [PATCH 10/14] usb-redir: Store max_packet_size in endp_data Gerd Hoffmann
2012-09-13 8:39 ` [Qemu-devel] [PATCH 11/14] usb-redir: Add support for migration Gerd Hoffmann
2012-09-13 8:39 ` [Qemu-devel] [PATCH 12/14] usb-redir: Add chardev open / close debug logging Gerd Hoffmann
2012-09-13 8:39 ` [Qemu-devel] [PATCH 13/14] usb-redir: Revert usb-redir part of commit 93bfef4c Gerd Hoffmann
2012-09-13 8:40 ` [Qemu-devel] [PATCH 14/14] uhci: Don't queue up packets after one with the SPD flag set Gerd Hoffmann
2012-09-14 7:59 ` [Qemu-devel] [PULL 00/14] usb patch queue Michael Tokarev
2012-09-14 8:27 ` Gerd Hoffmann
2012-09-14 15:21 ` Hans de Goede
2012-09-21 18:17 ` Aurelien Jarno
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=1347525600-28220-10-git-send-email-kraxel@redhat.com \
--to=kraxel@redhat.com \
--cc=hdegoede@redhat.com \
--cc=qemu-devel@nongnu.org \
/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).