Received: by 2002:a05:6a10:1287:0:0:0:0 with SMTP id d7csp3697576pxv; Mon, 26 Jul 2021 09:38:28 -0700 (PDT) X-Google-Smtp-Source: ABdhPJzltXNl57rbfOFdz0+91nHjdVE/T1PmmY6RVv5IdqIv4dUHTXHOVHa9fMJ78HMkBHIBL5Ka X-Received: by 2002:aa7:d353:: with SMTP id m19mr23411295edr.162.1627317508114; Mon, 26 Jul 2021 09:38:28 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1627317508; cv=none; d=google.com; s=arc-20160816; b=XYNXB/LyuNWI7aUatNmGYeL8j4qDCD+4WE6YbXxCsGmS+Hr4DU0WTp9tT+4FqdB7WQ GbzMpcsNH/ZbygbU4czsTWkeeIAmnapSQQSugTQmvC0i1q4K/Xrnn0c7z136WZruWLvE D0fndRnTI9608A4cdV+dFBT2G6WI9dBZvJP4OkJmM1EXW2sdJylmWUewIg1TzDBeVUTV UF/xspyY8kIMrnVup2YjIVFJ5ofW1B/ey3d7yrIoaCj2yzPQLTZ8hlA+AAtGa4MQv0e5 bzlX4twq89eY18a0v8DPFhlP5VYA67Kzev6tdTeExxXGdyS3dY92BrtRQYARuQrYEP5Y 0HYQ== 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=dnICHAWbnBYO6q91GqFduvxUiDW+9B43DLJjbB6dUTA=; b=RW02XZXAcF3gjZah6PWOEfJNaoVfXxyHSf+vhcAAqr3spb4EtQ6of6SU0kTC1/L3ML fKC6oK06Nb3pM0IJNZXi63ZsDWYObgN8BnKhND2xD2Jpsa07ffZUIva1bNwW7TV82Fok kyywvNT+O1JtKqWXeLFyzzxJ1JRTOR0IzqYj/MBTRHCSkxzlaQ4WlVDopBULao4Kk8bq k+HBD1Pxch0F3cRZyeOWgItBLfMUEmpKRpfmEHNZePzJbMwNAdkER/7v3P7gIGAxmqpx LtA0v7GcHwXMJY/vUPIwaxvEmJkjk5zxFyBCoWvqKbJtv065rXdvtJvhGbNoCcvMr8DP hsHQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linuxfoundation.org header.s=korg header.b=LbNVmgsG; 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 t11si350927ejd.8.2021.07.26.09.38.05; Mon, 26 Jul 2021 09:38:28 -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=LbNVmgsG; 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 S239869AbhGZPyb (ORCPT + 99 others); Mon, 26 Jul 2021 11:54:31 -0400 Received: from mail.kernel.org ([198.145.29.99]:49816 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S234281AbhGZPdV (ORCPT ); Mon, 26 Jul 2021 11:33:21 -0400 Received: by mail.kernel.org (Postfix) with ESMTPSA id 9008E60F5A; Mon, 26 Jul 2021 16:13:48 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=linuxfoundation.org; s=korg; t=1627316029; bh=x8tCLc27muwpogEJc6bh6d3dZ+ZtIKRzOH5nkYJr4Mk=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=LbNVmgsGM6BEXCqX5eIHCgP5sx30wHPKvg7zx7V6NBiMYgQE1GlUWx213iWnGLNDL Rs/tVXPtp9OQUfvOnp0NUJqdVpIKEuW4jLty6E95xV6jzdgR6czOU5IARB1mPXZXt1 +75i+40Qt+oM1tucWhaQnUI5QMT6Qgzuaj+7+MXs= From: Greg Kroah-Hartman To: linux-kernel@vger.kernel.org Cc: Greg Kroah-Hartman , stable@vger.kernel.org, Mathias Nyman Subject: [PATCH 5.13 161/223] usb: hub: Disable USB 3 device initiated lpm if exit latency is too high Date: Mon, 26 Jul 2021 17:39:13 +0200 Message-Id: <20210726153851.478748984@linuxfoundation.org> X-Mailer: git-send-email 2.32.0 In-Reply-To: <20210726153846.245305071@linuxfoundation.org> References: <20210726153846.245305071@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 @@ -4091,6 +4091,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. * @@ -4162,20 +4203,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.