From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from AS8PR04CU009.outbound.protection.outlook.com (mail-westeuropeazon11021135.outbound.protection.outlook.com [52.101.70.135]) by lore.virtuozzo.com (Postfix) with ESMTPS id 183D7802A5 for ; Tue, 6 Oct 2026 10:54:42 +0000 (UTC) ARC-Seal: i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none; b=OEQPIjMcb04FokVnCA0Fyu3Ofj2+hPE7mo2eMpMCbjCaFTs+9DWgPHsVWurN4ZnC36Id2+Us/wEyBMVkOETlUO5CEeb9EMMIaSuunvMvOHtcNveC/AUdKxpfMi7A/TTBssljXLgRoKGS/Wv0XNpQyhIs+BxHKLlH/UtwegmTwMpSLU5gtcXZOCrDRZFnQXz8tWBG8Q8jg5w4F/LobpIGM2Hj+9mMNargmMDmdgGGj8/M0QJdfW1u2HlZ6hQnXTIQlOAFg517i0U5wFhwOaFDf0RaCckZp9Dgv8fPc8OIbmo3OZ34Un8E3ChXSktBAT9PuEW8TOzJaPJAUPs5mDnP3w== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector10001; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=w+u57D63isvB4n2jUC2eGMYFAviHxU8Owab9sQeFe5E=; b=t4m19Hg/FXUPlNq60Hp4JnjcaDf5muSGdIouWB0kXnRbdsNuuCGPHBQG/x3j3gpRUyYNXTgneNwZcUQBvHXvjMVZb9VpewIOUQqc1Dh708o6f9ZGRJOfW5Q6E/pjmBEq76rwV/qPvMk/nxvvLTCBFyvg/q1JbRa1RvQ0XwLYDTF9C68OzWbheacpl7rpMjwgVNhIxuMI+OXKUrPisJo5w1grjy0TxB7Eod8i6QLXtEs51dZ8t0ku9/PimfyH7L6/Sl/p0Z9vhmtnKaIxk6N1ElG9EMozatwDB+edzEZfsNms/tcOVA2Gxv1k7YBDh9JGF081WLJwT93GUqQ4kSjXlw== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass (sender ip is 69.169.224.5) smtp.rcpttodomain=virtuozzo.com smtp.mailfrom=eu-central-1.amazonses.com; dmarc=pass (p=quarantine sp=quarantine pct=100) action=none header.from=sashiko.virtuozzo.com; dkim=pass (signature was verified) header.d=sashiko.virtuozzo.com; dkim=pass (signature was verified) header.d=amazonses.com; arc=none (0) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=virtuozzo.onmicrosoft.com; s=selector2-virtuozzo-onmicrosoft-com; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=w+u57D63isvB4n2jUC2eGMYFAviHxU8Owab9sQeFe5E=; b=f3fW8c8SVpoi9yElnEDjQno3vxccEsRcDUgITBcZRj9un4n2vWtWiQNNJ2fybe87NEcNymoEOf1jTHQIXTWbD17W5CtDG4ygF273obkkXvJVAqUl1B5QafcRfSO82N9usH0uMtvSXeX03sVICu6ajWx84nD1T0c2NDtftNtlHl8= Received: from PAZP264CA0228.FRAP264.PROD.OUTLOOK.COM (2603:10a6:102:238::6) by GV2PR08MB861741.eurprd08.prod.outlook.com (2603:10a6:150:3b9::22) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.21.496.15; Tue, 6 Oct 2026 10:54:36 +0000 Received: from MI3PEPF00008559.eurprd05.prod.outlook.com (2603:10a6:102:238:cafe::9d) by PAZP264CA0228.outlook.office365.com (2603:10a6:102:238::6) with Microsoft SMTP Server (version=TLS1_3, cipher=TLS_AES_256_GCM_SHA384) id 15.21.472.20 via Frontend Transport; Tue, 6 Oct 2026 10:54:36 +0000 Authentication-Results: mx.microsoft.com 1; spf=pass (sender IP is 69.169.224.5) smtp.mailfrom=eu-central-1.amazonses.com; dkim=pass (signature was verified) header.d=sashiko.virtuozzo.com;dkim=pass (signature was verified) header.d=amazonses.com;dmarc=pass action=none header.from=sashiko.virtuozzo.com; Received-SPF: Pass (protection.outlook.com: domain of eu-central-1.amazonses.com designates 69.169.224.5 as permitted sender) receiver=protection.outlook.com; client-ip=69.169.224.5; helo=b224-5.smtp-out.eu-central-1.amazonses.com; pr=C Received: from b224-5.smtp-out.eu-central-1.amazonses.com (69.169.224.5) by MI3PEPF00008559.mail.protection.outlook.com (10.167.240.21) with Microsoft SMTP Server (version=TLS1_3, cipher=TLS_AES_256_GCM_SHA384) id 15.21.496.14 via Frontend Transport; Tue, 6 Oct 2026 10:54:36 +0000 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/simple; s=23yjbh4k34hwzfubhuiim7m4inbd3ick; d=sashiko.virtuozzo.com; t=1791284075; h=From:Subject:To:Cc:In-Reply-To:References:Content-Type:Content-Transfer-Encoding:Date:Message-ID; bh=lX7+ddOt+xfzxp1HO9W8BBRoFcAhn2J7EUcW35JgiaE=; b=EL0963tPF9Ezq5Z/jiiGqqLjyWvTbWu1AmXH+UqGKKDpzskEayZlVDoyNlWL2cn3 zZY7Pjxo8F0TpQ5f0CYkdWVT7FOumZcYUCZu088jCBsbGHNCdVix3NnSHSkO5qIcjWd 8g3YWbvpLsHjrpzOEpNyrO7+c6sjPUFrzfWQWJoi1+GcspjSsBOyha3F2RUqkhxMTt3 KLCBhI4R0vnCTzWuGPWGWTzsBoXTSFEX+YvXkucdAcG6fng0t9Zm1GOasFZN2TsV+Jw FTpNGdj+Le0pwrCCnLMcCSJKCbxeM3PEPstV3nae2GLjYcd2+jlobp+payI2jyo9lUh 32XNWFQHEA== DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/simple; s=sokbgaaqhfgd6qjht2wmdajpuuanpimv; d=amazonses.com; t=1791284075; h=From:Subject:To:Cc:In-Reply-To:References:Content-Type:Content-Transfer-Encoding:Date:Message-ID:Feedback-ID; bh=lX7+ddOt+xfzxp1HO9W8BBRoFcAhn2J7EUcW35JgiaE=; b=Od/H69ZtZWpVSj0WnwjkX/RIqbbXnlUwo1fa2lIRV7uhlqG5waHg9eoJ6fGdM7K+ acM0kd1VF62BT/kDLDEQNxecrkolIbD1T8mO7Fa+yXRMqPIyZqsU07+amMbUSQdeMwq BL+5sTWkTRQxWtNT+2ObbkOF/KvawXxCJGWxTPos= From: no-reply@sashiko.virtuozzo.com Subject: Re: [PATCH QEMU HCI-8.0 v6 08/12] usb-host: hand off the device across cpr-transfer #VSTOR-137800 To: Andrey Drobyshev , svt-core@virtuozzo.com Cc: den@openvz.org, andrey.drobyshev@virtuozzo.com In-Reply-To: <20261006-usb-host_v3-v6-8-8688ec9576d1@virtuozzo.com> References: <20261006-usb-host_v3-v6-0-8688ec9576d1@virtuozzo.com> <20261006-usb-host_v3-v6-8-8688ec9576d1@virtuozzo.com> Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: quoted-printable Date: Tue, 6 Oct 2026 10:54:35 +0000 Message-ID: <010701a110d9dcc9-a17c6756-d54c-4acc-82c1-2ced38bde581-000000@eu-central-1.amazonses.com> Feedback-ID: ::1.eu-central-1.2wRQJBpg9g1fGRYexx3dUuYGS25Bux+2TEOx72/m6U4=:AmazonSES X-SES-Outgoing: 2026.10.06-69.169.224.5 X-EOPAttributedMessage: 0 X-EOPTenantAttributedMessage: 0bc7f26d-0264-416e-a6fc-8352af79c58f:0 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: MI3PEPF00008559:EE_|GV2PR08MB861741:EE_ MIME-Version: 1.0 X-MS-Office365-Filtering-Correlation-Id: 3fb400df-9406-42cc-38d6-08df23983649 X-LD-Processed: 0bc7f26d-0264-416e-a6fc-8352af79c58f,ExtAddr X-MS-Exchange-AtpMessageProperties: SA List-Id: svt-core@virtuozzo.com X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0;ARA:13230040|704161411799003|32142699015|9140799003|61400799027|376014|48200799018|5063699009|56012099006|4143699003|10067099003|55112099003|22082099003|16102099003|18002099003|4113699003|5113699003; X-Microsoft-Antispam-Message-Info: GRT2IhNbfucOpXzxJS8bJ9Mjq41azwJRamDk7WHldzuL1n07V1YHv7emq8fW8/KE0WUf+NwKVICTh8/M9pN0G3G3YxwVwsLkC64vSA2KDG1MeipzRJaYSa31UaXS5JPB8aE98wloAMRQhXbKzDjTOl1faO6f6U9e89b26p8SelV1gDj2nfGWiRd5H/xtDSyJi4qogl172C1lDTIXMfh/w4z3LdAS9raqrC0lPsDM+7VC5TYctrCkkvPxHpRX5vAyMT6XLlpkMVhPRtoi9RxusRQ1QlmhhO45WBcC4PTWypXoZOd800gyTZQBstTUdyGo7/SLn72t6haxxR/Gp1VjIUi9j2PZfHJj5tTvJoTL1SytqwJbSTpGd84GDI/b21Gmdag1SJse4B8vY9fiEutVpXezgc7VpkXEIJyGZM4bSw+qHu3jHahxVuDdfC5LJI6cM6iPoie1K9u0gKs7QLEWiTbmqDOZKucdRwnGWZULOn5qNUNf9pgnZpcMT66OAT1/Qdc+saN/+xGzgfGMfovLyVtFmsQHOoR/CxjdhXZlKG+nyJGADdQOliwyuR0E1m9ELxWktDRLmQqfz/wsAYmv1kuwLaETuXqdjLgersfjzd2vf6jFNmIF2nDEC1eDiKtyCXeybaXH2tyn+1qdFRA1J2NrMwgw4dE9LpQV6V88NyzlQ1zwJTVRn2r8+9KAYAHdJfu2d5BSrds3KiffI90MjUB3EhGa7YNtIChFrUX1HWJwfXEBMJbLNz07R0vzWEbCphwiSpjn2yQjtlAJb3Louud6i+4VMyDViTxlZH4du6ovKU5hjYF7s0dEGBnp+ghn X-Forefront-Antispam-Report: CIP:69.169.224.5;CTRY:US;LANG:en;SCL:1;SRV:;IPV:NLI;SFV:NSPM;H:b224-5.smtp-out.eu-central-1.amazonses.com;PTR:b224-5.smtp-out.eu-central-1.amazonses.com;CAT:NONE;SFS:(13230040)(704161411799003)(32142699015)(9140799003)(61400799027)(376014)(48200799018)(5063699009)(56012099006)(4143699003)(10067099003)(55112099003)(22082099003)(16102099003)(18002099003)(4113699003)(5113699003);DIR:OUT;SFP:1102; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: GYhzAWP1/GQ2UmMecoTgaLnWFvUpGTq1OhaGZY37GNXDLnveZ0VhWL5suiWqb4E05grqWzn7QeeXaotgMgzixXgDs+PsX3cmeVSIxeZ0L8Klu2RxtB2LzhW6L6LCuO4UXZXrQ+eGFabt5bnQStPAnGlKNbTuF1z4yiiHh44EVlx0yFt3Aj55GA0M+YhMbr2zKCnSqOsiwiU00PQ3PpznJcibQ0PB8uPuimymx9ioyvtXrChRcDNmI2oEgtmp7uATGMGj5U8A9jrML+lUqKBMc41e4nt/whx6Rx8FnuuM3KtA7/wTxl5CRrL++wxFKLbe0HPXxPK/5N6/c/n0odZ5Qe04bwn8cPCruwusVSqUukq5q4bTJNHNg4pjMRPjrDOCCYVxD7x92MIc4i3VOU0jGgjxxxvfn2ll8rDXrzE16lfylqOvXOc4aPppBGvyQI0/ X-ExternalRecipientOutboundConnectors: 0bc7f26d-0264-416e-a6fc-8352af79c58f X-Auto-Response-Suppress: DR, OOF, AutoReply X-OriginatorOrg: virtuozzo.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 06 Oct 2026 10:54:36.2008 (UTC) X-MS-Exchange-CrossTenant-Network-Message-Id: 3fb400df-9406-42cc-38d6-08df23983649 X-MS-Exchange-CrossTenant-Id: 0bc7f26d-0264-416e-a6fc-8352af79c58f X-MS-Exchange-CrossTenant-AuthSource: MI3PEPF00008559.eurprd05.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Anonymous X-MS-Exchange-CrossTenant-FromEntityHeader: Internet X-MS-Exchange-Transport-CrossTenantHeadersStamped: GV2PR08MB861741 Thank you for your contribution! Sashiko AI review found 4 potential issue(= s) to consider: - [Medium] usb-host: cpr_handed_off is set before the handoff outcome is kn= own and never cleared on close - [Medium] usb-host: target restarts URB reaping in post_load() before migr= ation is committed - [Medium] usb-host: per-device CPR handoff stops and restarts events for t= he whole libusb context - [Low] usb-host: commit message says .exit() closes the FD, but exit notif= ier only calls libusb_close() -- commit d075dcc6f67ba19d35e41dafb7069f178e496bbf Author: Andrey Drobyshev usb-host: hand off the device across cpr-transfer #VSTOR-137800 This patch makes the usb-host device hand off URB reaping together with the usbfs fd across cpr-transfer. The target stops reaping until post_load. The source stops reaping when it quiesces, restarts on resume after a failure, and skips device teardown at exit after a successful handoff. > diff --git a/hw/usb/host-libusb.c b/hw/usb/host-libusb.c > --- a/hw/usb/host-libusb.c > +++ b/hw/usb/host-libusb.c [ ... ] > +static int usb_host_cpr_quiesce(USBHostDevice *s, MigMode mode) > +{ > + if (usb_host_cpr_drain_xfers(s) < 0) { > + return -1; > + } > + if (mode =3D=3D MIG_MODE_CPR_TRANSFER) { > + usb_host_cpr_stop_events(); > + s->cpr_handed_off =3D true; > + } > + return 0; > +} [Severity: Medium] Is cpr_handed_off being set too early here? It is set from the vm-state FINISH_MIGRATE branch or from usb_host_pre_save(), before the outcome of the migration is known. The flag then means "handed off, awaiting outcome" rather than "handoff succeeded". The only place that clears it is usb_host_cpr_reissue(), which runs only when the VM resumes with cpr_drained set and s->dh non-NULL. Consider a failed or cancelled cpr-transfer where the VM stays paused, and the user then quits or does device_del. Both usb_host_exit_notifier() and usb_host_close() take the skip path: if (!s->cpr_handed_off) { usb_host_abort_xfers(s); ... usb_host_attach_kernel(s); } The source is still the only owner of the device in that case. Does this leave the interfaces claimed, skip libusb_reset_device(), and never rebind the host driver? In usb_host_close() the guest port also stays attached, and the iso rings are not freed. usb_host_close() also sets s->dh =3D NULL without clearing the flag. After that, usb_host_cpr_vm_state() returns early on !s->dh, so usb_host_cpr_reissue() can never clear it. Would a later reopen of the same USBHostDevice through autoscan then inherit cpr_handed_off =3D=3D true and cpr_drained? Could the flag be cleared in usb_host_close(), or the skip decision be based on a state that is only set once the migration has completed? [ ... ] > @@ -1344,10 +1365,17 @@ static void usb_host_exit_notifier(struct Notifie= r *n, void *data) > USBHostDevice *s =3D container_of(n, USBHostDevice, exit); > =20 > if (s->dh) { > + /* > + * Handed to new QEMU across cpr-transfer: do not reset, release > + * interfaces or rebind the host driver underneath it; just close > + * our handle. > + */ > + if (!s->cpr_handed_off) { > + usb_host_abort_xfers(s); > + usb_host_release_interfaces(s); > + libusb_reset_device(s->dh); > + usb_host_attach_kernel(s); > + } > libusb_close(s->dh); > } > } [Severity: Low] This isn't a bug, but the commit message says "On success the source's .exit() leaves the device untouched ... and just closes its own copy of the FD." usb_host_exit_notifier() only calls libusb_close(s->dh). That does not close the application-owned usbfs fd of a libusb_wrap_sys_device() handle. s->hostfd is closed only in usb_host_close(). Could the message be corrected? The message also says "The source stops reaping in .pre_save()". Normally this happens in the vm-state handler through usb_host_cpr_quiesce(). pre_save only does it as a fallback when the VM was already paused. [ ... ] > @@ -2000,6 +2042,7 @@ static int usb_host_post_load(void *opaque, int ver= sion_id) > * rescan in usb_host_post_load_bh() -- those are for cross-host mig= ration. > */ > if (cpr_is_incoming()) { > + usb_host_cpr_restart_events(); > return 0; > } [Severity: Medium] Can the target start reaping too early here? The target calls usb_host_cpr_restart_events() when the device section is loaded, not when migration has completed. Suppose another device section fails to load, or the channel breaks, while the target is still alive. The source then resumes, and usb_host_cpr_reissu= e() calls usb_host_cpr_restart_events() on its side: if (s->cpr_handed_off) { usb_host_cpr_restart_events(); s->cpr_handed_off =3D false; } Both processes could then reap URB completions on the shared usbfs fd. That is the isochronous wedge this patch is meant to prevent. Is anything making the target's takeover conditional on the source having committed? This window is narrow and depends on the target surviving a failed migration. [ ... ] > +static void usb_host_cpr_stop_events(void) > +{ > + const struct libusb_pollfd **poll =3D libusb_get_pollfds(ctx); > + > + libusb_set_pollfd_notifiers(ctx, NULL, NULL, NULL); > + if (poll) { > + for (int i =3D 0; poll[i] !=3D NULL; i++) { > + usb_host_del_fd(poll[i]->fd, ctx); > + } > + free(poll); > + } > +} > + > +static void usb_host_cpr_restart_events(void) > +{ > + const struct libusb_pollfd **poll =3D libusb_get_pollfds(ctx); > + > + libusb_set_pollfd_notifiers(ctx, usb_host_add_fd, usb_host_del_fd, c= tx); > + if (poll) { > + for (int i =3D 0; poll[i] !=3D NULL; i++) { > + usb_host_add_fd(poll[i]->fd, poll[i]->events, ctx); > + } > + free(poll); > + } > +} [Severity: Medium] Do these helpers act on more than the one device being handed off? Both call libusb_set_pollfd_notifiers(ctx, ...) and walk all of libusb_get_pollfds(ctx) on the static libusb context, while they are driven from per-device hooks (usb_host_realize(), usb_host_post_load(), usb_host_pre_save() and the vm-state handler) and the handoff state (cpr_handed_off) is per device. With more than one hostdevice=3D usb-host device: On the target, the first device's usb_host_post_load() calls usb_host_cpr_restart_events() and re-enables reaping for every device, including devices whose post_load has not yet run and whose source side may not be handed off. On the source, the first device's usb_host_cpr_reissue() after a failure restarts events for devices that are still handed off. While the notifiers are NULL, fds of devices realized or hot-added in that window are never registered either. Is the multi-device case intended to be supported? The conditional blocker added later in the series ("usb-host: make CPR migration blocker conditional") still seems to allow several hostdevice=3D devices with ids. [ ... ] > @@ -1455,6 +1489,14 @@ static void usb_host_realize(USBDevice *udev, Erro= r **errp) > error_setg(errp, "failed to open host usb device %s", s->hos= tdevice); > return; > } > + if (cpr_is_incoming()) { > + /* > + * The source still owns the shared fd until it hands off. = Don't > + * reap URBs on it yet, or we would steal the source's in-fl= ight > + * completions; .post_load() restarts events once we take ov= er. > + */ > + usb_host_cpr_stop_events(); > + } In usb_host_realize() on the target, does this disable event handling for the whole libusb context whenever any hostdevice=3D device is realized? See the previous comment on usb_host_cpr_stop_events(). --=20 Sashiko AI review =C2=B7 https://sashiko.vzint.dev/#/patchset/20261006-usb-= host_v3-v6-0-8688ec9576d1@virtuozzo.com?part=3D8