From: no-reply@sashiko.virtuozzo.com
To: Andrey Drobyshev <andrey.drobyshev@virtuozzo.com>,
svt-core@virtuozzo.com
Cc: den@openvz.org, andrey.drobyshev@virtuozzo.com
Subject: Re: [PATCH QEMU HCI-8.0 v8 07/14] usb-host: re-issue drained URBs if CPR is aborted #VSTOR-137800
Date: Tue, 6 Oct 2026 16:44:21 +0000 [thread overview]
Message-ID: <010701a1121a15c3-838dfbb7-16a2-407e-a0db-dda56b8f5726-000000@eu-central-1.amazonses.com> (raw)
In-Reply-To: <20261006-usb-host_v3-v8-7-72ae4fb8977b@virtuozzo.com>
Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
- [Medium] usb-host: paused-VM CPR drain replays fully completed URBs, not just partial OUTs
--
commit 9334effcb0d32b4173bab08303e8d2fef677d756
Author: Andrey Drobyshev <andrey.drobyshev@virtuozzo.com>
usb-host: re-issue drained URBs if CPR is aborted #VSTOR-137800
This commit queues the packets suppressed during the CPR drain on a new
cpr_inflight list. If CPR is aborted, the vm-state handler's resume branch
re-issues them on the preserved fd. Control transfers are completed with
USB_RET_IOERROR instead.
> diff --git a/hw/usb/host-libusb.c b/hw/usb/host-libusb.c
> index 413ddc12ee43..9cc7d72aa63a 100644
> --- a/hw/usb/host-libusb.c
> +++ b/hw/usb/host-libusb.c
[ ... ]
> @@ -433,9 +435,10 @@ static USBHostRequest *usb_host_req_find(USBHostDevice *s, USBPacket *p)
> /*
> * Classify a reap during the CPR drain (r->p is still set). The paused-VM
> * fallback (cpr_replay_all) can't deliver completions, so it suppresses every
> - * reap for the target to replay; otherwise one that moved no data is suppressed
> - * and one that moved some is kept as a short transfer. Returns true if
> - * suppressed, so the caller frees the request.
> + * reap; otherwise one that moved no data is suppressed and one that moved some
> + * is kept as a short transfer. Suppressed packets are queued on cpr_inflight
> + * for the target to replay. Returns true if suppressed, so the caller frees
> + * the request.
> */
> static bool usb_host_req_cpr_replay(USBHostRequest *r,
> struct libusb_transfer *xfer)
> @@ -462,6 +465,9 @@ static bool usb_host_req_cpr_replay(USBHostRequest *r,
> return false;
> }
> }
> + if (r->p->state == USB_PACKET_ASYNC) {
> + r->host->cpr_inflight = g_slist_append(r->host->cpr_inflight, r->p);
> + }
> return true;
> }
[Severity: Medium]
When cpr_replay_all is set by usb_host_pre_save() (paused-VM fallback), the
whole "if (!r->host->cpr_replay_all) { ... }" block is skipped. Control
then reaches the g_slist_append() for every reaped URB, whatever
xfer->status or xfer->actual_length is.
That includes URBs that finished with LIBUSB_TRANSFER_COMPLETED.
> [ ... ]
>
> +static void usb_host_cpr_reissue(USBHostDevice *s)
> +{
[ ... ]
> + for (it = s->cpr_inflight; it; it = it->next) {
> + p = it->data;
> + /*
> + * Replay from the start of the TD. A transfer that already moved some
> + * data is re-run in full, so an OUT fragment the device consumed may be
> + * sent twice. Only the paused-VM pre_save fallback queues such partial
> + * transfers here; the normal drain delivers them as short transfers.
> + */
> + p->actual_length = 0;
> + if (p->ep->nr == 0) {
> + /* control endpoint: can't be reconstructed, so error it out */
> + p->status = USB_RET_IOERROR;
> + usb_generic_async_ctrl_complete(udev, p);
> + } else {
> + usb_host_handle_data(udev, p);
Is the comment here, and the commit message, accurate about which
transfers get replayed?
The commit message says "an OUT fragment already consumed by the device may
be sent twice. Only the paused-VM .pre_save() fallback queues partial
transfers for re-issue". The code comment makes the same claim.
The path is usb_host_pre_save() setting cpr_replay_all = true, then
usb_host_cpr_quiesce(), then usb_host_req_cpr_replay() queuing every reap.
In that path fully completed URBs are queued as well, not only partial
ones.
On resume after an aborted CPR, usb_host_cpr_reissue() then handles them
as follows:
- A completed OUT transfer is sent to the device a second time.
- A completed IN transfer is resubmitted with actual_length reset to 0,
so the data already read is lost and the device will not resend it.
- A completed control transfer, for example SET_CONFIGURATION or another
SET_* request, is reported to the guest as USB_RET_IOERROR through
usb_generic_async_ctrl_complete().
Should the commit message and the comment describe this wider scope? Or
should usb_host_req_cpr_replay() deliver URBs with xfer->status ==
LIBUSB_TRANSFER_COMPLETED normally, even in cpr_replay_all mode, instead
of queueing them for replay?
> [ ... ]
--
Sashiko AI review · https://sashiko.vzint.dev/#/patchset/20261006-usb-host_v3-v8-0-72ae4fb8977b@virtuozzo.com?part=7
next prev parent reply other threads:[~2026-10-06 16:44 UTC|newest]
Thread overview: 29+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-10-06 16:27 [PATCH QEMU HCI-8.0 v8 00/14] usb-host: support CPR migration Andrey Drobyshev
2026-10-06 16:27 ` [PATCH QEMU HCI-8.0 v8 01/14] usb-host: don't leak hostdev FD on open failure #VSTOR-137800 Andrey Drobyshev
2026-10-06 16:31 ` no-reply
2026-10-06 16:27 ` [PATCH QEMU HCI-8.0 v8 02/14] usb-host: don't leak config descriptor on claim " Andrey Drobyshev
2026-10-06 16:29 ` no-reply
2026-10-06 16:27 ` [PATCH QEMU HCI-8.0 v8 03/14] usb-host: add migration blocker for CPR modes #VSTOR-137800 Andrey Drobyshev
2026-10-06 16:30 ` no-reply
2026-10-06 16:27 ` [PATCH QEMU HCI-8.0 v8 04/14] usb-host: preserve hostdev FD during CPR migration #VSTOR-137800 Andrey Drobyshev
2026-10-06 16:38 ` no-reply
2026-10-06 16:27 ` [PATCH QEMU HCI-8.0 v8 05/14] usb-host: factor out usb_host_reap_xfers() #VSTOR-137800 Andrey Drobyshev
2026-10-06 16:31 ` no-reply
2026-10-06 16:27 ` [PATCH QEMU HCI-8.0 v8 06/14] usb-host: drain in-flight URBs across CPR #VSTOR-137800 Andrey Drobyshev
2026-10-06 16:38 ` no-reply
2026-10-06 16:27 ` [PATCH QEMU HCI-8.0 v8 07/14] usb-host: re-issue drained URBs if CPR is aborted #VSTOR-137800 Andrey Drobyshev
2026-10-06 16:44 ` no-reply [this message]
2026-10-06 16:27 ` [PATCH QEMU HCI-8.0 v8 08/14] usb-host: skip product-string read on CPR incoming #VSTOR-137800 Andrey Drobyshev
2026-10-06 16:41 ` no-reply
2026-10-06 16:28 ` [PATCH QEMU HCI-8.0 v8 09/14] usb-host: factor out usb_host_start_events() #VSTOR-137800 Andrey Drobyshev
2026-10-06 16:41 ` no-reply
2026-10-06 16:28 ` [PATCH QEMU HCI-8.0 v8 10/14] usb-host: hand off the device across cpr-transfer #VSTOR-137800 Andrey Drobyshev
2026-10-06 16:50 ` no-reply
2026-10-06 16:28 ` [PATCH QEMU HCI-8.0 v8 11/14] usb: migrate the interface altsetting #VSTOR-137800 Andrey Drobyshev
2026-10-06 16:46 ` no-reply
2026-10-06 16:28 ` [PATCH QEMU HCI-8.0 v8 12/14] usb-host: reconfigure endpoints on CPR incoming #VSTOR-137800 Andrey Drobyshev
2026-10-06 16:52 ` no-reply
2026-10-06 16:28 ` [PATCH QEMU HCI-8.0 v8 13/14] hcd-xhci: resync isochronous endpoints after CPR #VSTOR-137800 Andrey Drobyshev
2026-10-06 16:53 ` no-reply
2026-10-06 16:28 ` [PATCH QEMU HCI-8.0 v8 14/14] usb-host: make CPR migration blocker conditional #VSTOR-137800 Andrey Drobyshev
2026-10-06 16:53 ` no-reply
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=010701a1121a15c3-838dfbb7-16a2-407e-a0db-dda56b8f5726-000000@eu-central-1.amazonses.com \
--to=no-reply@sashiko.virtuozzo.com \
--cc=andrey.drobyshev@virtuozzo.com \
--cc=den@openvz.org \
--cc=svt-core@virtuozzo.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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.