aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLuis R. Rodriguez <mcgrof@suse.com>2015-06-15 04:28:18 -0400
committerIngo Molnar <mingo@kernel.org>2015-06-18 05:23:42 -0400
commit7ea402d01cb68224972dde3ae68bd41131b1c3a1 (patch)
tree286c3ff171b8bb5c770b82b3965ae6fab59cba7b
parent1bf1735b478008c30acaff18ec6f4a3ff211c28a (diff)
x86/mm/pat, drivers/infiniband/ipath: Use arch_phys_wc_add() and require PAT disabled
We are burrying direct access to MTRR code support on x86 in order to take advantage of PAT. In the future, we also want to make the default behaviour of ioremap_nocache() to use strong UC, use of mtrr_add() on those systems would make write-combining void. In order to help both enable us to later make strong UC default and in order to phase out direct MTRR access code port the driver over to arch_phys_wc_add() and annotate that the device driver requires systems to boot with PAT disabled, with the 'nopat' kernel parameter. This is a workable compromise given that the ipath device driver powers the old HTX bus cards that only work in AMD systems, while the newer IB/qib device driver powers all PCI-e cards. The ipath device driver is obsolete, hardware is hard to find and because of this its a reasonable compromise to require users of ipath to boot with 'nopat'. Signed-off-by: Luis R. Rodriguez <mcgrof@suse.com> Signed-off-by: Borislav Petkov <bp@suse.de> Acked-by: Doug Ledford <dledford@redhat.com> Cc: Andrew Morton <akpm@linux-foundation.org> Cc: Andy Lutomirski <luto@amacapital.net> Cc: Andy Walls <awalls@md.metrocast.net> Cc: Antonino Daplas <adaplas@gmail.com> Cc: Arnd Bergmann <arnd@arndb.de> Cc: Bjorn Helgaas <bhelgaas@google.com> Cc: Borislav Petkov <bp@alien8.de> Cc: Brian Gerst <brgerst@gmail.com> Cc: Daniel Vetter <daniel.vetter@ffwll.ch> Cc: Dave Airlie <airlied@redhat.com> Cc: Dave Hansen <dave.hansen@linux.intel.com> Cc: Denys Vlasenko <dvlasenk@redhat.com> Cc: H. Peter Anvin <hpa@zytor.com> Cc: Hal Rosenstock <hal.rosenstock@gmail.com> Cc: Jean-Christophe Plagniol-Villard <plagnioj@jcrosoft.com> Cc: Juergen Gross <jgross@suse.com> Cc: Linus Torvalds <torvalds@linux-foundation.org> Cc: Michael S. Tsirkin <mst@redhat.com> Cc: Mike Marciniszyn <mike.marciniszyn@intel.com> Cc: Oleg Nesterov <oleg@redhat.com> Cc: Peter Zijlstra <peterz@infradead.org> Cc: Rickard Strandqvist <rickard_strandqvist@spectrumdigital.se> Cc: Roger Pau Monné <roger.pau@citrix.com> Cc: Roland Dreier <roland@purestorage.com> Cc: Sean Hefty <sean.hefty@intel.com> Cc: Stefan Bader <stefan.bader@canonical.com> Cc: Suresh Siddha <sbsiddha@gmail.com> Cc: Thomas Gleixner <tglx@linutronix.de> Cc: Tomi Valkeinen <tomi.valkeinen@ti.com> Cc: Ville Syrjälä <syrjala@sci.fi> Cc: infinipath@intel.com Cc: jbeulich@suse.com Cc: konrad.wilk@oracle.com Cc: linux-rdma@vger.kernel.org Cc: mchehab@osg.samsung.com Cc: toshi.kani@hp.com Link: http://lkml.kernel.org/r/1434053994-2196-4-git-send-email-mcgrof@do-not-panic.com Link: http://lkml.kernel.org/r/1434356898-25135-5-git-send-email-bp@alien8.de Signed-off-by: Ingo Molnar <mingo@kernel.org>
-rw-r--r--drivers/infiniband/hw/ipath/Kconfig3
-rw-r--r--drivers/infiniband/hw/ipath/ipath_driver.c18
-rw-r--r--drivers/infiniband/hw/ipath/ipath_kernel.h4
-rw-r--r--drivers/infiniband/hw/ipath/ipath_wc_x86_64.c43
4 files changed, 26 insertions, 42 deletions
diff --git a/drivers/infiniband/hw/ipath/Kconfig b/drivers/infiniband/hw/ipath/Kconfig
index 1d9bb115cbf6..8fe54ff00580 100644
--- a/drivers/infiniband/hw/ipath/Kconfig
+++ b/drivers/infiniband/hw/ipath/Kconfig
@@ -9,3 +9,6 @@ config INFINIBAND_IPATH
9 as IP-over-InfiniBand as well as with userspace applications 9 as IP-over-InfiniBand as well as with userspace applications
10 (in conjunction with InfiniBand userspace access). 10 (in conjunction with InfiniBand userspace access).
11 For QLogic PCIe QLE based cards, use the QIB driver instead. 11 For QLogic PCIe QLE based cards, use the QIB driver instead.
12
13 If you have this hardware you will need to boot with PAT disabled
14 on your x86-64 systems, use the nopat kernel parameter.
diff --git a/drivers/infiniband/hw/ipath/ipath_driver.c b/drivers/infiniband/hw/ipath/ipath_driver.c
index bd0caedafe99..2d7e503d13cb 100644
--- a/drivers/infiniband/hw/ipath/ipath_driver.c
+++ b/drivers/infiniband/hw/ipath/ipath_driver.c
@@ -42,6 +42,9 @@
42#include <linux/bitmap.h> 42#include <linux/bitmap.h>
43#include <linux/slab.h> 43#include <linux/slab.h>
44#include <linux/module.h> 44#include <linux/module.h>
45#ifdef CONFIG_X86_64
46#include <asm/pat.h>
47#endif
45 48
46#include "ipath_kernel.h" 49#include "ipath_kernel.h"
47#include "ipath_verbs.h" 50#include "ipath_verbs.h"
@@ -395,6 +398,14 @@ static int ipath_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
395 unsigned long long addr; 398 unsigned long long addr;
396 u32 bar0 = 0, bar1 = 0; 399 u32 bar0 = 0, bar1 = 0;
397 400
401#ifdef CONFIG_X86_64
402 if (WARN(pat_enabled(),
403 "ipath needs PAT disabled, boot with nopat kernel parameter\n")) {
404 ret = -ENODEV;
405 goto bail;
406 }
407#endif
408
398 dd = ipath_alloc_devdata(pdev); 409 dd = ipath_alloc_devdata(pdev);
399 if (IS_ERR(dd)) { 410 if (IS_ERR(dd)) {
400 ret = PTR_ERR(dd); 411 ret = PTR_ERR(dd);
@@ -542,6 +553,7 @@ static int ipath_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
542 dd->ipath_kregbase = __ioremap(addr, len, 553 dd->ipath_kregbase = __ioremap(addr, len,
543 (_PAGE_NO_CACHE|_PAGE_WRITETHRU)); 554 (_PAGE_NO_CACHE|_PAGE_WRITETHRU));
544#else 555#else
556 /* XXX: split this properly to enable on PAT */
545 dd->ipath_kregbase = ioremap_nocache(addr, len); 557 dd->ipath_kregbase = ioremap_nocache(addr, len);
546#endif 558#endif
547 559
@@ -587,12 +599,8 @@ static int ipath_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
587 599
588 ret = ipath_enable_wc(dd); 600 ret = ipath_enable_wc(dd);
589 601
590 if (ret) { 602 if (ret)
591 ipath_dev_err(dd, "Write combining not enabled "
592 "(err %d): performance may be poor\n",
593 -ret);
594 ret = 0; 603 ret = 0;
595 }
596 604
597 ipath_verify_pioperf(dd); 605 ipath_verify_pioperf(dd);
598 606
diff --git a/drivers/infiniband/hw/ipath/ipath_kernel.h b/drivers/infiniband/hw/ipath/ipath_kernel.h
index e08db7020cd4..f0f947122779 100644
--- a/drivers/infiniband/hw/ipath/ipath_kernel.h
+++ b/drivers/infiniband/hw/ipath/ipath_kernel.h
@@ -463,9 +463,7 @@ struct ipath_devdata {
463 /* offset in HT config space of slave/primary interface block */ 463 /* offset in HT config space of slave/primary interface block */
464 u8 ipath_ht_slave_off; 464 u8 ipath_ht_slave_off;
465 /* for write combining settings */ 465 /* for write combining settings */
466 unsigned long ipath_wc_cookie; 466 int wc_cookie;
467 unsigned long ipath_wc_base;
468 unsigned long ipath_wc_len;
469 /* ref count for each pkey */ 467 /* ref count for each pkey */
470 atomic_t ipath_pkeyrefs[4]; 468 atomic_t ipath_pkeyrefs[4];
471 /* shadow copy of struct page *'s for exp tid pages */ 469 /* 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 4ad0b932df1f..7b6e4c843e19 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 @@
37 */ 37 */
38 38
39#include <linux/pci.h> 39#include <linux/pci.h>
40#include <asm/mtrr.h>
41#include <asm/processor.h> 40#include <asm/processor.h>
42 41
43#include "ipath_kernel.h" 42#include "ipath_kernel.h"
@@ -122,27 +121,14 @@ int ipath_enable_wc(struct ipath_devdata *dd)
122 } 121 }
123 122
124 if (!ret) { 123 if (!ret) {
125 int cookie; 124 dd->wc_cookie = arch_phys_wc_add(pioaddr, piolen);
126 ipath_cdbg(VERBOSE, "Setting mtrr for chip to WC " 125 if (dd->wc_cookie < 0) {
127 "(addr %llx, len=0x%llx)\n", 126 ipath_dev_err(dd, "Seting mtrr failed on PIO buffers\n");
128 (unsigned long long) pioaddr, 127 ret = -ENODEV;
129 (unsigned long long) piolen); 128 } else if (dd->wc_cookie == 0)
130 cookie = mtrr_add(pioaddr, piolen, MTRR_TYPE_WRCOMB, 0); 129 ipath_cdbg(VERBOSE, "Set mtrr for chip to WC not needed\n");
131 if (cookie < 0) { 130 else
132 { 131 ipath_cdbg(VERBOSE, "Set mtrr for chip to WC\n");
133 dev_info(&dd->pcidev->dev,
134 "mtrr_add() WC for PIO bufs "
135 "failed (%d)\n",
136 cookie);
137 ret = -EINVAL;
138 }
139 } else {
140 ipath_cdbg(VERBOSE, "Set mtrr for chip to WC, "
141 "cookie is %d\n", cookie);
142 dd->ipath_wc_cookie = cookie;
143 dd->ipath_wc_base = (unsigned long) pioaddr;
144 dd->ipath_wc_len = (unsigned long) piolen;
145 }
146 } 132 }
147 133
148 return ret; 134 return ret;
@@ -154,16 +140,5 @@ int ipath_enable_wc(struct ipath_devdata *dd)
154 */ 140 */
155void ipath_disable_wc(struct ipath_devdata *dd) 141void ipath_disable_wc(struct ipath_devdata *dd)
156{ 142{
157 if (dd->ipath_wc_cookie) { 143 arch_phys_wc_del(dd->wc_cookie);
158 int r;
159 ipath_cdbg(VERBOSE, "undoing WCCOMB on pio buffers\n");
160 r = mtrr_del(dd->ipath_wc_cookie, dd->ipath_wc_base,
161 dd->ipath_wc_len);
162 if (r < 0)
163 dev_info(&dd->pcidev->dev,
164 "mtrr_del(%lx, %lx, %lx) failed: %d\n",
165 dd->ipath_wc_cookie, dd->ipath_wc_base,
166 dd->ipath_wc_len, r);
167 dd->ipath_wc_cookie = 0; /* even on failure */
168 }
169} 144}