From: "Luis R. Rodriguez" <[email protected]>

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 <[email protected]>
Cc: Mike Marciniszyn <[email protected]>
Cc: Roland Dreier <[email protected]>
Cc: Andy Lutomirski <[email protected]>
Cc: Suresh Siddha <[email protected]>
Cc: Venkatesh Pallipadi <[email protected]>
Cc: Ingo Molnar <[email protected]>
Cc: Linus Torvalds <[email protected]>
Cc: Thomas Gleixner <[email protected]>
Cc: Juergen Gross <[email protected]>
Cc: Daniel Vetter <[email protected]>
Cc: Dave Airlie <[email protected]>
Cc: Bjorn Helgaas <[email protected]>
Cc: Antonino Daplas <[email protected]>
Cc: Jean-Christophe Plagniol-Villard <[email protected]>
Cc: Tomi Valkeinen <[email protected]>
Cc: Dave Hansen <[email protected]>
Cc: Arnd Bergmann <[email protected]>
Cc: Michael S. Tsirkin <[email protected]>
Cc: [email protected]
Cc: Stefan Bader <[email protected]>
Cc: [email protected]
Cc: [email protected]
Cc: [email protected]
Cc: [email protected]
Cc: [email protected]
Cc: Roger Pau MonnĂ© <[email protected]>
Cc: [email protected]
Cc: [email protected]
Cc: [email protected]
Signed-off-by: Luis R. Rodriguez <[email protected]>
---
 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 [email protected]
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