From patchwork Sat Aug 17 00:10:15 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Kuppuswamy Sathyanarayanan X-Patchwork-Id: 11098435 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 7113313B1 for ; Sat, 17 Aug 2019 00:14:04 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 5C4AD28A96 for ; Sat, 17 Aug 2019 00:14:04 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 4D77128A9C; Sat, 17 Aug 2019 00:14:04 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-7.9 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id D7A3528A96 for ; Sat, 17 Aug 2019 00:14:03 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1725911AbfHQAN7 (ORCPT ); Fri, 16 Aug 2019 20:13:59 -0400 Received: from mga05.intel.com ([192.55.52.43]:12917 "EHLO mga05.intel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1725937AbfHQANY (ORCPT ); Fri, 16 Aug 2019 20:13:24 -0400 X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from orsmga007.jf.intel.com ([10.7.209.58]) by fmsmga105.fm.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 16 Aug 2019 17:13:22 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.64,395,1559545200"; d="scan'208";a="168194998" Received: from skuppusw-desk.jf.intel.com ([10.54.74.33]) by orsmga007.jf.intel.com with ESMTP; 16 Aug 2019 17:13:22 -0700 From: sathyanarayanan.kuppuswamy@linux.intel.com To: bhelgaas@google.com Cc: linux-pci@vger.kernel.org, linux-kernel@vger.kernel.org, ashok.raj@intel.com, keith.busch@intel.com, sathyanarayanan.kuppuswamy@linux.intel.com Subject: [PATCH v6 1/8] PCI/ATS: Fix pci_prg_resp_pasid_required() dependency issues Date: Fri, 16 Aug 2019 17:10:15 -0700 Message-Id: <56d8055230a9a79907dffa29b59707b417642256.1565997310.git.sathyanarayanan.kuppuswamy@linux.intel.com> X-Mailer: git-send-email 2.21.0 In-Reply-To: References: MIME-Version: 1.0 Sender: linux-pci-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-pci@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP From: Kuppuswamy Sathyanarayanan Since pci_prg_resp_pasid_required() function has dependency on both PASID and PRI, define it only if both CONFIG_PCI_PRI and CONFIG_PCI_PASID config options are enabled. Fixes: e5567f5f6762 ("PCI/ATS: Add pci_prg_resp_pasid_required() interface.") Signed-off-by: Kuppuswamy Sathyanarayanan --- drivers/pci/ats.c | 10 ++++++---- include/linux/pci-ats.h | 12 +++++++++--- 2 files changed, 15 insertions(+), 7 deletions(-) diff --git a/drivers/pci/ats.c b/drivers/pci/ats.c index e18499243f84..cdd936d10f68 100644 --- a/drivers/pci/ats.c +++ b/drivers/pci/ats.c @@ -395,6 +395,8 @@ int pci_pasid_features(struct pci_dev *pdev) } EXPORT_SYMBOL_GPL(pci_pasid_features); +#ifdef CONFIG_PCI_PRI + /** * pci_prg_resp_pasid_required - Return PRG Response PASID Required bit * status. @@ -402,10 +404,8 @@ EXPORT_SYMBOL_GPL(pci_pasid_features); * * Returns 1 if PASID is required in PRG Response Message, 0 otherwise. * - * Even though the PRG response PASID status is read from PRI Status - * Register, since this API will mainly be used by PASID users, this - * function is defined within #ifdef CONFIG_PCI_PASID instead of - * CONFIG_PCI_PRI. + * Since this API has dependency on both PRI and PASID, protect it + * with both CONFIG_PCI_PRI and CONFIG_PCI_PASID. */ int pci_prg_resp_pasid_required(struct pci_dev *pdev) { @@ -425,6 +425,8 @@ int pci_prg_resp_pasid_required(struct pci_dev *pdev) } EXPORT_SYMBOL_GPL(pci_prg_resp_pasid_required); +#endif + #define PASID_NUMBER_SHIFT 8 #define PASID_NUMBER_MASK (0x1f << PASID_NUMBER_SHIFT) /** diff --git a/include/linux/pci-ats.h b/include/linux/pci-ats.h index 1ebb88e7c184..1a0bdaee2f32 100644 --- a/include/linux/pci-ats.h +++ b/include/linux/pci-ats.h @@ -40,7 +40,6 @@ void pci_disable_pasid(struct pci_dev *pdev); void pci_restore_pasid_state(struct pci_dev *pdev); int pci_pasid_features(struct pci_dev *pdev); int pci_max_pasids(struct pci_dev *pdev); -int pci_prg_resp_pasid_required(struct pci_dev *pdev); #else /* CONFIG_PCI_PASID */ @@ -67,11 +66,18 @@ static inline int pci_max_pasids(struct pci_dev *pdev) return -EINVAL; } +#endif /* CONFIG_PCI_PASID */ + +#if defined(CONFIG_PCI_PRI) && defined(CONFIG_PCI_PASID) + +int pci_prg_resp_pasid_required(struct pci_dev *pdev); + +#else /* CONFIG_PCI_PASID && CONFIG_PCI_PRI */ + static inline int pci_prg_resp_pasid_required(struct pci_dev *pdev) { return 0; } -#endif /* CONFIG_PCI_PASID */ - +#endif #endif /* LINUX_PCI_ATS_H*/ From patchwork Sat Aug 17 00:10:16 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Kuppuswamy Sathyanarayanan X-Patchwork-Id: 11098429 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 623F113B1 for ; Sat, 17 Aug 2019 00:13:45 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 51D2728A96 for ; Sat, 17 Aug 2019 00:13:45 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 461D628A99; Sat, 17 Aug 2019 00:13:45 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-7.9 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 3931328A96 for ; Sat, 17 Aug 2019 00:13:44 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726089AbfHQANY (ORCPT ); Fri, 16 Aug 2019 20:13:24 -0400 Received: from mga05.intel.com ([192.55.52.43]:12918 "EHLO mga05.intel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726032AbfHQANY (ORCPT ); Fri, 16 Aug 2019 20:13:24 -0400 X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from orsmga007.jf.intel.com ([10.7.209.58]) by fmsmga105.fm.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 16 Aug 2019 17:13:23 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.64,395,1559545200"; d="scan'208";a="168195001" Received: from skuppusw-desk.jf.intel.com ([10.54.74.33]) by orsmga007.jf.intel.com with ESMTP; 16 Aug 2019 17:13:22 -0700 From: sathyanarayanan.kuppuswamy@linux.intel.com To: bhelgaas@google.com Cc: linux-pci@vger.kernel.org, linux-kernel@vger.kernel.org, ashok.raj@intel.com, keith.busch@intel.com, sathyanarayanan.kuppuswamy@linux.intel.com Subject: [PATCH v6 2/8] PCI/ATS: Cache PRI capability check result Date: Fri, 16 Aug 2019 17:10:16 -0700 Message-Id: <9e4ed11d29d3af4df7420a88f37e6dfed12eac86.1565997310.git.sathyanarayanan.kuppuswamy@linux.intel.com> X-Mailer: git-send-email 2.21.0 In-Reply-To: References: MIME-Version: 1.0 Sender: linux-pci-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-pci@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP From: Kuppuswamy Sathyanarayanan Currently, PRI capability checks are repeated across all PRI API's. Instead, cache the capability check result in pci_pri_init() and use it in other PRI API's. Signed-off-by: Kuppuswamy Sathyanarayanan --- drivers/pci/ats.c | 56 +++++++++++++++++++++++++-------------------- include/linux/pci.h | 1 + 2 files changed, 32 insertions(+), 25 deletions(-) diff --git a/drivers/pci/ats.c b/drivers/pci/ats.c index cdd936d10f68..b863562b6702 100644 --- a/drivers/pci/ats.c +++ b/drivers/pci/ats.c @@ -16,6 +16,19 @@ #include "pci.h" +static void pci_pri_init(struct pci_dev *pdev) +{ +#ifdef CONFIG_PCI_PRI + int pos; + + pos = pci_find_ext_capability(pdev, PCI_EXT_CAP_ID_PRI); + if (!pos) + return; + + pdev->pri_cap = pos; +#endif +} + void pci_ats_init(struct pci_dev *dev) { int pos; @@ -28,6 +41,8 @@ void pci_ats_init(struct pci_dev *dev) return; dev->ats_cap = pos; + + pci_pri_init(dev); } /** @@ -180,26 +195,25 @@ int pci_enable_pri(struct pci_dev *pdev, u32 reqs) { u16 control, status; u32 max_requests; - int pos; if (WARN_ON(pdev->pri_enabled)) return -EBUSY; - pos = pci_find_ext_capability(pdev, PCI_EXT_CAP_ID_PRI); - if (!pos) + if (!pdev->pri_cap) return -EINVAL; - pci_read_config_word(pdev, pos + PCI_PRI_STATUS, &status); + pci_read_config_word(pdev, pdev->pri_cap + PCI_PRI_STATUS, &status); if (!(status & PCI_PRI_STATUS_STOPPED)) return -EBUSY; - pci_read_config_dword(pdev, pos + PCI_PRI_MAX_REQ, &max_requests); + pci_read_config_dword(pdev, pdev->pri_cap + PCI_PRI_MAX_REQ, + &max_requests); reqs = min(max_requests, reqs); pdev->pri_reqs_alloc = reqs; - pci_write_config_dword(pdev, pos + PCI_PRI_ALLOC_REQ, reqs); + pci_write_config_dword(pdev, pdev->pri_cap + PCI_PRI_ALLOC_REQ, reqs); control = PCI_PRI_CTRL_ENABLE; - pci_write_config_word(pdev, pos + PCI_PRI_CTRL, control); + pci_write_config_word(pdev, pdev->pri_cap + PCI_PRI_CTRL, control); pdev->pri_enabled = 1; @@ -216,18 +230,16 @@ EXPORT_SYMBOL_GPL(pci_enable_pri); void pci_disable_pri(struct pci_dev *pdev) { u16 control; - int pos; if (WARN_ON(!pdev->pri_enabled)) return; - pos = pci_find_ext_capability(pdev, PCI_EXT_CAP_ID_PRI); - if (!pos) + if (!pdev->pri_cap) return; - pci_read_config_word(pdev, pos + PCI_PRI_CTRL, &control); + pci_read_config_word(pdev, pdev->pri_cap + PCI_PRI_CTRL, &control); control &= ~PCI_PRI_CTRL_ENABLE; - pci_write_config_word(pdev, pos + PCI_PRI_CTRL, control); + pci_write_config_word(pdev, pdev->pri_cap + PCI_PRI_CTRL, control); pdev->pri_enabled = 0; } @@ -241,17 +253,15 @@ void pci_restore_pri_state(struct pci_dev *pdev) { u16 control = PCI_PRI_CTRL_ENABLE; u32 reqs = pdev->pri_reqs_alloc; - int pos; if (!pdev->pri_enabled) return; - pos = pci_find_ext_capability(pdev, PCI_EXT_CAP_ID_PRI); - if (!pos) + if (!pdev->pri_cap) return; - pci_write_config_dword(pdev, pos + PCI_PRI_ALLOC_REQ, reqs); - pci_write_config_word(pdev, pos + PCI_PRI_CTRL, control); + pci_write_config_dword(pdev, pdev->pri_cap + PCI_PRI_ALLOC_REQ, reqs); + pci_write_config_word(pdev, pdev->pri_cap + PCI_PRI_CTRL, control); } EXPORT_SYMBOL_GPL(pci_restore_pri_state); @@ -265,17 +275,15 @@ EXPORT_SYMBOL_GPL(pci_restore_pri_state); int pci_reset_pri(struct pci_dev *pdev) { u16 control; - int pos; if (WARN_ON(pdev->pri_enabled)) return -EBUSY; - pos = pci_find_ext_capability(pdev, PCI_EXT_CAP_ID_PRI); - if (!pos) + if (!pdev->pri_cap) return -EINVAL; control = PCI_PRI_CTRL_RESET; - pci_write_config_word(pdev, pos + PCI_PRI_CTRL, control); + pci_write_config_word(pdev, pdev->pri_cap + PCI_PRI_CTRL, control); return 0; } @@ -410,13 +418,11 @@ EXPORT_SYMBOL_GPL(pci_pasid_features); int pci_prg_resp_pasid_required(struct pci_dev *pdev) { u16 status; - int pos; - pos = pci_find_ext_capability(pdev, PCI_EXT_CAP_ID_PRI); - if (!pos) + if (!pdev->pri_cap) return 0; - pci_read_config_word(pdev, pos + PCI_PRI_STATUS, &status); + pci_read_config_word(pdev, pdev->pri_cap + PCI_PRI_STATUS, &status); if (status & PCI_PRI_STATUS_PASID) return 1; diff --git a/include/linux/pci.h b/include/linux/pci.h index 9e700d9f9f28..56b55db099fc 100644 --- a/include/linux/pci.h +++ b/include/linux/pci.h @@ -455,6 +455,7 @@ struct pci_dev { atomic_t ats_ref_cnt; /* Number of VFs with ATS enabled */ #endif #ifdef CONFIG_PCI_PRI + u16 pri_cap; /* PRI Capability offset */ u32 pri_reqs_alloc; /* Number of PRI requests allocated */ #endif #ifdef CONFIG_PCI_PASID From patchwork Sat Aug 17 00:10:17 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Kuppuswamy Sathyanarayanan X-Patchwork-Id: 11098427 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 84A955700 for ; Sat, 17 Aug 2019 00:13:43 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 718DE28A96 for ; Sat, 17 Aug 2019 00:13:43 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 65E2728A97; Sat, 17 Aug 2019 00:13:43 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-7.9 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id E805628A9C for ; Sat, 17 Aug 2019 00:13:42 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726357AbfHQANi (ORCPT ); Fri, 16 Aug 2019 20:13:38 -0400 Received: from mga05.intel.com ([192.55.52.43]:12917 "EHLO mga05.intel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726047AbfHQANY (ORCPT ); Fri, 16 Aug 2019 20:13:24 -0400 X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from orsmga007.jf.intel.com ([10.7.209.58]) by fmsmga105.fm.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 16 Aug 2019 17:13:23 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.64,395,1559545200"; d="scan'208";a="168195004" Received: from skuppusw-desk.jf.intel.com ([10.54.74.33]) by orsmga007.jf.intel.com with ESMTP; 16 Aug 2019 17:13:22 -0700 From: sathyanarayanan.kuppuswamy@linux.intel.com To: bhelgaas@google.com Cc: linux-pci@vger.kernel.org, linux-kernel@vger.kernel.org, ashok.raj@intel.com, keith.busch@intel.com, sathyanarayanan.kuppuswamy@linux.intel.com Subject: [PATCH v6 3/8] PCI/ATS: Cache PASID capability check result Date: Fri, 16 Aug 2019 17:10:17 -0700 Message-Id: <8dab6ec5eb5b600311111986aaca0b831472c7e5.1565997310.git.sathyanarayanan.kuppuswamy@linux.intel.com> X-Mailer: git-send-email 2.21.0 In-Reply-To: References: MIME-Version: 1.0 Sender: linux-pci-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-pci@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP From: Kuppuswamy Sathyanarayanan Currently, PASID capability checks are repeated across all PASID API's. Instead, cache the capability check result in pci_pasid_init() and use it in other PASID API's. Signed-off-by: Kuppuswamy Sathyanarayanan --- drivers/pci/ats.c | 50 ++++++++++++++++++++++++++------------------- include/linux/pci.h | 1 + 2 files changed, 30 insertions(+), 21 deletions(-) diff --git a/drivers/pci/ats.c b/drivers/pci/ats.c index b863562b6702..022698a85c98 100644 --- a/drivers/pci/ats.c +++ b/drivers/pci/ats.c @@ -29,6 +29,19 @@ static void pci_pri_init(struct pci_dev *pdev) #endif } +static void pci_pasid_init(struct pci_dev *pdev) +{ +#ifdef CONFIG_PCI_PASID + int pos; + + pos = pci_find_ext_capability(pdev, PCI_EXT_CAP_ID_PASID); + if (!pos) + return; + + pdev->pasid_cap = pos; +#endif +} + void pci_ats_init(struct pci_dev *dev) { int pos; @@ -43,6 +56,8 @@ void pci_ats_init(struct pci_dev *dev) dev->ats_cap = pos; pci_pri_init(dev); + + pci_pasid_init(dev); } /** @@ -303,7 +318,6 @@ EXPORT_SYMBOL_GPL(pci_reset_pri); int pci_enable_pasid(struct pci_dev *pdev, int features) { u16 control, supported; - int pos; if (WARN_ON(pdev->pasid_enabled)) return -EBUSY; @@ -311,11 +325,11 @@ int pci_enable_pasid(struct pci_dev *pdev, int features) if (!pdev->eetlp_prefix_path) return -EINVAL; - pos = pci_find_ext_capability(pdev, PCI_EXT_CAP_ID_PASID); - if (!pos) + if (!pdev->pasid_cap) return -EINVAL; - pci_read_config_word(pdev, pos + PCI_PASID_CAP, &supported); + pci_read_config_word(pdev, pdev->pasid_cap + PCI_PASID_CAP, + &supported); supported &= PCI_PASID_CAP_EXEC | PCI_PASID_CAP_PRIV; /* User wants to enable anything unsupported? */ @@ -325,7 +339,7 @@ int pci_enable_pasid(struct pci_dev *pdev, int features) control = PCI_PASID_CTRL_ENABLE | features; pdev->pasid_features = features; - pci_write_config_word(pdev, pos + PCI_PASID_CTRL, control); + pci_write_config_word(pdev, pdev->pasid_cap + PCI_PASID_CTRL, control); pdev->pasid_enabled = 1; @@ -340,16 +354,14 @@ EXPORT_SYMBOL_GPL(pci_enable_pasid); void pci_disable_pasid(struct pci_dev *pdev) { u16 control = 0; - int pos; if (WARN_ON(!pdev->pasid_enabled)) return; - pos = pci_find_ext_capability(pdev, PCI_EXT_CAP_ID_PASID); - if (!pos) + if (!pdev->pasid_cap) return; - pci_write_config_word(pdev, pos + PCI_PASID_CTRL, control); + pci_write_config_word(pdev, pdev->pasid_cap + PCI_PASID_CTRL, control); pdev->pasid_enabled = 0; } @@ -362,17 +374,15 @@ EXPORT_SYMBOL_GPL(pci_disable_pasid); void pci_restore_pasid_state(struct pci_dev *pdev) { u16 control; - int pos; if (!pdev->pasid_enabled) return; - pos = pci_find_ext_capability(pdev, PCI_EXT_CAP_ID_PASID); - if (!pos) + if (!pdev->pasid_cap) return; control = PCI_PASID_CTRL_ENABLE | pdev->pasid_features; - pci_write_config_word(pdev, pos + PCI_PASID_CTRL, control); + pci_write_config_word(pdev, pdev->pasid_cap + PCI_PASID_CTRL, control); } EXPORT_SYMBOL_GPL(pci_restore_pasid_state); @@ -389,13 +399,12 @@ EXPORT_SYMBOL_GPL(pci_restore_pasid_state); int pci_pasid_features(struct pci_dev *pdev) { u16 supported; - int pos; - pos = pci_find_ext_capability(pdev, PCI_EXT_CAP_ID_PASID); - if (!pos) + if (!pdev->pasid_cap) return -EINVAL; - pci_read_config_word(pdev, pos + PCI_PASID_CAP, &supported); + pci_read_config_word(pdev, pdev->pasid_cap + PCI_PASID_CAP, + &supported); supported &= PCI_PASID_CAP_EXEC | PCI_PASID_CAP_PRIV; @@ -445,13 +454,12 @@ EXPORT_SYMBOL_GPL(pci_prg_resp_pasid_required); int pci_max_pasids(struct pci_dev *pdev) { u16 supported; - int pos; - pos = pci_find_ext_capability(pdev, PCI_EXT_CAP_ID_PASID); - if (!pos) + if (!pdev->pasid_cap) return -EINVAL; - pci_read_config_word(pdev, pos + PCI_PASID_CAP, &supported); + pci_read_config_word(pdev, pdev->pasid_cap + PCI_PASID_CAP, + &supported); supported = (supported & PASID_NUMBER_MASK) >> PASID_NUMBER_SHIFT; diff --git a/include/linux/pci.h b/include/linux/pci.h index 56b55db099fc..27224c0db849 100644 --- a/include/linux/pci.h +++ b/include/linux/pci.h @@ -459,6 +459,7 @@ struct pci_dev { u32 pri_reqs_alloc; /* Number of PRI requests allocated */ #endif #ifdef CONFIG_PCI_PASID + u16 pasid_cap; /* PASID Capability offset */ u16 pasid_features; #endif #ifdef CONFIG_PCI_P2PDMA From patchwork Sat Aug 17 00:10:18 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Kuppuswamy Sathyanarayanan X-Patchwork-Id: 11098433 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id EB67014F7 for ; Sat, 17 Aug 2019 00:13:47 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id DBC6228A96 for ; Sat, 17 Aug 2019 00:13:47 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id CFFF528A99; Sat, 17 Aug 2019 00:13:47 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-7.9 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 67C6528A97 for ; Sat, 17 Aug 2019 00:13:47 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726404AbfHQANp (ORCPT ); Fri, 16 Aug 2019 20:13:45 -0400 Received: from mga05.intel.com ([192.55.52.43]:12918 "EHLO mga05.intel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1725911AbfHQANY (ORCPT ); Fri, 16 Aug 2019 20:13:24 -0400 X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from orsmga007.jf.intel.com ([10.7.209.58]) by fmsmga105.fm.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 16 Aug 2019 17:13:23 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.64,395,1559545200"; d="scan'208";a="168195006" Received: from skuppusw-desk.jf.intel.com ([10.54.74.33]) by orsmga007.jf.intel.com with ESMTP; 16 Aug 2019 17:13:22 -0700 From: sathyanarayanan.kuppuswamy@linux.intel.com To: bhelgaas@google.com Cc: linux-pci@vger.kernel.org, linux-kernel@vger.kernel.org, ashok.raj@intel.com, keith.busch@intel.com, sathyanarayanan.kuppuswamy@linux.intel.com Subject: [PATCH v6 4/8] PCI/IOV: Add pci_physfn_reslock/unlock() interfaces Date: Fri, 16 Aug 2019 17:10:18 -0700 Message-Id: <6763a208e1782d7e58d72d131b8faad5529b890a.1565997310.git.sathyanarayanan.kuppuswamy@linux.intel.com> X-Mailer: git-send-email 2.21.0 In-Reply-To: References: MIME-Version: 1.0 Sender: linux-pci-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-pci@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP From: Kuppuswamy Sathyanarayanan As per PCIe spec r5.0, sec 9.3.7, in SR-IOV devices, capabilities like PASID, PRI, VC, etc are shared between PF and its associated VFs. So, to prevent race conditions between PF/VF while updating configuration registers of these shared capabilities, a new synchronization mechanism is required. As a first step, create shared resource lock and expose expose pci_physfn_reslock/unlock() API's. Users of these shared capabilities can use these lock/unlock interfaces to synchronize its access. Since the shared capability is always implemented by PF, reslock mutex has been added to pci_sriov structure which only exists for PF. NOTE: Currently this reslock is common for all shared capabilities between PF/VF. In future, if any performance impact has been noticed, we should create individual locks for each of the shared capability. Signed-off-by: Kuppuswamy Sathyanarayanan --- drivers/pci/iov.c | 1 + drivers/pci/pci.h | 40 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 41 insertions(+) diff --git a/drivers/pci/iov.c b/drivers/pci/iov.c index 525fd3f272b3..004e7076b065 100644 --- a/drivers/pci/iov.c +++ b/drivers/pci/iov.c @@ -507,6 +507,7 @@ static int sriov_init(struct pci_dev *dev, int pos) else iov->dev = dev; + mutex_init(&iov->reslock); dev->sriov = iov; dev->is_physfn = 1; rc = compute_max_vf_buses(dev); diff --git a/drivers/pci/pci.h b/drivers/pci/pci.h index d22d1b807701..c7fa09f3389a 100644 --- a/drivers/pci/pci.h +++ b/drivers/pci/pci.h @@ -304,6 +304,19 @@ struct pci_sriov { u16 subsystem_device; /* VF subsystem device */ resource_size_t barsz[PCI_SRIOV_NUM_BARS]; /* VF BAR size */ bool drivers_autoprobe; /* Auto probing of VFs by driver */ + /* + * reslock mutex is used for synchronizing updates to resources + * shared between PF and all associated VFs. For example, in + * SRIOV devices, PRI and PASID interfaces are shared between + * PF an all VFs, and hence we need proper locking mechanism to + * prevent both PF and VF update the PRI or PASID configuration + * registers at the same time. + * NOTE: Currently, this lock is shared by all capabilities that + * has shared resource between PF and VFs. If there is any performance + * impact then perhaps we need to create separate lock for each of + * the independent capability that has shared resources. + */ + struct mutex reslock; /* PF/VF shared resource lock */ }; /** @@ -433,6 +446,27 @@ void pci_iov_update_resource(struct pci_dev *dev, int resno); resource_size_t pci_sriov_resource_alignment(struct pci_dev *dev, int resno); void pci_restore_iov_state(struct pci_dev *dev); int pci_iov_bus_range(struct pci_bus *bus); +static inline void pci_physfn_reslock(struct pci_dev *dev) +{ + struct pci_dev *pf = pci_physfn(dev); + + /* For non SRIOV devices, locking is not needed */ + if (!pf->is_physfn) + return; + + mutex_lock(&pf->sriov->reslock); +} + +static inline void pci_physfn_resunlock(struct pci_dev *dev) +{ + struct pci_dev *pf = pci_physfn(dev); + + /* For non SRIOV devices, reslock is never held */ + if (!pf->is_physfn) + return; + + mutex_unlock(&pf->sriov->reslock); +} #else static inline int pci_iov_init(struct pci_dev *dev) @@ -453,6 +487,12 @@ static inline int pci_iov_bus_range(struct pci_bus *bus) { return 0; } +static inline void pci_physfn_reslock(struct pci_dev *dev) +{ +} +static inline void pci_physfn_resunlock(struct pci_dev *dev) +{ +} #endif /* CONFIG_PCI_IOV */ From patchwork Sat Aug 17 00:10:19 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Kuppuswamy Sathyanarayanan X-Patchwork-Id: 11098431 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id A1A8213B1 for ; Sat, 17 Aug 2019 00:13:47 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 910AC28A96 for ; Sat, 17 Aug 2019 00:13:47 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 858C628A9C; Sat, 17 Aug 2019 00:13:47 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-7.9 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id B496628A96 for ; Sat, 17 Aug 2019 00:13:46 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726047AbfHQANp (ORCPT ); Fri, 16 Aug 2019 20:13:45 -0400 Received: from mga14.intel.com ([192.55.52.115]:6694 "EHLO mga14.intel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1725938AbfHQANY (ORCPT ); Fri, 16 Aug 2019 20:13:24 -0400 X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from orsmga007.jf.intel.com ([10.7.209.58]) by fmsmga103.fm.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 16 Aug 2019 17:13:23 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.64,395,1559545200"; d="scan'208";a="168195010" Received: from skuppusw-desk.jf.intel.com ([10.54.74.33]) by orsmga007.jf.intel.com with ESMTP; 16 Aug 2019 17:13:22 -0700 From: sathyanarayanan.kuppuswamy@linux.intel.com To: bhelgaas@google.com Cc: linux-pci@vger.kernel.org, linux-kernel@vger.kernel.org, ashok.raj@intel.com, keith.busch@intel.com, sathyanarayanan.kuppuswamy@linux.intel.com Subject: [PATCH v6 5/8] PCI/ATS: Add PRI support for PCIe VF devices Date: Fri, 16 Aug 2019 17:10:19 -0700 Message-Id: <06f7a6bb9fca94fa8731e5225e91a14a676d07ca.1565997310.git.sathyanarayanan.kuppuswamy@linux.intel.com> X-Mailer: git-send-email 2.21.0 In-Reply-To: References: MIME-Version: 1.0 Sender: linux-pci-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-pci@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP From: Kuppuswamy Sathyanarayanan When IOMMU tries to enable Page Request Interface (PRI) for VF device in iommu_enable_dev_iotlb(), it always fails because PRI support for PCIe VF device is currently broken. Current implementation expects the given PCIe device (PF & VF) to implement PRI capability before enabling the PRI support. But this assumption is incorrect. As per PCIe spec r4.0, sec 9.3.7.11, all VFs associated with PF can only use the PRI of the PF and not implement it. Hence we need to create exception for handling the PRI support for PCIe VF device. Also, since PRI is a shared resource between PF/VF, following rules should apply. 1. Use proper locking before accessing/modifying PF resources in VF PRI enable/disable call. 2. Use reference count logic to track the usage of PRI resource. 3. Disable PRI only if the PRI reference count (pri_ref_cnt) is zero. Cc: Ashok Raj Cc: Keith Busch Suggested-by: Ashok Raj Signed-off-by: Kuppuswamy Sathyanarayanan --- drivers/pci/ats.c | 121 ++++++++++++++++++++++++++++++++++---------- include/linux/pci.h | 1 + 2 files changed, 95 insertions(+), 27 deletions(-) diff --git a/drivers/pci/ats.c b/drivers/pci/ats.c index 022698a85c98..e71187d83401 100644 --- a/drivers/pci/ats.c +++ b/drivers/pci/ats.c @@ -21,6 +21,15 @@ static void pci_pri_init(struct pci_dev *pdev) #ifdef CONFIG_PCI_PRI int pos; + /* + * As per PCIe r4.0, sec 9.3.7.11, only PF is permitted to + * implement PRI and all associated VFs can only use it. + * Since PF already initialized the PRI parameters there is + * no need to proceed further. + */ + if (pdev->is_virtfn) + return; + pos = pci_find_ext_capability(pdev, PCI_EXT_CAP_ID_PRI); if (!pos) return; @@ -208,31 +217,55 @@ EXPORT_SYMBOL_GPL(pci_ats_page_aligned); */ int pci_enable_pri(struct pci_dev *pdev, u32 reqs) { - u16 control, status; + u16 status; u32 max_requests; + int ret = 0; + struct pci_dev *pf = pci_physfn(pdev); if (WARN_ON(pdev->pri_enabled)) return -EBUSY; - if (!pdev->pri_cap) + if (!pf->pri_cap) return -EINVAL; - pci_read_config_word(pdev, pdev->pri_cap + PCI_PRI_STATUS, &status); - if (!(status & PCI_PRI_STATUS_STOPPED)) - return -EBUSY; + pci_physfn_reslock(pdev); + + if (pdev->is_virtfn && pf->pri_enabled) + goto update_status; - pci_read_config_dword(pdev, pdev->pri_cap + PCI_PRI_MAX_REQ, - &max_requests); + /* + * Before updating PRI registers, make sure there is no + * outstanding PRI requests. + */ + pci_read_config_word(pf, pf->pri_cap + PCI_PRI_STATUS, &status); + if (!(status & PCI_PRI_STATUS_STOPPED)) { + ret = -EBUSY; + goto done; + } + + pci_read_config_dword(pf, pf->pri_cap + PCI_PRI_MAX_REQ, &max_requests); reqs = min(max_requests, reqs); - pdev->pri_reqs_alloc = reqs; - pci_write_config_dword(pdev, pdev->pri_cap + PCI_PRI_ALLOC_REQ, reqs); + pf->pri_reqs_alloc = reqs; + pci_write_config_dword(pf, pf->pri_cap + PCI_PRI_ALLOC_REQ, reqs); - control = PCI_PRI_CTRL_ENABLE; - pci_write_config_word(pdev, pdev->pri_cap + PCI_PRI_CTRL, control); + pci_write_config_word(pf, pf->pri_cap + PCI_PRI_CTRL, + PCI_PRI_CTRL_ENABLE); - pdev->pri_enabled = 1; + /* + * If PRI is not already enabled in PF, increment the PF + * pri_ref_cnt to track the usage of PRI interface. + */ + if (pdev->is_virtfn && !pf->pri_enabled) { + atomic_inc(&pf->pri_ref_cnt); + pf->pri_enabled = 1; + } - return 0; +update_status: + atomic_inc(&pf->pri_ref_cnt); + pdev->pri_enabled = 1; +done: + pci_physfn_resunlock(pdev); + return ret; } EXPORT_SYMBOL_GPL(pci_enable_pri); @@ -245,18 +278,32 @@ EXPORT_SYMBOL_GPL(pci_enable_pri); void pci_disable_pri(struct pci_dev *pdev) { u16 control; + struct pci_dev *pf = pci_physfn(pdev); if (WARN_ON(!pdev->pri_enabled)) return; - if (!pdev->pri_cap) + if (!pf->pri_cap) return; - pci_read_config_word(pdev, pdev->pri_cap + PCI_PRI_CTRL, &control); + pci_physfn_reslock(pdev); + + atomic_dec(&pf->pri_ref_cnt); + + /* + * If pri_ref_cnt is not zero, then don't modify hardware + * registers. + */ + if (atomic_read(&pf->pri_ref_cnt)) + goto done; + + pci_read_config_word(pf, pf->pri_cap + PCI_PRI_CTRL, &control); control &= ~PCI_PRI_CTRL_ENABLE; - pci_write_config_word(pdev, pdev->pri_cap + PCI_PRI_CTRL, control); + pci_write_config_word(pf, pf->pri_cap + PCI_PRI_CTRL, control); +done: pdev->pri_enabled = 0; + pci_physfn_resunlock(pdev); } EXPORT_SYMBOL_GPL(pci_disable_pri); @@ -266,17 +313,29 @@ EXPORT_SYMBOL_GPL(pci_disable_pri); */ void pci_restore_pri_state(struct pci_dev *pdev) { - u16 control = PCI_PRI_CTRL_ENABLE; - u32 reqs = pdev->pri_reqs_alloc; + u16 control; + struct pci_dev *pf = pci_physfn(pdev); if (!pdev->pri_enabled) return; - if (!pdev->pri_cap) + if (!pf->pri_cap) return; - pci_write_config_dword(pdev, pdev->pri_cap + PCI_PRI_ALLOC_REQ, reqs); - pci_write_config_word(pdev, pdev->pri_cap + PCI_PRI_CTRL, control); + pci_physfn_reslock(pdev); + + /* If PRI is already enabled by other VF's or PF, return */ + pci_read_config_word(pf, pf->pri_cap + PCI_PRI_CTRL, &control); + if (control & PCI_PRI_CTRL_ENABLE) + goto done; + + pci_write_config_dword(pf, pf->pri_cap + PCI_PRI_ALLOC_REQ, + pf->pri_reqs_alloc); + pci_write_config_word(pf, pf->pri_cap + PCI_PRI_CTRL, + PCI_PRI_CTRL_ENABLE); + +done: + pci_physfn_resunlock(pdev); } EXPORT_SYMBOL_GPL(pci_restore_pri_state); @@ -289,17 +348,24 @@ EXPORT_SYMBOL_GPL(pci_restore_pri_state); */ int pci_reset_pri(struct pci_dev *pdev) { - u16 control; + struct pci_dev *pf = pci_physfn(pdev); if (WARN_ON(pdev->pri_enabled)) return -EBUSY; - if (!pdev->pri_cap) + if (!pf->pri_cap) return -EINVAL; - control = PCI_PRI_CTRL_RESET; - pci_write_config_word(pdev, pdev->pri_cap + PCI_PRI_CTRL, control); + pci_physfn_reslock(pdev); + + /* If PRI is already enabled in PF, skip reset and return */ + if (pf->pri_enabled) + goto done; + pci_write_config_word(pf, pf->pri_cap + PCI_PRI_CTRL, + PCI_PRI_CTRL_RESET); +done: + pci_physfn_resunlock(pdev); return 0; } EXPORT_SYMBOL_GPL(pci_reset_pri); @@ -427,11 +493,12 @@ EXPORT_SYMBOL_GPL(pci_pasid_features); int pci_prg_resp_pasid_required(struct pci_dev *pdev) { u16 status; + struct pci_dev *pf = pci_physfn(pdev); - if (!pdev->pri_cap) + if (!pf->pri_cap) return 0; - pci_read_config_word(pdev, pdev->pri_cap + PCI_PRI_STATUS, &status); + pci_read_config_word(pf, pf->pri_cap + PCI_PRI_STATUS, &status); if (status & PCI_PRI_STATUS_PASID) return 1; diff --git a/include/linux/pci.h b/include/linux/pci.h index 27224c0db849..cd07b2d071c1 100644 --- a/include/linux/pci.h +++ b/include/linux/pci.h @@ -457,6 +457,7 @@ struct pci_dev { #ifdef CONFIG_PCI_PRI u16 pri_cap; /* PRI Capability offset */ u32 pri_reqs_alloc; /* Number of PRI requests allocated */ + atomic_t pri_ref_cnt; /* Number of PF/VF PRI users */ #endif #ifdef CONFIG_PCI_PASID u16 pasid_cap; /* PASID Capability offset */ From patchwork Sat Aug 17 00:10:20 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Kuppuswamy Sathyanarayanan X-Patchwork-Id: 11098421 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 6D20A174A for ; Sat, 17 Aug 2019 00:13:28 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 5C28F28A96 for ; Sat, 17 Aug 2019 00:13:28 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 4FAC228A99; Sat, 17 Aug 2019 00:13:28 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-7.9 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id B718328A97 for ; Sat, 17 Aug 2019 00:13:27 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726188AbfHQANZ (ORCPT ); Fri, 16 Aug 2019 20:13:25 -0400 Received: from mga14.intel.com ([192.55.52.115]:6694 "EHLO mga14.intel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726129AbfHQANY (ORCPT ); Fri, 16 Aug 2019 20:13:24 -0400 X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from orsmga007.jf.intel.com ([10.7.209.58]) by fmsmga103.fm.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 16 Aug 2019 17:13:23 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.64,395,1559545200"; d="scan'208";a="168195013" Received: from skuppusw-desk.jf.intel.com ([10.54.74.33]) by orsmga007.jf.intel.com with ESMTP; 16 Aug 2019 17:13:22 -0700 From: sathyanarayanan.kuppuswamy@linux.intel.com To: bhelgaas@google.com Cc: linux-pci@vger.kernel.org, linux-kernel@vger.kernel.org, ashok.raj@intel.com, keith.busch@intel.com, sathyanarayanan.kuppuswamy@linux.intel.com Subject: [PATCH v6 6/8] PCI/ATS: Add PASID support for PCIe VF devices Date: Fri, 16 Aug 2019 17:10:20 -0700 Message-Id: <9a16830464e035035fb17199395d57b8570fe6ae.1565997310.git.sathyanarayanan.kuppuswamy@linux.intel.com> X-Mailer: git-send-email 2.21.0 In-Reply-To: References: MIME-Version: 1.0 Sender: linux-pci-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-pci@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP From: Kuppuswamy Sathyanarayanan When IOMMU tries to enable PASID for VF device in iommu_enable_dev_iotlb(), it always fails because PASID support for PCIe VF device is currently broken in PCIE driver. Current implementation expects the given PCIe device (PF & VF) to implement PASID capability before enabling the PASID support. But this assumption is incorrect. As per PCIe spec r4.0, sec 9.3.7.14, all VFs associated with PF can only use the PASID of the PF and not implement it. Also, since PASID is a shared resource between PF/VF, following rules should apply. 1. Use proper locking before accessing/modifying PF resources in VF PASID enable/disable call. 2. Use reference count logic to track the usage of PASID resource. 3. Disable PASID only if the PASID reference count (pasid_ref_cnt) is zero. Cc: Ashok Raj Cc: Keith Busch Suggested-by: Ashok Raj Signed-off-by: Kuppuswamy Sathyanarayanan --- drivers/pci/ats.c | 88 +++++++++++++++++++++++++++++++++++---------- include/linux/pci.h | 1 + 2 files changed, 70 insertions(+), 19 deletions(-) diff --git a/drivers/pci/ats.c b/drivers/pci/ats.c index e71187d83401..ca633482e565 100644 --- a/drivers/pci/ats.c +++ b/drivers/pci/ats.c @@ -43,6 +43,15 @@ static void pci_pasid_init(struct pci_dev *pdev) #ifdef CONFIG_PCI_PASID int pos; + /* + * As per PCIe r4.0, sec 9.3.7.14, only PF is permitted to + * implement PASID Capability and all associated VFs can + * only use it. Since PF already initialized the PASID + * parameters there is no need to proceed further. + */ + if (pdev->is_virtfn) + return; + pos = pci_find_ext_capability(pdev, PCI_EXT_CAP_ID_PASID); if (!pos) return; @@ -384,6 +393,8 @@ EXPORT_SYMBOL_GPL(pci_reset_pri); int pci_enable_pasid(struct pci_dev *pdev, int features) { u16 control, supported; + int ret = 0; + struct pci_dev *pf = pci_physfn(pdev); if (WARN_ON(pdev->pasid_enabled)) return -EBUSY; @@ -391,25 +402,42 @@ int pci_enable_pasid(struct pci_dev *pdev, int features) if (!pdev->eetlp_prefix_path) return -EINVAL; - if (!pdev->pasid_cap) + if (!pf->pasid_cap) return -EINVAL; - pci_read_config_word(pdev, pdev->pasid_cap + PCI_PASID_CAP, - &supported); + pci_physfn_reslock(pdev); + + if (pdev->is_virtfn && pf->pasid_enabled) + goto update_status; + + pci_read_config_word(pf, pf->pasid_cap + PCI_PASID_CAP, &supported); supported &= PCI_PASID_CAP_EXEC | PCI_PASID_CAP_PRIV; /* User wants to enable anything unsupported? */ - if ((supported & features) != features) - return -EINVAL; + if ((supported & features) != features) { + ret = -EINVAL; + goto done; + } control = PCI_PASID_CTRL_ENABLE | features; - pdev->pasid_features = features; - + pf->pasid_features = features; pci_write_config_word(pdev, pdev->pasid_cap + PCI_PASID_CTRL, control); - pdev->pasid_enabled = 1; + /* + * If PASID is not already enabled in PF, increment pasid_ref_cnt + * to count PF PASID usage. + */ + if (pdev->is_virtfn && !pf->pasid_enabled) { + atomic_inc(&pf->pasid_ref_cnt); + pf->pasid_enabled = 1; + } - return 0; +update_status: + atomic_inc(&pf->pasid_ref_cnt); + pdev->pasid_enabled = 1; +done: + pci_physfn_resunlock(pdev); + return ret; } EXPORT_SYMBOL_GPL(pci_enable_pasid); @@ -420,16 +448,28 @@ EXPORT_SYMBOL_GPL(pci_enable_pasid); void pci_disable_pasid(struct pci_dev *pdev) { u16 control = 0; + struct pci_dev *pf = pci_physfn(pdev); if (WARN_ON(!pdev->pasid_enabled)) return; - if (!pdev->pasid_cap) + if (!pf->pasid_cap) return; - pci_write_config_word(pdev, pdev->pasid_cap + PCI_PASID_CTRL, control); + pci_physfn_reslock(pdev); + + atomic_dec(&pf->pasid_ref_cnt); + if (atomic_read(&pf->pasid_ref_cnt)) + goto done; + + /* Disable PASID only if pasid_ref_cnt is zero */ + pci_write_config_word(pf, pf->pasid_cap + PCI_PASID_CTRL, control); + +done: pdev->pasid_enabled = 0; + pci_physfn_resunlock(pdev); + } EXPORT_SYMBOL_GPL(pci_disable_pasid); @@ -440,15 +480,25 @@ EXPORT_SYMBOL_GPL(pci_disable_pasid); void pci_restore_pasid_state(struct pci_dev *pdev) { u16 control; + struct pci_dev *pf = pci_physfn(pdev); if (!pdev->pasid_enabled) return; - if (!pdev->pasid_cap) + if (!pf->pasid_cap) return; + pci_physfn_reslock(pdev); + + pci_read_config_word(pf, pf->pasid_cap + PCI_PASID_CTRL, &control); + if (control & PCI_PASID_CTRL_ENABLE) + goto done; + control = PCI_PASID_CTRL_ENABLE | pdev->pasid_features; - pci_write_config_word(pdev, pdev->pasid_cap + PCI_PASID_CTRL, control); + pci_write_config_word(pf, pf->pasid_cap + PCI_PASID_CTRL, control); + +done: + pci_physfn_resunlock(pdev); } EXPORT_SYMBOL_GPL(pci_restore_pasid_state); @@ -465,12 +515,12 @@ EXPORT_SYMBOL_GPL(pci_restore_pasid_state); int pci_pasid_features(struct pci_dev *pdev) { u16 supported; + struct pci_dev *pf = pci_physfn(pdev); - if (!pdev->pasid_cap) + if (!pf->pasid_cap) return -EINVAL; - pci_read_config_word(pdev, pdev->pasid_cap + PCI_PASID_CAP, - &supported); + pci_read_config_word(pf, pf->pasid_cap + PCI_PASID_CAP, &supported); supported &= PCI_PASID_CAP_EXEC | PCI_PASID_CAP_PRIV; @@ -521,12 +571,12 @@ EXPORT_SYMBOL_GPL(pci_prg_resp_pasid_required); int pci_max_pasids(struct pci_dev *pdev) { u16 supported; + struct pci_dev *pf = pci_physfn(pdev); - if (!pdev->pasid_cap) + if (!pf->pasid_cap) return -EINVAL; - pci_read_config_word(pdev, pdev->pasid_cap + PCI_PASID_CAP, - &supported); + pci_read_config_word(pf, pf->pasid_cap + PCI_PASID_CAP, &supported); supported = (supported & PASID_NUMBER_MASK) >> PASID_NUMBER_SHIFT; diff --git a/include/linux/pci.h b/include/linux/pci.h index cd07b2d071c1..735dc731e0aa 100644 --- a/include/linux/pci.h +++ b/include/linux/pci.h @@ -462,6 +462,7 @@ struct pci_dev { #ifdef CONFIG_PCI_PASID u16 pasid_cap; /* PASID Capability offset */ u16 pasid_features; + atomic_t pasid_ref_cnt; /* Number of VFs with PASID enabled */ #endif #ifdef CONFIG_PCI_P2PDMA struct pci_p2pdma *p2pdma; From patchwork Sat Aug 17 00:10:21 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Kuppuswamy Sathyanarayanan X-Patchwork-Id: 11098425 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 4D607174A for ; Sat, 17 Aug 2019 00:13:43 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 3CBDE28A96 for ; Sat, 17 Aug 2019 00:13:43 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 318CF28A99; Sat, 17 Aug 2019 00:13:43 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-7.9 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id C547B28A97 for ; Sat, 17 Aug 2019 00:13:42 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726265AbfHQAN2 (ORCPT ); Fri, 16 Aug 2019 20:13:28 -0400 Received: from mga05.intel.com ([192.55.52.43]:12918 "EHLO mga05.intel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726126AbfHQANY (ORCPT ); Fri, 16 Aug 2019 20:13:24 -0400 X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from orsmga007.jf.intel.com ([10.7.209.58]) by fmsmga105.fm.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 16 Aug 2019 17:13:23 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.64,395,1559545200"; d="scan'208";a="168195015" Received: from skuppusw-desk.jf.intel.com ([10.54.74.33]) by orsmga007.jf.intel.com with ESMTP; 16 Aug 2019 17:13:22 -0700 From: sathyanarayanan.kuppuswamy@linux.intel.com To: bhelgaas@google.com Cc: linux-pci@vger.kernel.org, linux-kernel@vger.kernel.org, ashok.raj@intel.com, keith.busch@intel.com, sathyanarayanan.kuppuswamy@linux.intel.com Subject: [PATCH v6 7/8] PCI/ATS: Disable PF/VF ATS service independently Date: Fri, 16 Aug 2019 17:10:21 -0700 Message-Id: X-Mailer: git-send-email 2.21.0 In-Reply-To: References: MIME-Version: 1.0 Sender: linux-pci-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-pci@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP From: Kuppuswamy Sathyanarayanan Currently all VF's needs to be disable their ATS service before disabling the ATS service in corresponding PF device. But this logic is incorrect and does not align with the spec. Also it might lead to some power and performance impact in the system. As per PCIe spec r4.0, sec 9.3.7.8, ATS Capabilities in VFs and their associated PFs may be enabled/disabled independently. So remove this dependency logic in enable/disable code. Cc: Ashok Raj Cc: Keith Busch Suggested-by: Ashok Raj Signed-off-by: Kuppuswamy Sathyanarayanan --- drivers/pci/ats.c | 11 ----------- include/linux/pci.h | 1 - 2 files changed, 12 deletions(-) diff --git a/drivers/pci/ats.c b/drivers/pci/ats.c index ca633482e565..3a3e81630d7c 100644 --- a/drivers/pci/ats.c +++ b/drivers/pci/ats.c @@ -108,8 +108,6 @@ int pci_enable_ats(struct pci_dev *dev, int ps) pdev = pci_physfn(dev); if (pdev->ats_stu != ps) return -EINVAL; - - atomic_inc(&pdev->ats_ref_cnt); /* count enabled VFs */ } else { dev->ats_stu = ps; ctrl |= PCI_ATS_CTRL_STU(dev->ats_stu - PCI_ATS_MIN_STU); @@ -127,20 +125,11 @@ EXPORT_SYMBOL_GPL(pci_enable_ats); */ void pci_disable_ats(struct pci_dev *dev) { - struct pci_dev *pdev; u16 ctrl; if (WARN_ON(!dev->ats_enabled)) return; - if (atomic_read(&dev->ats_ref_cnt)) - return; /* VFs still enabled */ - - if (dev->is_virtfn) { - pdev = pci_physfn(dev); - atomic_dec(&pdev->ats_ref_cnt); - } - pci_read_config_word(dev, dev->ats_cap + PCI_ATS_CTRL, &ctrl); ctrl &= ~PCI_ATS_CTRL_ENABLE; pci_write_config_word(dev, dev->ats_cap + PCI_ATS_CTRL, ctrl); diff --git a/include/linux/pci.h b/include/linux/pci.h index 735dc731e0aa..5c72590df0bf 100644 --- a/include/linux/pci.h +++ b/include/linux/pci.h @@ -452,7 +452,6 @@ struct pci_dev { }; u16 ats_cap; /* ATS Capability offset */ u8 ats_stu; /* ATS Smallest Translation Unit */ - atomic_t ats_ref_cnt; /* Number of VFs with ATS enabled */ #endif #ifdef CONFIG_PCI_PRI u16 pri_cap; /* PRI Capability offset */ From patchwork Sat Aug 17 00:10:22 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Kuppuswamy Sathyanarayanan X-Patchwork-Id: 11098423 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 1DB6D13B1 for ; Sat, 17 Aug 2019 00:13:43 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 0D33D28A96 for ; Sat, 17 Aug 2019 00:13:43 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 019DF28A9D; Sat, 17 Aug 2019 00:13:42 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-7.9 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id A5C3F28A96 for ; Sat, 17 Aug 2019 00:13:42 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726252AbfHQAN1 (ORCPT ); Fri, 16 Aug 2019 20:13:27 -0400 Received: from mga14.intel.com ([192.55.52.115]:6694 "EHLO mga14.intel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726032AbfHQANZ (ORCPT ); Fri, 16 Aug 2019 20:13:25 -0400 X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from orsmga007.jf.intel.com ([10.7.209.58]) by fmsmga103.fm.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 16 Aug 2019 17:13:23 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.64,395,1559545200"; d="scan'208";a="168195018" Received: from skuppusw-desk.jf.intel.com ([10.54.74.33]) by orsmga007.jf.intel.com with ESMTP; 16 Aug 2019 17:13:22 -0700 From: sathyanarayanan.kuppuswamy@linux.intel.com To: bhelgaas@google.com Cc: linux-pci@vger.kernel.org, linux-kernel@vger.kernel.org, ashok.raj@intel.com, keith.busch@intel.com, sathyanarayanan.kuppuswamy@linux.intel.com Subject: [PATCH v6 8/8] PCI: Skip Enhanced Allocation (EA) initialization for VF device Date: Fri, 16 Aug 2019 17:10:22 -0700 Message-Id: <336c3f97a226f936ee3581b33d40ba00a8a7caa0.1565997310.git.sathyanarayanan.kuppuswamy@linux.intel.com> X-Mailer: git-send-email 2.21.0 In-Reply-To: References: MIME-Version: 1.0 Sender: linux-pci-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-pci@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP From: Kuppuswamy Sathyanarayanan As per PCIe r4.0, sec 9.3.6, VF must not implement Enhanced Allocation Capability. So skip pci_ea_init() for virtual devices. Cc: Ashok Raj Cc: Keith Busch Suggested-by: Ashok Raj Signed-off-by: Kuppuswamy Sathyanarayanan --- drivers/pci/pci.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c index 1b27b5af3d55..266600a11769 100644 --- a/drivers/pci/pci.c +++ b/drivers/pci/pci.c @@ -3025,6 +3025,13 @@ void pci_ea_init(struct pci_dev *dev) int offset; int i; + /* + * Per PCIe r4.0, sec 9.3.6, VF must not implement Enhanced + * Allocation Capability. + */ + if (dev->is_virtfn) + return; + /* find PCI EA capability in list */ ea = pci_find_capability(dev, PCI_CAP_ID_EA); if (!ea)