[PATCH v1 14/47] IB/ipath: use __arch_phys_wc_add()
From: Luis R. Rodriguez <hidden>
Date: 2015-03-20 23:51:49
Also in:
lkml, xen-devel
Subsystem:
infiniband subsystem, the rest · Maintainers:
Jason Gunthorpe, Leon Romanovsky, Linus Torvalds
From: "Luis R. Rodriguez" <redacted> This driver sadly does not have the MMIO registers and WC desired areas (PIO buffers in this case) properly split up and addressing a split is considerable work, as such this such requires using the __arch_phys_wc_add() call to ensure write combining is enforced using MTRR on x86 even when PAT is available. Cc: Rickard Strandqvist <redacted> Cc: Mike Marciniszyn <redacted> Cc: Roland Dreier <redacted> Cc: Andy Lutomirski <luto@amacapital.net> Cc: Suresh Siddha <redacted> Cc: Venkatesh Pallipadi <redacted> Cc: Ingo Molnar <redacted> Cc: Linus Torvalds <torvalds@linux-foundation.org> Cc: Thomas Gleixner <redacted> Cc: Juergen Gross <jgross@suse.com> Cc: Daniel Vetter <redacted> Cc: Dave Airlie <airlied@redhat.com> Cc: Bjorn Helgaas <bhelgaas@google.com> Cc: Antonino Daplas <adaplas@gmail.com> Cc: Jean-Christophe Plagniol-Villard <redacted> Cc: Tomi Valkeinen <redacted> Cc: Dave Hansen <dave.hansen@linux.intel.com> Cc: Arnd Bergmann <arnd@arndb.de> Cc: Michael S. Tsirkin <mst@redhat.com> Cc: venkatesh.pallipadi@intel.com Cc: Stefan Bader <redacted> Cc: konrad.wilk@oracle.com Cc: ville.syrjala@linux.intel.com Cc: david.vrabel@citrix.com Cc: jbeulich@suse.com Cc: toshi.kani@hp.com Cc: Roger Pau Monné <roger.pau@citrix.com> Cc: linux-fbdev@vger.kernel.org Cc: linux-kernel@vger.kernel.org Cc: xen-devel@lists.xensource.com Signed-off-by: Luis R. Rodriguez <redacted> --- drivers/infiniband/hw/ipath/ipath_driver.c | 7 ++-- drivers/infiniband/hw/ipath/ipath_kernel.h | 4 +-- drivers/infiniband/hw/ipath/ipath_wc_x86_64.c | 47 ++++++++++----------------- 3 files changed, 20 insertions(+), 38 deletions(-)
diff --git a/drivers/infiniband/hw/ipath/ipath_driver.c b/drivers/infiniband/hw/ipath/ipath_driver.c
index bd0caed..464f39c 100644
--- a/drivers/infiniband/hw/ipath/ipath_driver.c
+++ b/drivers/infiniband/hw/ipath/ipath_driver.c@@ -542,6 +542,7 @@ static int ipath_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) dd->ipath_kregbase = __ioremap(addr, len, (_PAGE_NO_CACHE|_PAGE_WRITETHRU)); #else + /* XXX: split pio on a separate ioremap_wc() */ dd->ipath_kregbase = ioremap_nocache(addr, len); #endif
@@ -587,12 +588,8 @@ static int ipath_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) ret = ipath_enable_wc(dd); - if (ret) { - ipath_dev_err(dd, "Write combining not enabled " - "(err %d): performance may be poor\n", - -ret); + if (ret) ret = 0; - } ipath_verify_pioperf(dd);
diff --git a/drivers/infiniband/hw/ipath/ipath_kernel.h b/drivers/infiniband/hw/ipath/ipath_kernel.h
index e08db70..f0f9471 100644
--- a/drivers/infiniband/hw/ipath/ipath_kernel.h
+++ b/drivers/infiniband/hw/ipath/ipath_kernel.h@@ -463,9 +463,7 @@ struct ipath_devdata { /* offset in HT config space of slave/primary interface block */ u8 ipath_ht_slave_off; /* for write combining settings */ - unsigned long ipath_wc_cookie; - unsigned long ipath_wc_base; - unsigned long ipath_wc_len; + int wc_cookie; /* ref count for each pkey */ atomic_t ipath_pkeyrefs[4]; /* shadow copy of struct page *'s for exp tid pages */
diff --git a/drivers/infiniband/hw/ipath/ipath_wc_x86_64.c b/drivers/infiniband/hw/ipath/ipath_wc_x86_64.c
index 70c1f3a..88709c1 100644
--- a/drivers/infiniband/hw/ipath/ipath_wc_x86_64.c
+++ b/drivers/infiniband/hw/ipath/ipath_wc_x86_64.c@@ -37,7 +37,6 @@ */ #include <linux/pci.h> -#include <asm/mtrr.h> #include <asm/processor.h> #include "ipath_kernel.h"
@@ -122,27 +121,26 @@ int ipath_enable_wc(struct ipath_devdata *dd) } if (!ret) { - int cookie; ipath_cdbg(VERBOSE, "Setting mtrr for chip to WC " "(addr %llx, len=0x%llx)\n", (unsigned long long) pioaddr, (unsigned long long) piolen); - cookie = mtrr_add(pioaddr, piolen, MTRR_TYPE_WRCOMB, 1); - if (cookie < 0) { - { - dev_info(&dd->pcidev->dev, - "mtrr_add() WC for PIO bufs " - "failed (%d)\n", - cookie); - ret = -EINVAL; - } - } else { - ipath_cdbg(VERBOSE, "Set mtrr for chip to WC, " - "cookie is %d\n", cookie); - dd->ipath_wc_cookie = cookie; - dd->ipath_wc_base = (unsigned long) pioaddr; - dd->ipath_wc_len = (unsigned long) piolen; - } + dd->wc_cookie = __arch_phys_wc_add(pioaddr, piolen); + if (dd->wc_cookie <= 0) { + /* + * If MTRR is not available on an architecture + * or if it could not be enabled at run time + * folks who care should work towards the + * ioremap_wc() split. + */ + if (!dd->wc_cookie) + ipath_dev_err(dd, "System does not support MTRR\n"); + else { + ipath_dev_err(dd, "Seting mtrr failed on PIO buffers\n"); + ret = -EINVAL; + } + } else + ipath_cdbg(VERBOSE, "Set mtrr for chip to WC\n"); } return ret;
@@ -154,16 +152,5 @@ int ipath_enable_wc(struct ipath_devdata *dd) */ void ipath_disable_wc(struct ipath_devdata *dd) { - if (dd->ipath_wc_cookie) { - int r; - ipath_cdbg(VERBOSE, "undoing WCCOMB on pio buffers\n"); - r = mtrr_del(dd->ipath_wc_cookie, dd->ipath_wc_base, - dd->ipath_wc_len); - if (r < 0) - dev_info(&dd->pcidev->dev, - "mtrr_del(%lx, %lx, %lx) failed: %d\n", - dd->ipath_wc_cookie, dd->ipath_wc_base, - dd->ipath_wc_len, r); - dd->ipath_wc_cookie = 0; /* even on failure */ - } + arch_phys_wc_del(dd->wc_cookie); }
--
2.3.2.209.gd67f9d5.dirty