Received: by 2002:a05:6a10:2726:0:0:0:0 with SMTP id ib38csp2874557pxb; Mon, 4 Apr 2022 01:02:38 -0700 (PDT) X-Google-Smtp-Source: ABdhPJz4TsQtFLd78/uv3NB+zfHZ8SEAV0myEEM09NtXpyvKX1GfA85PGgV2n6SYCqhntXW45Kgh X-Received: by 2002:a17:907:ea1:b0:6df:7900:e4de with SMTP id ho33-20020a1709070ea100b006df7900e4demr9622120ejc.26.1649059358269; Mon, 04 Apr 2022 01:02:38 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1649059358; cv=none; d=google.com; s=arc-20160816; b=D5SL+R/3cjkjnaRm77zUhg8WmMVAGu+XhXmDyROgqdrUhBHea4FHBl0Pk2MM+cCT06 j+vhYxlglvJGIP5QjRbpQgOVrNboWhzNZy8n4yy8KQzP8nrqAXsni85hymziStUWWiiR k+Xaou1njbC+EcOS0gsSQRi1RO7wNJHrXJa+GIFjNhPK70fDqxtFfbJIl54VyBBYxkg1 Tj2k/zSqC4wSbvI9zM1dcc+2XyVXRIjP/LeOZMbfi4Rw5ukOwiOv6Q0k9lHwR8hnc+4a b80VfbE7kfKdeiA76wr83w0TiToaiDZvg6XW3LAiZjTzaa1UX00WOq1jlFCfCO1JM8dK Vm8g== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:organization:in-reply-to:content-disposition :mime-version:references:message-id:subject:cc:to:from:date :dkim-signature; bh=0/o8MO3sJWRtpv9ffwvB8l0v3QB6VHViB9amkmTvu0w=; b=YTakt10NTbrN7+W/uG7+m5CgHQUyT0L/1PM8ybAV5JYlAAeyo/7WID1csGBs4LkL/2 UsbAQdRxKVjoz3b/j+4X6RRieQY+pIVnPWq2Avd1Xjyk5kjSktT+higYKOzZTwCBq/VO LHkZR70McDJkvYzpF/pLyklUUN0YqPRSS2ZXz+Ztb8lWgAxkNYpb4JvN7cpz7mGtac2T wnlX5qpesUFRV0x8sDfuWUcscBA6G8bhqQwqqKnWeCse9b1xOs6T4NXt2KWo+dUIF665 rosPz+r3rkbU52Snsms0dZDhhgABD00wCIv5d9KqEBiO0QBy/EPN5cRD8mF62NK2eAZq oY1w== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@intel.com header.s=Intel header.b=bilfmuEb; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=intel.com Return-Path: Received: from out1.vger.email (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id y19-20020a056402441300b00419dbec993fsi8810028eda.374.2022.04.04.01.02.11; Mon, 04 Apr 2022 01:02:38 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) client-ip=2620:137:e000::1:20; Authentication-Results: mx.google.com; dkim=pass header.i=@intel.com header.s=Intel header.b=bilfmuEb; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=intel.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1347834AbiDAOl1 (ORCPT + 99 others); Fri, 1 Apr 2022 10:41:27 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:57788 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1348334AbiDAOeF (ORCPT ); Fri, 1 Apr 2022 10:34:05 -0400 Received: from mga17.intel.com (mga17.intel.com [192.55.52.151]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 6F855A1AE for ; Fri, 1 Apr 2022 07:32:15 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1648823535; x=1680359535; h=date:from:to:cc:subject:message-id:references: mime-version:in-reply-to; bh=k7HxpemhrLq5N2ZQgjZ7mmy9HYZQUpqKUE2w6lYdwrk=; b=bilfmuEb92Sx7iVrVG0GTyBsc9xuoezZ63AY6XL+UP1fvr77RdpjIi3X mTnceIUbHRat92lhBCmD6X8/SA3vby319mfwnoiuYy+t7mtTAiKFBlduD UpdskfS2UyH+20JTy+6duv56i6DL1JvsivGwB1nz60b5OdJkUit9gAazk IOZWQXgydz2NOsZfBij5vIOCppWju/aznn2vs+Akav9W25R5uTQIsgWnm eFm/tPY67WcBlAxN7vxwoqxaaWj5gqxUmdQ6Hnfm7WxMmhEaJGSlesn8d aPMqNwiKrgXnqO+abzH/VgYdeWBLPI2ois6E6M5eysGgT0DTtGAQlEBPN Q==; X-IronPort-AV: E=McAfee;i="6200,9189,10304"; a="240741472" X-IronPort-AV: E=Sophos;i="5.90,227,1643702400"; d="scan'208";a="240741472" Received: from orsmga007.jf.intel.com ([10.7.209.58]) by fmsmga107.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 01 Apr 2022 07:32:12 -0700 X-IronPort-AV: E=Sophos;i="5.90,227,1643702400"; d="scan'208";a="547818197" Received: from lahna.fi.intel.com (HELO lahna) ([10.237.72.162]) by orsmga007-auth.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 01 Apr 2022 07:32:10 -0700 Received: by lahna (sSMTP sendmail emulation); Fri, 01 Apr 2022 17:30:57 +0300 Date: Fri, 1 Apr 2022 17:30:57 +0300 From: Mika Westerberg To: Brad Campbell Cc: linux-kernel@vger.kernel.org Subject: Re: Apple Thunderbolt Display chaining Message-ID: References: <5dcee6f7-cc8c-e3ce-920c-4ad3f5d77e14@fnarfbargle.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <5dcee6f7-cc8c-e3ce-920c-4ad3f5d77e14@fnarfbargle.com> Organization: Intel Finland Oy - BIC 0357606-4 - Westendinkatu 7, 02160 Espoo X-Spam-Status: No, score=-4.3 required=5.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_EF,RCVD_IN_DNSWL_MED,SPF_HELO_NONE, SPF_NONE,T_SCC_BODY_TEXT_LINE autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Hi, On Fri, Apr 01, 2022 at 01:48:13PM +0800, Brad Campbell wrote: > That I can do. I didn't crop or grep as I wasn't sure what might be additionally relevant. > 2 machines, 2 ports, 4 cold boots. Each time just the Thnuderbolt displays chained. Thanks for the logs! It looks like the Apple EFI CM always uses the lane 1 adapter. Can you try the below patch? Fingers crossed that it solves the chaining issue for both ;-) I had to patch the test.c because otherwise unit tests fail to compile when enabled. This should now setup the second tunnel always through the lane 0 adapter and thus share the bandwidth equally between the two lanes. diff --git a/drivers/thunderbolt/tb.c b/drivers/thunderbolt/tb.c index 8c20a50cc9d9..1ca6fe67ba56 100644 --- a/drivers/thunderbolt/tb.c +++ b/drivers/thunderbolt/tb.c @@ -1065,7 +1065,7 @@ static void tb_recalc_estimated_bandwidth(struct tb *tb) static void tb_tunnel_dp(struct tb *tb) { - int available_up, available_down, ret; + int available_up, available_down, ret, link_nr; struct tb_cm *tcm = tb_priv(tb); struct tb_port *port, *in, *out; struct tb_tunnel *tunnel; @@ -1110,6 +1110,20 @@ static void tb_tunnel_dp(struct tb *tb) return; } + /* + * This is only applicable to links that are not bonded (so + * when Thunderbolt 1 hardware is involved somewhere in the + * topology). For these try to share the DP bandwidth between + * the two lanes. + */ + link_nr = 1; + list_for_each_entry(tunnel, &tcm->tunnel_list, list) { + if (tb_tunnel_is_dp(tunnel)) { + link_nr = 0; + break; + } + } + /* * DP stream needs the domain to be active so runtime resume * both ends of the tunnel. @@ -1142,7 +1156,8 @@ static void tb_tunnel_dp(struct tb *tb) tb_attach_bandwidth_group(tcm, in, out); - tunnel = tb_tunnel_alloc_dp(tb, in, out, available_up, available_down); + tunnel = tb_tunnel_alloc_dp(tb, in, out, link_nr, available_up, + available_down); if (!tunnel) { tb_port_dbg(out, "could not allocate DP tunnel\n"); goto err_detach_group; diff --git a/drivers/thunderbolt/test.c b/drivers/thunderbolt/test.c index 6f027b3c2efe..5884c616b047 100644 --- a/drivers/thunderbolt/test.c +++ b/drivers/thunderbolt/test.c @@ -1365,7 +1365,7 @@ static void tb_test_tunnel_dp(struct kunit *test) in = &host->ports[5]; out = &dev->ports[13]; - tunnel = tb_tunnel_alloc_dp(NULL, in, out, 0, 0); + tunnel = tb_tunnel_alloc_dp(NULL, in, out, 1, 0, 0); KUNIT_ASSERT_TRUE(test, tunnel != NULL); KUNIT_EXPECT_EQ(test, tunnel->type, TB_TUNNEL_DP); KUNIT_EXPECT_PTR_EQ(test, tunnel->src_port, in); @@ -1411,7 +1411,7 @@ static void tb_test_tunnel_dp_chain(struct kunit *test) in = &host->ports[5]; out = &dev4->ports[14]; - tunnel = tb_tunnel_alloc_dp(NULL, in, out, 0, 0); + tunnel = tb_tunnel_alloc_dp(NULL, in, out, 1, 0, 0); KUNIT_ASSERT_TRUE(test, tunnel != NULL); KUNIT_EXPECT_EQ(test, tunnel->type, TB_TUNNEL_DP); KUNIT_EXPECT_PTR_EQ(test, tunnel->src_port, in); @@ -1461,7 +1461,7 @@ static void tb_test_tunnel_dp_tree(struct kunit *test) in = &dev2->ports[13]; out = &dev5->ports[13]; - tunnel = tb_tunnel_alloc_dp(NULL, in, out, 0, 0); + tunnel = tb_tunnel_alloc_dp(NULL, in, out, 1, 0, 0); KUNIT_ASSERT_TRUE(test, tunnel != NULL); KUNIT_EXPECT_EQ(test, tunnel->type, TB_TUNNEL_DP); KUNIT_EXPECT_PTR_EQ(test, tunnel->src_port, in); @@ -1526,7 +1526,7 @@ static void tb_test_tunnel_dp_max_length(struct kunit *test) in = &dev6->ports[13]; out = &dev12->ports[13]; - tunnel = tb_tunnel_alloc_dp(NULL, in, out, 0, 0); + tunnel = tb_tunnel_alloc_dp(NULL, in, out, 1, 0, 0); KUNIT_ASSERT_TRUE(test, tunnel != NULL); KUNIT_EXPECT_EQ(test, tunnel->type, TB_TUNNEL_DP); KUNIT_EXPECT_PTR_EQ(test, tunnel->src_port, in); @@ -1604,7 +1604,7 @@ static void tb_test_tunnel_3dp(struct kunit *test) KUNIT_ASSERT_EQ(test, tunnel1->npaths, 3); KUNIT_ASSERT_EQ(test, tunnel1->paths[0]->path_length, 3); - tunnel2 = tb_tunnel_alloc_dp(NULL, in2, out2, 0, 0); + tunnel2 = tb_tunnel_alloc_dp(NULL, in2, out2, 1, 0, 0); KUNIT_ASSERT_TRUE(test, tunnel2 != NULL); KUNIT_EXPECT_EQ(test, tunnel2->type, TB_TUNNEL_DP); KUNIT_EXPECT_PTR_EQ(test, tunnel2->src_port, in2); @@ -1612,7 +1612,7 @@ static void tb_test_tunnel_3dp(struct kunit *test) KUNIT_ASSERT_EQ(test, tunnel2->npaths, 3); KUNIT_ASSERT_EQ(test, tunnel2->paths[0]->path_length, 4); - tunnel3 = tb_tunnel_alloc_dp(NULL, in3, out3, 0, 0); + tunnel3 = tb_tunnel_alloc_dp(NULL, in3, out3, 1, 0, 0); KUNIT_ASSERT_TRUE(test, tunnel3 != NULL); KUNIT_EXPECT_EQ(test, tunnel3->type, TB_TUNNEL_DP); KUNIT_EXPECT_PTR_EQ(test, tunnel3->src_port, in3); @@ -1709,7 +1709,7 @@ static void tb_test_tunnel_port_on_path(struct kunit *test) in = &dev2->ports[13]; out = &dev5->ports[13]; - dp_tunnel = tb_tunnel_alloc_dp(NULL, in, out, 0, 0); + dp_tunnel = tb_tunnel_alloc_dp(NULL, in, out, 1, 0, 0); KUNIT_ASSERT_TRUE(test, dp_tunnel != NULL); KUNIT_EXPECT_TRUE(test, tb_tunnel_port_on_path(dp_tunnel, in)); @@ -2091,7 +2091,7 @@ static void tb_test_credit_alloc_dp(struct kunit *test) in = &host->ports[5]; out = &dev->ports[14]; - tunnel = tb_tunnel_alloc_dp(NULL, in, out, 0, 0); + tunnel = tb_tunnel_alloc_dp(NULL, in, out, 1, 0, 0); KUNIT_ASSERT_TRUE(test, tunnel != NULL); KUNIT_ASSERT_EQ(test, tunnel->npaths, (size_t)3); @@ -2327,7 +2327,7 @@ static struct tb_tunnel *TB_TEST_DP_TUNNEL1(struct kunit *test, in = &host->ports[5]; out = &dev->ports[13]; - dp_tunnel1 = tb_tunnel_alloc_dp(NULL, in, out, 0, 0); + dp_tunnel1 = tb_tunnel_alloc_dp(NULL, in, out, 1, 0, 0); KUNIT_ASSERT_TRUE(test, dp_tunnel1 != NULL); KUNIT_ASSERT_EQ(test, dp_tunnel1->npaths, (size_t)3); @@ -2364,7 +2364,7 @@ static struct tb_tunnel *TB_TEST_DP_TUNNEL2(struct kunit *test, in = &host->ports[6]; out = &dev->ports[14]; - dp_tunnel2 = tb_tunnel_alloc_dp(NULL, in, out, 0, 0); + dp_tunnel2 = tb_tunnel_alloc_dp(NULL, in, out, 1, 0, 0); KUNIT_ASSERT_TRUE(test, dp_tunnel2 != NULL); KUNIT_ASSERT_EQ(test, dp_tunnel2->npaths, (size_t)3); diff --git a/drivers/thunderbolt/tunnel.c b/drivers/thunderbolt/tunnel.c index d08441f36e7a..08fddd469ab6 100644 --- a/drivers/thunderbolt/tunnel.c +++ b/drivers/thunderbolt/tunnel.c @@ -1086,6 +1086,7 @@ struct tb_tunnel *tb_tunnel_discover_dp(struct tb *tb, struct tb_port *in, * @tb: Pointer to the domain structure * @in: DP in adapter port * @out: DP out adapter port + * @link_nr: Preferred lane adapter when the link is not bonded * @max_up: Maximum available upstream bandwidth for the DP tunnel (%0 * if not limited) * @max_down: Maximum available downstream bandwidth for the DP tunnel @@ -1097,8 +1098,8 @@ struct tb_tunnel *tb_tunnel_discover_dp(struct tb *tb, struct tb_port *in, * Return: Returns a tb_tunnel on success or NULL on failure. */ struct tb_tunnel *tb_tunnel_alloc_dp(struct tb *tb, struct tb_port *in, - struct tb_port *out, int max_up, - int max_down) + struct tb_port *out, int link_nr, + int max_up, int max_down) { struct tb_tunnel *tunnel; struct tb_path **paths; @@ -1124,21 +1125,21 @@ struct tb_tunnel *tb_tunnel_alloc_dp(struct tb *tb, struct tb_port *in, paths = tunnel->paths; path = tb_path_alloc(tb, in, TB_DP_VIDEO_HOPID, out, TB_DP_VIDEO_HOPID, - 1, "Video"); + link_nr, "Video"); if (!path) goto err_free; tb_dp_init_video_path(path); paths[TB_DP_VIDEO_PATH_OUT] = path; path = tb_path_alloc(tb, in, TB_DP_AUX_TX_HOPID, out, - TB_DP_AUX_TX_HOPID, 1, "AUX TX"); + TB_DP_AUX_TX_HOPID, link_nr, "AUX TX"); if (!path) goto err_free; tb_dp_init_aux_path(path); paths[TB_DP_AUX_PATH_OUT] = path; path = tb_path_alloc(tb, out, TB_DP_AUX_RX_HOPID, in, - TB_DP_AUX_RX_HOPID, 1, "AUX RX"); + TB_DP_AUX_RX_HOPID, link_nr, "AUX RX"); if (!path) goto err_free; tb_dp_init_aux_path(path); diff --git a/drivers/thunderbolt/tunnel.h b/drivers/thunderbolt/tunnel.h index ea605046d41f..89d6328dd04f 100644 --- a/drivers/thunderbolt/tunnel.h +++ b/drivers/thunderbolt/tunnel.h @@ -77,8 +77,8 @@ struct tb_tunnel *tb_tunnel_alloc_pci(struct tb *tb, struct tb_port *up, struct tb_tunnel *tb_tunnel_discover_dp(struct tb *tb, struct tb_port *in, bool alloc_hopid); struct tb_tunnel *tb_tunnel_alloc_dp(struct tb *tb, struct tb_port *in, - struct tb_port *out, int max_up, - int max_down); + struct tb_port *out, int link_nr, + int max_up, int max_down); struct tb_tunnel *tb_tunnel_alloc_dma(struct tb *tb, struct tb_port *nhi, struct tb_port *dst, int transmit_path, int transmit_ring, int receive_path, -- 2.32.0