From nobody Sun Jun 14 01:34:13 2026 Received: from mail-ej1-f49.google.com (mail-ej1-f49.google.com [209.85.218.49]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id C2E6F3E5576 for ; Mon, 4 May 2026 23:33:27 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.218.49 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1777937609; cv=none; b=aE6f5uVHjywATmantZWHESfM4eTB66Z4N9MqIY0dbwo2zhoDiYdKLBETNwgLkyF43osHsR4IqmEPJMSmTlhku9uRipNkyPVKYcvz/aENHKLqYkRIc9OxlMSmtbiRTum29bmn2V1//d34WNtXTQm6P0ZRe94C4Hq2rcLgjGXgQ6A= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1777937609; c=relaxed/simple; bh=wBRGmUyg6AVY/P/huNlzwdKpZmMnbjemwy3fA1SZKVA=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=NmOtVF9Ad6n1lgQsozpKOCxjrmxIsdcxRB8lqEczsXKt7lYx6NMfFc3q1RNoBQypdxgEbE76Ig6PZCo106ob2AtMzZhCfJ7HbVmiHLtPWg87WlS43+pFZBl3vPbL54sIzGbpDmt14ykDdlrJPHJK7FS1App33E4hq1EE1PT11vs= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=ECKpI/ne; arc=none smtp.client-ip=209.85.218.49 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="ECKpI/ne" Received: by mail-ej1-f49.google.com with SMTP id a640c23a62f3a-b9358bc9c50so711376366b.1 for ; Mon, 04 May 2026 16:33:27 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1777937606; x=1778542406; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=wK3MLCAgm2Nv519XuQTCTxz0g9HZ6PHRaUPNahte4HE=; b=ECKpI/ne7BFTLK4kNG4w63dUIxnrBi21N5D602gk95IfpGlkm0xLGZ7Xz73/LlNRV+ woh9vJQMmKFteMkivOraGc+mrqOHNXW8WpNIfF9cswK8doq2iFE5JGd6yX2pugDfnbc/ 7UZIKl1MVvFouxyeicsFVSKJT8vPURaLUFMC468Ay57NerpW0Py50Mb8Mu9Ke900YWXe I066ItEjjYWH+530e7gOqcVr+cyxI5br+++xQCF+aAyZZ2EfQM3AIgokVMMCPnR5HkVp K1yiXjIGFszocfbQWe71hnrIG1//AjBf0H1JzhHFEQCRD/xok9cT05wOrVA3zk4FwA0L z6bg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1777937606; x=1778542406; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to; bh=wK3MLCAgm2Nv519XuQTCTxz0g9HZ6PHRaUPNahte4HE=; b=cei5q9rbD9GhlgCsU06xFZmAXxayC3ju02o1AAumTmvN/v+LlzZp57c8Ev9ce2XorZ GMh9tLNMnEQAUPOe4tKgvQIRZzx0AVQr3xr7OQjrxB1KOAq+M06+OnmQiBgQ0VI5qo+i /ArW/JJ1/FgIcuSc7nFJmPBiWb5zL3dUPOAm+VkJqWUc0XVrGCHmrOlPQBVCI13N7zgi /PgFk0nJuwmWTABQC1dyheH0/nYMFkDxj6hIE8M7k0YDjVRDI6D12mclo6Wn6c/emjM3 RXgUVJuu9vuinS/2M7Fr2heF4DraYDKhImdC+KVcu2wXHLLknc2V4KCxGZEUdJ3W5zAz Zc/g== X-Forwarded-Encrypted: i=1; AFNElJ8zUYVoM5znlVcYwRVbD58SpkPnnpK23fuqeflqCtPDpcw9UTieRtmAfCYHSEaRLoiNEcxpK0Xzfy/Xo1k=@vger.kernel.org X-Gm-Message-State: AOJu0YzpKzbE/IT6jzSGMtOMk2VqmyxYwTZXtTS9G32sPk42h75pE+ja G6B+XdfzIcXT6j1efxLWvnW555yYp3VdkGoBned1kJFBvPGORGWgwG49 X-Gm-Gg: AeBDiet6Ez9DlzfoC5nbJbb7vAvyEX6zKDaTk+2BOgON096/5J8b6qr2dJ0+7b71J/d 0soAekYqgvqxPwt+oFs6Xsv2hjks50cJpWkBHP1pU0SlDA22+iax3lG7wc4UC5V5d4J4NPm+EMM KR2tCoCPKVEupzJbIXwly+L1MtKsXfmXPwtZaF0hoHZ3VOiCMf29D8vN60LKdKVkCExpg2lUioO r8EK+StETk9OAvTqK/6ow5NJRHJmW69toVuu3S8D2SBibJzyXEKiMihDVrsPlsy056hiaNKkwAz 3tb/zePnm4A/tWh+AHsoAi1UJAScf8oqqbOiZFOERKzxoeWPR75QJninLiVyDcbbbHADBOZyEhs 85/XpSeBuRB07NmUpd/HdaaLdgNlHF0/gj8Ma1R5ptdM32PAo4Nz4msrWKsA21+GxtMBWmyUDbJ nDAP6UDgMQtQbd/lA21y9NCkZmA9iK/75BEM2cYtwgySLjwVNdpoSMM5oEP+W5Ufov6RS+BDbXv MsrC/8cfrFMnMb7G//MlYUAGisXOC+QkwFBuFcEGLZ6wgEk3Z5c7w3+JwjxQCW2UY+B X-Received: by 2002:a17:907:a394:b0:bc1:6ec9:453a with SMTP id a640c23a62f3a-bc16ec95251mr420905366b.20.1777937606009; Mon, 04 May 2026 16:33:26 -0700 (PDT) Received: from nick-GTR-Pro.arnhem.chello.nl (2001-1c00-3281-1680-7a55-36ff-fe02-cdba.cable.dynamic.v6.ziggo.nl. [2001:1c00:3281:1680:7a55:36ff:fe02:cdba]) by smtp.gmail.com with ESMTPSA id a640c23a62f3a-bbe6aa4d524sm445224366b.26.2026.05.04.16.33.24 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 04 May 2026 16:33:25 -0700 (PDT) From: Nicola Lunghi To: mathias.nyman@intel.com, michal.pecio@gmail.com, niklas.neronin@linux.intel.com, gregkh@linuxfoundation.org Cc: linux-usb@vger.kernel.org, linux-kernel@vger.kernel.org, Nicola Lunghi Subject: [PATCH 1/2] usb: xhci: fix isoc silent reschedule creating stream gap on CFC controllers Date: Tue, 5 May 2026 01:31:43 +0200 Message-ID: <20260504233143.10242-3-nick83ola@gmail.com> X-Mailer: git-send-email 2.51.0 In-Reply-To: <20260504233143.10242-2-nick83ola@gmail.com> References: <20260504233143.10242-2-nick83ola@gmail.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable xhci_get_isoc_frame_id() silently rescheduled the first TRB to start_frame_id+1 when the requested start frame was out of the valid scheduling window or landed exactly on its boundary. This creates an explicit one-frame hole in the isochronous stream. Most USB audio devices tolerate a brief gap with a small glitch and recover automatically. However, some devices assume that once isochronous packets start streaming they flow continuously until the stream is explicitly stopped. Any gap causes the device firmware to permanently lose channel synchronization =E2=80=94 subsequent packets are routed to the wrong output channels until the device is reset. This was observed with the MOTU 1248 (USB ID 0x07fd:0x0005), where after a gap the 24-channel output stream shifts by a fixed number of channels, mapping audio intended for ch1/ch2 onto ch7/ch8 or other channel pairs depending on timing. Return -EINVAL instead so the caller falls back to TRB_SIA (Schedule Immediately After), which lets the hardware place the TRB right after the previous one without introducing a frame-aligned gap. Link: https://bugzilla.kernel.org/show_bug.cgi?id=3D220748 Assisted-by: Claude:claude-sonnet-4-6 sparse checkpatch Signed-off-by: Nicola Lunghi --- drivers/usb/host/xhci-ring.c | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c index e47e644b296e..03e47db82092 100644 --- a/drivers/usb/host/xhci-ring.c +++ b/drivers/usb/host/xhci-ring.c @@ -4030,15 +4030,21 @@ static int xhci_get_isoc_frame_id(struct xhci_hcd *= xhci, ret =3D -EINVAL; } =20 + /* + * If the first TRB's start frame is out of the scheduling window or + * lands exactly on its boundary, fall back to SIA (Schedule Immediately + * After) rather than forcing start_frame_id+1. A forced +1 creates an + * explicit one-frame hole that audio devices with strict continuity + * requirements cannot recover from. The caller handles -EINVAL by + * leaving sia_frame_id as TRB_SIA. + */ if (index =3D=3D 0) { if (ret =3D=3D -EINVAL || start_frame =3D=3D start_frame_id) { - start_frame =3D start_frame_id + 1; - if (urb->dev->speed =3D=3D USB_SPEED_LOW || - urb->dev->speed =3D=3D USB_SPEED_FULL) - urb->start_frame =3D start_frame; - else - urb->start_frame =3D start_frame << 3; - ret =3D 0; + xhci_dbg(xhci, "isoc: start frame %d %s window [%d, %d], using SIA\n", + start_frame, + ret =3D=3D -EINVAL ? "behind" : "at boundary of", + start_frame_id, end_frame_id); + return -EINVAL; } } =20 --=20 2.51.0 From nobody Sun Jun 14 01:34:13 2026 Received: from mail-ej1-f45.google.com (mail-ej1-f45.google.com [209.85.218.45]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id F1A6D3DD539 for ; Mon, 4 May 2026 23:33:31 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.218.45 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1777937613; cv=none; b=dXWDnkf6Kniu8SKyUAD+szxsgAeHKpPA6t6icbnDqjB2UYv19dcZnaszZLkOdnlZzcwfp1E0YKo9F89S9X6MNLs1nzPyFwW7CqSYmKg1+F8rfpcLJcNK+FjBN2vGHRCwNRg2Piro/2+EsavivEWZJKJdbUMz/YeKxdcnTJx2eQg= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1777937613; c=relaxed/simple; bh=bqRrm3879Svv52QqYWelCIlsClvl8DNCQvOp2/0bjWA=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=DvUABmeLjGAdrnAC0XxCuUA0yAK+U9sBRTICC7wXHOSEw8FLSPCOHyzQg1f+PLesW3mZgJM5xivDRTCbEOsV83KvGNxd/e86MedsLLVVnJelTJMaIQpBymVDpMnFLdNS0WsOJ6WLV+GHxQudCRffS6zxlIgPUZZKMFNOFpQ6av8= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=LSR0uRjZ; arc=none smtp.client-ip=209.85.218.45 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="LSR0uRjZ" Received: by mail-ej1-f45.google.com with SMTP id a640c23a62f3a-bc1f0830f44so262812466b.0 for ; Mon, 04 May 2026 16:33:31 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1777937610; x=1778542410; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=2/yyOFGwhnkUdJViXV/uZtVhX9EjoCfTIEWlX83FbgY=; b=LSR0uRjZFUCH5m/JCJFDxatLaXXOBPnyJ55EylZ2AKKdY8d3ZEu9T0eHlxSKKWQ+By PIgvo28z4IKF9f9mV8RFkTVJ3k/xs8TM6vp+bjQTG+lExAmTH5jlfOuW0/+EaGFvIRt4 Wt4B8Hdj4QumJh/MikjGDvr7oGcwv49WzJByB/bxXbCCpcOF9fb5iw77YFER8Lkan7S8 iinMIFGpViI6jvaINp1U242YmoiUJAWmaR7EKnY5byILp4np2bHJvMfJEn1RpwVasqzh 6XZUwMozIFpDngQchq4p4RQMX3/7lXOAVIgyjyp/77hPNm4c8nfgY+dfcF6dyomme7e9 vONQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1777937610; x=1778542410; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to; bh=2/yyOFGwhnkUdJViXV/uZtVhX9EjoCfTIEWlX83FbgY=; b=Msa4KysLobMDBbDXCscHt7nAqkVlSbVyXt0w69lxhLXZJZQMjmfevoywJqX+6cDBTu iio1gWcD7lpqirQ7vcCNFH/A+6jj+Oy02gF9veC3xvZf9ZUeIhW/0xLZFFc5EqWJBj8C zpLnJ4mNN1Smi7Z9AFKOXzprx7SvpSd4f/fBgFn31SE+t0QJjFJT/gTSD593yLw+TjSV koEyiVOzZWI4SjIx6ChakdPDB0F4cwbrzpvFeuWuXbc3xD/oFYSeW3Ik30z3muEWvxFT mO8z1Qgj2d4VzGF5abO2aJUt9zlCK/+xX58Viz7M0VUs8HQ6eCDDzKIpLjzKVbXrpNYt 8DQw== X-Forwarded-Encrypted: i=1; AFNElJ+khCQ7DX8dE50l8dH5el81dtLy9g2cQs3qLotdtcmYw59cshH2TozUFnphD6xx7Yn3PsOpK+l/xwpRoV8=@vger.kernel.org X-Gm-Message-State: AOJu0YwMl1fVZx1Ex0/fL+cHW0I2kwQO4YrgPVnWwaEzfFhZ35+GW/k0 E3lhUl9Maw8uUitfVRu1U7x2hMqVmvbxT1QBN6BISUHY9fNfwRPtGHjU X-Gm-Gg: AeBDieuqfX91PyJg5QoeBnmB35/K9gacIw+/2Lhk49YLitkcFiYAjkJH4AD50Q9NuRm HUwh4LgwGOICo20pKsgfSlwsrqpPdhqUo+AKPDcgSk8VTfa1KZQ3YHcFByDooMlgicimXcQ9uex lom0pSBeN3dT86bcdI1XRAhelDuJNsRcJn1mXr06sAiUfObGdD0zrOkdY2LKmgYBAnCii1KwxGC eugLZlLV8xYPWPc6jkNPdaCXPL4NF7e/O72apVpRnLizLDhD9dz7a4khfRn6bokxbnodfyunA7Q Mp+eXkS3kjgsFARPkr3U/9BfoHCSziX3qSDisVSPVbGKg6Ncc9L3Iluaq7oiT1fmBAzghCZf9a9 rrsdx4jWTU9mecHc5iHSaBgVNQ6wCvecImv18A6pm2Ly+cYlaOwys4iQUAUjw4zbyPcgzsfMTRg V6BneblUzZGeHlTXGutjliKC9RF97MoAR+SNpJOTvGU7E2Uw9E/u+j603SQPiCSKrC5xPpp+M4M XW/8YUc0B5L8b6zCuxk0fJ4O5+sXf5wdTzNxUc/bry4VSE5Ch2lkOzRwtbDTxu4joQ2 X-Received: by 2002:a17:907:6b89:b0:ba6:79c0:c743 with SMTP id a640c23a62f3a-bc3d1338a8amr86860966b.11.1777937610178; Mon, 04 May 2026 16:33:30 -0700 (PDT) Received: from nick-GTR-Pro.arnhem.chello.nl (2001-1c00-3281-1680-7a55-36ff-fe02-cdba.cable.dynamic.v6.ziggo.nl. [2001:1c00:3281:1680:7a55:36ff:fe02:cdba]) by smtp.gmail.com with ESMTPSA id a640c23a62f3a-bbe6aa4d524sm445224366b.26.2026.05.04.16.33.28 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 04 May 2026 16:33:28 -0700 (PDT) From: Nicola Lunghi To: mathias.nyman@intel.com, michal.pecio@gmail.com, niklas.neronin@linux.intel.com, gregkh@linuxfoundation.org Cc: linux-usb@vger.kernel.org, linux-kernel@vger.kernel.org, Nicola Lunghi Subject: [PATCH 2/2] usb: xhci: fix CFC sequential scheduling lost on ring drain race Date: Tue, 5 May 2026 01:31:44 +0200 Message-ID: <20260504233143.10242-4-nick83ola@gmail.com> X-Mailer: git-send-email 2.51.0 In-Reply-To: <20260504233143.10242-2-nick83ola@gmail.com> References: <20260504233143.10242-2-nick83ola@gmail.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable On CFC-capable xHCI controllers, xhci_queue_isoc_tx_prepare() uses next_frame_id for sequential isochronous scheduling only when the endpoint ring is non-empty and the endpoint is running. If all TDs are returned before the next URB is submitted (a ring drain race made more likely by fast TD-skip on xHCI 1.1+ controllers), the condition fails and the URB is scheduled ASAP =E2=80=94 potentially many frames ahead of wh= ere the stream should continue, creating a gap. Extend the condition to also use next_frame_id when a periodic completion is in progress for the endpoint, covering the transient window where the ring is empty but the stream has not actually stopped. Guard with URB_ISO_ASAP to preserve explicit ASAP scheduling. Link: https://bugzilla.kernel.org/show_bug.cgi?id=3D220748 Assisted-by: Claude:claude-sonnet-4-6 sparse checkpatch Signed-off-by: Nicola Lunghi --- drivers/usb/host/xhci-ring.c | 22 ++++++++++++++++------ 1 file changed, 16 insertions(+), 6 deletions(-) diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c index 03e47db82092..116a2dcd0bb2 100644 --- a/drivers/usb/host/xhci-ring.c +++ b/drivers/usb/host/xhci-ring.c @@ -4308,14 +4308,24 @@ int xhci_queue_isoc_tx_prepare(struct xhci_hcd *xhc= i, gfp_t mem_flags, */ check_interval(urb, ep_ctx); =20 - /* Calculate the start frame and put it in urb->start_frame. */ - if ((xhci->hcc_params & HCC_CFC) && !list_empty(&ep_ring->td_list)) { - if (GET_EP_CTX_STATE(ep_ctx) =3D=3D EP_STATE_RUNNING) { - urb->start_frame =3D xep->next_frame_id; - goto skip_start_over; - } + /* + * Calculate the start frame and put it in urb->start_frame. + * On CFC-capable controllers, use sequential scheduling from + * next_frame_id whenever the stream is running or a completion + * is in progress (ring transiently empty due to drain race). + * Skip this for explicit URB_ISO_ASAP requests. + */ + if ((xhci->hcc_params & HCC_CFC) && + !(urb->transfer_flags & URB_ISO_ASAP) && + (!list_empty(&ep_ring->td_list) || + hcd_periodic_completion_in_progress(xhci_to_hcd(xhci), urb->ep))) { + urb->start_frame =3D xep->next_frame_id; + goto skip_start_over; } =20 + xhci_dbg(xhci, "isoc: CFC sequential skipped for slot %u ep %u (ring_empt= y=3D%d), using ASAP\n", + slot_id, ep_index, list_empty(&ep_ring->td_list)); + start_frame =3D readl(&xhci->run_regs->microframe_index); start_frame &=3D 0x3fff; /* --=20 2.51.0