From patchwork Mon Apr 8 13:00:30 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mika Westerberg X-Patchwork-Id: 787144 Received: from mgamail.intel.com (mgamail.intel.com [192.198.163.12]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 867F36CDA8 for ; Mon, 8 Apr 2024 13:01:26 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=192.198.163.12 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1712581288; cv=none; b=YOkbMWmg1kLs4IqiJ7YlIYvRY+UbjaR6qrBSjpzw1KOU0yQ5dGJMip+U50DwB30UJwsmAfedVe4suU5YGQdLATeOT06pNGVWvks3u+BmYD8bYqidmYxhtn2EREZjskNjCt+2GFu9/xPl+Or/KzcUIGuwC0VI0PtieCMOxzMWoSI= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1712581288; c=relaxed/simple; bh=onkmaoZvkauW8Q4MGh3eVchFeNAmDaYgmCBvXuFcIGE=; h=From:To:Cc:Subject:Date:Message-ID:MIME-Version; b=KHmSI3ArpHRhtuKgkphw59u24t6/cCgZUtx5nVGMZZJZ8v6cQ7n+j2QRut0bFotl+KTPLhETuO0t6ZhfOVFh/YGKJXD15ecjuDNT86OOcELMpvCZ+PZpFNr14ylCdbky7neGIIJq5V6cijuHZ6i+kgbt+lhBMFq5JJcUO8fLu2M= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.intel.com; spf=none smtp.mailfrom=linux.intel.com; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b=DmsY9/4P; arc=none smtp.client-ip=192.198.163.12 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.intel.com Authentication-Results: smtp.subspace.kernel.org; spf=none smtp.mailfrom=linux.intel.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b="DmsY9/4P" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1712581286; x=1744117286; h=from:to:cc:subject:date:message-id:mime-version: content-transfer-encoding; bh=onkmaoZvkauW8Q4MGh3eVchFeNAmDaYgmCBvXuFcIGE=; b=DmsY9/4PUeBnv9CqrC3OJolvsHdFiwvpyAkX7PLM4eXaMS1s6qCKftmN vNK1X81BiN9/FClkUNRWBcBcchLuyDjng4CJl9iCwZzeKPEcthmKh8+ww 3GTFpds+xTkRBxX1pgLDh6LO2AV7liFYTLelfAKQI9Jl0JPtDhglTVrw/ sgDg6e7p3eYJ6eL6BlUxh/5njEp+IT5U75qKSsmviuVGMObau4l3LlEgI 9kBePzGmt2BJryupQN2WSR3odupaR3QLmdRocKNsuqobhi1FyOVz7Nfap KqciKI7UJjX6mVeofoUwgilhz28iwaKFS2GEeuYkCuJAg7GwYxzzVojDU g==; X-CSE-ConnectionGUID: MUS65IcYRHW87DwxT/fu+w== X-CSE-MsgGUID: p8dRn+lCT9mAGwf2iPy0Yg== X-IronPort-AV: E=McAfee;i="6600,9927,11038"; a="11630688" X-IronPort-AV: E=Sophos;i="6.07,186,1708416000"; d="scan'208";a="11630688" Received: from fmsmga001.fm.intel.com ([10.253.24.23]) by fmvoesa106.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 08 Apr 2024 06:00:35 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=McAfee;i="6600,9927,11037"; a="937091483" X-IronPort-AV: E=Sophos;i="6.07,186,1708416000"; d="scan'208";a="937091483" Received: from black.fi.intel.com ([10.237.72.28]) by fmsmga001.fm.intel.com with ESMTP; 08 Apr 2024 06:00:32 -0700 Received: by black.fi.intel.com (Postfix, from userid 1001) id CF6B924D; Mon, 8 Apr 2024 16:00:31 +0300 (EEST) From: Mika Westerberg To: Yehezkel Bernat , Michael Jamet , Lukas Wunner , Andreas Noever Cc: Gil Fine , linux-usb@vger.kernel.org, Mika Westerberg Subject: [PATCH 1/2] thunderbolt: Fix calculation of consumed USB3 bandwidth on a path Date: Mon, 8 Apr 2024 16:00:30 +0300 Message-ID: <20240408130031.51616-1-mika.westerberg@linux.intel.com> X-Mailer: git-send-email 2.43.0 Precedence: bulk X-Mailing-List: linux-usb@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 From: Gil Fine Currently, when setup a new USB3 tunnel that is starting from downstream USB3 adapter of first depth router (or deeper), to upstream USB3 adapter of a second depth router (or deeper), we calculate consumed bandwidth. For this calculation we take into account first USB3 tunnel consumed bandwidth while we shouldn't, because we just recalculating the first USB3 tunnel allocated bandwidth. Fix that, so that more bandwidth is available for the new USB3 tunnel being setup. While there, fix the kernel-doc to decribe more accurately the purpose of the function. Signed-off-by: Gil Fine Signed-off-by: Mika Westerberg --- drivers/thunderbolt/tb.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/drivers/thunderbolt/tb.c b/drivers/thunderbolt/tb.c index 3e44c78ac409..10e719dd837c 100644 --- a/drivers/thunderbolt/tb.c +++ b/drivers/thunderbolt/tb.c @@ -498,8 +498,9 @@ static struct tb_tunnel *tb_find_first_usb3_tunnel(struct tb *tb, * @consumed_down: Consumed downstream bandwidth (Mb/s) * * Calculates consumed USB3 and PCIe bandwidth at @port between path - * from @src_port to @dst_port. Does not take tunnel starting from - * @src_port and ending from @src_port into account. + * from @src_port to @dst_port. Does not take USB3 tunnel starting from + * @src_port and ending on @src_port into account because that bandwidth is + * already included in as part of the "first hop" USB3 tunnel. */ static int tb_consumed_usb3_pcie_bandwidth(struct tb *tb, struct tb_port *src_port, @@ -514,8 +515,8 @@ static int tb_consumed_usb3_pcie_bandwidth(struct tb *tb, *consumed_up = *consumed_down = 0; tunnel = tb_find_first_usb3_tunnel(tb, src_port, dst_port); - if (tunnel && tunnel->src_port != src_port && - tunnel->dst_port != dst_port) { + if (tunnel && !tb_port_is_usb3_down(src_port) && + !tb_port_is_usb3_up(dst_port)) { int ret; ret = tb_tunnel_consumed_bandwidth(tunnel, consumed_up, From patchwork Mon Apr 8 12:48:03 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mika Westerberg X-Patchwork-Id: 787145 Received: from mgamail.intel.com (mgamail.intel.com [192.198.163.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id E64CC6BFA9 for ; Mon, 8 Apr 2024 12:48:07 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=192.198.163.17 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1712580489; cv=none; b=NxoeK4dlUa6m5Ekez+EA152CIHEKI36tRTwr1jhnS27RRm7dL/of9B17D0dsaxFRz6o7mch7/EIZzTd4VtS/JhnrDUB0HgB8gedz8CozHFXpwsPsDEXL0OJ8epANFUMWF3vv42zwuxS6lMzNJV3P35bQtJM4TET2MTNULZSFK2s= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1712580489; c=relaxed/simple; bh=tcQY+L65bmhF7UovNVosDQjsP9ILz3Rb1zWcHkLKa78=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=WBclXK7JSW/A3ULYOdnIEcTnZ2Sqq/1Y82Wl4pksalJAulW6+KFLBAIQEEt9bYzL4pcFcmPfzqLQyH+mOGL6hKyMOWXgojYLydohh1t4gUKyG//fpHqPe5YYZKVEb6LQlNn2MCt4CrQcCahsY9YIPCDxiNYWxR+hTIj6I5Tao2Q= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.intel.com; spf=none smtp.mailfrom=linux.intel.com; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b=Yrj0hNvq; arc=none smtp.client-ip=192.198.163.17 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.intel.com Authentication-Results: smtp.subspace.kernel.org; spf=none smtp.mailfrom=linux.intel.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b="Yrj0hNvq" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1712580488; x=1744116488; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=tcQY+L65bmhF7UovNVosDQjsP9ILz3Rb1zWcHkLKa78=; b=Yrj0hNvq1FD2Sq31FTU0lLuFeT3oJoYQvqfes7+PEIWgglR+pbY0VkwQ X4ESn6+Kb7OYH8sS2jkba42iqpMzq2a9ODF8Uf25Kh9+Cf4Gnr20gtDZN 4ZeYmi96rSotaGxfjrFn+ZDD4nZZ9ynSfcYvoMnjR/wvVjc2kq7Cdu5Q6 hXMPllKeMRURjlGK4nReut+0vOmAG72zycVtiJLF39JC5H9WuKtHF3XMJ PY36PpcxI9oopOIj5w9CgGcjMlEmYJyr/tD39XhWW6AtBIkGdQdzk605A 2NA3Ws04MB+CLzQBsFoNikH6oTKTVdBKDc+UV3jej2RCPACR0NS/rbMn9 A==; X-CSE-ConnectionGUID: eHO257NzQwyQ1P3ssnkp8w== X-CSE-MsgGUID: yucwNryxQymoO9UUmNR2Ng== X-IronPort-AV: E=McAfee;i="6600,9927,11037"; a="7721280" X-IronPort-AV: E=Sophos;i="6.07,186,1708416000"; d="scan'208";a="7721280" Received: from fmsmga001.fm.intel.com ([10.253.24.23]) by fmvoesa111.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 08 Apr 2024 05:48:07 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=McAfee;i="6600,9927,11037"; a="937091419" X-IronPort-AV: E=Sophos;i="6.07,186,1708416000"; d="scan'208";a="937091419" Received: from black.fi.intel.com ([10.237.72.28]) by fmsmga001.fm.intel.com with ESMTP; 08 Apr 2024 05:48:04 -0700 Received: by black.fi.intel.com (Postfix, from userid 1001) id 1149B12C; Mon, 8 Apr 2024 15:48:04 +0300 (EEST) From: Mika Westerberg To: Yehezkel Bernat , Michael Jamet , Lukas Wunner , Andreas Noever Cc: Gil Fine , linux-usb@vger.kernel.org, Mika Westerberg Subject: [PATCH 2/2] thunderbolt: Avoid notify PM core about runtime PM resume Date: Mon, 8 Apr 2024 15:48:03 +0300 Message-ID: <20240408124803.12329-2-mika.westerberg@linux.intel.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20240408124803.12329-1-mika.westerberg@linux.intel.com> References: <20240408124803.12329-1-mika.westerberg@linux.intel.com> Precedence: bulk X-Mailing-List: linux-usb@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 From: Gil Fine Currently we notify PM core about occurred wakes after any resume. This is not actually needed after resume from runtime suspend. Hence, notify PM core about occurred wakes only after resume from system sleep. Also, if the wake occurred in USB4 router upstream port, we don't notify the PM core about it since it is not actually needed and can cause unexpected autowake (e.g. if /sys/power/wakeup_count is used). While there add the missing kernel-doc for tb_switch_resume(). Signed-off-by: Gil Fine Cc: stable@vger.kernel.org Signed-off-by: Mika Westerberg --- drivers/thunderbolt/switch.c | 27 +++++++++++++++++++++++++-- drivers/thunderbolt/tb.c | 4 ++-- drivers/thunderbolt/tb.h | 3 ++- drivers/thunderbolt/usb4.c | 13 +++++++------ 4 files changed, 36 insertions(+), 11 deletions(-) diff --git a/drivers/thunderbolt/switch.c b/drivers/thunderbolt/switch.c index 4edfd6e34e31..326433df5880 100644 --- a/drivers/thunderbolt/switch.c +++ b/drivers/thunderbolt/switch.c @@ -3448,7 +3448,26 @@ static int tb_switch_set_wake(struct tb_switch *sw, unsigned int flags) return tb_lc_set_wake(sw, flags); } -int tb_switch_resume(struct tb_switch *sw) +static void tb_switch_check_wakes(struct tb_switch *sw) +{ + if (device_may_wakeup(&sw->dev)) { + if (tb_switch_is_usb4(sw)) + usb4_switch_check_wakes(sw); + } +} + +/** + * tb_switch_resume() - Resume a switch after sleep + * @sw: Switch to resume + * @runtime: Is this resume from runtime suspend or system sleep + * + * Resumes and re-enumerates router (and all its children), if still plugged + * after suspend. Don't enumerate device router whose UID was changed during + * suspend. If this is resume from system sleep, notifies PM core about the + * wakes occurred during suspend. Disables all wakes, except USB4 wake of + * upstream port for USB4 routers that shall be always enabled. + */ +int tb_switch_resume(struct tb_switch *sw, bool runtime) { struct tb_port *port; int err; @@ -3497,6 +3516,9 @@ int tb_switch_resume(struct tb_switch *sw) if (err) return err; + if (!runtime) + tb_switch_check_wakes(sw); + /* Disable wakes */ tb_switch_set_wake(sw, 0); @@ -3526,7 +3548,8 @@ int tb_switch_resume(struct tb_switch *sw) */ if (tb_port_unlock(port)) tb_port_warn(port, "failed to unlock port\n"); - if (port->remote && tb_switch_resume(port->remote->sw)) { + if (port->remote && + tb_switch_resume(port->remote->sw, runtime)) { tb_port_warn(port, "lost during suspend, disconnecting\n"); tb_sw_set_unplugged(port->remote->sw); diff --git a/drivers/thunderbolt/tb.c b/drivers/thunderbolt/tb.c index 360cb95f39aa..3e44c78ac409 100644 --- a/drivers/thunderbolt/tb.c +++ b/drivers/thunderbolt/tb.c @@ -2942,7 +2942,7 @@ static int tb_resume_noirq(struct tb *tb) if (!tb_switch_is_usb4(tb->root_switch)) tb_switch_reset(tb->root_switch); - tb_switch_resume(tb->root_switch); + tb_switch_resume(tb->root_switch, false); tb_free_invalid_tunnels(tb); tb_free_unplugged_children(tb->root_switch); tb_restore_children(tb->root_switch); @@ -3068,7 +3068,7 @@ static int tb_runtime_resume(struct tb *tb) struct tb_tunnel *tunnel, *n; mutex_lock(&tb->lock); - tb_switch_resume(tb->root_switch); + tb_switch_resume(tb->root_switch, true); tb_free_invalid_tunnels(tb); tb_restore_children(tb->root_switch); list_for_each_entry_safe(tunnel, n, &tcm->tunnel_list, list) diff --git a/drivers/thunderbolt/tb.h b/drivers/thunderbolt/tb.h index feed8ecaf712..18aae4ccaed5 100644 --- a/drivers/thunderbolt/tb.h +++ b/drivers/thunderbolt/tb.h @@ -827,7 +827,7 @@ int tb_switch_configuration_valid(struct tb_switch *sw); int tb_switch_add(struct tb_switch *sw); void tb_switch_remove(struct tb_switch *sw); void tb_switch_suspend(struct tb_switch *sw, bool runtime); -int tb_switch_resume(struct tb_switch *sw); +int tb_switch_resume(struct tb_switch *sw, bool runtime); int tb_switch_reset(struct tb_switch *sw); int tb_switch_wait_for_bit(struct tb_switch *sw, u32 offset, u32 bit, u32 value, int timeout_msec); @@ -1288,6 +1288,7 @@ static inline bool tb_switch_is_usb4(const struct tb_switch *sw) return usb4_switch_version(sw) > 0; } +void usb4_switch_check_wakes(struct tb_switch *sw); int usb4_switch_setup(struct tb_switch *sw); int usb4_switch_configuration_valid(struct tb_switch *sw); int usb4_switch_read_uid(struct tb_switch *sw, u64 *uid); diff --git a/drivers/thunderbolt/usb4.c b/drivers/thunderbolt/usb4.c index 9860b49d7a2b..78b06e922fda 100644 --- a/drivers/thunderbolt/usb4.c +++ b/drivers/thunderbolt/usb4.c @@ -155,7 +155,13 @@ static inline int usb4_switch_op_data(struct tb_switch *sw, u16 opcode, tx_dwords, rx_data, rx_dwords); } -static void usb4_switch_check_wakes(struct tb_switch *sw) +/** + * usb4_switch_check_wakes() - Check for wakes and notify PM core about them + * @sw: Router whose wakes to check + * + * Checks wakes occurred during suspend and notify the PM core about them. + */ +void usb4_switch_check_wakes(struct tb_switch *sw) { bool wakeup_usb4 = false; struct usb4_port *usb4; @@ -163,9 +169,6 @@ static void usb4_switch_check_wakes(struct tb_switch *sw) bool wakeup = false; u32 val; - if (!device_may_wakeup(&sw->dev)) - return; - if (tb_route(sw)) { if (tb_sw_read(sw, &val, TB_CFG_SWITCH, ROUTER_CS_6, 1)) return; @@ -244,8 +247,6 @@ int usb4_switch_setup(struct tb_switch *sw) u32 val = 0; int ret; - usb4_switch_check_wakes(sw); - if (!tb_route(sw)) return 0;