From patchwork Sun Feb 23 12:20:55 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Stanislav Spassov X-Patchwork-Id: 1242651 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (no SPF record) smtp.mailfrom=vger.kernel.org (client-ip=209.132.180.67; helo=vger.kernel.org; envelope-from=linux-pci-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dmarc=pass (p=quarantine dis=none) header.from=amazon.com Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=amazon.com header.i=@amazon.com header.a=rsa-sha256 header.s=amazon201209 header.b=O+aizZUK; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 48QPTF0dg3z9sP7 for ; Sun, 23 Feb 2020 23:22:08 +1100 (AEDT) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726806AbgBWMWH (ORCPT ); Sun, 23 Feb 2020 07:22:07 -0500 Received: from smtp-fw-2101.amazon.com ([72.21.196.25]:1449 "EHLO smtp-fw-2101.amazon.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726023AbgBWMWH (ORCPT ); Sun, 23 Feb 2020 07:22:07 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=amazon.com; i=@amazon.com; q=dns/txt; s=amazon201209; t=1582460527; x=1613996527; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=lcnFscn91LfowQE1gEh7+eQLC7A7aDyLt4mHbYDGrHA=; b=O+aizZUKCk2eEzQvzG5zk5oscFFqeifYNncIfWVpfGipu8gvDABCxbM3 rwwUj/xdYplE0EyAEmdkIpQua/aSfx4sqdJ1SnVVo5Q/MAWaffQzSccFx L4Y+KwZ5EH5iCS+gGLwJ+0W5h+xCrnSYIFsoHVcyLQsCg2Nd9t4Pql/qI 4=; IronPort-SDR: TFIxAe00BbZavzHlPTEmqgSi2DF904VMgNoZ2FtfNhN1GWI//hLEJJBGYdSFBnFskiLYt8LpHW svwjO7/zbhAQ== X-IronPort-AV: E=Sophos;i="5.70,476,1574121600"; d="scan'208";a="18479465" Received: from iad12-co-svc-p1-lb1-vlan2.amazon.com (HELO email-inbound-relay-2a-1c1b5cdd.us-west-2.amazon.com) ([10.43.8.2]) by smtp-border-fw-out-2101.iad2.amazon.com with ESMTP; 23 Feb 2020 12:21:54 +0000 Received: from EX13MTAUEA002.ant.amazon.com (pdx4-ws-svc-p6-lb7-vlan2.pdx.amazon.com [10.170.41.162]) by email-inbound-relay-2a-1c1b5cdd.us-west-2.amazon.com (Postfix) with ESMTPS id CBA09A1BEC; Sun, 23 Feb 2020 12:21:52 +0000 (UTC) Received: from EX13D12EUC002.ant.amazon.com (10.43.164.134) by EX13MTAUEA002.ant.amazon.com (10.43.61.77) with Microsoft SMTP Server (TLS) id 15.0.1236.3; Sun, 23 Feb 2020 12:21:52 +0000 Received: from EX13MTAUEA001.ant.amazon.com (10.43.61.82) by EX13D12EUC002.ant.amazon.com (10.43.164.134) with Microsoft SMTP Server (TLS) id 15.0.1367.3; Sun, 23 Feb 2020 12:21:51 +0000 Received: from u961addbe640f56.ant.amazon.com (10.28.84.111) by mail-relay.amazon.com (10.43.61.243) with Microsoft SMTP Server id 15.0.1367.3 via Frontend Transport; Sun, 23 Feb 2020 12:21:49 +0000 From: Stanislav Spassov To: CC: Stanislav Spassov , Bjorn Helgaas , Thomas Gleixner , Andrew Morton , =?utf-8?q?Jan_H_=2E_Sch=C3=B6nherr?= , Wei Wang , Jonathan Corbet , Subject: [PATCH 1/3] PCI: Make PCIE_RESET_READY_POLL_MS configurable Date: Sun, 23 Feb 2020 13:20:55 +0100 Message-ID: <20200223122057.6504-2-stanspas@amazon.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20200223122057.6504-1-stanspas@amazon.com> References: <20200223122057.6504-1-stanspas@amazon.com> MIME-Version: 1.0 Sender: linux-pci-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-pci@vger.kernel.org From: Wei Wang The resonable value for the maximum time to wait for a PCI device to be ready after reset varies depending on the platform and the reliability of its set of devices. Signed-off-by: Wei Wang Signed-off-by: Stanislav Spassov --- .../admin-guide/kernel-parameters.txt | 5 +++++ drivers/pci/pci.c | 22 ++++++++++++++----- 2 files changed, 22 insertions(+), 5 deletions(-) diff --git a/Documentation/admin-guide/kernel-parameters.txt b/Documentation/admin-guide/kernel-parameters.txt index dbc22d684627..5e4dade9acc8 100644 --- a/Documentation/admin-guide/kernel-parameters.txt +++ b/Documentation/admin-guide/kernel-parameters.txt @@ -3653,6 +3653,11 @@ nomsi Do not use MSI for native PCIe PME signaling (this makes all PCIe root ports use INTx for all services). + pcie_reset_ready_poll_ms= [PCI,PCIE] + Specifies timeout for PCI(e) device readiness polling + after device reset (in milliseconds). + Default: 60000 = 60 seconds + pcmv= [HW,PCMCIA] BadgePAD 4 pd_ignore_unused diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c index d828ca835a98..db9b58ab6c68 100644 --- a/drivers/pci/pci.c +++ b/drivers/pci/pci.c @@ -149,7 +149,19 @@ static int __init pcie_port_pm_setup(char *str) __setup("pcie_port_pm=", pcie_port_pm_setup); /* Time to wait after a reset for device to become responsive */ -#define PCIE_RESET_READY_POLL_MS 60000 +#define PCIE_RESET_READY_POLL_MS_DEFAULT 60000 + +int __read_mostly pcie_reset_ready_poll_ms = PCIE_RESET_READY_POLL_MS_DEFAULT; + +static int __init pcie_reset_ready_poll_ms_setup(char *str) +{ + int timeout; + + if (!kstrtoint(str, 0, &timeout)) + pcie_reset_ready_poll_ms = timeout; + return 1; +} +__setup("pcie_reset_ready_poll_ms=", pcie_reset_ready_poll_ms_setup); /** * pci_bus_max_busnr - returns maximum PCI bus number of given bus' children @@ -4506,7 +4518,7 @@ int pcie_flr(struct pci_dev *dev) */ msleep(100); - return pci_dev_wait(dev, "FLR", PCIE_RESET_READY_POLL_MS); + return pci_dev_wait(dev, "FLR", pcie_reset_ready_poll_ms); } EXPORT_SYMBOL_GPL(pcie_flr); @@ -4551,7 +4563,7 @@ static int pci_af_flr(struct pci_dev *dev, int probe) */ msleep(100); - return pci_dev_wait(dev, "AF_FLR", PCIE_RESET_READY_POLL_MS); + return pci_dev_wait(dev, "AF_FLR", pcie_reset_ready_poll_ms); } /** @@ -4596,7 +4608,7 @@ static int pci_pm_reset(struct pci_dev *dev, int probe) pci_write_config_word(dev, dev->pm_cap + PCI_PM_CTRL, csr); pci_dev_d3_sleep(dev); - return pci_dev_wait(dev, "PM D3hot->D0", PCIE_RESET_READY_POLL_MS); + return pci_dev_wait(dev, "PM D3hot->D0", pcie_reset_ready_poll_ms); } /** @@ -4826,7 +4838,7 @@ int pci_bridge_secondary_bus_reset(struct pci_dev *dev) { pcibios_reset_secondary_bus(dev); - return pci_dev_wait(dev, "bus reset", PCIE_RESET_READY_POLL_MS); + return pci_dev_wait(dev, "bus reset", pcie_reset_ready_poll_ms); } EXPORT_SYMBOL_GPL(pci_bridge_secondary_bus_reset); From patchwork Sun Feb 23 12:20:56 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Stanislav Spassov X-Patchwork-Id: 1242653 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (no SPF record) smtp.mailfrom=vger.kernel.org (client-ip=209.132.180.67; helo=vger.kernel.org; envelope-from=linux-pci-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dmarc=pass (p=quarantine dis=none) header.from=amazon.com Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=amazon.com header.i=@amazon.com header.a=rsa-sha256 header.s=amazon201209 header.b=pX8BwdUN; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 48QPTM2zJBz9sP7 for ; Sun, 23 Feb 2020 23:22:15 +1100 (AEDT) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727282AbgBWMWO (ORCPT ); Sun, 23 Feb 2020 07:22:14 -0500 Received: from smtp-fw-6002.amazon.com ([52.95.49.90]:59592 "EHLO smtp-fw-6002.amazon.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726308AbgBWMWO (ORCPT ); Sun, 23 Feb 2020 07:22:14 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=amazon.com; i=@amazon.com; q=dns/txt; s=amazon201209; t=1582460534; x=1613996534; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=/5T9tN3oKmZA5iIMakG8TApXvG1ETaZYfCRIH79dVuo=; b=pX8BwdUNJctw1P5vpYTrQjhslIRv56QVmjGIPBEu1c8Y1BBA3H7vy3al oEwhYSyd1c8KxQofbWypST+36yphgYAlEjcY/MOKoeSFwLIPx7YWohPVa p/2I2/ctjpNU/spHP9Qij0/u0uO3Ng6w/MjS9iaaNis9HXA8PQxvAHgGL k=; IronPort-SDR: TI5SQvWH5ze2em/PV0bWW4zmHeGbOk0coTOZET/4fV6wr65b6w4TKf1pSkeQHPf5/pTL4yI89Y V73o5SEwKEvw== X-IronPort-AV: E=Sophos;i="5.70,476,1574121600"; d="scan'208";a="17759520" Received: from iad12-co-svc-p1-lb1-vlan3.amazon.com (HELO email-inbound-relay-2b-55156cd4.us-west-2.amazon.com) ([10.43.8.6]) by smtp-border-fw-out-6002.iad6.amazon.com with ESMTP; 23 Feb 2020 12:22:01 +0000 Received: from EX13MTAUEA002.ant.amazon.com (pdx4-ws-svc-p6-lb7-vlan2.pdx.amazon.com [10.170.41.162]) by email-inbound-relay-2b-55156cd4.us-west-2.amazon.com (Postfix) with ESMTPS id A3BF0A1E36; Sun, 23 Feb 2020 12:22:00 +0000 (UTC) Received: from EX13D09EUA001.ant.amazon.com (10.43.165.9) by EX13MTAUEA002.ant.amazon.com (10.43.61.77) with Microsoft SMTP Server (TLS) id 15.0.1236.3; Sun, 23 Feb 2020 12:22:00 +0000 Received: from EX13MTAUEA001.ant.amazon.com (10.43.61.82) by EX13D09EUA001.ant.amazon.com (10.43.165.9) with Microsoft SMTP Server (TLS) id 15.0.1367.3; Sun, 23 Feb 2020 12:21:58 +0000 Received: from u961addbe640f56.ant.amazon.com (10.28.84.111) by mail-relay.amazon.com (10.43.61.243) with Microsoft SMTP Server id 15.0.1367.3 via Frontend Transport; Sun, 23 Feb 2020 12:21:57 +0000 From: Stanislav Spassov To: CC: Stanislav Spassov , Bjorn Helgaas , Thomas Gleixner , Andrew Morton , =?utf-8?q?Jan_H_=2E_Sch=C3=B6nherr?= , Wei Wang Subject: [PATCH 2/3] PCI: Introduce per-device reset_ready_poll override Date: Sun, 23 Feb 2020 13:20:56 +0100 Message-ID: <20200223122057.6504-3-stanspas@amazon.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20200223122057.6504-1-stanspas@amazon.com> References: <20200223122057.6504-1-stanspas@amazon.com> MIME-Version: 1.0 Sender: linux-pci-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-pci@vger.kernel.org From: Stanislav Spassov A broken device may never become responsive after reset, hence the need for a timeout. However, waiting for too long can have unintended side effects such as triggering hung task timeouts for processes waiting on a lock held during the reset. Locks that are shared across multiple devices, such as VFIO's per-bus reflck, are especially problematic, because a single broken VF can cause hangs for processes working with other VFs on the same bus. To allow lowering the global default post-reset timeout, while still accommodating devices that require more time, this patch introduces a per-device override that can be configured via a quirk. Signed-off-by: Stanislav Spassov --- drivers/pci/pci.c | 19 ++++++++++++++----- drivers/pci/probe.c | 2 ++ include/linux/pci.h | 1 + 3 files changed, 17 insertions(+), 5 deletions(-) diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c index db9b58ab6c68..a554818968ed 100644 --- a/drivers/pci/pci.c +++ b/drivers/pci/pci.c @@ -1033,8 +1033,17 @@ void pci_wakeup_bus(struct pci_bus *bus) pci_walk_bus(bus, pci_wakeup, NULL); } -static int pci_dev_wait(struct pci_dev *dev, char *reset_type, int timeout) +static int pci_dev_get_reset_ready_poll_ms(struct pci_dev *dev) { + if (dev->reset_ready_poll_ms >= 0) + return dev->reset_ready_poll_ms; + + return pcie_reset_ready_poll_ms; +} + +static int pci_dev_wait(struct pci_dev *dev, char *reset_type) +{ + int timeout = pci_dev_get_reset_ready_poll_ms(dev); int delay = 1; u32 id; @@ -4518,7 +4527,7 @@ int pcie_flr(struct pci_dev *dev) */ msleep(100); - return pci_dev_wait(dev, "FLR", pcie_reset_ready_poll_ms); + return pci_dev_wait(dev, "FLR"); } EXPORT_SYMBOL_GPL(pcie_flr); @@ -4563,7 +4572,7 @@ static int pci_af_flr(struct pci_dev *dev, int probe) */ msleep(100); - return pci_dev_wait(dev, "AF_FLR", pcie_reset_ready_poll_ms); + return pci_dev_wait(dev, "AF_FLR"); } /** @@ -4608,7 +4617,7 @@ static int pci_pm_reset(struct pci_dev *dev, int probe) pci_write_config_word(dev, dev->pm_cap + PCI_PM_CTRL, csr); pci_dev_d3_sleep(dev); - return pci_dev_wait(dev, "PM D3hot->D0", pcie_reset_ready_poll_ms); + return pci_dev_wait(dev, "PM D3hot->D0"); } /** @@ -4838,7 +4847,7 @@ int pci_bridge_secondary_bus_reset(struct pci_dev *dev) { pcibios_reset_secondary_bus(dev); - return pci_dev_wait(dev, "bus reset", pcie_reset_ready_poll_ms); + return pci_dev_wait(dev, "bus reset"); } EXPORT_SYMBOL_GPL(pci_bridge_secondary_bus_reset); diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c index 512cb4312ddd..eeb79a45d504 100644 --- a/drivers/pci/probe.c +++ b/drivers/pci/probe.c @@ -2166,6 +2166,8 @@ struct pci_dev *pci_alloc_dev(struct pci_bus *bus) if (!dev) return NULL; + dev->reset_ready_poll_ms = -1; + INIT_LIST_HEAD(&dev->bus_list); dev->dev.type = &pci_dev_type; dev->bus = pci_bus_get(bus); diff --git a/include/linux/pci.h b/include/linux/pci.h index 3840a541a9de..049a41b9412b 100644 --- a/include/linux/pci.h +++ b/include/linux/pci.h @@ -468,6 +468,7 @@ struct pci_dev { size_t romlen; /* Length if not from BAR */ char *driver_override; /* Driver name to force a match */ + int reset_ready_poll_ms; unsigned long priv_flags; /* Private flags for the PCI driver */ }; From patchwork Sun Feb 23 12:20:57 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Stanislav Spassov X-Patchwork-Id: 1242652 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (no SPF record) smtp.mailfrom=vger.kernel.org (client-ip=209.132.180.67; helo=vger.kernel.org; envelope-from=linux-pci-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dmarc=pass (p=quarantine dis=none) header.from=amazon.com Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=amazon.com header.i=@amazon.com header.a=rsa-sha256 header.s=amazon201209 header.b=lZAIt/Re; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 48QPTF48h9z9sRJ for ; Sun, 23 Feb 2020 23:22:09 +1100 (AEDT) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726023AbgBWMWI (ORCPT ); Sun, 23 Feb 2020 07:22:08 -0500 Received: from smtp-fw-9101.amazon.com ([207.171.184.25]:45589 "EHLO smtp-fw-9101.amazon.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726308AbgBWMWI (ORCPT ); Sun, 23 Feb 2020 07:22:08 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=amazon.com; i=@amazon.com; q=dns/txt; s=amazon201209; t=1582460527; x=1613996527; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=Oi4U7lNb3iEL3XkkHqiUaqIeH88E0voXgDi5P1troPk=; b=lZAIt/RerD32pxu4QUPwjIyH44y7m5/4PJG7UPhPzfFDYq+BPcP5Fd+U U+0O1ry8ObTzCWEsy29zGneVTxpONGwRWaVu7D8jYsAUL+8jHpA8MzFPT 8izVjcsKcD7qAE7k1tsmaSAis/sJCGPGnr3CwzAbg3MeKwHmfY3N8EpE3 c=; IronPort-SDR: mAdSPJxwu5Z3OxFj8xqettTsmP2uZK0TiqcJZZejie8kpZKGHwvmv8jYwEtdXdIpCmM1l6Q/KB oy43eVG05Prw== X-IronPort-AV: E=Sophos;i="5.70,476,1574121600"; d="scan'208";a="18523238" Received: from sea32-co-svc-lb4-vlan3.sea.corp.amazon.com (HELO email-inbound-relay-2c-2225282c.us-west-2.amazon.com) ([10.47.23.38]) by smtp-border-fw-out-9101.sea19.amazon.com with ESMTP; 23 Feb 2020 12:22:05 +0000 Received: from EX13MTAUEA002.ant.amazon.com (pdx4-ws-svc-p6-lb7-vlan3.pdx.amazon.com [10.170.41.166]) by email-inbound-relay-2c-2225282c.us-west-2.amazon.com (Postfix) with ESMTPS id D8FFCA270E; Sun, 23 Feb 2020 12:22:04 +0000 (UTC) Received: from EX13D09EUC001.ant.amazon.com (10.43.164.146) by EX13MTAUEA002.ant.amazon.com (10.43.61.77) with Microsoft SMTP Server (TLS) id 15.0.1236.3; Sun, 23 Feb 2020 12:22:03 +0000 Received: from EX13MTAUEA001.ant.amazon.com (10.43.61.82) by EX13D09EUC001.ant.amazon.com (10.43.164.146) with Microsoft SMTP Server (TLS) id 15.0.1367.3; Sun, 23 Feb 2020 12:22:02 +0000 Received: from u961addbe640f56.ant.amazon.com (10.28.84.111) by mail-relay.amazon.com (10.43.61.243) with Microsoft SMTP Server id 15.0.1367.3 via Frontend Transport; Sun, 23 Feb 2020 12:22:01 +0000 From: Stanislav Spassov To: CC: Stanislav Spassov , Bjorn Helgaas , Thomas Gleixner , Andrew Morton , =?utf-8?q?Jan_H_=2E_Sch=C3=B6nherr?= , Wei Wang Subject: [PATCH 3/3] PCI: Add CRS handling to pci_dev_wait() Date: Sun, 23 Feb 2020 13:20:57 +0100 Message-ID: <20200223122057.6504-4-stanspas@amazon.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20200223122057.6504-1-stanspas@amazon.com> References: <20200223122057.6504-1-stanspas@amazon.com> MIME-Version: 1.0 Sender: linux-pci-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-pci@vger.kernel.org From: Stanislav Spassov The PCI Express specification dictates minimal amounts of time that the host needs to wait after triggering different kinds of resets before it is allowed to attempt accessing the device. After this waiting period, devices are required to be responsive to Configuration Space reads. However, if a device needs more time to actually complete the reset operation internally, it may respond to the read with a Completion Request Retry Status (CRS), and keep doing so on subsequent reads for as long as necessary. If the device is broken, it may even keep responding with CRS indefinitely. The specification also mandates that any Root Port that supports CRS and has CRS Software Visibility (CRS SV) enabled will synthesize the special value 0x0001 for the Vendor ID and set any other bits to 1 upon receiving a CRS Completion for a Configuration Read Request that includes both bytes of the Vendor ID (offset 0). IF CRS is supported by Root Port but CRS SV is not enabled, the request is retried autonomosly by the Root Port. Platform-specific configuration registers may exist to limit the number of or time taken by such retries. If CRS is not supported, or a different register (not Vendor ID) is polled, or the device is responding with CA/UR Completions (rather than CRS), the behavior is platform-dependent, but generally the Root Port synthesizes ~0 to complete the software read. Previously, pci_dev_wait() avoided taking advantage of CRS. However, on platforms where no limit/timeout can be configured as explained above, a device responding with CRS for too long (e.g. because it is stuck and cannot complete its reset) may trigger more severe error conditions (e.g. TOR timeout, 3-strike CPU CATERR), because the Root Port never reports back to the lower-level component requesting the transaction. This patch introduces special handling when CRS is available, and otherwise falls back to the previous behavior of polling COMMAND. Signed-off-by: Stanislav Spassov --- drivers/pci/pci.c | 128 +++++++++++++++++++++++++++++++++++++--------- 1 file changed, 105 insertions(+), 23 deletions(-) diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c index a554818968ed..e8bce8da9402 100644 --- a/drivers/pci/pci.c +++ b/drivers/pci/pci.c @@ -1041,44 +1041,126 @@ static int pci_dev_get_reset_ready_poll_ms(struct pci_dev *dev) return pcie_reset_ready_poll_ms; } -static int pci_dev_wait(struct pci_dev *dev, char *reset_type) +static bool pci_crs_sv_enabled(struct pci_dev *dev) +{ + struct pci_dev *root_port = pcie_find_root_port(dev); + u16 root_control; + + if (!root_port) + return false; + + if (pcie_capability_read_word(root_port, PCI_EXP_RTCTL, &root_control)) + return false; + + return root_control & PCI_EXP_RTCTL_CRSSVE; +} + +static int pci_dev_poll_until_ready(struct pci_dev *dev, + int where, + u32 mask, + u32 bad_value, + char *event, + int timeout, int *waited, + u32 *final_value) { - int timeout = pci_dev_get_reset_ready_poll_ms(dev); int delay = 1; - u32 id; + u32 value; - /* - * After reset, the device should not silently discard config - * requests, but it may still indicate that it needs more time by - * responding to them with CRS completions. The Root Port will - * generally synthesize ~0 data to complete the read (except when - * CRS SV is enabled and the read was for the Vendor ID; in that - * case it synthesizes 0x0001 data). - * - * Wait for the device to return a non-CRS completion. Read the - * Command register instead of Vendor ID so we don't have to - * contend with the CRS SV value. - */ - pci_read_config_dword(dev, PCI_COMMAND, &id); - while (id == ~0) { + if (!event) + event = ""; + + if (pci_read_config_dword(dev, where, &value)) + return -ENOTTY; + + while ((value & mask) == bad_value) { if (delay > timeout) { pci_warn(dev, "not ready %dms after %s; giving up\n", - delay - 1, reset_type); - return -ENOTTY; + delay - 1, event); + return -ETIMEDOUT; } if (delay > 1000) pci_info(dev, "not ready %dms after %s; waiting\n", - delay - 1, reset_type); + delay - 1, event); msleep(delay); delay *= 2; - pci_read_config_dword(dev, PCI_COMMAND, &id); + + if (pci_read_config_dword(dev, where, &value)) + return -ENOTTY; } if (delay > 1000) - pci_info(dev, "ready %dms after %s\n", delay - 1, - reset_type); + pci_info(dev, "ready %dms after %s\n", delay - 1, event); + + if (waited) + *waited = delay - 1; + + if (final_value) + *final_value = value; + + return 0; +} + +static int pci_dev_wait_crs(struct pci_dev *dev, char *reset_type, + int timeout, int *waited, u32 *id) +{ + return pci_dev_poll_until_ready(dev, PCI_VENDOR_ID, 0xffff, 0x0001, + reset_type, timeout, waited, id); +} + +static int pci_dev_wait(struct pci_dev *dev, char *reset_type) +{ + int timeout = pci_dev_get_reset_ready_poll_ms(dev); + int waited = 0; + + /* + * After reset, the device should not silently discard config + * requests, but it may still indicate that it needs more time by + * responding to them with CRS completions. For such completions: + * - If CRS SV is enabled on the Root Port, and the read request + * covers both bytes of the Vendor ID register, the Root Port + * will synthesize the value 0x0001 (and set any extra requested + * bytes to 0xff) + * - If CRS SV is not enabled on the Root Port, the Root Port must + * re-issue the Configuration Request as a new Request. + * Depending on platform-specific Root Complex configurations, + * the Root Port may stop retrying after a set number of attempts, + * or a configured timeout is hit, or continue indefinitely + * (ultimately resulting in non-PCI-specific errors, such as a + * TOR timeout). + */ + if (pci_crs_sv_enabled(dev)) { + u32 id; + + if (pci_dev_wait_crs(dev, reset_type, timeout, &waited, &id)) + return -ENOTTY; + + timeout -= waited; + + /* + * If Vendor/Device ID is valid, the device must be ready. + * Note: SR-IOV VFs return ~0 for reads to Vendor/Device + * ID and will not be recognized as ready by this check. + */ + if (id != 0x0000ffff && id != 0xffff0000 && + id != 0x00000000 && id != 0xffffffff) + return 0; + } + + /* + * Root Ports will generally indicate error scenarios (e.g. + * internal timeouts, or received Completion with CA/UR) by + * synthesizing an 'all bits set' value (~0). + * In case CRS is not supported/enabled, as well as for SR-IOV VFs, + * fall back to polling a different register that cannot validly + * contain ~0. As of PCIe 5.0, bits 11-15 of COMMAND are still RsvdP + * and must return 0 when read. + * XXX: These bits might become meaningful in the future + */ + if (pci_dev_poll_until_ready(dev, PCI_COMMAND, ~0, ~0, + reset_type, timeout, NULL, NULL)) + return -ENOTTY; return 0; }