From: "Luis R. Rodriguez" <mcg...@suse.com>

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 <rickard_strandqv...@spectrumdigital.se>
Cc: Mike Marciniszyn <mike.marcinis...@intel.com>
Cc: Roland Dreier <rol...@purestorage.com>
Cc: Andy Lutomirski <l...@amacapital.net>
Cc: Suresh Siddha <suresh.b.sid...@intel.com>
Cc: Venkatesh Pallipadi <venkatesh.pallip...@intel.com>
Cc: Ingo Molnar <mi...@elte.hu>
Cc: Linus Torvalds <torva...@linux-foundation.org>
Cc: Thomas Gleixner <t...@linutronix.de>
Cc: Juergen Gross <jgr...@suse.com>
Cc: Daniel Vetter <daniel.vet...@ffwll.ch>
Cc: Dave Airlie <airl...@redhat.com>
Cc: Bjorn Helgaas <bhelg...@google.com>
Cc: Antonino Daplas <adap...@gmail.com>
Cc: Jean-Christophe Plagniol-Villard <plagn...@jcrosoft.com>
Cc: Tomi Valkeinen <tomi.valkei...@ti.com>
Cc: Dave Hansen <dave.han...@linux.intel.com>
Cc: Arnd Bergmann <a...@arndb.de>
Cc: Michael S. Tsirkin <m...@redhat.com>
Cc: venkatesh.pallip...@intel.com
Cc: Stefan Bader <stefan.ba...@canonical.com>
Cc: konrad.w...@oracle.com
Cc: ville.syrj...@linux.intel.com
Cc: david.vra...@citrix.com
Cc: jbeul...@suse.com
Cc: toshi.k...@hp.com
Cc: Roger Pau Monné <roger....@citrix.com>
Cc: linux-fb...@vger.kernel.org
Cc: linux-kernel@vger.kernel.org
Cc: xen-de...@lists.xensource.com
Signed-off-by: Luis R. Rodriguez <mcg...@suse.com>
---
 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

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

Reply via email to