From patchwork Tue Aug 15 03:23:23 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ding Tianhong X-Patchwork-Id: 110073 Delivered-To: patch@linaro.org Received: by 10.140.95.78 with SMTP id h72csp5155538qge; Mon, 14 Aug 2017 20:24:09 -0700 (PDT) X-Received: by 10.84.217.212 with SMTP id d20mr30481048plj.343.1502767449341; Mon, 14 Aug 2017 20:24:09 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1502767449; cv=none; d=google.com; s=arc-20160816; b=zQGi3fuHNDeNVdB3a/L23Lob5CwW9WDkHDbHB7K6UttpDNqq8hKTq76cyfiZoqnDzZ 9ophA0iygkeF0Iy41lDghMp0c/U8KB+nsXnvNn/BjY/lIlk3BVmv7d0wP4EKhaFa0XfK ysIuk/5RwpOktJZPz0WdfuaRKsG8hXMmDzJphmjoKNLFNhjZATz1WEpkMH03s6LfJCxK GcOnk5w5JpD8qIyo4P9yN+rrFVTpz6MvNlPr0neq5xlVOxrmJeCCFHK+7qE3j0t9P5Ub eOksXP05DHdfOn9Pj8gXjBVxfSius7ZoaJ2DpbqXVvSYegFhZa8OM/lej7HJjOVNYOKQ QUgA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:arc-authentication-results; bh=1bwkm+rMLLKKzja1PGQzk+pTxpchYmjWAGDbV8Zc914=; b=lh/cVhhbJcHUroWamfpiETlUseVbC5bUNpZM+TrvrHP50X/quMrRASVLg2OjVdiGkt 9lwnp+jZ8jpYAfB0ocw6qw02pTtOzk8FC0vooe7m0GM+O/7HoV1lgE+v0J5uOAOClCQO gXMQwZwwZKja4wTKA2mF5ojoSnbqLJAT2OsP9F584ig5PtYq9oibtsGOGCRymQTS5qqW E397ol2GUZWn9BWf4TRAuTa+k+olHT7JRTvwxaaWcZEYTjw/CIDT3mj0sxjuGuK/c88z d9uUDTm1ywNv7fV3Mgjb+0n51zMLiisa5Duhtc+B+JOK1xeJFBpIC2I/InXhEtAeo5MW mKWg== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id h12si5689000plk.95.2017.08.14.20.24.09; Mon, 14 Aug 2017 20:24:09 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753320AbdHODYG (ORCPT + 25 others); Mon, 14 Aug 2017 23:24:06 -0400 Received: from szxga04-in.huawei.com ([45.249.212.190]:3519 "EHLO szxga04-in.huawei.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753064AbdHODYC (ORCPT ); Mon, 14 Aug 2017 23:24:02 -0400 Received: from 172.30.72.60 (EHLO DGGEMS405-HUB.china.huawei.com) ([172.30.72.60]) by dggrg04-dlp.huawei.com (MOS 4.4.6-GA FastPath queued) with ESMTP id DFE31816; Tue, 15 Aug 2017 11:23:46 +0800 (CST) Received: from localhost (10.177.23.32) by DGGEMS405-HUB.china.huawei.com (10.3.19.205) with Microsoft SMTP Server id 14.3.301.0; Tue, 15 Aug 2017 11:23:35 +0800 From: Ding Tianhong To: , , , , , , , , , , , , , , , , , , , , , , , , , CC: Ding Tianhong Subject: [PATCH v11 1/5] PCI: Disable PCIe Relaxed Ordering if unsupported Date: Tue, 15 Aug 2017 11:23:23 +0800 Message-ID: <1502767407-6812-2-git-send-email-dingtianhong@huawei.com> X-Mailer: git-send-email 1.8.5.2.msysgit.0 In-Reply-To: <1502767407-6812-1-git-send-email-dingtianhong@huawei.com> References: <1502767407-6812-1-git-send-email-dingtianhong@huawei.com> MIME-Version: 1.0 X-Originating-IP: [10.177.23.32] X-CFilter-Loop: Reflected X-Mirapoint-Virus-RAPID-Raw: score=unknown(0), refid=str=0001.0A010206.59926944.0033, ss=1, re=0.000, recu=0.000, reip=0.000, cl=1, cld=1, fgs=0, ip=0.0.0.0, so=2014-11-16 11:51:01, dmn=2013-03-21 17:37:32 X-Mirapoint-Loop-Id: 3e9016546f12a79081b55a0067b0b68a Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org When bit4 is set in the PCIe Device Control register, it indicates whether the device is permitted to use relaxed ordering. On some platforms using relaxed ordering can have performance issues or due to erratum can cause data-corruption. In such cases devices must avoid using relaxed ordering. The patch adds a new flag PCI_DEV_FLAGS_NO_RELAXED_ORDERING to indicate that Relaxed Ordering (RO) attribute should not be used for Transaction Layer Packets (TLP) targeted towards these affected root complexes. This patch checks if there is any node in the hierarchy that indicates that using relaxed ordering is not safe. In such cases the patch turns off the relaxed ordering by clearing the capability for this device. Signed-off-by: Casey Leedom Signed-off-by: Ding Tianhong Acked-by: Ashok Raj Acked-by: Alexander Duyck Acked-by: Casey Leedom --- drivers/pci/probe.c | 43 +++++++++++++++++++++++++++++++++++++++++++ drivers/pci/quirks.c | 11 +++++++++++ include/linux/pci.h | 3 +++ 3 files changed, 57 insertions(+) -- 1.8.3.1 diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c index c31310d..779e646 100644 --- a/drivers/pci/probe.c +++ b/drivers/pci/probe.c @@ -1762,6 +1762,48 @@ static void pci_configure_extended_tags(struct pci_dev *dev) PCI_EXP_DEVCTL_EXT_TAG); } +/** + * pcie_relaxed_ordering_enabled - Probe for PCIe relaxed ordering enable + * @dev: PCI device to query + * + * Returns true if the device has enabled relaxed ordering attribute. + */ +bool pcie_relaxed_ordering_enabled(struct pci_dev *dev) +{ + u16 v; + + pcie_capability_read_word(dev, PCI_EXP_DEVCTL, &v); + + return !!(v & PCI_EXP_DEVCTL_RELAX_EN); +} +EXPORT_SYMBOL(pcie_relaxed_ordering_enabled); + +static void pci_configure_relaxed_ordering(struct pci_dev *dev) +{ + struct pci_dev *root; + + /* PCI_EXP_DEVICE_RELAX_EN is RsvdP in VFs */ + if (dev->is_virtfn) + return; + + if (!pcie_relaxed_ordering_enabled(dev)) + return; + + /* + * For now, we only deal with Relaxed Ordering issues with Root + * Ports. Peer-to-Peer DMA is another can of worms. + */ + root = pci_find_pcie_root_port(dev); + if (!root) + return; + + if (root->dev_flags & PCI_DEV_FLAGS_NO_RELAXED_ORDERING) { + pcie_capability_clear_word(dev, PCI_EXP_DEVCTL, + PCI_EXP_DEVCTL_RELAX_EN); + dev_info(&dev->dev, "Disable Relaxed Ordering because the Root Port didn't support it\n"); + } +} + static void pci_configure_device(struct pci_dev *dev) { struct hotplug_params hpp; @@ -1769,6 +1811,7 @@ static void pci_configure_device(struct pci_dev *dev) pci_configure_mps(dev); pci_configure_extended_tags(dev); + pci_configure_relaxed_ordering(dev); memset(&hpp, 0, sizeof(hpp)); ret = pci_get_hp_params(dev, &hpp); diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c index 6967c6b..61b59bf 100644 --- a/drivers/pci/quirks.c +++ b/drivers/pci/quirks.c @@ -4016,6 +4016,17 @@ static void quirk_tw686x_class(struct pci_dev *pdev) quirk_tw686x_class); /* + * Some devices have problems with Transaction Layer Packets with the Relaxed + * Ordering Attribute set. Such devices should mark themselves and other + * Device Drivers should check before sending TLPs with RO set. + */ +static void quirk_relaxedordering_disable(struct pci_dev *dev) +{ + dev->dev_flags |= PCI_DEV_FLAGS_NO_RELAXED_ORDERING; + dev_info(&dev->dev, "Disable Relaxed Ordering Attributes to avoid PCIe Completion erratum\n"); +} + +/* * Per PCIe r3.0, sec 2.2.9, "Completion headers must supply the same * values for the Attribute as were supplied in the header of the * corresponding Request, except as explicitly allowed when IDO is used." diff --git a/include/linux/pci.h b/include/linux/pci.h index 4869e66..29606fb 100644 --- a/include/linux/pci.h +++ b/include/linux/pci.h @@ -188,6 +188,8 @@ enum pci_dev_flags { * the direct_complete optimization. */ PCI_DEV_FLAGS_NEEDS_RESUME = (__force pci_dev_flags_t) (1 << 11), + /* Don't use Relaxed Ordering for TLPs directed at this device */ + PCI_DEV_FLAGS_NO_RELAXED_ORDERING = (__force pci_dev_flags_t) (1 << 12), }; enum pci_irq_reroute_variant { @@ -1125,6 +1127,7 @@ int pci_add_ext_cap_save_buffer(struct pci_dev *dev, void pci_pme_wakeup_bus(struct pci_bus *bus); void pci_d3cold_enable(struct pci_dev *dev); void pci_d3cold_disable(struct pci_dev *dev); +bool pcie_relaxed_ordering_enabled(struct pci_dev *dev); /* PCI Virtual Channel */ int pci_save_vc_state(struct pci_dev *dev);