Received: by 2002:a05:6a10:1287:0:0:0:0 with SMTP id d7csp3663429pxv; Mon, 26 Jul 2021 08:58:50 -0700 (PDT) X-Google-Smtp-Source: ABdhPJwMXzd8NgAJ1hAKHBkjgZufavGRcaz5kO46Qv0kSQtwlYSoccJg1cYoIzzBLlD89fdSl4y8 X-Received: by 2002:a17:906:d101:: with SMTP id b1mr835623ejz.424.1627315130307; Mon, 26 Jul 2021 08:58:50 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1627315130; cv=none; d=google.com; s=arc-20160816; b=aMDhUB7/VAltGr8dkaiRqEIX9AVw34OlgTG7ghgUlfMalQQhcdgzp3EVGfPlrxLtDA 2/2fCjNQ5endrAb7bJzStqifuLy44srvvcWsHaTMHM2sqVM1rR50tCviRMb0P6us5F9/ 267VmnWsdBQpyWwOQYEfxtQdKN/e5V/AvjYzuiOAsOdUh1MHC9s5Y6xj1QWjuLLtz2mV tS3hRqmPzFmk32ScnlaTKlThQG2cCGZm1AjpMOToEuP9CZ//F3Qbu+hidhElbtzlwWOv jgylFj2PRMk2moAjaKee0Zzc/4UNOmJ2KykbrShog0izeAIFgjyptWQMlN3FZeXw6Usq DRag== 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=rVfqwAOsV7+CVihR03Dcx+k9GkV952gimcdO1wYSllw=; b=0L5U2cN8G4OEcNaHtIl3FXPVZKd4JuPHKktDkS98T+c5LECLQreNREuWtASJOlt26d hjY3+WOk28NIbf9GMJ7VRs3EHEXSBaa4hN9cq9DyaQsoWUogjDfjs7fLAYAugnuAepOh PH4uioCgQZeNj3WHwv5AYTfSh1nKqXYWnFzGdhdgWCIgZufpj3WfNi1t75beGJAjx6WS imjKaBtZRj51PQq8WgCVdmdlXRDHOSzqtEW3zHXL8sE9Su7G3Lf1yTK6wXDJwCQFfzcK bidaoLNIZMBNuTlsv+MEIzjjirvIADd7H+nt/2EA9ZwTP1twE1A4n0P03hpHeHKFL5IM XA6w== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linuxfoundation.org header.s=korg header.b=vpGoxXii; 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 l27si263528eja.265.2021.07.26.08.58.27; Mon, 26 Jul 2021 08:58:50 -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=vpGoxXii; 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 S236721AbhGZPQ1 (ORCPT + 99 others); Mon, 26 Jul 2021 11:16:27 -0400 Received: from mail.kernel.org ([198.145.29.99]:48942 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S236424AbhGZPJJ (ORCPT ); Mon, 26 Jul 2021 11:09:09 -0400 Received: by mail.kernel.org (Postfix) with ESMTPSA id 9493E60F90; Mon, 26 Jul 2021 15:49:01 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=linuxfoundation.org; s=korg; t=1627314542; bh=Cwq+8dyJMvXzlZKPNdv7obyM9DWNnChKCNQHbIamU0I=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=vpGoxXiiIwV9vEA5i1EzFgaaBuds8Nmb4nQlLNVQKkZzDB7tXgQNSWMIPVepgvDfn Wi9fJYTOF6QoIXcmZcmQ9H77KZHR80KFvyiLMsvJvhBmtuilLdLOo3Po0s2CPaEbp+ Pym7WJyoOMX5yhbFio1nLwkrbTd9VyqRXCa/4+5Q= From: Greg Kroah-Hartman To: linux-kernel@vger.kernel.org Cc: Greg Kroah-Hartman , stable@vger.kernel.org, Mathias Nyman Subject: [PATCH 4.14 64/82] usb: hub: Disable USB 3 device initiated lpm if exit latency is too high Date: Mon, 26 Jul 2021 17:39:04 +0200 Message-Id: <20210726153830.251984163@linuxfoundation.org> X-Mailer: git-send-email 2.32.0 In-Reply-To: <20210726153828.144714469@linuxfoundation.org> References: <20210726153828.144714469@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 @@ -3904,6 +3904,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. * @@ -3975,20 +4016,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.