Virtuozzo QEMU development (svt-core@virtuozzo.com)
 help / color / mirror / Atom feed
From: no-reply@sashiko.virtuozzo.com
To: svt-core@virtuozzo.com,
	 Andrey Drobyshev <andrey.drobyshev@virtuozzo.com>
Cc: den@openvz.org, andrey.drobyshev@virtuozzo.com
Subject: Re: [PATCH QEMU HCI-8.0 v8 13/14] hcd-xhci: resync isochronous endpoints after CPR #VSTOR-137800
Date: Tue, 6 Oct 2026 16:53:30 +0000	[thread overview]
Message-ID: <010701a1122276a6-8ce4d6a0-292d-4bf1-a23d-706b549512bf-000000@eu-central-1.amazonses.com> (raw)
In-Reply-To: <20261006-usb-host_v3-v8-13-72ae4fb8977b@virtuozzo.com>

Thank you for your contribution! Sashiko AI review found 2 potential issue(s) to consider:
- [Medium] usb-xhci: cpr_iso_resync flag is not consumed by an empty-ring kick and drops a later valid TD
- [Medium] usb-xhci: CPR iso resync relies on a fabricated CC_MISSED_SERVICE_ERROR that only Linux guests may handle
--

commit b3cbde381fc3538ebb617db181b3540f42917e1d
Author: Andrey Drobyshev <andrey.drobyshev@virtuozzo.com>

hcd-xhci: resync isochronous endpoints after CPR #VSTOR-137800

This patch sets a per-endpoint flag in usb_xhci_post_load() for running
isochronous endpoints when CPR is incoming. The first isochronous TD
that reaches xhci_submit() is then completed with CC_MISSED_SERVICE_ERROR
instead of being sent to the device. The aim is to make the guest driver
skip and resync.

> diff --git a/hw/usb/hcd-xhci.c b/hw/usb/hcd-xhci.c
> --- a/hw/usb/hcd-xhci.c
> +++ b/hw/usb/hcd-xhci.c

[ ... ]

> @@ -1047,6 +1049,11 @@ static void xhci_set_ep_state(XHCIState *xhci, XHCIEPContext *epctx,
>      ctx[0] &= ~EP_STATE_MASK;
>      ctx[0] |= state;
>  
> +    if (state != EP_RUNNING) {
> +        /* a stop/reset before the first kick ends the post-CPR resync window */
> +        epctx->cpr_iso_resync = false;
> +    }
> +

[ ... ]

> @@ -1811,6 +1818,19 @@ static int xhci_submit(XHCIState *xhci, XHCITransfer *xfer, XHCIEPContext *epctx
>          xfer->pkts = 1;
>          xfer->iso_xfer = true;
>          xfer->timed_xfer = true;
> +        if (epctx->cpr_iso_resync) {
> +            /*
> +             * First iso TD after a CPR resume: our transfer state was
> +             * rebuilt from guest memory and no longer lines up with what
> +             * the guest consumed.  Report a missed service, like real HW,
> +             * to kick the driver's skip logic into resyncing.
> +             */
> +            epctx->cpr_iso_resync = false;
> +            xfer->status = CC_MISSED_SERVICE_ERROR;
> +            xhci_xfer_report(xfer);
> +            xfer->complete = 1;
> +            return 0;
> +        }

[Severity: Medium]
Can a later, correctly ordered isochronous TD be dropped here?

The comment in xhci_set_ep_state() says the resync window ends at the
first kick. The code ends it only at the first isochronous submit or at
the first non-running state change.

The post-load kick runs xhci_kick_epctx(). That function can return
without reaching xhci_submit():

    - it returns on !xhci_slot_ok()
    - it returns on !ring->dequeue
    - it breaks out of the loop when xhci_ring_chain_length() <= 0,
      which for ET_ISO_OUT/ET_ISO_IN only reports CC_RING_OVERRUN or
      CC_RING_UNDERRUN

xhci_kick_epctx() then calls xhci_set_ep_state(..., EP_RUNNING). The new
clearing code only fires for state != EP_RUNNING, so cpr_iso_resync
stays set.

The next isochronous TD the guest queues may arrive long after resume
and be in sync. It would hit this block in xhci_submit(), never be sent
to the device, and the guest would get a CC_MISSED_SERVICE_ERROR. For
iso OUT this loses one chunk of data and makes the guest run its skip
logic needlessly.

Should cpr_iso_resync be cleared when the post-load kick finishes,
rather than only on the first iso submit?

[Severity: Medium]
Does this approach depend on guest-specific handling of
CC_MISSED_SERVICE_ERROR?

The commit message says the error "arms the guest driver's skip logic".
That matches Linux xhci-hcd behaviour (ep->skip). Nothing in the patch
shows how other guests would handle this fabricated event. If a guest
treats it as a hard error or ignores it, the endpoint could stay wedged,
and the first TD's data is dropped anyway.

> @@ -3510,6 +3530,11 @@ static int usb_xhci_post_load(void *opaque, int version_id)
>              xhci_init_epctx(epctx, pctx, ep_ctx);
>              epctx->state = state;
>              if (state == EP_RUNNING) {
> +                if (cpr_is_incoming() &&
> +                    (epctx->type == ET_ISO_IN || epctx->type == ET_ISO_OUT)) {
> +                    /* only iso streams need resyncing; see xhci_submit() */
> +                    epctx->cpr_iso_resync = true;
> +                }

Also, usb_xhci_post_load() rebuilds the same transient state, including
mfindex_last via xhci_init_epctx(), for ordinary incoming migration.

Only the cpr_is_incoming() case gets the resync here.

Is the difference between CPR and regular incoming migration
intentional? If so, could the commit message explain it?

-- 
Sashiko AI review · https://sashiko.vzint.dev/#/patchset/20261006-usb-host_v3-v8-0-72ae4fb8977b@virtuozzo.com?part=13

  reply	other threads:[~2026-10-06 16:53 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
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 [this message]
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=010701a1122276a6-8ce4d6a0-292d-4bf1-a23d-706b549512bf-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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox