From patchwork Fri Jan 5 11:25:40 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Ilpo_J=C3=A4rvinen?= X-Patchwork-Id: 185351 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a05:7301:6f82:b0:100:9c79:88ff with SMTP id tb2csp6157639dyb; Fri, 5 Jan 2024 03:26:42 -0800 (PST) X-Google-Smtp-Source: AGHT+IFddDbOWCTY8gUeLgWOeuO984EN0NMQoz/LRUlTldO4L6Olt0PqVrP7rHcUxQOjTrCIdmBV X-Received: by 2002:a2e:8053:0:b0:2cc:b9c2:1b50 with SMTP id p19-20020a2e8053000000b002ccb9c21b50mr931475ljg.106.1704454002235; Fri, 05 Jan 2024 03:26:42 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1704454002; cv=none; d=google.com; s=arc-20160816; b=aDcc8LbFIVNIoYM8Q7PvhGWD8NUW1ZwEApkTrErypWrCVNtDhChMt86sKWhgmc7jx1 7G5JUKphWsNambeyziSMhoXiLn/mNKh+ggfBaGNqkZa0tr9MdNmmifZ3tYIgQYWzE8Dr R/r2h8tFn/+fqJK64+5e3GUxTXmZ5ks82aNoGEe1N5aa4YH6taaS9mHdXrrCqnjK9aMy Jis1YUZUYeAMZxK4UiTl57s55fwu5JNN59GDBBsQmxIrGwsdKctqL/a7cUdqNOBsa3jT pVutk1iZdEHWjqTmvs5PmiHBdbjbL7ffZTWN0Vwb0ZbQetnjmJpS/VGgk49M21R+kRf6 8BOw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=content-transfer-encoding:mime-version:list-unsubscribe :list-subscribe:list-id:precedence:references:in-reply-to:message-id :date:subject:cc:to:from:dkim-signature; bh=cB/wnbwBTr5VAlJikKzvF6gO1TdzTQMRmwiZFsYJsAY=; fh=+mTvAJKsxUzZ4ByKc/wnpBkRiM9bT1Guol5DBNNfsS4=; b=h+P4ntb4LfoJ3/2qki3K97yhmorRJiRjNSATDk1ILjDRS/dk3AK1NoRA4WcGIDiEL1 sWzbjcRSEyoQFnvCkN2BoI9+TWON40dtmaMQnWa51etMGL8xVAWCgXOnNYJ9EWSsdArG v8aZYEbUJ8KsDxKTDOnaCh3jqvMv9WO3gLg/mvXw+zr7f7VczYbRl5G3OPxHohfpqKpV zppDWosyt/rD/QwHNJT9NAAD8DnNsNOFmdROPiSLQeSLHAj/S4TMN/Secvh3JnXcFoQb jChFyHTqP0owKY++EnjMWS2KQ99bbgYT1CyC4GgeTWQA+40NRtQuDL0YfXubwe1yC0ke 0FSA== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@intel.com header.s=Intel header.b=JnE0p1n3; spf=pass (google.com: domain of linux-kernel+bounces-17788-ouuuleilei=gmail.com@vger.kernel.org designates 2604:1380:4601:e00::3 as permitted sender) smtp.mailfrom="linux-kernel+bounces-17788-ouuuleilei=gmail.com@vger.kernel.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=intel.com Received: from am.mirrors.kernel.org (am.mirrors.kernel.org. [2604:1380:4601:e00::3]) by mx.google.com with ESMTPS id u21-20020a509515000000b00555a55a5c4csi576836eda.474.2024.01.05.03.26.42 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 05 Jan 2024 03:26:42 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel+bounces-17788-ouuuleilei=gmail.com@vger.kernel.org designates 2604:1380:4601:e00::3 as permitted sender) client-ip=2604:1380:4601:e00::3; Authentication-Results: mx.google.com; dkim=pass header.i=@intel.com header.s=Intel header.b=JnE0p1n3; spf=pass (google.com: domain of linux-kernel+bounces-17788-ouuuleilei=gmail.com@vger.kernel.org designates 2604:1380:4601:e00::3 as permitted sender) smtp.mailfrom="linux-kernel+bounces-17788-ouuuleilei=gmail.com@vger.kernel.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=intel.com Received: from smtp.subspace.kernel.org (wormhole.subspace.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by am.mirrors.kernel.org (Postfix) with ESMTPS id CF4C31F21128 for ; Fri, 5 Jan 2024 11:26:41 +0000 (UTC) Received: from localhost.localdomain (localhost.localdomain [127.0.0.1]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 3F13D2D046; Fri, 5 Jan 2024 11:26:18 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b="JnE0p1n3" X-Original-To: linux-kernel@vger.kernel.org Received: from mgamail.intel.com (mgamail.intel.com [198.175.65.10]) (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 2BB9E2CCBD; Fri, 5 Jan 2024 11:26:13 +0000 (UTC) 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 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1704453974; x=1735989974; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=EB6yc3eYH0bqf6SvAry+9WDusbCWU03uB068cag5tAg=; b=JnE0p1n3mFmM/VCJ66oNumYFGY3sJ2gNy7+68loovwj3gZECOyMlWHdS G13rxRb8h1kDAZDCsf9HXBf4nAqgUMuCBPAevM6kS/2NW+6QxXM2M4iPY FG/F9Vppjcfso6KgINM1fpyh+bpxZ++HIb35W1h2NHkHYpBGq99Zheakv WYbOEjQh9IjoV00TdgXVaI0TZInpBsFe6ZCfFs9CBNg4AXUoKYjurre7k XadztQDDs8qubrnvUpueF3hh75kyzUmh5TDLsuVzsYafJo62XWIspM7n8 VPimxLMtzmP3/hJUQMSGvqcYQhjIrp2xOUrsmpG/SGsxZT0MHLMw0ECIA Q==; X-IronPort-AV: E=McAfee;i="6600,9927,10943"; a="10858342" X-IronPort-AV: E=Sophos;i="6.04,333,1695711600"; d="scan'208";a="10858342" Received: from orsmga007.jf.intel.com ([10.7.209.58]) by orvoesa102.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 05 Jan 2024 03:26:13 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=McAfee;i="6600,9927,10943"; a="773827811" X-IronPort-AV: E=Sophos;i="6.04,333,1695711600"; d="scan'208";a="773827811" Received: from ijarvine-desk1.ger.corp.intel.com (HELO localhost) ([10.246.32.38]) by orsmga007-auth.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 05 Jan 2024 03:26:06 -0800 From: =?utf-8?q?Ilpo_J=C3=A4rvinen?= To: linux-pci@vger.kernel.org, Bjorn Helgaas , Lorenzo Pieralisi , Rob Herring , =?utf-8?q?Krzysztof_Wilczy=C5=84ski?= , Lukas Wunner , Alexandru Gagniuc , Krishna chaitanya chundru , Srinivas Pandruvada , "Rafael J. Wysocki" , linux-pm@vger.kernel.org, Jonathan Corbet , linux-doc@vger.kernel.org, linux-kernel@vger.kernel.org Cc: Alex Deucher , Daniel Lezcano , Amit Kucheria , Zhang Rui , =?utf-8?q?Ilpo_J=C3=A4rvinen?= Subject: [PATCH v4 1/8] PCI: Protect Link Control 2 Register with RMW locking Date: Fri, 5 Jan 2024 13:25:40 +0200 Message-Id: <20240105112547.7301-2-ilpo.jarvinen@linux.intel.com> X-Mailer: git-send-email 2.39.2 In-Reply-To: <20240105112547.7301-1-ilpo.jarvinen@linux.intel.com> References: <20240105112547.7301-1-ilpo.jarvinen@linux.intel.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-getmail-retrieved-from-mailbox: INBOX X-GMAIL-THRID: 1787249559902689236 X-GMAIL-MSGID: 1787249559902689236 PCIe Bandwidth Controller performs RMW accesses the Link Control 2 Register which can occur concurrently to other sources of Link Control 2 Register writes. Therefore, add Link Control 2 Register among the PCI Express Capability Registers that need RMW locking. Signed-off-by: Ilpo Järvinen Reviewed-by: Lukas Wunner --- Documentation/PCI/pciebus-howto.rst | 14 +++++++++----- include/linux/pci.h | 1 + 2 files changed, 10 insertions(+), 5 deletions(-) diff --git a/Documentation/PCI/pciebus-howto.rst b/Documentation/PCI/pciebus-howto.rst index a0027e8fb0d0..cd7857dd37aa 100644 --- a/Documentation/PCI/pciebus-howto.rst +++ b/Documentation/PCI/pciebus-howto.rst @@ -217,8 +217,12 @@ capability structure except the PCI Express capability structure, that is shared between many drivers including the service drivers. RMW Capability accessors (pcie_capability_clear_and_set_word(), pcie_capability_set_word(), and pcie_capability_clear_word()) protect -a selected set of PCI Express Capability Registers (Link Control -Register and Root Control Register). Any change to those registers -should be performed using RMW accessors to avoid problems due to -concurrent updates. For the up-to-date list of protected registers, -see pcie_capability_clear_and_set_word(). +a selected set of PCI Express Capability Registers: + +* Link Control Register +* Root Control Register +* Link Control 2 Register + +Any change to those registers should be performed using RMW accessors to +avoid problems due to concurrent updates. For the up-to-date list of +protected registers, see pcie_capability_clear_and_set_word(). diff --git a/include/linux/pci.h b/include/linux/pci.h index 60ca768bc867..345a3d2a3fcd 100644 --- a/include/linux/pci.h +++ b/include/linux/pci.h @@ -1269,6 +1269,7 @@ static inline int pcie_capability_clear_and_set_word(struct pci_dev *dev, { switch (pos) { case PCI_EXP_LNKCTL: + case PCI_EXP_LNKCTL2: case PCI_EXP_RTCTL: return pcie_capability_clear_and_set_word_locked(dev, pos, clear, set); From patchwork Fri Jan 5 11:25:41 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Ilpo_J=C3=A4rvinen?= X-Patchwork-Id: 185352 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a05:7301:6f82:b0:100:9c79:88ff with SMTP id tb2csp6157778dyb; Fri, 5 Jan 2024 03:27:00 -0800 (PST) X-Google-Smtp-Source: AGHT+IHKyPPpMaNBpUA6BvNt30GXaMxpaNqkN1hLBde3LG6K+Y54Uc+yTdUz60XkPchl5+3opM6b X-Received: by 2002:a05:6102:418f:b0:467:895a:b14d with SMTP id cd15-20020a056102418f00b00467895ab14dmr1915849vsb.34.1704454020607; Fri, 05 Jan 2024 03:27:00 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1704454020; cv=none; d=google.com; s=arc-20160816; b=vOJETtUldYzYUgB23BuEaK0u99ziS4vb0B6WZ8oFmkyzO2NbIaT8j0MXYDPmhEvjr4 zommDT5PpSiUdbhFyZ9Ln6k/srlwpgaPKlrDls2Hkttlo8yBjAoysc4P43nO3t+QpIf1 bPs++f81r6hMHsI65hXBPaOI4Rh1nDd5zFk01cKGLqNJHGfK8DnaxhsOpab2vAcEfN0j Pt0MABnGx+5JqT502lmlTy6/PX4ALWdOtlrVm9ce5KR/c9BHnr/4WL4v9WYrTvodyY6P GVIgELKtotdkwtu12/GFjWhOrp0xDT+D025BKvzJMIRrQxQZYZe0J8LugJ9ndRbYZBi8 fmAQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=content-transfer-encoding:mime-version:list-unsubscribe :list-subscribe:list-id:precedence:references:in-reply-to:message-id :date:subject:cc:to:from:dkim-signature; bh=hefQSnHzLE53Gi10PGpfzuWtAqw52w5xk9K24TY0buQ=; fh=4l79BtXUK6LwLm+02V9ji/QzN1hYYeXaJ5aUSPIdZ4s=; b=bmNbe3+AO6pBnhzrpqaXJMVF3qbAwKpmq0tD31zzJ/+68FEY+iPt9cLgnbjUexALI+ dEwlTC5F5SiVgsawuhVvYDoGJrVkSsGhjGMMpYJMRpl73pzbM4xdW+MTfszuVx1vWBp/ 1gFaHrLYYhV3uNrBoOYd5fSZn9iatmTZHjk3WQjrYyWpSv/We0vzMLOBMvjCNWdZ1yOj mzfieBMxPrBAMI6rjuo967F2PYfYbhnF6A5u142CF3FPMGcM3YlWm/zmCHnNLALs72Gm EozoCeoU0QR1sr6fmUZOo+aVaKLoPx6ZZQ2oVnhyzbnI/Aq12Cc/DnmNCtBqvBslhD7/ 8juQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@intel.com header.s=Intel header.b=cu9p16su; spf=pass (google.com: domain of linux-kernel+bounces-17789-ouuuleilei=gmail.com@vger.kernel.org designates 147.75.199.223 as permitted sender) smtp.mailfrom="linux-kernel+bounces-17789-ouuuleilei=gmail.com@vger.kernel.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=intel.com Received: from ny.mirrors.kernel.org (ny.mirrors.kernel.org. [147.75.199.223]) by mx.google.com with ESMTPS id n9-20020a05622a11c900b0042979ee12fasi600708qtk.568.2024.01.05.03.27.00 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 05 Jan 2024 03:27:00 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel+bounces-17789-ouuuleilei=gmail.com@vger.kernel.org designates 147.75.199.223 as permitted sender) client-ip=147.75.199.223; Authentication-Results: mx.google.com; dkim=pass header.i=@intel.com header.s=Intel header.b=cu9p16su; spf=pass (google.com: domain of linux-kernel+bounces-17789-ouuuleilei=gmail.com@vger.kernel.org designates 147.75.199.223 as permitted sender) smtp.mailfrom="linux-kernel+bounces-17789-ouuuleilei=gmail.com@vger.kernel.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=intel.com Received: from smtp.subspace.kernel.org (wormhole.subspace.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ny.mirrors.kernel.org (Postfix) with ESMTPS id 5805E1C22F1B for ; Fri, 5 Jan 2024 11:27:00 +0000 (UTC) Received: from localhost.localdomain (localhost.localdomain [127.0.0.1]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 0D9DD2CCBF; Fri, 5 Jan 2024 11:26:33 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b="cu9p16su" X-Original-To: linux-kernel@vger.kernel.org Received: from mgamail.intel.com (mgamail.intel.com [192.55.52.43]) (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 DFA59C2CA; Fri, 5 Jan 2024 11:26:28 +0000 (UTC) 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 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1704453989; x=1735989989; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=Tt0hr44xsfolQHhOcEQ5H8NjkPqTdHCgyfspbkFMmI0=; b=cu9p16suIYUOy9GWNp1Jdf9ywyxinWN6NWGBOX0jxAgxwVgpwzjE5ycv aaC7IEKhQSo+ZmQ6sS44BRYHIciFq9gtYmIF4IbhzK9jTI+1ZxzDIUiQe smPtQ07ToiMP62Ym6wsnuixTqy/3Wl6GLjCCQpG1iPsWd/I+TK590jzZD 3y55UAsUERZRB1VwdH2oixCm6AeHgXr2KbeGWnjgDjUkZrYduVDbIyaL0 kqqHqFyyuOHDcXebdKePVf55DqCk5Af0XvkfndnAI3aYKYQL64RfBy4o5 PC5/vsauIJELX/ghIqLL7FBtKMW6ntlcUJKU3ozKr7CdALA0claJf1kyw Q==; X-IronPort-AV: E=McAfee;i="6600,9927,10943"; a="483662411" X-IronPort-AV: E=Sophos;i="6.04,333,1695711600"; d="scan'208";a="483662411" Received: from orsmga003.jf.intel.com ([10.7.209.27]) by fmsmga105.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 05 Jan 2024 03:26:27 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=McAfee;i="6600,9927,10943"; a="730447507" X-IronPort-AV: E=Sophos;i="6.04,333,1695711600"; d="scan'208";a="730447507" Received: from ijarvine-desk1.ger.corp.intel.com (HELO localhost) ([10.246.32.38]) by orsmga003-auth.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 05 Jan 2024 03:26:19 -0800 From: =?utf-8?q?Ilpo_J=C3=A4rvinen?= To: linux-pci@vger.kernel.org, Bjorn Helgaas , Lorenzo Pieralisi , Rob Herring , =?utf-8?q?Krzysztof_Wilczy=C5=84ski?= , Lukas Wunner , Alexandru Gagniuc , Krishna chaitanya chundru , Srinivas Pandruvada , "Rafael J. Wysocki" , linux-pm@vger.kernel.org, Alex Deucher , =?utf-8?q?Christian_K=C3=B6nig?= , "Pan, Xinhui" , David Airlie , Daniel Vetter , amd-gfx@lists.freedesktop.org, dri-devel@lists.freedesktop.org, linux-kernel@vger.kernel.org Cc: Alex Deucher , Daniel Lezcano , Amit Kucheria , Zhang Rui , =?utf-8?q?Ilpo_J=C3=A4rvinen?= Subject: [PATCH v4 2/8] drm/radeon: Use RMW accessors for changing LNKCTL2 Date: Fri, 5 Jan 2024 13:25:41 +0200 Message-Id: <20240105112547.7301-3-ilpo.jarvinen@linux.intel.com> X-Mailer: git-send-email 2.39.2 In-Reply-To: <20240105112547.7301-1-ilpo.jarvinen@linux.intel.com> References: <20240105112547.7301-1-ilpo.jarvinen@linux.intel.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-getmail-retrieved-from-mailbox: INBOX X-GMAIL-THRID: 1787249578647872364 X-GMAIL-MSGID: 1787249578647872364 Don't assume that only the driver would be accessing LNKCTL2. In the case of upstream (parent), the driver does not even own the device it's changing the registers for. Use RMW capability accessors which do proper locking to avoid losing concurrent updates to the register value. This change is also useful as a cleanup. Suggested-by: Lukas Wunner Signed-off-by: Ilpo Järvinen --- drivers/gpu/drm/radeon/cik.c | 40 ++++++++++++++---------------------- drivers/gpu/drm/radeon/si.c | 40 ++++++++++++++---------------------- 2 files changed, 30 insertions(+), 50 deletions(-) diff --git a/drivers/gpu/drm/radeon/cik.c b/drivers/gpu/drm/radeon/cik.c index 10be30366c2b..b5e96a8fc2c1 100644 --- a/drivers/gpu/drm/radeon/cik.c +++ b/drivers/gpu/drm/radeon/cik.c @@ -9592,28 +9592,18 @@ static void cik_pcie_gen3_enable(struct radeon_device *rdev) PCI_EXP_LNKCTL_HAWD); /* linkctl2 */ - pcie_capability_read_word(root, PCI_EXP_LNKCTL2, - &tmp16); - tmp16 &= ~(PCI_EXP_LNKCTL2_ENTER_COMP | - PCI_EXP_LNKCTL2_TX_MARGIN); - tmp16 |= (bridge_cfg2 & - (PCI_EXP_LNKCTL2_ENTER_COMP | - PCI_EXP_LNKCTL2_TX_MARGIN)); - pcie_capability_write_word(root, - PCI_EXP_LNKCTL2, - tmp16); - - pcie_capability_read_word(rdev->pdev, - PCI_EXP_LNKCTL2, - &tmp16); - tmp16 &= ~(PCI_EXP_LNKCTL2_ENTER_COMP | - PCI_EXP_LNKCTL2_TX_MARGIN); - tmp16 |= (gpu_cfg2 & - (PCI_EXP_LNKCTL2_ENTER_COMP | - PCI_EXP_LNKCTL2_TX_MARGIN)); - pcie_capability_write_word(rdev->pdev, - PCI_EXP_LNKCTL2, - tmp16); + pcie_capability_clear_and_set_word(root, PCI_EXP_LNKCTL2, + PCI_EXP_LNKCTL2_ENTER_COMP | + PCI_EXP_LNKCTL2_TX_MARGIN, + bridge_cfg2 | + (PCI_EXP_LNKCTL2_ENTER_COMP | + PCI_EXP_LNKCTL2_TX_MARGIN)); + pcie_capability_clear_and_set_word(rdev->pdev, PCI_EXP_LNKCTL2, + PCI_EXP_LNKCTL2_ENTER_COMP | + PCI_EXP_LNKCTL2_TX_MARGIN, + gpu_cfg2 | + (PCI_EXP_LNKCTL2_ENTER_COMP | + PCI_EXP_LNKCTL2_TX_MARGIN)); tmp = RREG32_PCIE_PORT(PCIE_LC_CNTL4); tmp &= ~LC_SET_QUIESCE; @@ -9627,15 +9617,15 @@ static void cik_pcie_gen3_enable(struct radeon_device *rdev) speed_cntl &= ~LC_FORCE_DIS_SW_SPEED_CHANGE; WREG32_PCIE_PORT(PCIE_LC_SPEED_CNTL, speed_cntl); - pcie_capability_read_word(rdev->pdev, PCI_EXP_LNKCTL2, &tmp16); - tmp16 &= ~PCI_EXP_LNKCTL2_TLS; + tmp16 = 0; if (speed_cap == PCIE_SPEED_8_0GT) tmp16 |= PCI_EXP_LNKCTL2_TLS_8_0GT; /* gen3 */ else if (speed_cap == PCIE_SPEED_5_0GT) tmp16 |= PCI_EXP_LNKCTL2_TLS_5_0GT; /* gen2 */ else tmp16 |= PCI_EXP_LNKCTL2_TLS_2_5GT; /* gen1 */ - pcie_capability_write_word(rdev->pdev, PCI_EXP_LNKCTL2, tmp16); + pcie_capability_clear_and_set_word(rdev->pdev, PCI_EXP_LNKCTL2, + PCI_EXP_LNKCTL2_TLS, tmp16); speed_cntl = RREG32_PCIE_PORT(PCIE_LC_SPEED_CNTL); speed_cntl |= LC_INITIATE_LINK_SPEED_CHANGE; diff --git a/drivers/gpu/drm/radeon/si.c b/drivers/gpu/drm/radeon/si.c index a91012447b56..32871ca09a0f 100644 --- a/drivers/gpu/drm/radeon/si.c +++ b/drivers/gpu/drm/radeon/si.c @@ -7189,28 +7189,18 @@ static void si_pcie_gen3_enable(struct radeon_device *rdev) PCI_EXP_LNKCTL_HAWD); /* linkctl2 */ - pcie_capability_read_word(root, PCI_EXP_LNKCTL2, - &tmp16); - tmp16 &= ~(PCI_EXP_LNKCTL2_ENTER_COMP | - PCI_EXP_LNKCTL2_TX_MARGIN); - tmp16 |= (bridge_cfg2 & - (PCI_EXP_LNKCTL2_ENTER_COMP | - PCI_EXP_LNKCTL2_TX_MARGIN)); - pcie_capability_write_word(root, - PCI_EXP_LNKCTL2, - tmp16); - - pcie_capability_read_word(rdev->pdev, - PCI_EXP_LNKCTL2, - &tmp16); - tmp16 &= ~(PCI_EXP_LNKCTL2_ENTER_COMP | - PCI_EXP_LNKCTL2_TX_MARGIN); - tmp16 |= (gpu_cfg2 & - (PCI_EXP_LNKCTL2_ENTER_COMP | - PCI_EXP_LNKCTL2_TX_MARGIN)); - pcie_capability_write_word(rdev->pdev, - PCI_EXP_LNKCTL2, - tmp16); + pcie_capability_clear_and_set_word(root, PCI_EXP_LNKCTL2, + PCI_EXP_LNKCTL2_ENTER_COMP | + PCI_EXP_LNKCTL2_TX_MARGIN, + bridge_cfg2 & + (PCI_EXP_LNKCTL2_ENTER_COMP | + PCI_EXP_LNKCTL2_TX_MARGIN)); + pcie_capability_clear_and_set_word(rdev->pdev, PCI_EXP_LNKCTL2, + PCI_EXP_LNKCTL2_ENTER_COMP | + PCI_EXP_LNKCTL2_TX_MARGIN, + gpu_cfg2 & + (PCI_EXP_LNKCTL2_ENTER_COMP | + PCI_EXP_LNKCTL2_TX_MARGIN)); tmp = RREG32_PCIE_PORT(PCIE_LC_CNTL4); tmp &= ~LC_SET_QUIESCE; @@ -7224,15 +7214,15 @@ static void si_pcie_gen3_enable(struct radeon_device *rdev) speed_cntl &= ~LC_FORCE_DIS_SW_SPEED_CHANGE; WREG32_PCIE_PORT(PCIE_LC_SPEED_CNTL, speed_cntl); - pcie_capability_read_word(rdev->pdev, PCI_EXP_LNKCTL2, &tmp16); - tmp16 &= ~PCI_EXP_LNKCTL2_TLS; + tmp16 = 0; if (speed_cap == PCIE_SPEED_8_0GT) tmp16 |= PCI_EXP_LNKCTL2_TLS_8_0GT; /* gen3 */ else if (speed_cap == PCIE_SPEED_5_0GT) tmp16 |= PCI_EXP_LNKCTL2_TLS_5_0GT; /* gen2 */ else tmp16 |= PCI_EXP_LNKCTL2_TLS_2_5GT; /* gen1 */ - pcie_capability_write_word(rdev->pdev, PCI_EXP_LNKCTL2, tmp16); + pcie_capability_clear_and_set_word(rdev->pdev, PCI_EXP_LNKCTL2, + PCI_EXP_LNKCTL2_TLS, tmp16); speed_cntl = RREG32_PCIE_PORT(PCIE_LC_SPEED_CNTL); speed_cntl |= LC_INITIATE_LINK_SPEED_CHANGE; From patchwork Fri Jan 5 11:25:42 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Ilpo_J=C3=A4rvinen?= X-Patchwork-Id: 185353 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a05:7301:6f82:b0:100:9c79:88ff with SMTP id tb2csp6158339dyb; Fri, 5 Jan 2024 03:28:25 -0800 (PST) X-Google-Smtp-Source: AGHT+IEG/WGCYoqtVTRxflQfU9a2sdqop7OvYgooTTbcMWQwByddut/Bumb5djXSBMeMgxIMeo1I X-Received: by 2002:a92:ca48:0:b0:35f:d727:1db6 with SMTP id q8-20020a92ca48000000b0035fd7271db6mr2190730ilo.2.1704454105411; Fri, 05 Jan 2024 03:28:25 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1704454105; cv=none; d=google.com; s=arc-20160816; b=CHjh3FjMZndyNOAAoZv6+lgxw+X9FoER6ge+Q8WDkx296U8nAc//1sSpTP/KbvEXpX HlEqt1zhFHHwnRpukbZX4Patm+KtJKNlrKElxPH53J7y4SdG/mPqwb9kfsLjc6QDqXE+ iKOz2a9Mw1NPfy7prN8hULeM59M1KpJqpQbCgiMsmSZDiqAtH5oon0x+Y+XF4RG3fsvw 765ihLSCFPnlDuNDyXY5KmrqfAbAiYj+WNQGzUynFSo6MnO6/m3+y8jdkfKbA9ZLuzfM uWGqXYIhY6sQMFIDmOU+iAMiMwqtfoNqZBCpP1H7xMzi0lRS/7FGfxGqxU3Qf2SbJg6w Ka5w== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=content-transfer-encoding:mime-version:list-unsubscribe :list-subscribe:list-id:precedence:references:in-reply-to:message-id :date:subject:cc:to:from:dkim-signature; bh=dLrvfjEZMZ+6rGqUWoBhT+VUu3D6zow1H7KQSYfsvzA=; fh=4l79BtXUK6LwLm+02V9ji/QzN1hYYeXaJ5aUSPIdZ4s=; b=BhwaD/podEM7XNoEybfYPrWp12Vc5rfhCQesy6VACifQYbtFpE+MvG5PRPgz9xqI7T dx5NOqHgzLCE7ZYJLb9T+RXCJlRSEroL1YmKa4ixmedYG1awxpi17Zsf8WinhUaH0WoZ z1NahtLeFDNAf5Ny3K2TSttRFX2CnNCsCYxgkr3xP1kr66o4uVOD7pn4SrMDf7+LwrGc Ag1LbF8+XHojKPM/9Hn/hPn/gcOZ16ZvDq2jR56DEXC/2F0UVgliNyMxOhDBXe37uBxe xD7aeyKJeEN2Kf7sO7i8EOrCSr8iYiGam8VxT38b/Qw/6AzmK19TcNHP1WdpIl6warD+ TRPQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@intel.com header.s=Intel header.b=g1Edk1rR; spf=pass (google.com: domain of linux-kernel+bounces-17790-ouuuleilei=gmail.com@vger.kernel.org designates 2604:1380:40f1:3f00::1 as permitted sender) smtp.mailfrom="linux-kernel+bounces-17790-ouuuleilei=gmail.com@vger.kernel.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=intel.com Received: from sy.mirrors.kernel.org (sy.mirrors.kernel.org. [2604:1380:40f1:3f00::1]) by mx.google.com with ESMTPS id r25-20020a63a019000000b005c6faf0a670si1137334pge.257.2024.01.05.03.28.25 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 05 Jan 2024 03:28:25 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel+bounces-17790-ouuuleilei=gmail.com@vger.kernel.org designates 2604:1380:40f1:3f00::1 as permitted sender) client-ip=2604:1380:40f1:3f00::1; Authentication-Results: mx.google.com; dkim=pass header.i=@intel.com header.s=Intel header.b=g1Edk1rR; spf=pass (google.com: domain of linux-kernel+bounces-17790-ouuuleilei=gmail.com@vger.kernel.org designates 2604:1380:40f1:3f00::1 as permitted sender) smtp.mailfrom="linux-kernel+bounces-17790-ouuuleilei=gmail.com@vger.kernel.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=intel.com Received: from smtp.subspace.kernel.org (wormhole.subspace.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by sy.mirrors.kernel.org (Postfix) with ESMTPS id 207CCB239C8 for ; Fri, 5 Jan 2024 11:27:21 +0000 (UTC) Received: from localhost.localdomain (localhost.localdomain [127.0.0.1]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 095412D602; Fri, 5 Jan 2024 11:26:46 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b="g1Edk1rR" X-Original-To: linux-kernel@vger.kernel.org Received: from mgamail.intel.com (mgamail.intel.com [198.175.65.10]) (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 1C9F72D035; Fri, 5 Jan 2024 11:26:41 +0000 (UTC) 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 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1704454002; x=1735990002; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=nDVupTEiteyopEd8zWRHCGA5BVo9wD2+mWl2dTWBRrI=; b=g1Edk1rRWkuXXQm5XlWM2Q4X+5LpOJpKvHKsaTiFmEFMzTzvRhW9CU33 ML+qJrBgLR19QPOSl8LLhHkARdAEwQQ3m0wEJn647/eYaoleTF2Q3Etzm BrnCs1nZjEfFXYSxld6mtC1ppdROyZIUxIyaPZEFe3cvehLVUryhaTYhm DRs69tU7CK3B1RtzkhSNacinnK7htAxFGAhcyzwB19QKvZA8NmbbiUJwb qwZB1du4StJyjm1u2FyD3CZgUcW0YcVhMSyUVgR8U2h9Xr1EO8JiJ7yjM 9498QDnIAVFtJS39lKjyMQ+nvKrqQe8ValnWpcP1fQo1V8yE94/5BS6ZM g==; X-IronPort-AV: E=McAfee;i="6600,9927,10943"; a="10858441" X-IronPort-AV: E=Sophos;i="6.04,333,1695711600"; d="scan'208";a="10858441" Received: from orsmga007.jf.intel.com ([10.7.209.58]) by orvoesa102.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 05 Jan 2024 03:26:41 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=McAfee;i="6600,9927,10943"; a="773827832" X-IronPort-AV: E=Sophos;i="6.04,333,1695711600"; d="scan'208";a="773827832" Received: from ijarvine-desk1.ger.corp.intel.com (HELO localhost) ([10.246.32.38]) by orsmga007-auth.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 05 Jan 2024 03:26:33 -0800 From: =?utf-8?q?Ilpo_J=C3=A4rvinen?= To: linux-pci@vger.kernel.org, Bjorn Helgaas , Lorenzo Pieralisi , Rob Herring , =?utf-8?q?Krzysztof_Wilczy=C5=84ski?= , Lukas Wunner , Alexandru Gagniuc , Krishna chaitanya chundru , Srinivas Pandruvada , "Rafael J. Wysocki" , linux-pm@vger.kernel.org, Alex Deucher , =?utf-8?q?Christian_K=C3=B6nig?= , "Pan, Xinhui" , David Airlie , Daniel Vetter , amd-gfx@lists.freedesktop.org, dri-devel@lists.freedesktop.org, linux-kernel@vger.kernel.org Cc: Alex Deucher , Daniel Lezcano , Amit Kucheria , Zhang Rui , =?utf-8?q?Ilpo_J=C3=A4rvinen?= Subject: [PATCH v4 3/8] drm/amdgpu: Use RMW accessors for changing LNKCTL2 Date: Fri, 5 Jan 2024 13:25:42 +0200 Message-Id: <20240105112547.7301-4-ilpo.jarvinen@linux.intel.com> X-Mailer: git-send-email 2.39.2 In-Reply-To: <20240105112547.7301-1-ilpo.jarvinen@linux.intel.com> References: <20240105112547.7301-1-ilpo.jarvinen@linux.intel.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-getmail-retrieved-from-mailbox: INBOX X-GMAIL-THRID: 1787249667773888849 X-GMAIL-MSGID: 1787249667773888849 Don't assume that only the driver would be accessing LNKCTL2. In the case of upstream (parent), the driver does not even own the device it's changing the registers for. Use RMW capability accessors which do proper locking to avoid losing concurrent updates to the register value. This change is also useful as a cleanup. Suggested-by: Lukas Wunner Signed-off-by: Ilpo Järvinen --- drivers/gpu/drm/amd/amdgpu/cik.c | 41 ++++++++++++-------------------- drivers/gpu/drm/amd/amdgpu/si.c | 41 ++++++++++++-------------------- 2 files changed, 30 insertions(+), 52 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/cik.c b/drivers/gpu/drm/amd/amdgpu/cik.c index 4dfaa017cf7f..a3a643254d7a 100644 --- a/drivers/gpu/drm/amd/amdgpu/cik.c +++ b/drivers/gpu/drm/amd/amdgpu/cik.c @@ -1638,28 +1638,18 @@ static void cik_pcie_gen3_enable(struct amdgpu_device *adev) PCI_EXP_LNKCTL_HAWD); /* linkctl2 */ - pcie_capability_read_word(root, PCI_EXP_LNKCTL2, - &tmp16); - tmp16 &= ~(PCI_EXP_LNKCTL2_ENTER_COMP | - PCI_EXP_LNKCTL2_TX_MARGIN); - tmp16 |= (bridge_cfg2 & - (PCI_EXP_LNKCTL2_ENTER_COMP | - PCI_EXP_LNKCTL2_TX_MARGIN)); - pcie_capability_write_word(root, - PCI_EXP_LNKCTL2, - tmp16); - - pcie_capability_read_word(adev->pdev, - PCI_EXP_LNKCTL2, - &tmp16); - tmp16 &= ~(PCI_EXP_LNKCTL2_ENTER_COMP | - PCI_EXP_LNKCTL2_TX_MARGIN); - tmp16 |= (gpu_cfg2 & - (PCI_EXP_LNKCTL2_ENTER_COMP | - PCI_EXP_LNKCTL2_TX_MARGIN)); - pcie_capability_write_word(adev->pdev, - PCI_EXP_LNKCTL2, - tmp16); + pcie_capability_clear_and_set_word(root, PCI_EXP_LNKCTL2, + PCI_EXP_LNKCTL2_ENTER_COMP | + PCI_EXP_LNKCTL2_TX_MARGIN, + bridge_cfg2 & + (PCI_EXP_LNKCTL2_ENTER_COMP | + PCI_EXP_LNKCTL2_TX_MARGIN)); + pcie_capability_clear_and_set_word(adev->pdev, PCI_EXP_LNKCTL2, + PCI_EXP_LNKCTL2_ENTER_COMP | + PCI_EXP_LNKCTL2_TX_MARGIN, + gpu_cfg2 & + (PCI_EXP_LNKCTL2_ENTER_COMP | + PCI_EXP_LNKCTL2_TX_MARGIN)); tmp = RREG32_PCIE(ixPCIE_LC_CNTL4); tmp &= ~PCIE_LC_CNTL4__LC_SET_QUIESCE_MASK; @@ -1674,16 +1664,15 @@ static void cik_pcie_gen3_enable(struct amdgpu_device *adev) speed_cntl &= ~PCIE_LC_SPEED_CNTL__LC_FORCE_DIS_SW_SPEED_CHANGE_MASK; WREG32_PCIE(ixPCIE_LC_SPEED_CNTL, speed_cntl); - pcie_capability_read_word(adev->pdev, PCI_EXP_LNKCTL2, &tmp16); - tmp16 &= ~PCI_EXP_LNKCTL2_TLS; - + tmp16 = 0; if (adev->pm.pcie_gen_mask & CAIL_PCIE_LINK_SPEED_SUPPORT_GEN3) tmp16 |= PCI_EXP_LNKCTL2_TLS_8_0GT; /* gen3 */ else if (adev->pm.pcie_gen_mask & CAIL_PCIE_LINK_SPEED_SUPPORT_GEN2) tmp16 |= PCI_EXP_LNKCTL2_TLS_5_0GT; /* gen2 */ else tmp16 |= PCI_EXP_LNKCTL2_TLS_2_5GT; /* gen1 */ - pcie_capability_write_word(adev->pdev, PCI_EXP_LNKCTL2, tmp16); + pcie_capability_clear_and_set_word(adev->pdev, PCI_EXP_LNKCTL2, + PCI_EXP_LNKCTL2_TLS, tmp16); speed_cntl = RREG32_PCIE(ixPCIE_LC_SPEED_CNTL); speed_cntl |= PCIE_LC_SPEED_CNTL__LC_INITIATE_LINK_SPEED_CHANGE_MASK; diff --git a/drivers/gpu/drm/amd/amdgpu/si.c b/drivers/gpu/drm/amd/amdgpu/si.c index a757526153e5..23e4ef4fff7c 100644 --- a/drivers/gpu/drm/amd/amdgpu/si.c +++ b/drivers/gpu/drm/amd/amdgpu/si.c @@ -2331,28 +2331,18 @@ static void si_pcie_gen3_enable(struct amdgpu_device *adev) gpu_cfg & PCI_EXP_LNKCTL_HAWD); - pcie_capability_read_word(root, PCI_EXP_LNKCTL2, - &tmp16); - tmp16 &= ~(PCI_EXP_LNKCTL2_ENTER_COMP | - PCI_EXP_LNKCTL2_TX_MARGIN); - tmp16 |= (bridge_cfg2 & - (PCI_EXP_LNKCTL2_ENTER_COMP | - PCI_EXP_LNKCTL2_TX_MARGIN)); - pcie_capability_write_word(root, - PCI_EXP_LNKCTL2, - tmp16); - - pcie_capability_read_word(adev->pdev, - PCI_EXP_LNKCTL2, - &tmp16); - tmp16 &= ~(PCI_EXP_LNKCTL2_ENTER_COMP | - PCI_EXP_LNKCTL2_TX_MARGIN); - tmp16 |= (gpu_cfg2 & - (PCI_EXP_LNKCTL2_ENTER_COMP | - PCI_EXP_LNKCTL2_TX_MARGIN)); - pcie_capability_write_word(adev->pdev, - PCI_EXP_LNKCTL2, - tmp16); + pcie_capability_clear_and_set_word(root, PCI_EXP_LNKCTL2, + PCI_EXP_LNKCTL2_ENTER_COMP | + PCI_EXP_LNKCTL2_TX_MARGIN, + bridge_cfg2 & + (PCI_EXP_LNKCTL2_ENTER_COMP | + PCI_EXP_LNKCTL2_TX_MARGIN)); + pcie_capability_clear_and_set_word(adev->pdev, PCI_EXP_LNKCTL2, + PCI_EXP_LNKCTL2_ENTER_COMP | + PCI_EXP_LNKCTL2_TX_MARGIN, + gpu_cfg2 & + (PCI_EXP_LNKCTL2_ENTER_COMP | + PCI_EXP_LNKCTL2_TX_MARGIN)); tmp = RREG32_PCIE_PORT(PCIE_LC_CNTL4); tmp &= ~LC_SET_QUIESCE; @@ -2365,16 +2355,15 @@ static void si_pcie_gen3_enable(struct amdgpu_device *adev) speed_cntl &= ~LC_FORCE_DIS_SW_SPEED_CHANGE; WREG32_PCIE_PORT(PCIE_LC_SPEED_CNTL, speed_cntl); - pcie_capability_read_word(adev->pdev, PCI_EXP_LNKCTL2, &tmp16); - tmp16 &= ~PCI_EXP_LNKCTL2_TLS; - + tmp16 = 0; if (adev->pm.pcie_gen_mask & CAIL_PCIE_LINK_SPEED_SUPPORT_GEN3) tmp16 |= PCI_EXP_LNKCTL2_TLS_8_0GT; /* gen3 */ else if (adev->pm.pcie_gen_mask & CAIL_PCIE_LINK_SPEED_SUPPORT_GEN2) tmp16 |= PCI_EXP_LNKCTL2_TLS_5_0GT; /* gen2 */ else tmp16 |= PCI_EXP_LNKCTL2_TLS_2_5GT; /* gen1 */ - pcie_capability_write_word(adev->pdev, PCI_EXP_LNKCTL2, tmp16); + pcie_capability_clear_and_set_word(adev->pdev, PCI_EXP_LNKCTL2, + PCI_EXP_LNKCTL2_TLS, tmp16); speed_cntl = RREG32_PCIE_PORT(PCIE_LC_SPEED_CNTL); speed_cntl |= LC_INITIATE_LINK_SPEED_CHANGE; From patchwork Fri Jan 5 11:25:43 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Ilpo_J=C3=A4rvinen?= X-Patchwork-Id: 185367 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a05:7301:6f82:b0:100:9c79:88ff with SMTP id tb2csp6161762dyb; Fri, 5 Jan 2024 03:36:00 -0800 (PST) X-Google-Smtp-Source: AGHT+IFrvEzE9bQukHYlYJJGStW0EoxUVFH5mg1yNOvr6W8Beo6KJLUNeEhC9AWscWriKWN2WMOs X-Received: by 2002:a17:906:b847:b0:a27:59fa:51de with SMTP id ga7-20020a170906b84700b00a2759fa51demr1160233ejb.0.1704454560102; Fri, 05 Jan 2024 03:36:00 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1704454560; cv=none; d=google.com; s=arc-20160816; b=KjLAizL4v/RWdb0WMC6C6nY077Da4Qc0LMRDIEVvKnljoT7jix8dZ8I4g62vmR6/qq rGAIaPxyA+slGo9skRAoB87wHA4seoGkj935aUqeoB4k6/SpB9jC4gQNDiyZR+XiyJZN dVOSfSMgPhsQYPy5c/qh9Yi9y4eSxyVeI4tRaSGGZ2WFn0Ju/Kjo9IDG7nBzYsqXbzj9 tRQxXi9NuoyasC4FMZ8Sw59XaXuM3/K2qMNvMP1s6RY+GYVW7rPYqAwp3u3Se5qckCys xQm6ujXP7mDKlAmryUoSYN4hN+6vmjXC/ct/TqeWHdmYU9R21arT4edACfRbre32oMzB RWQw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=content-transfer-encoding:mime-version:list-unsubscribe :list-subscribe:list-id:precedence:references:in-reply-to:message-id :date:subject:cc:to:from:dkim-signature; bh=7cklxLauo7FdvQkOkIJk0Qu3HOKf/vHqBcFh13VLnvM=; fh=3IS8BFyCJJkxBqsmH9hH+0/bt1Mj0Fo8MDeGD/PXanY=; b=K2svZ/w3ZypHr7+MiX1Vp9Zo3VbC+9rLQ4EUZnjk4BIFcTgT7vYvBqXyQopvmFteWI Muzj7F60i31bjydhZ+t9DNw3r8PPZgHyEWbH4MK2jhb6czbB4x6FTYWTZn7ZOCj08ySo T06cbYNntNw69P7jMUmInKyFZ/IKCsu7BJroSUph1lDu84gzlVo5Q94IbxXcD2Jp/KNj vzKWwhcq2gDRGEb7Xn1EkE+/OytvXkVosW1avoKLiTfC2sTeaxK47BvSxPh8Cz0z1O24 +4y5QSTYxGerh4zdL4G/ZI4X0VBFB1kxcziRik1bEGxUla6P3bhCVxsyj4VxFA1u5Wuu U4Dg== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@intel.com header.s=Intel header.b=A3KTqhxj; spf=pass (google.com: domain of linux-kernel+bounces-17791-ouuuleilei=gmail.com@vger.kernel.org designates 2604:1380:4601:e00::3 as permitted sender) smtp.mailfrom="linux-kernel+bounces-17791-ouuuleilei=gmail.com@vger.kernel.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=intel.com Received: from am.mirrors.kernel.org (am.mirrors.kernel.org. [2604:1380:4601:e00::3]) by mx.google.com with ESMTPS id au13-20020a170907092d00b00a236f1dfff0si500442ejc.396.2024.01.05.03.35.59 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 05 Jan 2024 03:36:00 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel+bounces-17791-ouuuleilei=gmail.com@vger.kernel.org designates 2604:1380:4601:e00::3 as permitted sender) client-ip=2604:1380:4601:e00::3; Authentication-Results: mx.google.com; dkim=pass header.i=@intel.com header.s=Intel header.b=A3KTqhxj; spf=pass (google.com: domain of linux-kernel+bounces-17791-ouuuleilei=gmail.com@vger.kernel.org designates 2604:1380:4601:e00::3 as permitted sender) smtp.mailfrom="linux-kernel+bounces-17791-ouuuleilei=gmail.com@vger.kernel.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=intel.com Received: from smtp.subspace.kernel.org (wormhole.subspace.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by am.mirrors.kernel.org (Postfix) with ESMTPS id DAE881F25BA4 for ; Fri, 5 Jan 2024 11:27:42 +0000 (UTC) Received: from localhost.localdomain (localhost.localdomain [127.0.0.1]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 219312D615; Fri, 5 Jan 2024 11:27:00 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b="A3KTqhxj" X-Original-To: linux-kernel@vger.kernel.org Received: from mgamail.intel.com (mgamail.intel.com [192.55.52.115]) (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 3197128E3F; Fri, 5 Jan 2024 11:26:55 +0000 (UTC) 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 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1704454016; x=1735990016; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=2mz6UXD8CKZpj6xVnd1sdog26enPJbDhqYo4qIbUESI=; b=A3KTqhxjo2+2tda5wtl+DNRBvpMb8h7jzvy43R9242BOgv2cKlgtA26p ag6J0XTTQxlxpXdn7h39GQb1hU3kVWWa6TnYfGcBg+oAOj/nrHitZXS4M hC7BN3hcVRuK7DQUnnxODs5t/WlJgTulfep6yGoHUreGAzJP/vVYWlTT/ LLRUuReFz8ntL2UDnrPanycqgF9ycvJFoqNKRG30vPSzPAgNL+E3AN97X mbhtFcT6/aMOW9EFhway0uyqviNIWun38DS3ztN87Ts2EeP6XWi1DKhiE XhPvD3r+wHWIEEU1IN0S6IN5kf8X58vQUX6M10KM8BKX2jn9iTVG2VtM6 Q==; X-IronPort-AV: E=McAfee;i="6600,9927,10943"; a="397208915" X-IronPort-AV: E=Sophos;i="6.04,333,1695711600"; d="scan'208";a="397208915" Received: from fmsmga004.fm.intel.com ([10.253.24.48]) by fmsmga103.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 05 Jan 2024 03:26:55 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=McAfee;i="6600,9927,10943"; a="851118164" X-IronPort-AV: E=Sophos;i="6.04,333,1695711600"; d="scan'208";a="851118164" Received: from ijarvine-desk1.ger.corp.intel.com (HELO localhost) ([10.246.32.38]) by fmsmga004-auth.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 05 Jan 2024 03:26:47 -0800 From: =?utf-8?q?Ilpo_J=C3=A4rvinen?= To: linux-pci@vger.kernel.org, Bjorn Helgaas , Lorenzo Pieralisi , Rob Herring , =?utf-8?q?Krzysztof_Wilczy=C5=84ski?= , Lukas Wunner , Alexandru Gagniuc , Krishna chaitanya chundru , Srinivas Pandruvada , "Rafael J. Wysocki" , linux-pm@vger.kernel.org, Dennis Dalessandro , Jason Gunthorpe , Leon Romanovsky , linux-rdma@vger.kernel.org, linux-kernel@vger.kernel.org Cc: Alex Deucher , Daniel Lezcano , Amit Kucheria , Zhang Rui , =?utf-8?q?Ilpo_J=C3=A4rvinen?= , Dean Luick Subject: [PATCH v4 4/8] RDMA/hfi1: Use RMW accessors for changing LNKCTL2 Date: Fri, 5 Jan 2024 13:25:43 +0200 Message-Id: <20240105112547.7301-5-ilpo.jarvinen@linux.intel.com> X-Mailer: git-send-email 2.39.2 In-Reply-To: <20240105112547.7301-1-ilpo.jarvinen@linux.intel.com> References: <20240105112547.7301-1-ilpo.jarvinen@linux.intel.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-getmail-retrieved-from-mailbox: INBOX X-GMAIL-THRID: 1787250144890191146 X-GMAIL-MSGID: 1787250144890191146 Don't assume that only the driver would be accessing LNKCTL2. In the case of upstream (parent), the driver does not even own the device it's changing the registers for. Use RMW capability accessors which do proper locking to avoid losing concurrent updates to the register value. This change is also useful as a cleanup. Suggested-by: Lukas Wunner Signed-off-by: Ilpo Järvinen Reviewed-by: Dean Luick --- drivers/infiniband/hw/hfi1/pcie.c | 30 ++++++++---------------------- 1 file changed, 8 insertions(+), 22 deletions(-) diff --git a/drivers/infiniband/hw/hfi1/pcie.c b/drivers/infiniband/hw/hfi1/pcie.c index 119ec2f1382b..7133964749f8 100644 --- a/drivers/infiniband/hw/hfi1/pcie.c +++ b/drivers/infiniband/hw/hfi1/pcie.c @@ -1207,14 +1207,11 @@ int do_pcie_gen3_transition(struct hfi1_devdata *dd) (u32)lnkctl2); /* only write to parent if target is not as high as ours */ if ((lnkctl2 & PCI_EXP_LNKCTL2_TLS) < target_vector) { - lnkctl2 &= ~PCI_EXP_LNKCTL2_TLS; - lnkctl2 |= target_vector; - dd_dev_info(dd, "%s: ..new link control2: 0x%x\n", __func__, - (u32)lnkctl2); - ret = pcie_capability_write_word(parent, - PCI_EXP_LNKCTL2, lnkctl2); + ret = pcie_capability_clear_and_set_word(parent, PCI_EXP_LNKCTL2, + PCI_EXP_LNKCTL2_TLS, + target_vector); if (ret) { - dd_dev_err(dd, "Unable to write to PCI config\n"); + dd_dev_err(dd, "Unable to change parent PCI target speed\n"); return_error = 1; goto done; } @@ -1223,22 +1220,11 @@ int do_pcie_gen3_transition(struct hfi1_devdata *dd) } dd_dev_info(dd, "%s: setting target link speed\n", __func__); - ret = pcie_capability_read_word(dd->pcidev, PCI_EXP_LNKCTL2, &lnkctl2); + ret = pcie_capability_clear_and_set_word(dd->pcidev, PCI_EXP_LNKCTL2, + PCI_EXP_LNKCTL2_TLS, + target_vector); if (ret) { - dd_dev_err(dd, "Unable to read from PCI config\n"); - return_error = 1; - goto done; - } - - dd_dev_info(dd, "%s: ..old link control2: 0x%x\n", __func__, - (u32)lnkctl2); - lnkctl2 &= ~PCI_EXP_LNKCTL2_TLS; - lnkctl2 |= target_vector; - dd_dev_info(dd, "%s: ..new link control2: 0x%x\n", __func__, - (u32)lnkctl2); - ret = pcie_capability_write_word(dd->pcidev, PCI_EXP_LNKCTL2, lnkctl2); - if (ret) { - dd_dev_err(dd, "Unable to write to PCI config\n"); + dd_dev_err(dd, "Unable to change device PCI target speed\n"); return_error = 1; goto done; } From patchwork Fri Jan 5 11:25:44 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Ilpo_J=C3=A4rvinen?= X-Patchwork-Id: 185354 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a05:7301:6f82:b0:100:9c79:88ff with SMTP id tb2csp6158735dyb; Fri, 5 Jan 2024 03:29:27 -0800 (PST) X-Google-Smtp-Source: AGHT+IFlXLPHpi71q7wiX4X50iUJ0QCYxhr8KxJ2pQV704p2TmRxGkAkZeeYjRuw0U8+aykxj1cn X-Received: by 2002:a05:6a20:9488:b0:197:7126:50de with SMTP id hs8-20020a056a20948800b00197712650demr1450591pzb.110.1704454166349; Fri, 05 Jan 2024 03:29:26 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1704454166; cv=none; d=google.com; s=arc-20160816; b=PcVjXaf/GvmCQaUu8ZAfOgLpxKitJsBItnZa8R2fDa1pvAWFrZL8HULJn5GHwg5ADh 78z3jS8eWKJUGQAjHqHj1HLu7OfwplEumyFzj5H6rMAq3CZPfOrpQNEISMYOECX4AlP4 VbohO6Mwx+n8BhCOy606ZCiYdhbEj1hDEpb5c/m7wUI4AAdtZyluH7MbkjvK0Ssn1ppS hGrGtdziBAjG6YGBc0lILsfAGwTbAI2RsEoNQ1+3v99N35HbgEZIvgOB1yBqSlEq3Is1 b/mvrOODKBLg27mo6graDcXVfmgO0GMgm5y11xt3EKBj/sRQTzjkO4uPBTnv+jaxX6Td HdYg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=content-transfer-encoding:mime-version:list-unsubscribe :list-subscribe:list-id:precedence:references:in-reply-to:message-id :date:subject:cc:to:from:dkim-signature; bh=ahcVsLHw6SphvRX/Qjgjkg2MHPqQTUjKgCxX17JlWZg=; fh=FtDFtB29BmkffzJkDuXZpudHAVuiyxnYnFGomBJZqcM=; b=RH1bfwWiUIk59RY8LU+FhwuIHVWf11YA7vMPMSouTDmLY2QxdbxcV1n8sV1h2EkKsK dlBVgkajpXjTfp5yjGc6Zvsk2bildd75tvAMDHbfvNBMRW0eChJnW5Nq3h9hMx/fDj14 nTQh9yjXMXylLNP86PV9MfZNPfRxbVCVu+v2cO3bQFcNXoMv6FShjxZ2bpmdm6B7SJBB T8X1ZiBE2Baq3RqK0G4TK816Kgxqmiud0idR8ijAbG4Q8/zKqLQeGq5KGYmKvFFk3YVZ UZjnBHPemU7wjFTBNn83gFhzTUtPirhHlDd3xzYpbx8Xl6SPcuRR7wrouy3AS/zoJAXS HICw== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@intel.com header.s=Intel header.b=lxlPsrIT; spf=pass (google.com: domain of linux-kernel+bounces-17792-ouuuleilei=gmail.com@vger.kernel.org designates 2604:1380:40f1:3f00::1 as permitted sender) smtp.mailfrom="linux-kernel+bounces-17792-ouuuleilei=gmail.com@vger.kernel.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=intel.com Received: from sy.mirrors.kernel.org (sy.mirrors.kernel.org. [2604:1380:40f1:3f00::1]) by mx.google.com with ESMTPS id d18-20020a170902729200b001d43aa8fa34si1072793pll.338.2024.01.05.03.29.25 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 05 Jan 2024 03:29:26 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel+bounces-17792-ouuuleilei=gmail.com@vger.kernel.org designates 2604:1380:40f1:3f00::1 as permitted sender) client-ip=2604:1380:40f1:3f00::1; Authentication-Results: mx.google.com; dkim=pass header.i=@intel.com header.s=Intel header.b=lxlPsrIT; spf=pass (google.com: domain of linux-kernel+bounces-17792-ouuuleilei=gmail.com@vger.kernel.org designates 2604:1380:40f1:3f00::1 as permitted sender) smtp.mailfrom="linux-kernel+bounces-17792-ouuuleilei=gmail.com@vger.kernel.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=intel.com Received: from smtp.subspace.kernel.org (wormhole.subspace.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by sy.mirrors.kernel.org (Postfix) with ESMTPS id 4E477B24EBE for ; Fri, 5 Jan 2024 11:28:03 +0000 (UTC) Received: from localhost.localdomain (localhost.localdomain [127.0.0.1]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 6D9672D62D; Fri, 5 Jan 2024 11:27:11 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b="lxlPsrIT" X-Original-To: linux-kernel@vger.kernel.org Received: from mgamail.intel.com (mgamail.intel.com [192.55.52.115]) (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 3D7CA2D61D; Fri, 5 Jan 2024 11:27:07 +0000 (UTC) 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 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1704454027; x=1735990027; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=dWfFMBnvHZMaEWNUAkYHN3XtGYpRfC4Z4Lvgh2Ajbkg=; b=lxlPsrITKYJblklUYxngOMRXcoSZ6KnIueRK4vAtx76rgMmNQ2GfiD83 obWNcKddYhONKFIE2+DrW4eezhV/MPGbu6x8QxrYFZmcTetCjbL/TDmWk IBmGdDz8B758KufE2dp6zWPGUmTZsXIGO953LM7HgLUFUjYsfCcKSeb0a wuxFY9MUF/1kivTofXW6u2bs2jLOoJx4MZT06KNHEnX1dHgkG1CfVymo8 yg4JWSEMbEf8unNptiHbrnMV8ua4U2xQMqrRSTWzWvM4jR/OEPNYS5H1m zAQXRXitgSifMXSJe1gJB7Xap0c4jhxluT9MKN96fVUOiRUZBCY1GEEHf A==; X-IronPort-AV: E=McAfee;i="6600,9927,10943"; a="397208958" X-IronPort-AV: E=Sophos;i="6.04,333,1695711600"; d="scan'208";a="397208958" Received: from fmsmga004.fm.intel.com ([10.253.24.48]) by fmsmga103.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 05 Jan 2024 03:27:06 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=McAfee;i="6600,9927,10943"; a="851118190" X-IronPort-AV: E=Sophos;i="6.04,333,1695711600"; d="scan'208";a="851118190" Received: from ijarvine-desk1.ger.corp.intel.com (HELO localhost) ([10.246.32.38]) by fmsmga004-auth.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 05 Jan 2024 03:27:00 -0800 From: =?utf-8?q?Ilpo_J=C3=A4rvinen?= To: linux-pci@vger.kernel.org, Bjorn Helgaas , Lorenzo Pieralisi , Rob Herring , =?utf-8?q?Krzysztof_Wilczy=C5=84ski?= , Lukas Wunner , Alexandru Gagniuc , Krishna chaitanya chundru , Srinivas Pandruvada , "Rafael J. Wysocki" , linux-pm@vger.kernel.org, linux-kernel@vger.kernel.org Cc: Alex Deucher , Daniel Lezcano , Amit Kucheria , Zhang Rui , =?utf-8?q?Ilpo_J=C3=A4rvinen?= Subject: [PATCH v4 5/8] PCI: Store all PCIe Supported Link Speeds Date: Fri, 5 Jan 2024 13:25:44 +0200 Message-Id: <20240105112547.7301-6-ilpo.jarvinen@linux.intel.com> X-Mailer: git-send-email 2.39.2 In-Reply-To: <20240105112547.7301-1-ilpo.jarvinen@linux.intel.com> References: <20240105112547.7301-1-ilpo.jarvinen@linux.intel.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-getmail-retrieved-from-mailbox: INBOX X-GMAIL-THRID: 1787249731866164047 X-GMAIL-MSGID: 1787249731866164047 PCIe bandwidth controller added by a subsequent commit will require selecting PCIe Link Speeds that are lower than the Maximum Link Speed. The struct pci_bus only stores max_bus_speed. Even if PCIe r6.1 sec 8.2.1 currently disallows gaps in supported Link Speeds, the Implementation Note in PCIe r6.1 sec 7.5.3.18, recommends determining supported Link Speeds using the Supported Link Speeds Vector in the Link Capabilities 2 Register (when available) to "avoid software being confused if a future specification defines Links that do not require support for all slower speeds." Reuse code in pcie_get_speed_cap() to add pcie_get_supported_speeds() to query the Supported Link Speeds Vector of a PCIe device. The value is taken directly from the Supported Link Speeds Vector or synthetized from the Max Link Speed in the Link Capabilities Register when the Link Capabilities 2 Register is not available. The Supported Link Speeds Vector in the Link Capabilities Register 2 corresponds to the bus below on Root Ports and Downstream Ports, whereas it corresponds to the bus above on Upstream Ports and Endpoints (PCIe r6.1 sec 7.5.3.18): "Supported Link Speeds Vector - This field indicates the supported Link speed(s) of the associated Port." Add supported_speeds into the struct pci_bus that caches the intersection of the upstream and downstream Supported Link Speeds Vectors. When the Function 0 is enumerated, calculate the intersection and set supported_speeds (as per PCIe r6.1 sec 7.5.3.18, the Multi-Function Devices must have the same speeds for all Functions). If no Upstream Port or Endpoint exists, supported_speeds is set to 2.5GT/s. supported_speeds contains a set of Link Speeds only in the case where PCIe Link Speed can be determined. The Root Complex Integrated Endpoints do not have a well-defined Link Speed because they do not seem to implement either of the Link Capabilities Registers, which is allowed by PCIe r6.1 sec 7.5.3 (the same limitation applies to determining cur_bus_speed and max_bus_speed that are PCI_SPEED_UNKNOWN in such case). This is of no concern from PCIe bandwidth controller point of view because such devices are not attached into a PCIe Root Port that could be controlled. supported_speeds field keeps the extra reserved zero at the least significant bit to match the Link Capabilities 2 Register layouting. Suggested-by: Lukas Wunner Signed-off-by: Ilpo Järvinen --- drivers/pci/pci.c | 59 ++++++++++++++++++++++++----------- drivers/pci/probe.c | 8 +++++ drivers/pci/remove.c | 3 ++ include/linux/pci.h | 10 ++++++ include/uapi/linux/pci_regs.h | 1 + 5 files changed, 63 insertions(+), 18 deletions(-) diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c index 55bc3576a985..9c037e90df8a 100644 --- a/drivers/pci/pci.c +++ b/drivers/pci/pci.c @@ -6283,38 +6283,61 @@ u32 pcie_bandwidth_available(struct pci_dev *dev, struct pci_dev **limiting_dev, EXPORT_SYMBOL(pcie_bandwidth_available); /** - * pcie_get_speed_cap - query for the PCI device's link speed capability + * pcie_get_supported_speeds - query Supported Link Speed Vector * @dev: PCI device to query * - * Query the PCI device speed capability. Return the maximum link speed - * supported by the device. + * Query @dev supported link speeds. + * + * Implementation Note in PCIe r6.0.1 sec 7.5.3.18 recommends determining + * supported link speeds using the Supported Link Speeds Vector in the Link + * Capabilities 2 Register (when available). + * + * Link Capabilities 2 was added in PCIe r3.0, sec 7.8.18. + * + * Without Link Capabilities 2, i.e., prior to PCIe r3.0, Supported Link + * Speeds field in Link Capabilities is used and only 2.5 GT/s and 5.0 GT/s + * speeds were defined. + * + * For @dev without Supported Link Speed Vector, the field is synthetized + * from the Max Link Speed field in the Link Capabilities Register. + * + * Return: Supported Link Speeds Vector */ -enum pci_bus_speed pcie_get_speed_cap(struct pci_dev *dev) +u8 pcie_get_supported_speeds(struct pci_dev *dev) { u32 lnkcap2, lnkcap; + u8 speeds; - /* - * Link Capabilities 2 was added in PCIe r3.0, sec 7.8.18. The - * implementation note there recommends using the Supported Link - * Speeds Vector in Link Capabilities 2 when supported. - * - * Without Link Capabilities 2, i.e., prior to PCIe r3.0, software - * should use the Supported Link Speeds field in Link Capabilities, - * where only 2.5 GT/s and 5.0 GT/s speeds were defined. - */ pcie_capability_read_dword(dev, PCI_EXP_LNKCAP2, &lnkcap2); + speeds = lnkcap2 & PCI_EXP_LNKCAP2_SLS; /* PCIe r3.0-compliant */ - if (lnkcap2) - return PCIE_LNKCAP2_SLS2SPEED(lnkcap2); + if (speeds) + return speeds; pcie_capability_read_dword(dev, PCI_EXP_LNKCAP, &lnkcap); + + /* Synthetize from the Max Link Speed field */ if ((lnkcap & PCI_EXP_LNKCAP_SLS) == PCI_EXP_LNKCAP_SLS_5_0GB) - return PCIE_SPEED_5_0GT; + speeds = PCI_EXP_LNKCAP2_SLS_5_0GB | PCI_EXP_LNKCAP2_SLS_2_5GB; else if ((lnkcap & PCI_EXP_LNKCAP_SLS) == PCI_EXP_LNKCAP_SLS_2_5GB) - return PCIE_SPEED_2_5GT; + speeds = PCI_EXP_LNKCAP2_SLS_2_5GB; + + return speeds; +} +EXPORT_SYMBOL_GPL(pcie_get_supported_speeds); - return PCI_SPEED_UNKNOWN; +/** + * pcie_get_speed_cap - query for the PCI device's link speed capability + * @dev: PCI device to query + * + * Query the PCI device speed capability. + * + * Return: the maximum link speed supported by the device. + */ +enum pci_bus_speed pcie_get_speed_cap(struct pci_dev *dev) +{ + return PCIE_LNKCAP2_SLS2SPEED(pcie_get_supported_speeds(dev)); } EXPORT_SYMBOL(pcie_get_speed_cap); diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c index ed6b7f48736a..98700b55e5fd 100644 --- a/drivers/pci/probe.c +++ b/drivers/pci/probe.c @@ -819,6 +819,8 @@ static void pci_set_bus_speed(struct pci_bus *bus) pcie_capability_read_dword(bridge, PCI_EXP_LNKCAP, &linkcap); bus->max_bus_speed = pcie_link_speed[linkcap & PCI_EXP_LNKCAP_SLS]; + if (bus->max_bus_speed != PCI_SPEED_UNKNOWN) + bus->supported_speeds = PCI_EXP_LNKCAP2_SLS_2_5GB; pcie_capability_read_word(bridge, PCI_EXP_LNKSTA, &linksta); pcie_update_link_speed(bus, linksta); @@ -2538,6 +2540,7 @@ static void pci_set_msi_domain(struct pci_dev *dev) void pci_device_add(struct pci_dev *dev, struct pci_bus *bus) { + u8 speeds = 0; int ret; pci_configure_device(dev); @@ -2564,11 +2567,16 @@ void pci_device_add(struct pci_dev *dev, struct pci_bus *bus) pci_init_capabilities(dev); + if (bus->self && pci_is_pcie(dev) && PCI_FUNC(dev->devfn) == 0) { + speeds = pcie_get_supported_speeds(bus->self) & + pcie_get_supported_speeds(dev); + } /* * Add the device to our list of discovered devices * and the bus list for fixup functions, etc. */ down_write(&pci_bus_sem); + bus->supported_speeds = speeds; list_add_tail(&dev->bus_list, &bus->devices); up_write(&pci_bus_sem); diff --git a/drivers/pci/remove.c b/drivers/pci/remove.c index d749ea8250d6..c492527e994a 100644 --- a/drivers/pci/remove.c +++ b/drivers/pci/remove.c @@ -36,6 +36,9 @@ static void pci_destroy_dev(struct pci_dev *dev) device_del(&dev->dev); down_write(&pci_bus_sem); + if (pci_is_pcie(dev) && PCI_FUNC(dev->devfn) == 0 && + dev->bus->max_bus_speed != PCI_SPEED_UNKNOWN) + dev->bus->supported_speeds = PCI_EXP_LNKCAP2_SLS_2_5GB; list_del(&dev->bus_list); up_write(&pci_bus_sem); diff --git a/include/linux/pci.h b/include/linux/pci.h index 345a3d2a3fcd..1e368d7563c5 100644 --- a/include/linux/pci.h +++ b/include/linux/pci.h @@ -303,6 +303,7 @@ enum pci_bus_speed { PCI_SPEED_UNKNOWN = 0xff, }; +u8 pcie_get_supported_speeds(struct pci_dev *dev); enum pci_bus_speed pcie_get_speed_cap(struct pci_dev *dev); enum pcie_link_width pcie_get_width_cap(struct pci_dev *dev); @@ -644,6 +645,14 @@ struct pci_bus_resource { #define PCI_REGION_FLAG_MASK 0x0fU /* These bits of resource flags tell us the PCI region flags */ +/* + * @supported_speeds: PCIe Supported Link Speeds Vector (+ reserved 0 at + * LSB). Combination of downstream and upstream + * Supported Link Speeds Vectors. 0 when speed cannot + * be determined (e.g., for Root Complex Integrated + * Endpoints without the relevant Capability + * Registers). + */ struct pci_bus { struct list_head node; /* Node in list of buses */ struct pci_bus *parent; /* Parent bus this bridge is on */ @@ -664,6 +673,7 @@ struct pci_bus { unsigned char primary; /* Number of primary bridge */ unsigned char max_bus_speed; /* enum pci_bus_speed */ unsigned char cur_bus_speed; /* enum pci_bus_speed */ + u8 supported_speeds; /* Supported Link Speeds Vector */ #ifdef CONFIG_PCI_DOMAINS_GENERIC int domain_nr; #endif diff --git a/include/uapi/linux/pci_regs.h b/include/uapi/linux/pci_regs.h index a39193213ff2..7f929e04222b 100644 --- a/include/uapi/linux/pci_regs.h +++ b/include/uapi/linux/pci_regs.h @@ -676,6 +676,7 @@ #define PCI_EXP_DEVSTA2 0x2a /* Device Status 2 */ #define PCI_CAP_EXP_RC_ENDPOINT_SIZEOF_V2 0x2c /* end of v2 EPs w/o link */ #define PCI_EXP_LNKCAP2 0x2c /* Link Capabilities 2 */ +#define PCI_EXP_LNKCAP2_SLS 0x000000fe /* Supported Link Speeds Vector */ #define PCI_EXP_LNKCAP2_SLS_2_5GB 0x00000002 /* Supported Speed 2.5GT/s */ #define PCI_EXP_LNKCAP2_SLS_5_0GB 0x00000004 /* Supported Speed 5GT/s */ #define PCI_EXP_LNKCAP2_SLS_8_0GB 0x00000008 /* Supported Speed 8GT/s */ From patchwork Fri Jan 5 11:25:45 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Ilpo_J=C3=A4rvinen?= X-Patchwork-Id: 185357 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a05:7301:6f82:b0:100:9c79:88ff with SMTP id tb2csp6158959dyb; Fri, 5 Jan 2024 03:29:56 -0800 (PST) X-Google-Smtp-Source: AGHT+IH4LKa07YLwGbeSe1Z34YrSx8uSdxWm5LhpATQJYDSVeksHHYqWdoNe96KSWHqfbjRig/8O X-Received: by 2002:a17:902:c40a:b0:1d4:3e0e:5d04 with SMTP id k10-20020a170902c40a00b001d43e0e5d04mr1831692plk.98.1704454196608; Fri, 05 Jan 2024 03:29:56 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1704454196; cv=none; d=google.com; s=arc-20160816; b=ABzwqVW0YuLNw9Z4VLP+WJv60P7SnjITJeTjL8p5dqJ1AY4MJfMv72BoTXGV2ZDDws NscwCtcx6UEYcCEfjgFuMz1m0ZSudHfEqIEUvZceC1ewHqiRW50XyDeyvgpgANS0CR8k MuW5ePWuILxI8Z0kd7OYEkeeQHHqNyg5L4WYA8vOKF/R68p3lDZPUXm0zhtfS9kOb2xo XmGiQCE6PFTC/ZXiLlRil1O/fmbCO0CPAtYXghOW1O9YhxmgMEubHxzcJLqhODOEGflM 71dWQyiZ5MGlYqCuePGBt9xsEqs09k9LMWD8wtHfHCQwIgJ+HQfhH+NdSID8TNNt2bPV eIrA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=content-transfer-encoding:mime-version:list-unsubscribe :list-subscribe:list-id:precedence:references:in-reply-to:message-id :date:subject:cc:to:from:dkim-signature; bh=f7QMGsoePiDoOPHDyT822m7KdJAqNv9CaTaJuA/GX6U=; fh=iGIx2GuEPHdFPRPyCcDZ8gIyl77xwP8ohFtQvWIR6L0=; b=efqs27uBSWibFL4KgNMr8OYM74Z985FxFBmTDnxA8UnIXDVu5OzclYX5NSmlp7UnGz BTS6CmPXDrhptLqWflpJbsGyYPnSntJ7f2L3zEi9gyj3LZEQRh0hG/xNhK6mfcJ0WqLf mPvdkNq+2C/DyXNCdhI+POQl6L6OmiA8IqJGmt9IsjWd6Ck+vWK7rzTrX8Kda88obrUc epx6YeZidv6gNpPzKODACf04po3A612XmtN7BEOnmxnEDWMS3csSjvFe4xNWzGaX77TP DOvED4NlgWz1o8Y1a6WP8rdmuwc2XY2uoXQ083NHZ5xcFE477k7Okxc6GffHuU81Bone aN0Q== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@intel.com header.s=Intel header.b=TeJlQLr6; spf=pass (google.com: domain of linux-kernel+bounces-17793-ouuuleilei=gmail.com@vger.kernel.org designates 2604:1380:40f1:3f00::1 as permitted sender) smtp.mailfrom="linux-kernel+bounces-17793-ouuuleilei=gmail.com@vger.kernel.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=intel.com Received: from sy.mirrors.kernel.org (sy.mirrors.kernel.org. [2604:1380:40f1:3f00::1]) by mx.google.com with ESMTPS id a10-20020a170902ecca00b001d40bfdc2c6si1099599plh.63.2024.01.05.03.29.56 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 05 Jan 2024 03:29:56 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel+bounces-17793-ouuuleilei=gmail.com@vger.kernel.org designates 2604:1380:40f1:3f00::1 as permitted sender) client-ip=2604:1380:40f1:3f00::1; Authentication-Results: mx.google.com; dkim=pass header.i=@intel.com header.s=Intel header.b=TeJlQLr6; spf=pass (google.com: domain of linux-kernel+bounces-17793-ouuuleilei=gmail.com@vger.kernel.org designates 2604:1380:40f1:3f00::1 as permitted sender) smtp.mailfrom="linux-kernel+bounces-17793-ouuuleilei=gmail.com@vger.kernel.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=intel.com Received: from smtp.subspace.kernel.org (wormhole.subspace.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by sy.mirrors.kernel.org (Postfix) with ESMTPS id 94C2FB24FFF for ; Fri, 5 Jan 2024 11:28:24 +0000 (UTC) Received: from localhost.localdomain (localhost.localdomain [127.0.0.1]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 6E8672D639; Fri, 5 Jan 2024 11:27:23 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b="TeJlQLr6" X-Original-To: linux-kernel@vger.kernel.org Received: from mgamail.intel.com (mgamail.intel.com [192.55.52.115]) (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 04A9D2D627; Fri, 5 Jan 2024 11:27:18 +0000 (UTC) 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 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1704454039; x=1735990039; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=ORVziuOqV52qk13dBcXsOyQmiqdWdcwRmv7YZT6kchI=; b=TeJlQLr6MRAYnMRhZi0iMtmUmtJPwhHz9Bxl1OCVGxZZ+ocAOxoCU5K7 6UnJXC8yHADiPFPZx2JLvYOW0yb2zvdv8G9nMfm3CekjE7AXHqfAa60y/ P2M9+Jlj8bhW4/vMopsh7SNeK0lIIRfAggFZNPJT8HGs33ebpWJE4yI/K RRkU8Qvi6juF68vLmq0ttJEbyhdq5GLewTySVVAn6zfG9iXQhqF+UJHFW b1P4QXf4t7XLAIibQ2K033rva58Z7FhAhtx09YzS2fiGToxzTcohR+rUg s8h8Datg5eFJMRjvxt8POV8dbxHWdqvsXiVBC3qceNDz6jsDvoMLM8F/d g==; X-IronPort-AV: E=McAfee;i="6600,9927,10943"; a="397208990" X-IronPort-AV: E=Sophos;i="6.04,333,1695711600"; d="scan'208";a="397208990" Received: from fmsmga004.fm.intel.com ([10.253.24.48]) by fmsmga103.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 05 Jan 2024 03:27:18 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=McAfee;i="6600,9927,10943"; a="851118223" X-IronPort-AV: E=Sophos;i="6.04,333,1695711600"; d="scan'208";a="851118223" Received: from ijarvine-desk1.ger.corp.intel.com (HELO localhost) ([10.246.32.38]) by fmsmga004-auth.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 05 Jan 2024 03:27:12 -0800 From: =?utf-8?q?Ilpo_J=C3=A4rvinen?= To: linux-pci@vger.kernel.org, Bjorn Helgaas , Lorenzo Pieralisi , Rob Herring , =?utf-8?q?Krzysztof_Wilczy=C5=84ski?= , Lukas Wunner , Alexandru Gagniuc , Krishna chaitanya chundru , Srinivas Pandruvada , "Rafael J. Wysocki" , linux-pm@vger.kernel.org, =?utf-8?q?Ilpo_J=C3=A4rvinen?= , linux-kernel@vger.kernel.org Cc: Alex Deucher , Daniel Lezcano , Amit Kucheria , Zhang Rui Subject: [PATCH v4 6/8] PCI/link: Re-add BW notification portdrv as PCIe BW controller Date: Fri, 5 Jan 2024 13:25:45 +0200 Message-Id: <20240105112547.7301-7-ilpo.jarvinen@linux.intel.com> X-Mailer: git-send-email 2.39.2 In-Reply-To: <20240105112547.7301-1-ilpo.jarvinen@linux.intel.com> References: <20240105112547.7301-1-ilpo.jarvinen@linux.intel.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-getmail-retrieved-from-mailbox: INBOX X-GMAIL-THRID: 1787249763669318961 X-GMAIL-MSGID: 1787249763669318961 This mostly reverts b4c7d2076b4e ("PCI/LINK: Remove bandwidth notification") and builds PCIe bandwidth controller on top of it. The PCIe bandwidth notification were first added in the commit e8303bb7a75c ("PCI/LINK: Report degraded links via link bandwidth notification") but later had to be removed. The significant changes compared with the old bandwidth notification driver include: 1) Don't print the notifications into kernel log, just keep the Link Speed cached into the struct pci_bus updated. While somewhat unfortunate, the log spam was the source of complaints that eventually lead to the removal of the bandwidth notifications driver (see the links below for further information). 2) Besides the Link Bandwidth Management Interrupt, enable also Link Autonomous Bandwidth Interrupt to cover the other source of bandwidth changes. 3) Use threaded IRQ with IRQF_ONESHOT to handle Bandwidth Notification Interrupts to address the problem fixed in the commit 3e82a7f9031f ("PCI/LINK: Supply IRQ handler so level-triggered IRQs are acked")). 4) Handle Link Speed updates robustly. Refresh the cached Link Speed when enabling Bandwidth Notification Interrupts, and solve the race between Link Speed read and LBMS/LABS update in pcie_bandwidth_notification_irq_thread(). 5) Use concurrency safe LNKCTL RMW operations. 6) The driver is now called PCIe bwctrl (bandwidth controller) instead of just bandwidth notifications because of increased scope and functionality within the driver. PCIe bandwidth controller introduces an in-kernel API to set PCIe Link Speed. This new API is intended to be used in an upcoming commit that adds a thermal cooling device to throttle PCIe bandwidth when thermal thresholds are reached. No users are introduced in this commit yet. The PCIe bandwidth control procedure is as follows. The highest speed supported by the Port and the PCIe device which is not higher than the requested speed is selected and written into the Target Link Speed in the Link Control 2 Register. Then bandwidth controller retrains the PCIe Link. Bandwidth Notifications enable the cur_bus_speed in the struct pci_bus to keep track PCIe Link Speed changes. While Bandwidth Notifications should also be generated when bandwidth controller alters the PCIe Link Speed, a few platforms do not deliver LMBS interrupt after Link Training as expected. Thus, after changing the Link Speed, bandwidth controller makes additional read for the Link Status Register to ensure cur_bus_speed is consistent with the new PCIe Link Speed. Link: https://lore.kernel.org/all/20190429185611.121751-1-helgaas@kernel.org/ Link: https://lore.kernel.org/linux-pci/20190501142942.26972-1-keith.busch@intel.com/ Link: https://lore.kernel.org/linux-pci/20200115221008.GA191037@google.com/ Suggested-by: Lukas Wunner Signed-off-by: Ilpo Järvinen --- MAINTAINERS | 7 + drivers/pci/pcie/Kconfig | 12 ++ drivers/pci/pcie/Makefile | 1 + drivers/pci/pcie/bwctrl.c | 263 +++++++++++++++++++++++++++++++++++++ drivers/pci/pcie/portdrv.c | 9 +- drivers/pci/pcie/portdrv.h | 10 +- include/linux/pci-bwctrl.h | 17 +++ 7 files changed, 313 insertions(+), 6 deletions(-) create mode 100644 drivers/pci/pcie/bwctrl.c create mode 100644 include/linux/pci-bwctrl.h diff --git a/MAINTAINERS b/MAINTAINERS index 97f51d5ec1cf..ccc5d50bf340 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -16766,6 +16766,13 @@ F: include/linux/pci* F: include/uapi/linux/pci* F: lib/pci* +PCIE BANDWIDTH CONTROLLER +M: Ilpo Järvinen +L: linux-pci@vger.kernel.org +S: Supported +F: drivers/pci/pcie/bwctrl.c +F: include/linux/pci-bwctrl.h + PCIE DRIVER FOR AMAZON ANNAPURNA LABS M: Jonathan Chocron L: linux-pci@vger.kernel.org diff --git a/drivers/pci/pcie/Kconfig b/drivers/pci/pcie/Kconfig index 8999fcebde6a..f1ef6030d2c2 100644 --- a/drivers/pci/pcie/Kconfig +++ b/drivers/pci/pcie/Kconfig @@ -146,6 +146,18 @@ config PCIE_PTM This is only useful if you have devices that support PTM, but it is safe to enable even if you don't. +config PCIE_BW + bool "PCI Express Bandwidth Controller" + depends on PCIEPORTBUS + help + This enables PCI Express Bandwidth Controller. The Bandwidth + Controller allows controlling PCIe Link Speed and listens for Link + Bandwidth Change Notifications. The current Link Speed is available + through /sys/bus/pci/devices/.../current_link_speed. + + If you know Link Width or Speed changes occur (e.g., to correct + unreliable links), you may answer Y. + config PCIE_EDR bool "PCI Express Error Disconnect Recover support" depends on PCIE_DPC && ACPI diff --git a/drivers/pci/pcie/Makefile b/drivers/pci/pcie/Makefile index 8de4ed5f98f1..175065a495cf 100644 --- a/drivers/pci/pcie/Makefile +++ b/drivers/pci/pcie/Makefile @@ -12,4 +12,5 @@ obj-$(CONFIG_PCIEAER_INJECT) += aer_inject.o obj-$(CONFIG_PCIE_PME) += pme.o obj-$(CONFIG_PCIE_DPC) += dpc.o obj-$(CONFIG_PCIE_PTM) += ptm.o +obj-$(CONFIG_PCIE_BW) += bwctrl.o obj-$(CONFIG_PCIE_EDR) += edr.o diff --git a/drivers/pci/pcie/bwctrl.c b/drivers/pci/pcie/bwctrl.c new file mode 100644 index 000000000000..e17c98c25f06 --- /dev/null +++ b/drivers/pci/pcie/bwctrl.c @@ -0,0 +1,263 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * PCIe bandwidth controller + * + * Author: Alexandru Gagniuc + * + * Copyright (C) 2019 Dell Inc + * Copyright (C) 2023 Intel Corporation + * + * The PCIe bandwidth controller provides a way to alter PCIe Link Speeds + * and notify the operating system when the Link Width or Speed changes. The + * notification capability is required for all Root Ports and Downstream + * Ports supporting Link Width wider than x1 and/or multiple Link Speeds. + * + * This service port driver hooks into the Bandwidth Notification interrupt + * watching for changes or links becoming degraded in operation. It updates + * the cached Current Link Speed that is exposed to user space through sysfs. + */ + +#define dev_fmt(fmt) "bwctrl: " fmt + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "../pci.h" +#include "portdrv.h" + +/** + * struct pcie_bwctrl_service_data - PCIe bandwidth controller + * @set_speed_mutex: serializes link speed changes + */ +struct pcie_bwctrl_service_data { + struct mutex set_speed_mutex; +}; + +static bool pcie_valid_speed(enum pci_bus_speed speed) +{ + return (speed >= PCIE_SPEED_2_5GT) && (speed <= PCIE_SPEED_64_0GT); +} + +static u16 pci_bus_speed2lnkctl2(enum pci_bus_speed speed) +{ + static const u8 speed_conv[] = { + [PCIE_SPEED_2_5GT] = PCI_EXP_LNKCTL2_TLS_2_5GT, + [PCIE_SPEED_5_0GT] = PCI_EXP_LNKCTL2_TLS_5_0GT, + [PCIE_SPEED_8_0GT] = PCI_EXP_LNKCTL2_TLS_8_0GT, + [PCIE_SPEED_16_0GT] = PCI_EXP_LNKCTL2_TLS_16_0GT, + [PCIE_SPEED_32_0GT] = PCI_EXP_LNKCTL2_TLS_32_0GT, + [PCIE_SPEED_64_0GT] = PCI_EXP_LNKCTL2_TLS_64_0GT, + }; + + if (WARN_ON_ONCE(!pcie_valid_speed(speed))) + return 0; + + return speed_conv[speed]; +} + +static inline u16 pcie_supported_speeds2target_speed(u8 supported_speeds) +{ + return __fls(supported_speeds); +} + +static void pcie_bwnotif_enable(struct pci_dev *dev) +{ + u16 link_status; + int ret; + + pcie_capability_set_word(dev, PCI_EXP_LNKCTL, + PCI_EXP_LNKCTL_LBMIE | PCI_EXP_LNKCTL_LABIE); + pcie_capability_write_word(dev, PCI_EXP_LNKSTA, + PCI_EXP_LNKSTA_LBMS | PCI_EXP_LNKSTA_LABS); + + /* Read after enabling notifications to ensure link speed is up to date */ + ret = pcie_capability_read_word(dev, PCI_EXP_LNKSTA, &link_status); + if (ret == PCIBIOS_SUCCESSFUL) + pcie_update_link_speed(dev->subordinate, link_status); +} + +static void pcie_bwnotif_disable(struct pci_dev *dev) +{ + pcie_capability_clear_word(dev, PCI_EXP_LNKCTL, + PCI_EXP_LNKCTL_LBMIE | PCI_EXP_LNKCTL_LABIE); +} + +static irqreturn_t pcie_bwnotif_irq_thread(int irq, void *context) +{ + struct pcie_device *srv = context; + struct pci_dev *port = srv->port; + u16 link_status, events; + int ret; + + ret = pcie_capability_read_word(port, PCI_EXP_LNKSTA, &link_status); + events = link_status & (PCI_EXP_LNKSTA_LBMS | PCI_EXP_LNKSTA_LABS); + + if (ret != PCIBIOS_SUCCESSFUL || !events) + return IRQ_NONE; + + pcie_capability_write_word(port, PCI_EXP_LNKSTA, events); + + /* + * The write to clear LBMS prevents getting interrupt from the + * latest link speed when the link speed changes between the above + * LNKSTA read and write. Therefore, re-read the speed before + * updating it. + */ + ret = pcie_capability_read_word(port, PCI_EXP_LNKSTA, &link_status); + if (ret != PCIBIOS_SUCCESSFUL) + return IRQ_HANDLED; + pcie_update_link_speed(port->subordinate, link_status); + + return IRQ_HANDLED; +} + +/** + * pcie_bwctrl_select_speed - Select Target Link Speed + * @srv: PCIe Port + * @speed_req: requested PCIe Link Speed + * + * Select Target Link Speed by take into account Supported Link Speeds of + * both the Root Port and the Endpoint. + * + * Return: Target Link Speed (1=2.5GT/s, 2=5GT/s, 3=8GT/s, etc.) + */ +static u16 pcie_bwctrl_select_speed(struct pcie_device *srv, enum pci_bus_speed speed_req) +{ + struct pci_bus *bus = srv->port->subordinate; + u8 desired_speeds; + + if (WARN_ON_ONCE(!bus->supported_speeds)) + return PCI_EXP_LNKCAP2_SLS_2_5GB; + + desired_speeds = GENMASK(pci_bus_speed2lnkctl2(speed_req), + __fls(PCI_EXP_LNKCAP2_SLS_2_5GB)); + + return pcie_supported_speeds2target_speed(bus->supported_speeds & desired_speeds); +} + +/** + * pcie_bwctrl_set_current_speed - Set downstream Link Speed for PCIe Port + * @srv: PCIe Port + * @speed_req: requested PCIe Link Speed + * + * Attempts to set PCIe Port Link Speed to @speed_req. @speed_req may be + * adjusted downwards to the best speed supported by both the Port and PCIe + * Device underneath it. + * + * Return: + * * 0 - on success + * * -EINVAL - @speed_req is not a PCIe Link Speed + * * -ETIMEDOUT - changing Link Speed took too long + * * -EAGAIN - Link Speed was changed but @speed_req was not achieved + */ +int pcie_bwctrl_set_current_speed(struct pcie_device *srv, enum pci_bus_speed speed_req) +{ + struct pcie_bwctrl_service_data *data = get_service_data(srv); + struct pci_dev *port = srv->port; + u16 target_speed, link_status; + int ret; + + if (WARN_ON_ONCE(!pcie_valid_speed(speed_req))) + return -EINVAL; + + if (port->subordinate->cur_bus_speed == speed_req) + return 0; + + target_speed = pcie_bwctrl_select_speed(srv, speed_req); + + mutex_lock(&data->set_speed_mutex); + ret = pcie_capability_clear_and_set_word(port, PCI_EXP_LNKCTL2, + PCI_EXP_LNKCTL2_TLS, target_speed); + if (ret != PCIBIOS_SUCCESSFUL) { + ret = pcibios_err_to_errno(ret); + goto unlock; + } + + ret = pcie_retrain_link(port, true); + if (ret < 0) + goto unlock; + + /* + * Ensure link speed updates also with platforms that have problems + * with notifications + */ + ret = pcie_capability_read_word(port, PCI_EXP_LNKSTA, &link_status); + if (ret == PCIBIOS_SUCCESSFUL) + pcie_update_link_speed(port->subordinate, link_status); + + if (port->subordinate->cur_bus_speed != speed_req) + ret = -EAGAIN; + +unlock: + mutex_unlock(&data->set_speed_mutex); + + return ret; +} + +static int pcie_bwnotif_probe(struct pcie_device *srv) +{ + struct pcie_bwctrl_service_data *data; + struct pci_dev *port = srv->port; + int ret; + + data = devm_kzalloc(&srv->device, sizeof(*data), GFP_KERNEL); + if (!data) + return -ENOMEM; + + mutex_init(&data->set_speed_mutex); + set_service_data(srv, data); + + ret = devm_request_threaded_irq(&srv->device, srv->irq, NULL, + pcie_bwnotif_irq_thread, + IRQF_SHARED | IRQF_ONESHOT, + "PCIe BW ctrl", srv); + if (ret) + return ret; + + pcie_bwnotif_enable(port); + pci_info(port, "enabled with IRQ %d\n", srv->irq); + + return 0; +} + +static void pcie_bwnotif_remove(struct pcie_device *srv) +{ + struct pcie_bwctrl_service_data *data = get_service_data(srv); + + pcie_bwnotif_disable(srv->port); + mutex_destroy(&data->set_speed_mutex); +} + +static int pcie_bwnotif_suspend(struct pcie_device *srv) +{ + pcie_bwnotif_disable(srv->port); + return 0; +} + +static int pcie_bwnotif_resume(struct pcie_device *srv) +{ + pcie_bwnotif_enable(srv->port); + return 0; +} + +static struct pcie_port_service_driver pcie_bwctrl_driver = { + .name = "pcie_bwctrl", + .port_type = PCIE_ANY_PORT, + .service = PCIE_PORT_SERVICE_BWCTRL, + .probe = pcie_bwnotif_probe, + .suspend = pcie_bwnotif_suspend, + .resume = pcie_bwnotif_resume, + .remove = pcie_bwnotif_remove, +}; + +int __init pcie_bwctrl_init(void) +{ + return pcie_port_service_register(&pcie_bwctrl_driver); +} diff --git a/drivers/pci/pcie/portdrv.c b/drivers/pci/pcie/portdrv.c index 14a4b89a3b83..e8a348949d70 100644 --- a/drivers/pci/pcie/portdrv.c +++ b/drivers/pci/pcie/portdrv.c @@ -68,7 +68,7 @@ static int pcie_message_numbers(struct pci_dev *dev, int mask, */ if (mask & (PCIE_PORT_SERVICE_PME | PCIE_PORT_SERVICE_HP | - PCIE_PORT_SERVICE_BWNOTIF)) { + PCIE_PORT_SERVICE_BWCTRL)) { pcie_capability_read_word(dev, PCI_EXP_FLAGS, ®16); *pme = FIELD_GET(PCI_EXP_FLAGS_IRQ, reg16); nvec = *pme + 1; @@ -150,11 +150,11 @@ static int pcie_port_enable_irq_vec(struct pci_dev *dev, int *irqs, int mask) /* PME, hotplug and bandwidth notification share an MSI/MSI-X vector */ if (mask & (PCIE_PORT_SERVICE_PME | PCIE_PORT_SERVICE_HP | - PCIE_PORT_SERVICE_BWNOTIF)) { + PCIE_PORT_SERVICE_BWCTRL)) { pcie_irq = pci_irq_vector(dev, pme); irqs[PCIE_PORT_SERVICE_PME_SHIFT] = pcie_irq; irqs[PCIE_PORT_SERVICE_HP_SHIFT] = pcie_irq; - irqs[PCIE_PORT_SERVICE_BWNOTIF_SHIFT] = pcie_irq; + irqs[PCIE_PORT_SERVICE_BWCTRL_SHIFT] = pcie_irq; } if (mask & PCIE_PORT_SERVICE_AER) @@ -271,7 +271,7 @@ static int get_port_device_capability(struct pci_dev *dev) pcie_capability_read_dword(dev, PCI_EXP_LNKCAP, &linkcap); if (linkcap & PCI_EXP_LNKCAP_LBNC) - services |= PCIE_PORT_SERVICE_BWNOTIF; + services |= PCIE_PORT_SERVICE_BWCTRL; } return services; @@ -829,6 +829,7 @@ static void __init pcie_init_services(void) pcie_pme_init(); pcie_dpc_init(); pcie_hp_init(); + pcie_bwctrl_init(); } static int __init pcie_portdrv_init(void) diff --git a/drivers/pci/pcie/portdrv.h b/drivers/pci/pcie/portdrv.h index 1f3803bde7ee..9628bb04a8ff 100644 --- a/drivers/pci/pcie/portdrv.h +++ b/drivers/pci/pcie/portdrv.h @@ -20,8 +20,8 @@ #define PCIE_PORT_SERVICE_HP (1 << PCIE_PORT_SERVICE_HP_SHIFT) #define PCIE_PORT_SERVICE_DPC_SHIFT 3 /* Downstream Port Containment */ #define PCIE_PORT_SERVICE_DPC (1 << PCIE_PORT_SERVICE_DPC_SHIFT) -#define PCIE_PORT_SERVICE_BWNOTIF_SHIFT 4 /* Bandwidth notification */ -#define PCIE_PORT_SERVICE_BWNOTIF (1 << PCIE_PORT_SERVICE_BWNOTIF_SHIFT) +#define PCIE_PORT_SERVICE_BWCTRL_SHIFT 4 /* Bandwidth Controller (notifications) */ +#define PCIE_PORT_SERVICE_BWCTRL (1 << PCIE_PORT_SERVICE_BWCTRL_SHIFT) #define PCIE_PORT_DEVICE_MAXSERVICES 5 @@ -51,6 +51,12 @@ int pcie_dpc_init(void); static inline int pcie_dpc_init(void) { return 0; } #endif +#ifdef CONFIG_PCIE_BW +int pcie_bwctrl_init(void); +#else +static inline int pcie_bwctrl_init(void) { return 0; } +#endif + /* Port Type */ #define PCIE_ANY_PORT (~0) diff --git a/include/linux/pci-bwctrl.h b/include/linux/pci-bwctrl.h new file mode 100644 index 000000000000..be51f6f2b340 --- /dev/null +++ b/include/linux/pci-bwctrl.h @@ -0,0 +1,17 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * PCIe bandwidth controller + * + * Copyright (C) 2023 Intel Corporation + */ + +#ifndef LINUX_PCI_BWCTRL_H +#define LINUX_PCI_BWCTRL_H + +#include + +struct pcie_device; + +int pcie_bwctrl_set_current_speed(struct pcie_device *srv, enum pci_bus_speed speed_req); + +#endif From patchwork Fri Jan 5 11:25:46 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Ilpo_J=C3=A4rvinen?= X-Patchwork-Id: 185358 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a05:7301:6f82:b0:100:9c79:88ff with SMTP id tb2csp6159203dyb; Fri, 5 Jan 2024 03:30:28 -0800 (PST) X-Google-Smtp-Source: AGHT+IGoNrxwIhxLGlmIiSWvvm5qkGdY3PAVUmz/7zcRIi1iN+mgGO1JgAcAKuw8uliUgBH2zC1Y X-Received: by 2002:a05:6870:c697:b0:203:ec56:f0a2 with SMTP id cv23-20020a056870c69700b00203ec56f0a2mr2029857oab.44.1704454228216; Fri, 05 Jan 2024 03:30:28 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1704454228; cv=none; d=google.com; s=arc-20160816; b=0f1qKbQKB8y0Xe8ZFKchvWPsQC6ktZThTuNeY/Dr0zbFKDt1nDTjeysdRiY94KGo3H XnJaQ/hwatb0vLXY32fIzOP2WUvl/6m/3xdGdnLhRTr/D0JBzdgJU35KJVdqG78tX+fj lkitlRllz5QP3gUkx4pvKpI7ctHkLR9z1InFRdpOvP1FCC92UnwJcOSQZ94ouiY1mljB 2qa+Rg9zGoBJtG+cbOYE66bMl950oS371SpkOr0XKDTXTbZ1MBOCc4zaIAQ9gLgvJbm1 18ak6u+LwimNqzGK4+QX9LdbBMyoEO0w0JH6ou38qTDaXY0aLDFh0O0b6rUYlHDPJbGy gvSQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=content-transfer-encoding:mime-version:list-unsubscribe :list-subscribe:list-id:precedence:references:in-reply-to:message-id :date:subject:cc:to:from:dkim-signature; bh=wql3/NldYvSGEoEk5fWgdBwwNWgdOfSOjmaif7SpKPA=; fh=6kw6ElUUBZWBt0kt5gFbKtjIy5IPniKqMnWFK7Y2ljs=; b=R5xHSnYomz6ftBIUPHNEE+UH+zotcULYz5u8x4//ujgdvZvdM/IOjLmceVgYR5UVAq 5nS554/lo8to2EsUMVFYE8EvSExaA/u8xbBVnJCPfl/v3fGLSA2D8ewvIkRjYyCsBfbz dkPGc44Rgiv8TE9bK0RaXv7CsWwGbZTFYiuZHKAf9PoYEmjmerdxl7ccyVOoetxar/RK ULbQwhSwx0pspffylk7T+SbJjqDIRyX9Vw5Zf9yrGNZ5kvU6O/vAAAYK6747ujHzoBbB ZGIyGXWQp5Bd7xllpeIPJo8JF/GtpAiqAgF1vgmxejkjI5UerLQU3l/TZm400dJ4Fr5B SY1A== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@intel.com header.s=Intel header.b=cE+MrRpG; spf=pass (google.com: domain of linux-kernel+bounces-17794-ouuuleilei=gmail.com@vger.kernel.org designates 2604:1380:40f1:3f00::1 as permitted sender) smtp.mailfrom="linux-kernel+bounces-17794-ouuuleilei=gmail.com@vger.kernel.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=intel.com Received: from sy.mirrors.kernel.org (sy.mirrors.kernel.org. [2604:1380:40f1:3f00::1]) by mx.google.com with ESMTPS id s129-20020a632c87000000b005ce0764f139si1101652pgs.770.2024.01.05.03.30.27 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 05 Jan 2024 03:30:28 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel+bounces-17794-ouuuleilei=gmail.com@vger.kernel.org designates 2604:1380:40f1:3f00::1 as permitted sender) client-ip=2604:1380:40f1:3f00::1; Authentication-Results: mx.google.com; dkim=pass header.i=@intel.com header.s=Intel header.b=cE+MrRpG; spf=pass (google.com: domain of linux-kernel+bounces-17794-ouuuleilei=gmail.com@vger.kernel.org designates 2604:1380:40f1:3f00::1 as permitted sender) smtp.mailfrom="linux-kernel+bounces-17794-ouuuleilei=gmail.com@vger.kernel.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=intel.com Received: from smtp.subspace.kernel.org (wormhole.subspace.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by sy.mirrors.kernel.org (Postfix) with ESMTPS id 49749B250FD for ; Fri, 5 Jan 2024 11:28:45 +0000 (UTC) Received: from localhost.localdomain (localhost.localdomain [127.0.0.1]) by smtp.subspace.kernel.org (Postfix) with ESMTP id E9CBE2D78A; Fri, 5 Jan 2024 11:27:34 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b="cE+MrRpG" X-Original-To: linux-kernel@vger.kernel.org Received: from mgamail.intel.com (mgamail.intel.com [198.175.65.10]) (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 D84E42D604; Fri, 5 Jan 2024 11:27:30 +0000 (UTC) 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 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1704454051; x=1735990051; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=4XhcGmmYjn0I6IWJn/zmvmCpFHXqHm+/LLv5Dqbi2Nw=; b=cE+MrRpG8JdYmytRJMw5pz1lC9JeCwONhmdd9Cgzd0HfFjNSwXgcVl53 Ft0ur/wIbr6mRzIIYIcGpHVqrI/LEuQGmaV+eziJeTQuioSwMyFwy0LaC e+DtN49v2eYkdEG7E/zzbRv+nDIETS1dxi1hYSp9z+7p7HiJFvLq2PMFq Spq5CMl7exUn8BN4vZvr9UuZPus79s3TOcQasm5P9TGNSTOCgQVffy5SY CcZdcGC/WUtwXunUpy4IX7Ss1LEkqoMsfbj9Jziuof/uz15sWVxkK2ZQ4 +y2pG0OTrTUQpNra+xqvs2oHsG9AaHVU3Gy3WRa8bxyaevTR6wU5Js9hH g==; X-IronPort-AV: E=McAfee;i="6600,9927,10943"; a="10858546" X-IronPort-AV: E=Sophos;i="6.04,333,1695711600"; d="scan'208";a="10858546" Received: from orsmga007.jf.intel.com ([10.7.209.58]) by orvoesa102.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 05 Jan 2024 03:27:30 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=McAfee;i="6600,9927,10943"; a="773827916" X-IronPort-AV: E=Sophos;i="6.04,333,1695711600"; d="scan'208";a="773827916" Received: from ijarvine-desk1.ger.corp.intel.com (HELO localhost) ([10.246.32.38]) by orsmga007-auth.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 05 Jan 2024 03:27:23 -0800 From: =?utf-8?q?Ilpo_J=C3=A4rvinen?= To: linux-pci@vger.kernel.org, Bjorn Helgaas , Lorenzo Pieralisi , Rob Herring , =?utf-8?q?Krzysztof_Wilczy=C5=84ski?= , Lukas Wunner , Alexandru Gagniuc , Krishna chaitanya chundru , Srinivas Pandruvada , "Rafael J. Wysocki" , linux-pm@vger.kernel.org, =?utf-8?q?Ilpo_J=C3=A4rvinen?= , Daniel Lezcano , Zhang Rui , Lukasz Luba , linux-kernel@vger.kernel.org Cc: Alex Deucher , Amit Kucheria Subject: [PATCH v4 7/8] thermal: Add PCIe cooling driver Date: Fri, 5 Jan 2024 13:25:46 +0200 Message-Id: <20240105112547.7301-8-ilpo.jarvinen@linux.intel.com> X-Mailer: git-send-email 2.39.2 In-Reply-To: <20240105112547.7301-1-ilpo.jarvinen@linux.intel.com> References: <20240105112547.7301-1-ilpo.jarvinen@linux.intel.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-getmail-retrieved-from-mailbox: INBOX X-GMAIL-THRID: 1787249796745881894 X-GMAIL-MSGID: 1787249796745881894 Add a thermal cooling driver to provide path to access PCIe bandwidth controller using the usual thermal interfaces. A cooling device is instantiated for controllable PCIe Ports from the bwctrl service driver. The thermal side state 0 means no throttling, i.e., maximum supported PCIe Link Speed. Signed-off-by: Ilpo Järvinen Acked-by: Rafael J. Wysocki # From the cooling device interface perspective --- MAINTAINERS | 1 + drivers/pci/pcie/bwctrl.c | 6 ++ drivers/thermal/Kconfig | 10 +++ drivers/thermal/Makefile | 2 + drivers/thermal/pcie_cooling.c | 107 +++++++++++++++++++++++++++++++++ include/linux/pci-bwctrl.h | 16 +++++ 6 files changed, 142 insertions(+) create mode 100644 drivers/thermal/pcie_cooling.c diff --git a/MAINTAINERS b/MAINTAINERS index ccc5d50bf340..0cacc7e777c5 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -16771,6 +16771,7 @@ M: Ilpo Järvinen L: linux-pci@vger.kernel.org S: Supported F: drivers/pci/pcie/bwctrl.c +F: drivers/thermal/pcie_cooling.c F: include/linux/pci-bwctrl.h PCIE DRIVER FOR AMAZON ANNAPURNA LABS diff --git a/drivers/pci/pcie/bwctrl.c b/drivers/pci/pcie/bwctrl.c index e17c98c25f06..6c50fabfea39 100644 --- a/drivers/pci/pcie/bwctrl.c +++ b/drivers/pci/pcie/bwctrl.c @@ -35,9 +35,11 @@ /** * struct pcie_bwctrl_service_data - PCIe bandwidth controller * @set_speed_mutex: serializes link speed changes + * @cdev: thermal cooling device associated with the port */ struct pcie_bwctrl_service_data { struct mutex set_speed_mutex; + struct thermal_cooling_device *cdev; }; static bool pcie_valid_speed(enum pci_bus_speed speed) @@ -224,6 +226,8 @@ static int pcie_bwnotif_probe(struct pcie_device *srv) pcie_bwnotif_enable(port); pci_info(port, "enabled with IRQ %d\n", srv->irq); + data->cdev = pcie_cooling_device_register(port, srv); + return 0; } @@ -231,6 +235,8 @@ static void pcie_bwnotif_remove(struct pcie_device *srv) { struct pcie_bwctrl_service_data *data = get_service_data(srv); + if (data->cdev) + pcie_cooling_device_unregister(data->cdev); pcie_bwnotif_disable(srv->port); mutex_destroy(&data->set_speed_mutex); } diff --git a/drivers/thermal/Kconfig b/drivers/thermal/Kconfig index c81a00fbca7d..3a071396f1c6 100644 --- a/drivers/thermal/Kconfig +++ b/drivers/thermal/Kconfig @@ -219,6 +219,16 @@ config DEVFREQ_THERMAL If you want this support, you should say Y here. +config PCIE_THERMAL + bool "PCIe cooling support" + depends on PCIEPORTBUS + select PCIE_BW + help + This implements PCIe cooling mechanism through bandwidth reduction + for PCIe devices. + + If you want this support, you should say Y here. + config THERMAL_EMULATION bool "Thermal emulation mode support" help diff --git a/drivers/thermal/Makefile b/drivers/thermal/Makefile index c934cab309ae..a0b25a2742b7 100644 --- a/drivers/thermal/Makefile +++ b/drivers/thermal/Makefile @@ -30,6 +30,8 @@ thermal_sys-$(CONFIG_CPU_IDLE_THERMAL) += cpuidle_cooling.o # devfreq cooling thermal_sys-$(CONFIG_DEVFREQ_THERMAL) += devfreq_cooling.o +thermal_sys-$(CONFIG_PCIE_THERMAL) += pcie_cooling.o + obj-$(CONFIG_K3_THERMAL) += k3_bandgap.o k3_j72xx_bandgap.o # platform thermal drivers obj-y += broadcom/ diff --git a/drivers/thermal/pcie_cooling.c b/drivers/thermal/pcie_cooling.c new file mode 100644 index 000000000000..5fc52d410161 --- /dev/null +++ b/drivers/thermal/pcie_cooling.c @@ -0,0 +1,107 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * PCIe cooling device + * + * Copyright (C) 2023 Intel Corporation + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#define COOLING_DEV_TYPE_PREFIX "PCIe_Port_Link_Speed_" + +struct pcie_cooling_device { + struct pci_dev *port; + struct pcie_device *pdev; +}; + +static int pcie_cooling_get_max_level(struct thermal_cooling_device *cdev, unsigned long *state) +{ + struct pcie_cooling_device *pcie_cdev = cdev->devdata; + + /* cooling state 0 is same as the maximum PCIe speed */ + *state = pcie_cdev->port->subordinate->max_bus_speed - PCIE_SPEED_2_5GT; + + return 0; +} + +static int pcie_cooling_get_cur_level(struct thermal_cooling_device *cdev, unsigned long *state) +{ + struct pcie_cooling_device *pcie_cdev = cdev->devdata; + + /* cooling state 0 is same as the maximum PCIe speed */ + *state = cdev->max_state - + (pcie_cdev->port->subordinate->cur_bus_speed - PCIE_SPEED_2_5GT); + + return 0; +} + +static int pcie_cooling_set_cur_level(struct thermal_cooling_device *cdev, unsigned long state) +{ + struct pcie_cooling_device *pcie_cdev = cdev->devdata; + enum pci_bus_speed speed; + + /* cooling state 0 is same as the maximum PCIe speed */ + speed = (cdev->max_state - state) + PCIE_SPEED_2_5GT; + + return pcie_bwctrl_set_current_speed(pcie_cdev->pdev, speed); +} + +static struct thermal_cooling_device_ops pcie_cooling_ops = { + .get_max_state = pcie_cooling_get_max_level, + .get_cur_state = pcie_cooling_get_cur_level, + .set_cur_state = pcie_cooling_set_cur_level, +}; + +struct thermal_cooling_device *pcie_cooling_device_register(struct pci_dev *port, + struct pcie_device *pdev) +{ + struct pcie_cooling_device *pcie_cdev; + struct thermal_cooling_device *cdev; + size_t name_len; + char *name; + + pcie_cdev = kzalloc(sizeof(*pcie_cdev), GFP_KERNEL); + if (!pcie_cdev) + return ERR_PTR(-ENOMEM); + + pcie_cdev->port = port; + pcie_cdev->pdev = pdev; + + name_len = strlen(COOLING_DEV_TYPE_PREFIX) + strlen(pci_name(port)) + 1; + name = kzalloc(name_len, GFP_KERNEL); + if (!name) { + kfree(pcie_cdev); + return ERR_PTR(-ENOMEM); + } + + snprintf(name, name_len, COOLING_DEV_TYPE_PREFIX "%s", pci_name(port)); + cdev = thermal_cooling_device_register(name, pcie_cdev, &pcie_cooling_ops); + kfree(name); + + return cdev; +} + +void pcie_cooling_device_unregister(struct thermal_cooling_device *cdev) +{ + struct pcie_cooling_device *pcie_cdev = cdev->devdata; + + thermal_cooling_device_unregister(cdev); + kfree(pcie_cdev); +} + +/* For bus_speed <-> state arithmetic */ +static_assert(PCIE_SPEED_2_5GT + 1 == PCIE_SPEED_5_0GT); +static_assert(PCIE_SPEED_5_0GT + 1 == PCIE_SPEED_8_0GT); +static_assert(PCIE_SPEED_8_0GT + 1 == PCIE_SPEED_16_0GT); +static_assert(PCIE_SPEED_16_0GT + 1 == PCIE_SPEED_32_0GT); +static_assert(PCIE_SPEED_32_0GT + 1 == PCIE_SPEED_64_0GT); + +MODULE_AUTHOR("Ilpo Järvinen "); +MODULE_DESCRIPTION("PCIe cooling driver"); diff --git a/include/linux/pci-bwctrl.h b/include/linux/pci-bwctrl.h index be51f6f2b340..ec5b1c3515d8 100644 --- a/include/linux/pci-bwctrl.h +++ b/include/linux/pci-bwctrl.h @@ -11,7 +11,23 @@ #include struct pcie_device; +struct thermal_cooling_device; int pcie_bwctrl_set_current_speed(struct pcie_device *srv, enum pci_bus_speed speed_req); +#ifdef CONFIG_PCIE_THERMAL +struct thermal_cooling_device *pcie_cooling_device_register(struct pci_dev *port, + struct pcie_device *pdev); +void pcie_cooling_device_unregister(struct thermal_cooling_device *cdev); +#else +static inline struct thermal_cooling_device *pcie_cooling_device_register(struct pci_dev *port, + struct pcie_device *pdev) +{ + return NULL; +} +static inline void pcie_cooling_device_unregister(struct thermal_cooling_device *cdev) +{ +} +#endif + #endif From patchwork Fri Jan 5 11:25:47 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Ilpo_J=C3=A4rvinen?= X-Patchwork-Id: 185368 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a05:7301:6f82:b0:100:9c79:88ff with SMTP id tb2csp6162110dyb; Fri, 5 Jan 2024 03:36:49 -0800 (PST) X-Google-Smtp-Source: AGHT+IE4FfjYMicSqb4JHEo3qDsHkHlK3teTRF2YBNfPDd/4fwjd7csLMX/0MI03+5smJ0YiGtyl X-Received: by 2002:a50:99c6:0:b0:557:7e5:1c46 with SMTP id n6-20020a5099c6000000b0055707e51c46mr1083404edb.65.1704454608765; Fri, 05 Jan 2024 03:36:48 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1704454608; cv=none; d=google.com; s=arc-20160816; b=XLf93Tv7rCZFQN3OqsmjvHHdmnv/ksgsqWY+qfk0vI7LYZCZ6B8wBkbO0GmiP8LO0+ ywWD4H9VkVefkmtlD/TtdGLZlDY3EaXrHulzkk7tHN6trvV16CmZcoUMumI9TFWb0FLA tn74e5ra6yXgzb6dte0K7vqhqXDS89fNaBmxcyS4dApkTKGGiRO4aAWX4gppPEmMMyT1 pGQv7YBJapzLPytv0AXMTiJvNnzI869sXT/qZ+BubwuRYB2kF8Je2FJe9CcgHRos1by+ QeyQ34ij33yZ+/E4TOQWWNtkYPy0id1CN4g3egGmd/myTqDPPBZvqzKoB7vDWnhzJltG 84wg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=content-transfer-encoding:mime-version:list-unsubscribe :list-subscribe:list-id:precedence:references:in-reply-to:message-id :date:subject:cc:to:from:dkim-signature; bh=6OxZeXLPWxOTgIfFnaCjssh4EXNpwnoYEk6jQb324O0=; fh=VLiKFHRmR71D4lCAVoyxwqE6NbAGco6Qb1FYS2YenJk=; b=k+KOBIRPPEt2j7qx275opmzGRifz3cO6vPfQC5jNBZGHBJh8DDalknfVFRwwYbYWXJ tuiKRKuKE7qhGSia/QeYDIIthjI4ay+agxYOZLI5sNKMsv6PzaP0r8bKl+pS3ulZwJwr UcLD2lhBuaG2P2TF+KfURAFEPKPgpfEBiSvdJlKFKu2z2Kq/TN7eXEi1v+VS9L6tVeYt vprw4yrFKfYj4RQn5WJvL68f+n+fnrbptjQnL1bZrL+ViguCGq/0UnB1aoEFBvksz6j2 VmqbF91R+9CnfcwpaIKG+ZaRJzPLqz1dIXfOpbyzZpzVsUtSOMghomGmV0gp43fa9VlM EZfw== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@intel.com header.s=Intel header.b=eeaDqJLa; spf=pass (google.com: domain of linux-kernel+bounces-17795-ouuuleilei=gmail.com@vger.kernel.org designates 147.75.80.249 as permitted sender) smtp.mailfrom="linux-kernel+bounces-17795-ouuuleilei=gmail.com@vger.kernel.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=intel.com Received: from am.mirrors.kernel.org (am.mirrors.kernel.org. [147.75.80.249]) by mx.google.com with ESMTPS id cy13-20020a0564021c8d00b00554107338f6si586897edb.58.2024.01.05.03.36.48 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 05 Jan 2024 03:36:48 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel+bounces-17795-ouuuleilei=gmail.com@vger.kernel.org designates 147.75.80.249 as permitted sender) client-ip=147.75.80.249; Authentication-Results: mx.google.com; dkim=pass header.i=@intel.com header.s=Intel header.b=eeaDqJLa; spf=pass (google.com: domain of linux-kernel+bounces-17795-ouuuleilei=gmail.com@vger.kernel.org designates 147.75.80.249 as permitted sender) smtp.mailfrom="linux-kernel+bounces-17795-ouuuleilei=gmail.com@vger.kernel.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=intel.com Received: from smtp.subspace.kernel.org (wormhole.subspace.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by am.mirrors.kernel.org (Postfix) with ESMTPS id 078521F26B45 for ; Fri, 5 Jan 2024 11:29:06 +0000 (UTC) Received: from localhost.localdomain (localhost.localdomain [127.0.0.1]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 7CCCE2D7A5; Fri, 5 Jan 2024 11:27:47 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b="eeaDqJLa" X-Original-To: linux-kernel@vger.kernel.org Received: from mgamail.intel.com (mgamail.intel.com [198.175.65.10]) (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 626372D794; Fri, 5 Jan 2024 11:27:43 +0000 (UTC) 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 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1704454063; x=1735990063; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=kR6iE6AEvZSwRlwNTc873KfVG2hddl+2KEMVRuzw/cU=; b=eeaDqJLaTMXpc5hGUxzjgBJvMIznHgx0AiTtYHFVJOKLxCtVq4B0zhAc 0hQKUEjFd4NHBV4c7Z+UlUBKaZOnHgnlJWa4/q8Upop2yA+trxcztt0Mo a3PnM0QVymhI2XzkeOXYwhpLgZKm6ohTGtZKlXTPauNOGdIXjiMMEPh7F m0BieJgRlH1c16Rmei3cqFzU8DLpST52P6tbDk4qCEMZmHYQ3EkX8cn17 XWVMnQnK91FEXylCfYpB/enetHdFOnmiYrFbvngknetrnAOLK2VwXWS3r 01USXuQJf6zrIcTK9uH4D+IkwpNchTTIYXkmkB/dTh5Ed4zR2Z6baq4z3 w==; X-IronPort-AV: E=McAfee;i="6600,9927,10943"; a="10858583" X-IronPort-AV: E=Sophos;i="6.04,333,1695711600"; d="scan'208";a="10858583" Received: from orsmga007.jf.intel.com ([10.7.209.58]) by orvoesa102.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 05 Jan 2024 03:27:43 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=McAfee;i="6600,9927,10943"; a="773827930" X-IronPort-AV: E=Sophos;i="6.04,333,1695711600"; d="scan'208";a="773827930" Received: from ijarvine-desk1.ger.corp.intel.com (HELO localhost) ([10.246.32.38]) by orsmga007-auth.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 05 Jan 2024 03:27:36 -0800 From: =?utf-8?q?Ilpo_J=C3=A4rvinen?= To: linux-pci@vger.kernel.org, Bjorn Helgaas , Lorenzo Pieralisi , Rob Herring , =?utf-8?q?Krzysztof_Wilczy=C5=84ski?= , Lukas Wunner , Alexandru Gagniuc , Krishna chaitanya chundru , Srinivas Pandruvada , "Rafael J. Wysocki" , linux-pm@vger.kernel.org, Shuah Khan , =?utf-8?q?Ilpo_J=C3=A4rvinen?= , linux-kernel@vger.kernel.org, linux-kselftest@vger.kernel.org Cc: Alex Deucher , Daniel Lezcano , Amit Kucheria , Zhang Rui Subject: [PATCH v4 8/8] selftests/pcie_bwctrl: Create selftests Date: Fri, 5 Jan 2024 13:25:47 +0200 Message-Id: <20240105112547.7301-9-ilpo.jarvinen@linux.intel.com> X-Mailer: git-send-email 2.39.2 In-Reply-To: <20240105112547.7301-1-ilpo.jarvinen@linux.intel.com> References: <20240105112547.7301-1-ilpo.jarvinen@linux.intel.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-getmail-retrieved-from-mailbox: INBOX X-GMAIL-THRID: 1787250195641418748 X-GMAIL-MSGID: 1787250195641418748 Create selftests for PCIe BW control through the PCIe cooling device sysfs interface. First, the BW control selftest finds the PCIe Port to test with. By default, the PCIe Port with the highest Link Speed is selected but another PCIe Port can be provided with -d parameter. The actual test steps the cur_state of the cooling device one-by-one from max_state to what the cur_state was initially. The speed change is confirmed by observing the current_link_speed for the corresponding PCIe Port. Signed-off-by: Ilpo Järvinen --- MAINTAINERS | 1 + tools/testing/selftests/Makefile | 1 + tools/testing/selftests/pcie_bwctrl/Makefile | 2 + .../pcie_bwctrl/set_pcie_cooling_state.sh | 122 ++++++++++++++++++ .../selftests/pcie_bwctrl/set_pcie_speed.sh | 67 ++++++++++ 5 files changed, 193 insertions(+) create mode 100644 tools/testing/selftests/pcie_bwctrl/Makefile create mode 100755 tools/testing/selftests/pcie_bwctrl/set_pcie_cooling_state.sh create mode 100755 tools/testing/selftests/pcie_bwctrl/set_pcie_speed.sh diff --git a/MAINTAINERS b/MAINTAINERS index 0cacc7e777c5..b59e5ffdeac0 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -16773,6 +16773,7 @@ S: Supported F: drivers/pci/pcie/bwctrl.c F: drivers/thermal/pcie_cooling.c F: include/linux/pci-bwctrl.h +F: tools/testing/selftests/pcie_bwctrl/ PCIE DRIVER FOR AMAZON ANNAPURNA LABS M: Jonathan Chocron diff --git a/tools/testing/selftests/Makefile b/tools/testing/selftests/Makefile index 3b2061d1c1a5..a86f78c80372 100644 --- a/tools/testing/selftests/Makefile +++ b/tools/testing/selftests/Makefile @@ -60,6 +60,7 @@ TARGETS += net/mptcp TARGETS += net/openvswitch TARGETS += netfilter TARGETS += nsfs +TARGETS += pcie_bwctrl TARGETS += perf_events TARGETS += pidfd TARGETS += pid_namespace diff --git a/tools/testing/selftests/pcie_bwctrl/Makefile b/tools/testing/selftests/pcie_bwctrl/Makefile new file mode 100644 index 000000000000..3e84e26341d1 --- /dev/null +++ b/tools/testing/selftests/pcie_bwctrl/Makefile @@ -0,0 +1,2 @@ +TEST_PROGS = set_pcie_cooling_state.sh +include ../lib.mk diff --git a/tools/testing/selftests/pcie_bwctrl/set_pcie_cooling_state.sh b/tools/testing/selftests/pcie_bwctrl/set_pcie_cooling_state.sh new file mode 100755 index 000000000000..3a8f91f0309e --- /dev/null +++ b/tools/testing/selftests/pcie_bwctrl/set_pcie_cooling_state.sh @@ -0,0 +1,122 @@ +#!/bin/bash +# SPDX-License-Identifier: GPL-2.0-or-later + +SYSFS= +# Kselftest framework requirement - SKIP code is 4. +ksft_skip=4 +retval=0 +skipmsg="skip all tests:" + +PCIEPORTTYPE="PCIe_Port_Link_Speed" + +prerequisite() +{ + local ports + + if [ $UID != 0 ]; then + echo $skipmsg must be run as root >&2 + exit $ksft_skip + fi + + SYSFS=`mount -t sysfs | head -1 | awk '{ print $3 }'` + + if [ ! -d "$SYSFS" ]; then + echo $skipmsg sysfs is not mounted >&2 + exit $ksft_skip + fi + + if ! ls $SYSFS/class/thermal/cooling_device* > /dev/null 2>&1; then + echo $skipmsg thermal cooling devices missing >&2 + exit $ksft_skip + fi + + ports=`grep -e "^$PCIEPORTTYPE" $SYSFS/class/thermal/cooling_device*/type | wc -l` + if [ $ports -eq 0 ]; then + echo $skipmsg pcie cooling devices missing >&2 + exit $ksft_skip + fi +} + +testport= +find_pcie_port() +{ + local patt="$1" + local pcieports + local max + local cur + local delta + local bestdelta=-1 + + pcieports=`grep -l -F -e "$patt" /sys/class/thermal/cooling_device*/type` + if [ -z "$pcieports" ]; then + return + fi + pcieports=${pcieports//\/type/} + # Find the port with the highest PCIe Link Speed + for port in $pcieports; do + max=`cat $port/max_state` + cur=`cat $port/cur_state` + delta=$((max-cur)) + if [ $delta -gt $bestdelta ]; then + testport="$port" + bestdelta=$delta + fi + done +} + +sysfspcidev= +find_sysfs_pci_dev() +{ + local typefile="$1/type" + local pcidir + + pcidir="$SYSFS/bus/pci/devices/`sed -e "s|^${PCIEPORTTYPE}_||g" $typefile`" + + if [ -r "$pcidir/current_link_speed" ]; then + sysfspcidev="$pcidir/current_link_speed" + fi +} + +usage() +{ + echo "Usage $0 [ -d dev ]" + echo -e "\t-d: PCIe port BDF string (e.g., 0000:00:04.0)" +} + +pattern="$PCIEPORTTYPE" +parse_arguments() +{ + while getopts d:h opt; do + case $opt in + h) + usage "$0" + exit 0 + ;; + d) + pattern="$PCIEPORTTYPE_$OPTARG" + ;; + *) + usage "$0" + exit 0 + ;; + esac + done +} + +parse_arguments "$@" +prerequisite +find_pcie_port "$pattern" +if [ -z "$testport" ]; then + echo $skipmsg "pcie cooling device not found from sysfs" >&2 + exit $ksft_skip +fi +find_sysfs_pci_dev "$testport" +if [ -z "$sysfspcidev" ]; then + echo $skipmsg "PCIe port device not found from sysfs" >&2 + exit $ksft_skip +fi + +./set_pcie_speed.sh "$testport" "$sysfspcidev" +retval=$? + +exit $retval diff --git a/tools/testing/selftests/pcie_bwctrl/set_pcie_speed.sh b/tools/testing/selftests/pcie_bwctrl/set_pcie_speed.sh new file mode 100755 index 000000000000..584596949312 --- /dev/null +++ b/tools/testing/selftests/pcie_bwctrl/set_pcie_speed.sh @@ -0,0 +1,67 @@ +#!/bin/bash +# SPDX-License-Identifier: GPL-2.0-or-later + +set -e + +TESTNAME=set_pcie_speed + +declare -a PCIELINKSPEED=( + "2.5 GT/s PCIe" + "5.0 GT/s PCIe" + "8.0 GT/s PCIe" + "16.0 GT/s PCIe" + "32.0 GT/s PCIe" + "64.0 GT/s PCIe" +) + +# Kselftest framework requirement - SKIP code is 4. +ksft_skip=4 +retval=0 + +coolingdev="$1" +statefile="$coolingdev/cur_state" +maxfile="$coolingdev/max_state" +linkspeedfile="$2" + +oldstate=`cat $statefile` +maxstate=`cat $maxfile` + +set_state() +{ + local state=$1 + local linkspeed + local expected_linkspeed + + echo $state > $statefile + + sleep 1 + + linkspeed="`cat $linkspeedfile`" + expected_linkspeed=$((maxstate-state)) + expected_str="${PCIELINKSPEED[$expected_linkspeed]}" + if [ ! "${expected_str}" = "${linkspeed}" ]; then + echo "$TESTNAME failed: expected: ${expected_str}; got ${linkspeed}" + retval=1 + fi +} + +cleanup_skip () +{ + set_state $oldstate + exit $ksft_skip +} + +trap cleanup_skip EXIT + +echo "$TESTNAME: testing states $maxstate .. $oldstate with $coolingdev" +for i in $(seq $maxstate -1 $oldstate); do + set_state "$i" +done + +trap EXIT +if [ $retval -eq 0 ]; then + echo "$TESTNAME [PASS]" +else + echo "$TESTNAME [FAIL]" +fi +exit $retval