From 758bfae226c2297c884c62e7b36064c2d3c14a63 Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Fri, 21 Sep 2012 18:57:41 -0300 Subject: [RHEL6 qemu-kvm PATCH 20/23] usb-redir: Add an already_in_flight packet-id queue RH-Author: Hans de Goede Message-id: <1348253864-3050-20-git-send-email-hdegoede@redhat.com> Patchwork-id: 42196 O-Subject: [RHEL-6.4 qemu-kvm PATCH 19/22] usb-redir: Add an already_in_flight packet-id queue Bugzilla: 805172 RH-Acked-by: Uri Lublin RH-Acked-by: Arnon Gilboa RH-Acked-by: Gerd Hoffmann 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 Signed-off-by: Gerd Hoffmann Upstream commit: 9a8d4067a63702dfb62d0ae3399600a853ad5daa Conflicts: usb-redir.c --- usb-redir.c | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) Signed-off-by: Eduardo Habkost --- usb-redir.c | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/usb-redir.c b/usb-redir.c index f0906de..c1c20a1 100644 --- a/usb-redir.c +++ b/usb-redir.c @@ -99,6 +99,7 @@ struct USBRedirDevice { struct endp_data endpoint[MAX_ENDPOINTS]; QTAILQ_HEAD(, AsyncURB) asyncq; 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; @@ -370,6 +371,25 @@ 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(USBRedirDevice *dev) +{ + AsyncURB *aurb; + + QTAILQ_FOREACH(aurb, &dev->asyncq, next) { + packet_id_queue_add(&dev->already_in_flight, aurb->packet->id); + } +} + +static int usbredir_already_in_flight(USBRedirDevice *dev, USBPacket *p) +{ + if (packet_id_queue_remove(&dev->already_in_flight, p->id)) { + /* RHEL-6: so that we can find the packet when we get the completion */ + async_alloc(dev, p); + return 1; + } + return 0; +} + static AsyncURB *async_find(USBRedirDevice *dev, uint64_t id) { AsyncURB *aurb; @@ -582,6 +602,10 @@ static int usbredir_handle_bulk_data(USBRedirDevice *dev, USBPacket *p, DPRINTF("bulk-out ep %02X len %d id %"PRIu64"\n", ep, p->len, p->id); + if (usbredir_already_in_flight(dev, p)) { + return USB_RET_ASYNC; + } + async_alloc(dev, p); bulk_packet.endpoint = ep; @@ -661,6 +685,10 @@ static int usbredir_handle_interrupt_data(USBRedirDevice *dev, DPRINTF("interrupt-out ep %02X len %d id %"PRIu64"\n", ep, p->len, p->id); + if (usbredir_already_in_flight(dev, p)) { + return USB_RET_ASYNC; + } + async_alloc(dev, p); interrupt_packet.endpoint = ep; @@ -811,6 +839,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)) { + return USB_RET_ASYNC; + } + /* Special cases for certain standard device requests */ switch (request) { case DeviceOutRequest | USB_REQ_SET_ADDRESS: @@ -1026,6 +1058,7 @@ static int usbredir_initfn(USBDevice *udev) QTAILQ_INIT(&dev->asyncq); 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); } @@ -1049,6 +1082,7 @@ static void usbredir_cleanup_device_queues(USBRedirDevice *dev) async_free(dev, aurb); } 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.11.4