Received: by 2002:a05:6a10:1287:0:0:0:0 with SMTP id d7csp3679321pxv; Mon, 26 Jul 2021 09:14:41 -0700 (PDT) X-Google-Smtp-Source: ABdhPJxD4qDeFUKQIuS5tX4tJ30i+06wlNRRfKIQhAzM2NDJHsKwwGbwnPJh0vt93IaKqKaZhdcY X-Received: by 2002:a92:280a:: with SMTP id l10mr13670141ilf.125.1627316081075; Mon, 26 Jul 2021 09:14:41 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1627316081; cv=none; d=google.com; s=arc-20160816; b=nWs/wEOvgcjlmNFKMZXaD2P1s5ffI64Ux2K845N7PFdz5pYbZfNcjMSYjURKCHVr3u kYLKpuIJwbx6h17yAtylTU7gaJzKuGBS5gXCNGfZVsPtzj+7RAs/EL7I5+zyEtFVzrGP d7t2Q+9Z/BXiDXfilmG7um4a6mTSslJbfmbe3BA4zrw1JtF1i++faJNKWR75jLak6Dnf R4iYO74EENf4PpsP2eDGCFsegAP83OAbv25YqgaBW84AVzMnwbMLwkoJBsLEhSp1fGWe rAh3C5Kw/ZTzwf9VYa0G59TNozU4uETjIZTBqJbUh5lMEyfCVibAcs2aIEf2dwgeafIr z/8w== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :user-agent:references:in-reply-to:message-id:date:subject:cc:to :from:dkim-signature; bh=ZugzdRtnIBrbgUyVSCmDzoWTTIqoifFRKKMf6ieDH0M=; b=sCdfeIin3Hx7jSbsSt+AagK1YgbmcdHtdHMlrr3THn5Tcc3igiuHllhbikVRJPTNxx 3CYfrOc7cRrE4UF1Si7NRpxKFklgUt2ym3vegDSfik4kF1u2iiQ8F6xJBCHNCqsiRUoS MJqoazq2tCvfMZPDm6HGWgmjg3AAL8NcDDlKE4wYCwm8EtV3d6RVwIsHmSkD0i9/pne3 BgAFJzhGTmFqNAG4pK5Ir7PjA0rInJzwc0W0WWjJhTqzvIPgSIRGeUvWTWRvUAdGsrGS Mi7UhpQGuEgU1frU5VyAx8Z6xG+7iILjBAAQ3sj/e0s3ayZERrle3c9BiNFhYAZaY6Md r9Qg== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linuxfoundation.org header.s=korg header.b=DKdS7tX+; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linuxfoundation.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id l3si246128iln.90.2021.07.26.09.14.29; Mon, 26 Jul 2021 09:14:41 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) client-ip=23.128.96.18; Authentication-Results: mx.google.com; dkim=pass header.i=@linuxfoundation.org header.s=korg header.b=DKdS7tX+; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linuxfoundation.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S233141AbhGZPcC (ORCPT + 99 others); Mon, 26 Jul 2021 11:32:02 -0400 Received: from mail.kernel.org ([198.145.29.99]:58254 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S236937AbhGZPRx (ORCPT ); Mon, 26 Jul 2021 11:17:53 -0400 Received: by mail.kernel.org (Postfix) with ESMTPSA id 2D4FD60F42; Mon, 26 Jul 2021 15:58:20 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=linuxfoundation.org; s=korg; t=1627315101; bh=zp7LGnjMMIR9x5k3zi1DMY0hDXLQ+vcT+EVLX2AU+pI=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=DKdS7tX+jqUVSFatdSPuWLE0zmbdoYIkb/dUaxPMfc2KLz3EjBc9hj1bP1hjsjQC5 WX7vVltEc1v1Xxo37FN3ZPCeP/5G8aEss5ed4pVsMqB440zZ8wNWyht5+yKktBCCrp g+DJxGqnIYKgGzFInFr99rqNEQh0fpaK3KSkwwaE= From: Greg Kroah-Hartman To: linux-kernel@vger.kernel.org Cc: Greg Kroah-Hartman , stable@vger.kernel.org, Mathias Nyman Subject: [PATCH 5.4 079/108] usb: hub: Disable USB 3 device initiated lpm if exit latency is too high Date: Mon, 26 Jul 2021 17:39:20 +0200 Message-Id: <20210726153834.211225004@linuxfoundation.org> X-Mailer: git-send-email 2.32.0 In-Reply-To: <20210726153831.696295003@linuxfoundation.org> References: <20210726153831.696295003@linuxfoundation.org> User-Agent: quilt/0.66 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Mathias Nyman commit 1b7f56fbc7a1b66967b6114d1b5f5a257c3abae6 upstream. The device initiated link power management U1/U2 states should not be enabled in case the system exit latency plus one bus interval (125us) is greater than the shortest service interval of any periodic endpoint. This is the case for both U1 and U2 sytstem exit latencies and link states. See USB 3.2 section 9.4.9 "Set Feature" for more details Note, before this patch the host and device initiated U1/U2 lpm states were both enabled with lpm. After this patch it's possible to end up with only host inititated U1/U2 lpm in case the exit latencies won't allow device initiated lpm. If this case we still want to set the udev->usb3_lpm_ux_enabled flag so that sysfs users can see the link may go to U1/U2. Signed-off-by: Mathias Nyman Cc: stable Link: https://lore.kernel.org/r/20210715150122.1995966-2-mathias.nyman@linux.intel.com Signed-off-by: Greg Kroah-Hartman --- drivers/usb/core/hub.c | 68 ++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 56 insertions(+), 12 deletions(-) --- a/drivers/usb/core/hub.c +++ b/drivers/usb/core/hub.c @@ -4023,6 +4023,47 @@ static int usb_set_lpm_timeout(struct us } /* + * Don't allow device intiated U1/U2 if the system exit latency + one bus + * interval is greater than the minimum service interval of any active + * periodic endpoint. See USB 3.2 section 9.4.9 + */ +static bool usb_device_may_initiate_lpm(struct usb_device *udev, + enum usb3_link_state state) +{ + unsigned int sel; /* us */ + int i, j; + + if (state == USB3_LPM_U1) + sel = DIV_ROUND_UP(udev->u1_params.sel, 1000); + else if (state == USB3_LPM_U2) + sel = DIV_ROUND_UP(udev->u2_params.sel, 1000); + else + return false; + + for (i = 0; i < udev->actconfig->desc.bNumInterfaces; i++) { + struct usb_interface *intf; + struct usb_endpoint_descriptor *desc; + unsigned int interval; + + intf = udev->actconfig->interface[i]; + if (!intf) + continue; + + for (j = 0; j < intf->cur_altsetting->desc.bNumEndpoints; j++) { + desc = &intf->cur_altsetting->endpoint[j].desc; + + if (usb_endpoint_xfer_int(desc) || + usb_endpoint_xfer_isoc(desc)) { + interval = (1 << (desc->bInterval - 1)) * 125; + if (sel + 125 > interval) + return false; + } + } + } + return true; +} + +/* * Enable the hub-initiated U1/U2 idle timeouts, and enable device-initiated * U1/U2 entry. * @@ -4094,20 +4135,23 @@ static void usb_enable_link_state(struct * U1/U2_ENABLE */ if (udev->actconfig && - usb_set_device_initiated_lpm(udev, state, true) == 0) { - if (state == USB3_LPM_U1) - udev->usb3_lpm_u1_enabled = 1; - else if (state == USB3_LPM_U2) - udev->usb3_lpm_u2_enabled = 1; - } else { - /* Don't request U1/U2 entry if the device - * cannot transition to U1/U2. - */ - usb_set_lpm_timeout(udev, state, 0); - hcd->driver->disable_usb3_lpm_timeout(hcd, udev, state); + usb_device_may_initiate_lpm(udev, state)) { + if (usb_set_device_initiated_lpm(udev, state, true)) { + /* + * Request to enable device initiated U1/U2 failed, + * better to turn off lpm in this case. + */ + usb_set_lpm_timeout(udev, state, 0); + hcd->driver->disable_usb3_lpm_timeout(hcd, udev, state); + return; + } } -} + if (state == USB3_LPM_U1) + udev->usb3_lpm_u1_enabled = 1; + else if (state == USB3_LPM_U2) + udev->usb3_lpm_u2_enabled = 1; +} /* * Disable the hub-initiated U1/U2 idle timeouts, and disable device-initiated * U1/U2 entry.