Received: by 2002:a05:6a10:1287:0:0:0:0 with SMTP id d7csp3718506pxv; Mon, 26 Jul 2021 10:09:29 -0700 (PDT) X-Google-Smtp-Source: ABdhPJwIfmg5SL9+OaH01yl8MdS8hOouHNF04ipWgrDJ3vWw8FvNsQ+aLhp49giqesrqCmpIeuew X-Received: by 2002:a17:906:cec1:: with SMTP id si1mr18041900ejb.18.1627319369208; Mon, 26 Jul 2021 10:09:29 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1627319369; cv=none; d=google.com; s=arc-20160816; b=tGKJ1M1iNdHjJVytxvpysBcRBQL+lwJPYqYo2mezowETvE4a3S/PMt6mL9u3fhnKM1 nkfl+LTrQ2KLXRR/n81fVWnI+HpLxzcn1i8Xz/APMbBMgxlDTN+tBYxhC4n9nAXrXqNI WZShKf2KJauTnZrWOdvxbzx2KCf/ig8cVAazMlQ2R7abULAEtIVXKdDkd7/j10M/zm+q ttdAvjyDO/uIWkcZ+3nC0hrZiGB1Qe7WoiFCOOHTMTgU55LtLR0hQEXspTJ81+r6yCW0 qVNDHWBEMgStI/O/HfJWj8wD/oUkVx/cf7wxJGKy9Jkd2kFwET3jYKCXEzxzQFigdvcK 6lVA== 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=OVum1fTBUs2O0ZEZCK3pEDAoBluksW1MfEedv0ZWSxY=; b=PO1pf5SYsURPZcbiVaaiAWhrT7CKt8Uqj7L48rVJfZpI+LWaN+6JDOVnor8xwyv/XT OENnLVAiV/2knICS+voSpktQVe68+ByqupfwdyBnQqxOp3NbLkRzNMx5s2q9hGqlzKBT bhQvHqkncTa7O49wWZJ8OJ2Ug5qgtF2COM0mvi15EwtkMncRIKzcw5L69lqGukZaYhfF tSjm/dyCjTB85hfemz8Pw9igQiJe3Q8OzGkbtFmWw0P/LFhqKSSelZKIVUb98C8Ilmjh YhoKA/Ct3XQJq2an+Ix0sgZuCDMYmpF36SMwWNms70NlJsvxrJp2lG2kRaHxXjntU/Cz UrUQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linuxfoundation.org header.s=korg header.b=jJTRhJP4; 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 bl4si539489ejb.17.2021.07.26.10.09.06; Mon, 26 Jul 2021 10:09:29 -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=jJTRhJP4; 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 S238533AbhGZPnZ (ORCPT + 99 others); Mon, 26 Jul 2021 11:43:25 -0400 Received: from mail.kernel.org ([198.145.29.99]:39848 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S237984AbhGZPYa (ORCPT ); Mon, 26 Jul 2021 11:24:30 -0400 Received: by mail.kernel.org (Postfix) with ESMTPSA id B50CB60240; Mon, 26 Jul 2021 16:04:57 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=linuxfoundation.org; s=korg; t=1627315498; bh=mnj6/nMHSkzSa5oVj/k2KRf5LjmK7tEvyMJxrO3dIGA=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=jJTRhJP4/Xel/xpnhVcndGK12xwip5o9fXHzRdGyIJ+zlHozQ6YCik/zxkNe8ni8G JbIRGsorR8pOGPuFSfZY+5eX6sL6qbA4AKcLN+CQT1Erq/T+tZuc24U9Am77uO6r6i hfSBte1QkhFiRqU9O2/0bVqnlFwla+DkmcAFp2MY= From: Greg Kroah-Hartman To: linux-kernel@vger.kernel.org Cc: Greg Kroah-Hartman , stable@vger.kernel.org, Mathias Nyman Subject: [PATCH 5.10 121/167] usb: hub: Disable USB 3 device initiated lpm if exit latency is too high Date: Mon, 26 Jul 2021 17:39:14 +0200 Message-Id: <20210726153843.467430768@linuxfoundation.org> X-Mailer: git-send-email 2.32.0 In-Reply-To: <20210726153839.371771838@linuxfoundation.org> References: <20210726153839.371771838@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 @@ -4041,6 +4041,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. * @@ -4112,20 +4153,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.