Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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>

authored by

Luis R. Rodriguez and committed by
Ingo Molnar
7ea402d0 1bf1735b

+26 -42
+3
drivers/infiniband/hw/ipath/Kconfig
··· 9 9 as IP-over-InfiniBand as well as with userspace applications 10 10 (in conjunction with InfiniBand userspace access). 11 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.
+13 -5
drivers/infiniband/hw/ipath/ipath_driver.c
··· 42 42 #include <linux/bitmap.h> 43 43 #include <linux/slab.h> 44 44 #include <linux/module.h> 45 + #ifdef CONFIG_X86_64 46 + #include <asm/pat.h> 47 + #endif 45 48 46 49 #include "ipath_kernel.h" 47 50 #include "ipath_verbs.h" ··· 398 395 unsigned long long addr; 399 396 u32 bar0 = 0, bar1 = 0; 400 397 398 + #ifdef CONFIG_X86_64 399 + if (WARN(pat_enabled(), 400 + "ipath needs PAT disabled, boot with nopat kernel parameter\n")) { 401 + ret = -ENODEV; 402 + goto bail; 403 + } 404 + #endif 405 + 401 406 dd = ipath_alloc_devdata(pdev); 402 407 if (IS_ERR(dd)) { 403 408 ret = PTR_ERR(dd); ··· 553 542 dd->ipath_kregbase = __ioremap(addr, len, 554 543 (_PAGE_NO_CACHE|_PAGE_WRITETHRU)); 555 544 #else 545 + /* XXX: split this properly to enable on PAT */ 556 546 dd->ipath_kregbase = ioremap_nocache(addr, len); 557 547 #endif 558 548 ··· 599 587 600 588 ret = ipath_enable_wc(dd); 601 589 602 - if (ret) { 603 - ipath_dev_err(dd, "Write combining not enabled " 604 - "(err %d): performance may be poor\n", 605 - -ret); 590 + if (ret) 606 591 ret = 0; 607 - } 608 592 609 593 ipath_verify_pioperf(dd); 610 594
+1 -3
drivers/infiniband/hw/ipath/ipath_kernel.h
··· 463 463 /* offset in HT config space of slave/primary interface block */ 464 464 u8 ipath_ht_slave_off; 465 465 /* for write combining settings */ 466 - unsigned long ipath_wc_cookie; 467 - unsigned long ipath_wc_base; 468 - unsigned long ipath_wc_len; 466 + int wc_cookie; 469 467 /* ref count for each pkey */ 470 468 atomic_t ipath_pkeyrefs[4]; 471 469 /* shadow copy of struct page *'s for exp tid pages */
+9 -34
drivers/infiniband/hw/ipath/ipath_wc_x86_64.c
··· 37 37 */ 38 38 39 39 #include <linux/pci.h> 40 - #include <asm/mtrr.h> 41 40 #include <asm/processor.h> 42 41 43 42 #include "ipath_kernel.h" ··· 121 122 } 122 123 123 124 if (!ret) { 124 - int cookie; 125 - ipath_cdbg(VERBOSE, "Setting mtrr for chip to WC " 126 - "(addr %llx, len=0x%llx)\n", 127 - (unsigned long long) pioaddr, 128 - (unsigned long long) piolen); 129 - cookie = mtrr_add(pioaddr, piolen, MTRR_TYPE_WRCOMB, 0); 130 - if (cookie < 0) { 131 - { 132 - dev_info(&dd->pcidev->dev, 133 - "mtrr_add() WC for PIO bufs " 134 - "failed (%d)\n", 135 - cookie); 136 - ret = -EINVAL; 137 - } 138 - } else { 139 - ipath_cdbg(VERBOSE, "Set mtrr for chip to WC, " 140 - "cookie is %d\n", cookie); 141 - dd->ipath_wc_cookie = cookie; 142 - dd->ipath_wc_base = (unsigned long) pioaddr; 143 - dd->ipath_wc_len = (unsigned long) piolen; 144 - } 125 + dd->wc_cookie = arch_phys_wc_add(pioaddr, piolen); 126 + if (dd->wc_cookie < 0) { 127 + ipath_dev_err(dd, "Seting mtrr failed on PIO buffers\n"); 128 + ret = -ENODEV; 129 + } else if (dd->wc_cookie == 0) 130 + ipath_cdbg(VERBOSE, "Set mtrr for chip to WC not needed\n"); 131 + else 132 + ipath_cdbg(VERBOSE, "Set mtrr for chip to WC\n"); 145 133 } 146 134 147 135 return ret; ··· 140 154 */ 141 155 void ipath_disable_wc(struct ipath_devdata *dd) 142 156 { 143 - if (dd->ipath_wc_cookie) { 144 - int r; 145 - ipath_cdbg(VERBOSE, "undoing WCCOMB on pio buffers\n"); 146 - r = mtrr_del(dd->ipath_wc_cookie, dd->ipath_wc_base, 147 - dd->ipath_wc_len); 148 - if (r < 0) 149 - dev_info(&dd->pcidev->dev, 150 - "mtrr_del(%lx, %lx, %lx) failed: %d\n", 151 - dd->ipath_wc_cookie, dd->ipath_wc_base, 152 - dd->ipath_wc_len, r); 153 - dd->ipath_wc_cookie = 0; /* even on failure */ 154 - } 157 + arch_phys_wc_del(dd->wc_cookie); 155 158 }