All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v5 0/6] pmem api, generic ioremap_cache, and memremap
@ 2015-06-22  8:24 ` Dan Williams
  0 siblings, 0 replies; 85+ messages in thread
From: Dan Williams @ 2015-06-22  8:24 UTC (permalink / raw)
  To: arnd, mingo, bp, hpa, tglx, ross.zwisler, akpm
  Cc: jgross, x86, toshi.kani, linux-nvdimm, benh, mcgrof, konrad.wilk,
	linux-kernel, stefan.bader, luto, linux-mm, geert, ralf, hmh,
	mpe, tj, paulus, hch

The pmem api is responsible for shepherding data out to persistent
media.  The pmem driver uses this api, when available, to assert that
data is durable by the time bio_endio() is invoked.  When an
architecture or cpu can not make persistence guarantees the driver warns
and falls back to "best effort" implementation.

Changes since v4 [1]:

1/ Christoph asked me to pull the dangling piece of yarn [2] and the
whole sweater came apart, but for the better.  This finally unifies all
the disparate ways archs had chosen to implement ioremap and friends,
and uncovered several cases where drivers were incorrectly including
<asm/io.h> instead of <linux/io.h>.

2/ Drop pmem ops and introduce a cheap arch_has_pmem_api() conditional
to use at each site where a pmem api call is made (Christoph and Andy)

3/ Document the wmb(), "sfence", in the x86 implementation of
arch_wmb_pmem() (Andy)

4/ Document and rename arch_sync_pmem(), now named arch_wmb_pmem(). (Andy)

This has been run through a defconfig build of all archs and is exposed
to the kbuild robot via nvdimm.git.

[1]: https://lists.01.org/pipermail/linux-nvdimm/2015-June/001189.html
[2]: https://lists.01.org/pipermail/linux-nvdimm/2015-June/001208.html

---

Dan Williams (5):
      arch, drivers: don't include <asm/io.h> directly, use <linux/io.h> instead
      arch: unify ioremap prototypes and macro aliases
      cleanup IORESOURCE_CACHEABLE vs ioremap()
      devm: fix ioremap_cache() usage
      arch: introduce memremap_cache() and memremap_wt()

Ross Zwisler (1):
      arch, x86: pmem api for ensuring durability of persistent memory updates


 arch/alpha/include/asm/io.h                 |    7 +-
 arch/arc/include/asm/io.h                   |    6 -
 arch/arm/Kconfig                            |    1 
 arch/arm/include/asm/io.h                   |   31 ++++++--
 arch/arm/mach-clps711x/board-cdb89712.c     |    2 
 arch/arm/mach-shmobile/pm-rcar.c            |    2 
 arch/arm64/Kconfig                          |    1 
 arch/arm64/include/asm/io.h                 |   23 ++++--
 arch/arm64/kernel/efi.c                     |    4 -
 arch/arm64/kernel/smp_spin_table.c          |   10 +-
 arch/avr32/include/asm/io.h                 |   22 +++--
 arch/avr32/mm/ioremap.c                     |    2 
 arch/cris/include/asm/io.h                  |    8 +-
 arch/cris/mm/ioremap.c                      |    2 
 arch/frv/Kconfig                            |    1 
 arch/frv/include/asm/io.h                   |   23 ++----
 arch/hexagon/include/asm/io.h               |    5 +
 arch/ia64/include/asm/io.h                  |   10 --
 arch/ia64/kernel/cyclone.c                  |    2 
 arch/ia64/mm/ioremap.c                      |    4 -
 arch/m32r/include/asm/io.h                  |    9 +-
 arch/m68k/Kconfig                           |    1 
 arch/m68k/include/asm/io_mm.h               |   21 +++--
 arch/m68k/include/asm/io_no.h               |   34 +++++---
 arch/m68k/include/asm/raw_io.h              |    3 -
 arch/m68k/mm/kmap.c                         |    2 
 arch/metag/Kconfig                          |    1 
 arch/metag/include/asm/io.h                 |   35 +++++----
 arch/microblaze/include/asm/io.h            |    6 -
 arch/microblaze/mm/pgtable.c                |    2 
 arch/mips/Kconfig                           |    1 
 arch/mips/include/asm/io.h                  |   42 ++++------
 arch/mn10300/include/asm/io.h               |   10 +-
 arch/nios2/include/asm/io.h                 |   15 +---
 arch/openrisc/include/asm/io.h              |    3 -
 arch/openrisc/mm/ioremap.c                  |    2 
 arch/parisc/include/asm/io.h                |    6 -
 arch/parisc/mm/ioremap.c                    |    2 
 arch/powerpc/Kconfig                        |    1 
 arch/powerpc/include/asm/io.h               |    7 +-
 arch/powerpc/kernel/pci_of_scan.c           |    2 
 arch/s390/include/asm/io.h                  |    8 +-
 arch/sh/include/asm/io.h                    |    9 ++
 arch/sparc/include/asm/io_32.h              |    7 --
 arch/sparc/include/asm/io_64.h              |    8 +-
 arch/sparc/kernel/ioport.c                  |    2 
 arch/sparc/kernel/pci.c                     |    3 -
 arch/tile/include/asm/io.h                  |   17 +++-
 arch/unicore32/include/asm/io.h             |   25 +++++-
 arch/x86/Kconfig                            |    2 
 arch/x86/include/asm/cacheflush.h           |   71 +++++++++++++++++
 arch/x86/include/asm/io.h                   |   15 +++-
 arch/x86/kernel/crash_dump_64.c             |    6 +
 arch/x86/kernel/kdebugfs.c                  |    8 +-
 arch/x86/kernel/ksysfs.c                    |   28 +++----
 arch/x86/mm/ioremap.c                       |   10 +-
 arch/xtensa/Kconfig                         |    1 
 arch/xtensa/include/asm/io.h                |   13 ++-
 drivers/acpi/apei/einj.c                    |    8 +-
 drivers/acpi/apei/erst.c                    |    4 -
 drivers/block/Kconfig                       |    1 
 drivers/block/pmem.c                        |   46 ++++++++++-
 drivers/firmware/google/memconsole.c        |    4 -
 drivers/isdn/icn/icn.h                      |    2 
 drivers/mtd/devices/slram.c                 |    2 
 drivers/mtd/nand/diskonchip.c               |    2 
 drivers/mtd/onenand/generic.c               |    2 
 drivers/net/ethernet/sfc/io.h               |    2 
 drivers/pci/probe.c                         |    3 -
 drivers/pnp/manager.c                       |    2 
 drivers/scsi/aic94xx/aic94xx_init.c         |    7 --
 drivers/scsi/arcmsr/arcmsr_hba.c            |    5 -
 drivers/scsi/mvsas/mv_init.c                |   15 +---
 drivers/scsi/sun3x_esp.c                    |    2 
 drivers/staging/comedi/drivers/ii_pci20kc.c |    1 
 drivers/tty/serial/8250/8250_core.c         |    2 
 drivers/video/fbdev/ocfb.c                  |    1 
 drivers/video/fbdev/s1d13xxxfb.c            |    3 -
 drivers/video/fbdev/stifb.c                 |    1 
 include/asm-generic/iomap.h                 |    8 --
 include/linux/compiler.h                    |    2 
 include/linux/device.h                      |    5 +
 include/linux/io-mapping.h                  |    2 
 include/linux/io.h                          |   64 ++++++++++++++++
 include/linux/mtd/map.h                     |    2 
 include/linux/pmem.h                        |  110 +++++++++++++++++++++++++++
 include/video/vga.h                         |    2 
 kernel/resource.c                           |   41 ++++++++++
 lib/Kconfig                                 |    8 ++
 lib/devres.c                                |   48 +++++-------
 lib/pci_iomap.c                             |    7 --
 91 files changed, 684 insertions(+), 334 deletions(-)
 create mode 100644 include/linux/pmem.h

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org.  For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>

^ permalink raw reply	[flat|nested] 85+ messages in thread

* [PATCH v5 0/6] pmem api, generic ioremap_cache, and memremap
@ 2015-06-22  8:24 ` Dan Williams
  0 siblings, 0 replies; 85+ messages in thread
From: Dan Williams @ 2015-06-22  8:24 UTC (permalink / raw)
  To: arnd, mingo, bp, hpa, tglx, ross.zwisler, akpm
  Cc: jgross, x86, toshi.kani, linux-nvdimm, benh, mcgrof, konrad.wilk,
	linux-kernel, stefan.bader, luto, linux-mm, geert, ralf, hmh,
	mpe, tj, paulus, hch

The pmem api is responsible for shepherding data out to persistent
media.  The pmem driver uses this api, when available, to assert that
data is durable by the time bio_endio() is invoked.  When an
architecture or cpu can not make persistence guarantees the driver warns
and falls back to "best effort" implementation.

Changes since v4 [1]:

1/ Christoph asked me to pull the dangling piece of yarn [2] and the
whole sweater came apart, but for the better.  This finally unifies all
the disparate ways archs had chosen to implement ioremap and friends,
and uncovered several cases where drivers were incorrectly including
<asm/io.h> instead of <linux/io.h>.

2/ Drop pmem ops and introduce a cheap arch_has_pmem_api() conditional
to use at each site where a pmem api call is made (Christoph and Andy)

3/ Document the wmb(), "sfence", in the x86 implementation of
arch_wmb_pmem() (Andy)

4/ Document and rename arch_sync_pmem(), now named arch_wmb_pmem(). (Andy)

This has been run through a defconfig build of all archs and is exposed
to the kbuild robot via nvdimm.git.

[1]: https://lists.01.org/pipermail/linux-nvdimm/2015-June/001189.html
[2]: https://lists.01.org/pipermail/linux-nvdimm/2015-June/001208.html

---

Dan Williams (5):
      arch, drivers: don't include <asm/io.h> directly, use <linux/io.h> instead
      arch: unify ioremap prototypes and macro aliases
      cleanup IORESOURCE_CACHEABLE vs ioremap()
      devm: fix ioremap_cache() usage
      arch: introduce memremap_cache() and memremap_wt()

Ross Zwisler (1):
      arch, x86: pmem api for ensuring durability of persistent memory updates


 arch/alpha/include/asm/io.h                 |    7 +-
 arch/arc/include/asm/io.h                   |    6 -
 arch/arm/Kconfig                            |    1 
 arch/arm/include/asm/io.h                   |   31 ++++++--
 arch/arm/mach-clps711x/board-cdb89712.c     |    2 
 arch/arm/mach-shmobile/pm-rcar.c            |    2 
 arch/arm64/Kconfig                          |    1 
 arch/arm64/include/asm/io.h                 |   23 ++++--
 arch/arm64/kernel/efi.c                     |    4 -
 arch/arm64/kernel/smp_spin_table.c          |   10 +-
 arch/avr32/include/asm/io.h                 |   22 +++--
 arch/avr32/mm/ioremap.c                     |    2 
 arch/cris/include/asm/io.h                  |    8 +-
 arch/cris/mm/ioremap.c                      |    2 
 arch/frv/Kconfig                            |    1 
 arch/frv/include/asm/io.h                   |   23 ++----
 arch/hexagon/include/asm/io.h               |    5 +
 arch/ia64/include/asm/io.h                  |   10 --
 arch/ia64/kernel/cyclone.c                  |    2 
 arch/ia64/mm/ioremap.c                      |    4 -
 arch/m32r/include/asm/io.h                  |    9 +-
 arch/m68k/Kconfig                           |    1 
 arch/m68k/include/asm/io_mm.h               |   21 +++--
 arch/m68k/include/asm/io_no.h               |   34 +++++---
 arch/m68k/include/asm/raw_io.h              |    3 -
 arch/m68k/mm/kmap.c                         |    2 
 arch/metag/Kconfig                          |    1 
 arch/metag/include/asm/io.h                 |   35 +++++----
 arch/microblaze/include/asm/io.h            |    6 -
 arch/microblaze/mm/pgtable.c                |    2 
 arch/mips/Kconfig                           |    1 
 arch/mips/include/asm/io.h                  |   42 ++++------
 arch/mn10300/include/asm/io.h               |   10 +-
 arch/nios2/include/asm/io.h                 |   15 +---
 arch/openrisc/include/asm/io.h              |    3 -
 arch/openrisc/mm/ioremap.c                  |    2 
 arch/parisc/include/asm/io.h                |    6 -
 arch/parisc/mm/ioremap.c                    |    2 
 arch/powerpc/Kconfig                        |    1 
 arch/powerpc/include/asm/io.h               |    7 +-
 arch/powerpc/kernel/pci_of_scan.c           |    2 
 arch/s390/include/asm/io.h                  |    8 +-
 arch/sh/include/asm/io.h                    |    9 ++
 arch/sparc/include/asm/io_32.h              |    7 --
 arch/sparc/include/asm/io_64.h              |    8 +-
 arch/sparc/kernel/ioport.c                  |    2 
 arch/sparc/kernel/pci.c                     |    3 -
 arch/tile/include/asm/io.h                  |   17 +++-
 arch/unicore32/include/asm/io.h             |   25 +++++-
 arch/x86/Kconfig                            |    2 
 arch/x86/include/asm/cacheflush.h           |   71 +++++++++++++++++
 arch/x86/include/asm/io.h                   |   15 +++-
 arch/x86/kernel/crash_dump_64.c             |    6 +
 arch/x86/kernel/kdebugfs.c                  |    8 +-
 arch/x86/kernel/ksysfs.c                    |   28 +++----
 arch/x86/mm/ioremap.c                       |   10 +-
 arch/xtensa/Kconfig                         |    1 
 arch/xtensa/include/asm/io.h                |   13 ++-
 drivers/acpi/apei/einj.c                    |    8 +-
 drivers/acpi/apei/erst.c                    |    4 -
 drivers/block/Kconfig                       |    1 
 drivers/block/pmem.c                        |   46 ++++++++++-
 drivers/firmware/google/memconsole.c        |    4 -
 drivers/isdn/icn/icn.h                      |    2 
 drivers/mtd/devices/slram.c                 |    2 
 drivers/mtd/nand/diskonchip.c               |    2 
 drivers/mtd/onenand/generic.c               |    2 
 drivers/net/ethernet/sfc/io.h               |    2 
 drivers/pci/probe.c                         |    3 -
 drivers/pnp/manager.c                       |    2 
 drivers/scsi/aic94xx/aic94xx_init.c         |    7 --
 drivers/scsi/arcmsr/arcmsr_hba.c            |    5 -
 drivers/scsi/mvsas/mv_init.c                |   15 +---
 drivers/scsi/sun3x_esp.c                    |    2 
 drivers/staging/comedi/drivers/ii_pci20kc.c |    1 
 drivers/tty/serial/8250/8250_core.c         |    2 
 drivers/video/fbdev/ocfb.c                  |    1 
 drivers/video/fbdev/s1d13xxxfb.c            |    3 -
 drivers/video/fbdev/stifb.c                 |    1 
 include/asm-generic/iomap.h                 |    8 --
 include/linux/compiler.h                    |    2 
 include/linux/device.h                      |    5 +
 include/linux/io-mapping.h                  |    2 
 include/linux/io.h                          |   64 ++++++++++++++++
 include/linux/mtd/map.h                     |    2 
 include/linux/pmem.h                        |  110 +++++++++++++++++++++++++++
 include/video/vga.h                         |    2 
 kernel/resource.c                           |   41 ++++++++++
 lib/Kconfig                                 |    8 ++
 lib/devres.c                                |   48 +++++-------
 lib/pci_iomap.c                             |    7 --
 91 files changed, 684 insertions(+), 334 deletions(-)
 create mode 100644 include/linux/pmem.h
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
Please read the FAQ at  http://www.tux.org/lkml/

^ permalink raw reply	[flat|nested] 85+ messages in thread

* [PATCH v5 1/6] arch, drivers: don't include <asm/io.h> directly, use <linux/io.h> instead
  2015-06-22  8:24 ` Dan Williams
@ 2015-06-22  8:24   ` Dan Williams
  -1 siblings, 0 replies; 85+ messages in thread
From: Dan Williams @ 2015-06-22  8:24 UTC (permalink / raw)
  To: arnd, mingo, bp, hpa, tglx, ross.zwisler, akpm
  Cc: jgross, x86, toshi.kani, linux-nvdimm, benh, mcgrof, konrad.wilk,
	linux-kernel, stefan.bader, luto, linux-mm, geert, ralf, hmh,
	mpe, tj, paulus, hch

Preparation for uniform definition of ioremap, ioremap_wc, ioremap_wt,
and ioremap_cache, tree-wide.

Signed-off-by: Dan Williams <dan.j.williams@intel.com>
---
 arch/arm/mach-shmobile/pm-rcar.c            |    2 +-
 arch/ia64/kernel/cyclone.c                  |    2 +-
 drivers/isdn/icn/icn.h                      |    2 +-
 drivers/mtd/devices/slram.c                 |    2 +-
 drivers/mtd/nand/diskonchip.c               |    2 +-
 drivers/mtd/onenand/generic.c               |    2 +-
 drivers/scsi/sun3x_esp.c                    |    2 +-
 drivers/staging/comedi/drivers/ii_pci20kc.c |    1 +
 drivers/tty/serial/8250/8250_core.c         |    2 +-
 drivers/video/fbdev/s1d13xxxfb.c            |    3 +--
 drivers/video/fbdev/stifb.c                 |    1 +
 include/linux/io-mapping.h                  |    2 +-
 include/linux/mtd/map.h                     |    2 +-
 include/video/vga.h                         |    2 +-
 14 files changed, 14 insertions(+), 13 deletions(-)

diff --git a/arch/arm/mach-shmobile/pm-rcar.c b/arch/arm/mach-shmobile/pm-rcar.c
index 00022ee56f80..9d3dde00c2fe 100644
--- a/arch/arm/mach-shmobile/pm-rcar.c
+++ b/arch/arm/mach-shmobile/pm-rcar.c
@@ -12,7 +12,7 @@
 #include <linux/err.h>
 #include <linux/mm.h>
 #include <linux/spinlock.h>
-#include <asm/io.h>
+#include <linux/io.h>
 #include "pm-rcar.h"
 
 /* SYSC */
diff --git a/arch/ia64/kernel/cyclone.c b/arch/ia64/kernel/cyclone.c
index 4826ff957a3d..5fa3848ba224 100644
--- a/arch/ia64/kernel/cyclone.c
+++ b/arch/ia64/kernel/cyclone.c
@@ -4,7 +4,7 @@
 #include <linux/errno.h>
 #include <linux/timex.h>
 #include <linux/clocksource.h>
-#include <asm/io.h>
+#include <linux/io.h>
 
 /* IBM Summit (EXA) Cyclone counter code*/
 #define CYCLONE_CBAR_ADDR 0xFEB00CD0
diff --git a/drivers/isdn/icn/icn.h b/drivers/isdn/icn/icn.h
index b713466997a0..f8f2e76d34bf 100644
--- a/drivers/isdn/icn/icn.h
+++ b/drivers/isdn/icn/icn.h
@@ -38,7 +38,7 @@ typedef struct icn_cdef {
 #include <linux/errno.h>
 #include <linux/fs.h>
 #include <linux/major.h>
-#include <asm/io.h>
+#include <linux/io.h>
 #include <linux/kernel.h>
 #include <linux/signal.h>
 #include <linux/slab.h>
diff --git a/drivers/mtd/devices/slram.c b/drivers/mtd/devices/slram.c
index 2fc4957cbe7f..a70eb83e68f1 100644
--- a/drivers/mtd/devices/slram.c
+++ b/drivers/mtd/devices/slram.c
@@ -41,7 +41,7 @@
 #include <linux/fs.h>
 #include <linux/ioctl.h>
 #include <linux/init.h>
-#include <asm/io.h>
+#include <linux/io.h>
 
 #include <linux/mtd/mtd.h>
 
diff --git a/drivers/mtd/nand/diskonchip.c b/drivers/mtd/nand/diskonchip.c
index f68a7bccecdc..c8f7c69c5204 100644
--- a/drivers/mtd/nand/diskonchip.c
+++ b/drivers/mtd/nand/diskonchip.c
@@ -24,7 +24,7 @@
 #include <linux/rslib.h>
 #include <linux/moduleparam.h>
 #include <linux/slab.h>
-#include <asm/io.h>
+#include <linux/io.h>
 
 #include <linux/mtd/mtd.h>
 #include <linux/mtd/nand.h>
diff --git a/drivers/mtd/onenand/generic.c b/drivers/mtd/onenand/generic.c
index 32a216d31141..ab7bda0bb245 100644
--- a/drivers/mtd/onenand/generic.c
+++ b/drivers/mtd/onenand/generic.c
@@ -18,7 +18,7 @@
 #include <linux/mtd/mtd.h>
 #include <linux/mtd/onenand.h>
 #include <linux/mtd/partitions.h>
-#include <asm/io.h>
+#include <linux/io.h>
 
 /*
  * Note: Driver name and platform data format have been updated!
diff --git a/drivers/scsi/sun3x_esp.c b/drivers/scsi/sun3x_esp.c
index e26e81de7c45..d50c5ed8f428 100644
--- a/drivers/scsi/sun3x_esp.c
+++ b/drivers/scsi/sun3x_esp.c
@@ -12,9 +12,9 @@
 #include <linux/platform_device.h>
 #include <linux/dma-mapping.h>
 #include <linux/interrupt.h>
+#include <linux/io.h>
 
 #include <asm/sun3x.h>
-#include <asm/io.h>
 #include <asm/dma.h>
 #include <asm/dvma.h>
 
diff --git a/drivers/staging/comedi/drivers/ii_pci20kc.c b/drivers/staging/comedi/drivers/ii_pci20kc.c
index 0768bc42a5db..14ef1f67dd42 100644
--- a/drivers/staging/comedi/drivers/ii_pci20kc.c
+++ b/drivers/staging/comedi/drivers/ii_pci20kc.c
@@ -28,6 +28,7 @@
  */
 
 #include <linux/module.h>
+#include <linux/io.h>
 #include "../comedidev.h"
 
 /*
diff --git a/drivers/tty/serial/8250/8250_core.c b/drivers/tty/serial/8250/8250_core.c
index 4506e405c8f3..7b6c3d56b8c7 100644
--- a/drivers/tty/serial/8250/8250_core.c
+++ b/drivers/tty/serial/8250/8250_core.c
@@ -38,11 +38,11 @@
 #include <linux/slab.h>
 #include <linux/uaccess.h>
 #include <linux/pm_runtime.h>
+#include <linux/io.h>
 #ifdef CONFIG_SPARC
 #include <linux/sunserialcore.h>
 #endif
 
-#include <asm/io.h>
 #include <asm/irq.h>
 
 #include "8250.h"
diff --git a/drivers/video/fbdev/s1d13xxxfb.c b/drivers/video/fbdev/s1d13xxxfb.c
index 83433cb0dfba..96aa46dc696c 100644
--- a/drivers/video/fbdev/s1d13xxxfb.c
+++ b/drivers/video/fbdev/s1d13xxxfb.c
@@ -32,8 +32,7 @@
 #include <linux/spinlock_types.h>
 #include <linux/spinlock.h>
 #include <linux/slab.h>
-
-#include <asm/io.h>
+#include <linux/io.h>
 
 #include <video/s1d13xxxfb.h>
 
diff --git a/drivers/video/fbdev/stifb.c b/drivers/video/fbdev/stifb.c
index 86621fabbb8b..158f19bcae44 100644
--- a/drivers/video/fbdev/stifb.c
+++ b/drivers/video/fbdev/stifb.c
@@ -64,6 +64,7 @@
 #include <linux/fb.h>
 #include <linux/init.h>
 #include <linux/ioport.h>
+#include <linux/io.h>
 
 #include <asm/grfioctl.h>	/* for HP-UX compatibility */
 #include <asm/uaccess.h>
diff --git a/include/linux/io-mapping.h b/include/linux/io-mapping.h
index c27dde7215b5..e399029b68c5 100644
--- a/include/linux/io-mapping.h
+++ b/include/linux/io-mapping.h
@@ -21,7 +21,7 @@
 #include <linux/types.h>
 #include <linux/slab.h>
 #include <linux/bug.h>
-#include <asm/io.h>
+#include <linux/io.h>
 #include <asm/page.h>
 
 /*
diff --git a/include/linux/mtd/map.h b/include/linux/mtd/map.h
index 29975c73a953..366cf77953b5 100644
--- a/include/linux/mtd/map.h
+++ b/include/linux/mtd/map.h
@@ -27,9 +27,9 @@
 #include <linux/string.h>
 #include <linux/bug.h>
 #include <linux/kernel.h>
+#include <linux/io.h>
 
 #include <asm/unaligned.h>
-#include <asm/io.h>
 #include <asm/barrier.h>
 
 #ifdef CONFIG_MTD_MAP_BANK_WIDTH_1
diff --git a/include/video/vga.h b/include/video/vga.h
index cac567f22e62..d334e64c1c19 100644
--- a/include/video/vga.h
+++ b/include/video/vga.h
@@ -18,7 +18,7 @@
 #define __linux_video_vga_h__
 
 #include <linux/types.h>
-#include <asm/io.h>
+#include <linux/io.h>
 #include <asm/vga.h>
 #include <asm/byteorder.h>
 

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org.  For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>

^ permalink raw reply related	[flat|nested] 85+ messages in thread

* [PATCH v5 1/6] arch, drivers: don't include <asm/io.h> directly, use <linux/io.h> instead
@ 2015-06-22  8:24   ` Dan Williams
  0 siblings, 0 replies; 85+ messages in thread
From: Dan Williams @ 2015-06-22  8:24 UTC (permalink / raw)
  To: arnd, mingo, bp, hpa, tglx, ross.zwisler, akpm
  Cc: jgross, x86, toshi.kani, linux-nvdimm, benh, mcgrof, konrad.wilk,
	linux-kernel, stefan.bader, luto, linux-mm, geert, ralf, hmh,
	mpe, tj, paulus, hch

Preparation for uniform definition of ioremap, ioremap_wc, ioremap_wt,
and ioremap_cache, tree-wide.

Signed-off-by: Dan Williams <dan.j.williams@intel.com>
---
 arch/arm/mach-shmobile/pm-rcar.c            |    2 +-
 arch/ia64/kernel/cyclone.c                  |    2 +-
 drivers/isdn/icn/icn.h                      |    2 +-
 drivers/mtd/devices/slram.c                 |    2 +-
 drivers/mtd/nand/diskonchip.c               |    2 +-
 drivers/mtd/onenand/generic.c               |    2 +-
 drivers/scsi/sun3x_esp.c                    |    2 +-
 drivers/staging/comedi/drivers/ii_pci20kc.c |    1 +
 drivers/tty/serial/8250/8250_core.c         |    2 +-
 drivers/video/fbdev/s1d13xxxfb.c            |    3 +--
 drivers/video/fbdev/stifb.c                 |    1 +
 include/linux/io-mapping.h                  |    2 +-
 include/linux/mtd/map.h                     |    2 +-
 include/video/vga.h                         |    2 +-
 14 files changed, 14 insertions(+), 13 deletions(-)

diff --git a/arch/arm/mach-shmobile/pm-rcar.c b/arch/arm/mach-shmobile/pm-rcar.c
index 00022ee56f80..9d3dde00c2fe 100644
--- a/arch/arm/mach-shmobile/pm-rcar.c
+++ b/arch/arm/mach-shmobile/pm-rcar.c
@@ -12,7 +12,7 @@
 #include <linux/err.h>
 #include <linux/mm.h>
 #include <linux/spinlock.h>
-#include <asm/io.h>
+#include <linux/io.h>
 #include "pm-rcar.h"
 
 /* SYSC */
diff --git a/arch/ia64/kernel/cyclone.c b/arch/ia64/kernel/cyclone.c
index 4826ff957a3d..5fa3848ba224 100644
--- a/arch/ia64/kernel/cyclone.c
+++ b/arch/ia64/kernel/cyclone.c
@@ -4,7 +4,7 @@
 #include <linux/errno.h>
 #include <linux/timex.h>
 #include <linux/clocksource.h>
-#include <asm/io.h>
+#include <linux/io.h>
 
 /* IBM Summit (EXA) Cyclone counter code*/
 #define CYCLONE_CBAR_ADDR 0xFEB00CD0
diff --git a/drivers/isdn/icn/icn.h b/drivers/isdn/icn/icn.h
index b713466997a0..f8f2e76d34bf 100644
--- a/drivers/isdn/icn/icn.h
+++ b/drivers/isdn/icn/icn.h
@@ -38,7 +38,7 @@ typedef struct icn_cdef {
 #include <linux/errno.h>
 #include <linux/fs.h>
 #include <linux/major.h>
-#include <asm/io.h>
+#include <linux/io.h>
 #include <linux/kernel.h>
 #include <linux/signal.h>
 #include <linux/slab.h>
diff --git a/drivers/mtd/devices/slram.c b/drivers/mtd/devices/slram.c
index 2fc4957cbe7f..a70eb83e68f1 100644
--- a/drivers/mtd/devices/slram.c
+++ b/drivers/mtd/devices/slram.c
@@ -41,7 +41,7 @@
 #include <linux/fs.h>
 #include <linux/ioctl.h>
 #include <linux/init.h>
-#include <asm/io.h>
+#include <linux/io.h>
 
 #include <linux/mtd/mtd.h>
 
diff --git a/drivers/mtd/nand/diskonchip.c b/drivers/mtd/nand/diskonchip.c
index f68a7bccecdc..c8f7c69c5204 100644
--- a/drivers/mtd/nand/diskonchip.c
+++ b/drivers/mtd/nand/diskonchip.c
@@ -24,7 +24,7 @@
 #include <linux/rslib.h>
 #include <linux/moduleparam.h>
 #include <linux/slab.h>
-#include <asm/io.h>
+#include <linux/io.h>
 
 #include <linux/mtd/mtd.h>
 #include <linux/mtd/nand.h>
diff --git a/drivers/mtd/onenand/generic.c b/drivers/mtd/onenand/generic.c
index 32a216d31141..ab7bda0bb245 100644
--- a/drivers/mtd/onenand/generic.c
+++ b/drivers/mtd/onenand/generic.c
@@ -18,7 +18,7 @@
 #include <linux/mtd/mtd.h>
 #include <linux/mtd/onenand.h>
 #include <linux/mtd/partitions.h>
-#include <asm/io.h>
+#include <linux/io.h>
 
 /*
  * Note: Driver name and platform data format have been updated!
diff --git a/drivers/scsi/sun3x_esp.c b/drivers/scsi/sun3x_esp.c
index e26e81de7c45..d50c5ed8f428 100644
--- a/drivers/scsi/sun3x_esp.c
+++ b/drivers/scsi/sun3x_esp.c
@@ -12,9 +12,9 @@
 #include <linux/platform_device.h>
 #include <linux/dma-mapping.h>
 #include <linux/interrupt.h>
+#include <linux/io.h>
 
 #include <asm/sun3x.h>
-#include <asm/io.h>
 #include <asm/dma.h>
 #include <asm/dvma.h>
 
diff --git a/drivers/staging/comedi/drivers/ii_pci20kc.c b/drivers/staging/comedi/drivers/ii_pci20kc.c
index 0768bc42a5db..14ef1f67dd42 100644
--- a/drivers/staging/comedi/drivers/ii_pci20kc.c
+++ b/drivers/staging/comedi/drivers/ii_pci20kc.c
@@ -28,6 +28,7 @@
  */
 
 #include <linux/module.h>
+#include <linux/io.h>
 #include "../comedidev.h"
 
 /*
diff --git a/drivers/tty/serial/8250/8250_core.c b/drivers/tty/serial/8250/8250_core.c
index 4506e405c8f3..7b6c3d56b8c7 100644
--- a/drivers/tty/serial/8250/8250_core.c
+++ b/drivers/tty/serial/8250/8250_core.c
@@ -38,11 +38,11 @@
 #include <linux/slab.h>
 #include <linux/uaccess.h>
 #include <linux/pm_runtime.h>
+#include <linux/io.h>
 #ifdef CONFIG_SPARC
 #include <linux/sunserialcore.h>
 #endif
 
-#include <asm/io.h>
 #include <asm/irq.h>
 
 #include "8250.h"
diff --git a/drivers/video/fbdev/s1d13xxxfb.c b/drivers/video/fbdev/s1d13xxxfb.c
index 83433cb0dfba..96aa46dc696c 100644
--- a/drivers/video/fbdev/s1d13xxxfb.c
+++ b/drivers/video/fbdev/s1d13xxxfb.c
@@ -32,8 +32,7 @@
 #include <linux/spinlock_types.h>
 #include <linux/spinlock.h>
 #include <linux/slab.h>
-
-#include <asm/io.h>
+#include <linux/io.h>
 
 #include <video/s1d13xxxfb.h>
 
diff --git a/drivers/video/fbdev/stifb.c b/drivers/video/fbdev/stifb.c
index 86621fabbb8b..158f19bcae44 100644
--- a/drivers/video/fbdev/stifb.c
+++ b/drivers/video/fbdev/stifb.c
@@ -64,6 +64,7 @@
 #include <linux/fb.h>
 #include <linux/init.h>
 #include <linux/ioport.h>
+#include <linux/io.h>
 
 #include <asm/grfioctl.h>	/* for HP-UX compatibility */
 #include <asm/uaccess.h>
diff --git a/include/linux/io-mapping.h b/include/linux/io-mapping.h
index c27dde7215b5..e399029b68c5 100644
--- a/include/linux/io-mapping.h
+++ b/include/linux/io-mapping.h
@@ -21,7 +21,7 @@
 #include <linux/types.h>
 #include <linux/slab.h>
 #include <linux/bug.h>
-#include <asm/io.h>
+#include <linux/io.h>
 #include <asm/page.h>
 
 /*
diff --git a/include/linux/mtd/map.h b/include/linux/mtd/map.h
index 29975c73a953..366cf77953b5 100644
--- a/include/linux/mtd/map.h
+++ b/include/linux/mtd/map.h
@@ -27,9 +27,9 @@
 #include <linux/string.h>
 #include <linux/bug.h>
 #include <linux/kernel.h>
+#include <linux/io.h>
 
 #include <asm/unaligned.h>
-#include <asm/io.h>
 #include <asm/barrier.h>
 
 #ifdef CONFIG_MTD_MAP_BANK_WIDTH_1
diff --git a/include/video/vga.h b/include/video/vga.h
index cac567f22e62..d334e64c1c19 100644
--- a/include/video/vga.h
+++ b/include/video/vga.h
@@ -18,7 +18,7 @@
 #define __linux_video_vga_h__
 
 #include <linux/types.h>
-#include <asm/io.h>
+#include <linux/io.h>
 #include <asm/vga.h>
 #include <asm/byteorder.h>
 

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
Please read the FAQ at  http://www.tux.org/lkml/

^ permalink raw reply related	[flat|nested] 85+ messages in thread

* [PATCH v5 2/6] arch: unify ioremap prototypes and macro aliases
  2015-06-22  8:24 ` Dan Williams
@ 2015-06-22  8:24   ` Dan Williams
  -1 siblings, 0 replies; 85+ messages in thread
From: Dan Williams @ 2015-06-22  8:24 UTC (permalink / raw)
  To: arnd, mingo, bp, hpa, tglx, ross.zwisler, akpm
  Cc: jgross, x86, toshi.kani, linux-nvdimm, benh, mcgrof, konrad.wilk,
	linux-kernel, stefan.bader, luto, linux-mm, geert, ralf, hmh,
	mpe, tj, paulus, hch

Some archs define the first parameter to ioremap() as unsigned long,
while the balance define it as resource_size_t.  Unify on
resource_size_t to enable passing ioremap function pointers.  Also, some
archs use function-like macros for defining ioremap aliases, but
asm-generic/io.h expects object-like macros, unify on the latter.

Move all handling of ioremap aliasing (i.e. ioremap_wt => ioremap) to
include/linux/io.h.  Add a check to include/linux/io.h to warn at
compile time if an arch violates expectations.

Kill ARCH_HAS_IOREMAP_WC and ARCH_HAS_IOREMAP_WT in favor of just
testing for ioremap_wc, and ioremap_wt being defined.  This arrangement
allows drivers to know when ioremap_<foo> are being re-directed to plain
ioremap.

Reported-by: kbuild test robot <fengguang.wu@intel.com>
Signed-off-by: Dan Williams <dan.j.williams@intel.com>
---
 arch/alpha/include/asm/io.h      |    7 +++--
 arch/arc/include/asm/io.h        |    6 ----
 arch/arm/include/asm/io.h        |   31 ++++++++++++++++----
 arch/arm64/include/asm/io.h      |   23 ++++++++++++---
 arch/avr32/include/asm/io.h      |   22 +++++++-------
 arch/avr32/mm/ioremap.c          |    2 +
 arch/cris/include/asm/io.h       |    8 +++--
 arch/cris/mm/ioremap.c           |    2 +
 arch/frv/include/asm/io.h        |   23 +++++++--------
 arch/hexagon/include/asm/io.h    |    5 +++
 arch/ia64/include/asm/io.h       |   10 +------
 arch/ia64/mm/ioremap.c           |    4 +--
 arch/m32r/include/asm/io.h       |    9 +++---
 arch/m68k/include/asm/io_mm.h    |   21 +++++++++-----
 arch/m68k/include/asm/io_no.h    |   34 ++++++++++++++--------
 arch/m68k/include/asm/raw_io.h   |    3 +-
 arch/m68k/mm/kmap.c              |    2 +
 arch/metag/include/asm/io.h      |   35 ++++++++++++++---------
 arch/microblaze/include/asm/io.h |    6 ----
 arch/microblaze/mm/pgtable.c     |    2 +
 arch/mips/include/asm/io.h       |   42 ++++++++++------------------
 arch/mn10300/include/asm/io.h    |   10 ++++---
 arch/nios2/include/asm/io.h      |   15 +++-------
 arch/openrisc/include/asm/io.h   |    3 +-
 arch/openrisc/mm/ioremap.c       |    2 +
 arch/parisc/include/asm/io.h     |    6 +---
 arch/parisc/mm/ioremap.c         |    2 +
 arch/powerpc/include/asm/io.h    |    7 ++---
 arch/s390/include/asm/io.h       |    8 ++---
 arch/sh/include/asm/io.h         |    9 +++++-
 arch/sparc/include/asm/io_32.h   |    7 +----
 arch/sparc/include/asm/io_64.h   |    8 ++---
 arch/sparc/kernel/ioport.c       |    2 +
 arch/tile/include/asm/io.h       |   17 +++++++----
 arch/unicore32/include/asm/io.h  |   25 +++++++++++++---
 arch/x86/include/asm/io.h        |    9 ++++--
 arch/xtensa/include/asm/io.h     |   13 +++++----
 drivers/net/ethernet/sfc/io.h    |    2 +
 include/asm-generic/iomap.h      |    8 -----
 include/linux/io.h               |   58 ++++++++++++++++++++++++++++++++++++++
 40 files changed, 300 insertions(+), 208 deletions(-)

diff --git a/arch/alpha/include/asm/io.h b/arch/alpha/include/asm/io.h
index f05bdb4b1cb9..6b63689c27a6 100644
--- a/arch/alpha/include/asm/io.h
+++ b/arch/alpha/include/asm/io.h
@@ -282,10 +282,11 @@ extern inline void ioport_unmap(void __iomem *addr)
 {
 }
 
-static inline void __iomem *ioremap(unsigned long port, unsigned long size)
+static inline void __iomem *ioremap(resource_size_t port, unsigned long size)
 {
 	return IO_CONCAT(__IO_PREFIX,ioremap) (port, size);
 }
+#define ioremap ioremap
 
 static inline void __iomem *__ioremap(unsigned long port, unsigned long size,
 				      unsigned long flags)
@@ -293,16 +294,18 @@ static inline void __iomem *__ioremap(unsigned long port, unsigned long size,
 	return ioremap(port, size);
 }
 
-static inline void __iomem * ioremap_nocache(unsigned long offset,
+static inline void __iomem * ioremap_nocache(resource_size_t offset,
 					     unsigned long size)
 {
 	return ioremap(offset, size);
 } 
+#define ioremap_nocache ioremap_nocache
 
 static inline void iounmap(volatile void __iomem *addr)
 {
 	IO_CONCAT(__IO_PREFIX,iounmap)(addr);
 }
+#define iounmap iounmap
 
 static inline int __is_ioaddr(unsigned long addr)
 {
diff --git a/arch/arc/include/asm/io.h b/arch/arc/include/asm/io.h
index 7cc4ced5dbf4..e6f782863026 100644
--- a/arch/arc/include/asm/io.h
+++ b/arch/arc/include/asm/io.h
@@ -13,14 +13,8 @@
 #include <asm/byteorder.h>
 #include <asm/page.h>
 
-extern void __iomem *ioremap(unsigned long physaddr, unsigned long size);
 extern void __iomem *ioremap_prot(phys_addr_t offset, unsigned long size,
 				  unsigned long flags);
-extern void iounmap(const void __iomem *addr);
-
-#define ioremap_nocache(phy, sz)	ioremap(phy, sz)
-#define ioremap_wc(phy, sz)		ioremap(phy, sz)
-#define ioremap_wt(phy, sz)		ioremap(phy, sz)
 
 /* Change struct page to physical address */
 #define page_to_phys(page)		(page_to_pfn(page) << PAGE_SHIFT)
diff --git a/arch/arm/include/asm/io.h b/arch/arm/include/asm/io.h
index 1b7677d1e5e1..ecd410c716d8 100644
--- a/arch/arm/include/asm/io.h
+++ b/arch/arm/include/asm/io.h
@@ -332,12 +332,31 @@ extern void _memset_io(volatile void __iomem *, int, size_t);
  * Documentation/io-mapping.txt.
  *
  */
-#define ioremap(cookie,size)		__arm_ioremap((cookie), (size), MT_DEVICE)
-#define ioremap_nocache(cookie,size)	__arm_ioremap((cookie), (size), MT_DEVICE)
-#define ioremap_cache(cookie,size)	__arm_ioremap((cookie), (size), MT_DEVICE_CACHED)
-#define ioremap_wc(cookie,size)		__arm_ioremap((cookie), (size), MT_DEVICE_WC)
-#define ioremap_wt(cookie,size)		__arm_ioremap((cookie), (size), MT_DEVICE)
-#define iounmap				__arm_iounmap
+static inline void __iomem *ioremap(resource_size_t cookie, unsigned long size)
+{
+	return __arm_ioremap(cookie, size, MT_DEVICE);
+}
+#define ioremap ioremap
+
+static inline void __iomem *ioremap_cache(resource_size_t cookie,
+		unsigned long size)
+{
+	return __arm_ioremap(cookie, size, MT_DEVICE_CACHED);
+}
+#define ioremap_cache ioremap_cache
+
+static inline void __iomem *ioremap_wc(resource_size_t cookie,
+		unsigned long size)
+{
+	return __arm_ioremap(cookie, size, MT_DEVICE_WC);
+}
+#define ioremap_wc ioremap_wc
+
+static inline void iounmap(volatile void __iomem *addr)
+{
+	__arm_iounmap(addr);
+}
+#define iounmap iounmap
 
 /*
  * io{read,write}{16,32}be() macros
diff --git a/arch/arm64/include/asm/io.h b/arch/arm64/include/asm/io.h
index 7116d3973058..56782487bf3c 100644
--- a/arch/arm64/include/asm/io.h
+++ b/arch/arm64/include/asm/io.h
@@ -166,12 +166,25 @@ extern void __memset_io(volatile void __iomem *, int, size_t);
 extern void __iomem *__ioremap(phys_addr_t phys_addr, size_t size, pgprot_t prot);
 extern void __iounmap(volatile void __iomem *addr);
 extern void __iomem *ioremap_cache(phys_addr_t phys_addr, size_t size);
+#define ioremap_cache ioremap_cache
 
-#define ioremap(addr, size)		__ioremap((addr), (size), __pgprot(PROT_DEVICE_nGnRE))
-#define ioremap_nocache(addr, size)	__ioremap((addr), (size), __pgprot(PROT_DEVICE_nGnRE))
-#define ioremap_wc(addr, size)		__ioremap((addr), (size), __pgprot(PROT_NORMAL_NC))
-#define ioremap_wt(addr, size)		__ioremap((addr), (size), __pgprot(PROT_DEVICE_nGnRE))
-#define iounmap				__iounmap
+static inline void __iomem *ioremap(resource_size_t addr, unsigned long size)
+{
+	return __ioremap(addr, size, __pgprot(PROT_DEVICE_nGnRE));
+}
+#define ioremap ioremap
+
+static inline void __iomem *ioremap_wc(resource_size_t addr, unsigned long size)
+{
+	return __ioremap(addr, size, __pgprot(PROT_NORMAL_NC));
+}
+#define ioremap_wc ioremap_wc
+
+static inline void iounmap(volatile void __iomem *addr)
+{
+	return __iounmap(addr);
+}
+#define iounmap iounmap
 
 /*
  * io{read,write}{16,32}be() macros
diff --git a/arch/avr32/include/asm/io.h b/arch/avr32/include/asm/io.h
index e998ff5d8e1a..80af4cb6c5b6 100644
--- a/arch/avr32/include/asm/io.h
+++ b/arch/avr32/include/asm/io.h
@@ -274,7 +274,7 @@ static inline void memset_io(volatile void __iomem *addr, unsigned char val,
 
 extern void __iomem *__ioremap(unsigned long offset, size_t size,
 			       unsigned long flags);
-extern void __iounmap(void __iomem *addr);
+extern void __iounmap(volatile void __iomem *addr);
 
 /*
  * ioremap	-   map bus memory into CPU space
@@ -286,17 +286,17 @@ extern void __iounmap(void __iomem *addr);
  * the other mmio helpers. The returned address is not guaranteed to
  * be usable directly as a virtual address.
  */
-#define ioremap(offset, size)			\
-	__ioremap((offset), (size), 0)
-
-#define ioremap_nocache(offset, size)		\
-	__ioremap((offset), (size), 0)
-
-#define iounmap(addr)				\
-	__iounmap(addr)
+static inline void __iomem *ioremap(resource_size_t offset, unsigned long size)
+{
+	return __ioremap(offset, size, 0);
+}
+#define ioremap ioremap
 
-#define ioremap_wc ioremap_nocache
-#define ioremap_wt ioremap_nocache
+static inline void iounmap(volatile void __iomem *addr)
+{
+	return __iounmap(addr);
+}
+#define iounmap iounmap
 
 #define cached(addr) P1SEGADDR(addr)
 #define uncached(addr) P2SEGADDR(addr)
diff --git a/arch/avr32/mm/ioremap.c b/arch/avr32/mm/ioremap.c
index 7def0d84cec6..f3eacbe5dff6 100644
--- a/arch/avr32/mm/ioremap.c
+++ b/arch/avr32/mm/ioremap.c
@@ -73,7 +73,7 @@ void __iomem *__ioremap(unsigned long phys_addr, size_t size,
 }
 EXPORT_SYMBOL(__ioremap);
 
-void __iounmap(void __iomem *addr)
+void __iounmap(volatile void __iomem *addr)
 {
 	struct vm_struct *p;
 
diff --git a/arch/cris/include/asm/io.h b/arch/cris/include/asm/io.h
index 752a3f45df60..cd55a5709433 100644
--- a/arch/cris/include/asm/io.h
+++ b/arch/cris/include/asm/io.h
@@ -37,14 +37,14 @@ static inline void * phys_to_virt(unsigned long address)
 extern void __iomem * __ioremap(unsigned long offset, unsigned long size, unsigned long flags);
 extern void __iomem * __ioremap_prot(unsigned long phys_addr, unsigned long size, pgprot_t prot);
 
-static inline void __iomem * ioremap (unsigned long offset, unsigned long size)
+static inline void __iomem * ioremap(resource_size_t offset, unsigned long size)
 {
 	return __ioremap(offset, size, 0);
 }
+#define ioremap ioremap
 
-extern void iounmap(volatile void * __iomem addr);
-
-extern void __iomem * ioremap_nocache(unsigned long offset, unsigned long size);
+extern void __iomem * ioremap_nocache(resource_size_t offset, unsigned long size);
+#define ioremap_nocache ioremap_nocache
 
 /*
  * IO bus memory addresses are also 1:1 with the physical address
diff --git a/arch/cris/mm/ioremap.c b/arch/cris/mm/ioremap.c
index 80fdb995a8ce..13cef92df503 100644
--- a/arch/cris/mm/ioremap.c
+++ b/arch/cris/mm/ioremap.c
@@ -76,7 +76,7 @@ void __iomem * __ioremap(unsigned long phys_addr, unsigned long size, unsigned l
  * Must be freed with iounmap.
  */
 
-void __iomem *ioremap_nocache(unsigned long phys_addr, unsigned long size)
+void __iomem *ioremap_nocache(resource_size_t phys_addr, unsigned long size)
 {
         return __ioremap(phys_addr | MEM_NON_CACHEABLE, size, 0);
 }
diff --git a/arch/frv/include/asm/io.h b/arch/frv/include/asm/io.h
index a31b63ec4930..bde570d29c89 100644
--- a/arch/frv/include/asm/io.h
+++ b/arch/frv/include/asm/io.h
@@ -17,8 +17,6 @@
 
 #ifdef __KERNEL__
 
-#define ARCH_HAS_IOREMAP_WT
-
 #include <linux/types.h>
 #include <asm/virtconvert.h>
 #include <asm/string.h>
@@ -257,29 +255,28 @@ static inline void writel(uint32_t datum, volatile void __iomem *addr)
 
 extern void __iomem *__ioremap(unsigned long physaddr, unsigned long size, int cacheflag);
 
-static inline void __iomem *ioremap(unsigned long physaddr, unsigned long size)
-{
-	return __ioremap(physaddr, size, IOMAP_NOCACHE_SER);
-}
-
-static inline void __iomem *ioremap_nocache(unsigned long physaddr, unsigned long size)
+static inline void __iomem *ioremap(resource_size_t physaddr, unsigned long size)
 {
 	return __ioremap(physaddr, size, IOMAP_NOCACHE_SER);
 }
+#define ioremap ioremap
 
-static inline void __iomem *ioremap_wt(unsigned long physaddr, unsigned long size)
+static inline void __iomem *ioremap_wt(resource_size_t physaddr, unsigned long size)
 {
 	return __ioremap(physaddr, size, IOMAP_WRITETHROUGH);
 }
+#define ioremap_wt ioremap_wt
 
-static inline void __iomem *ioremap_fullcache(unsigned long physaddr, unsigned long size)
+static inline void __iomem *ioremap_fullcache(resource_size_t physaddr, unsigned long size)
 {
 	return __ioremap(physaddr, size, IOMAP_FULL_CACHING);
 }
 
-#define ioremap_wc ioremap_nocache
-
-extern void iounmap(void volatile __iomem *addr);
+static inline void __iomem *ioremap_cache(resource_size_t physaddr, unsigned long size)
+{
+	return ioremap_fullcache(physaddr, size);
+}
+#define ioremap_cache ioremap_cache
 
 static inline void __iomem *ioport_map(unsigned long port, unsigned int nr)
 {
diff --git a/arch/hexagon/include/asm/io.h b/arch/hexagon/include/asm/io.h
index 66f5e9a61efc..e5ecc08b7627 100644
--- a/arch/hexagon/include/asm/io.h
+++ b/arch/hexagon/include/asm/io.h
@@ -191,16 +191,19 @@ static inline void writel(u32 data, volatile void __iomem *addr)
  * This is probably too long for an inline.
  */
 void __iomem *ioremap_nocache(unsigned long phys_addr, unsigned long size);
+#define ioremap_nocache ioremap_nocache
 
-static inline void __iomem *ioremap(unsigned long phys_addr, unsigned long size)
+static inline void __iomem *ioremap(resouce_size_t phys_addr, unsigned long size)
 {
 	return ioremap_nocache(phys_addr, size);
 }
+#define ioremap ioremap
 
 static inline void iounmap(volatile void __iomem *addr)
 {
 	__iounmap(addr);
 }
+#define iounmap iounmap
 
 #define __raw_writel writel
 
diff --git a/arch/ia64/include/asm/io.h b/arch/ia64/include/asm/io.h
index 80a7e34be009..ea4c7a243973 100644
--- a/arch/ia64/include/asm/io.h
+++ b/arch/ia64/include/asm/io.h
@@ -424,18 +424,12 @@ __writeq (unsigned long val, volatile void __iomem *addr)
 
 # ifdef __KERNEL__
 
-extern void __iomem * ioremap(unsigned long offset, unsigned long size);
-extern void __iomem * ioremap_nocache (unsigned long offset, unsigned long size);
-extern void iounmap (volatile void __iomem *addr);
+extern void __iomem * ioremap_nocache (resource_size_t offset, unsigned long size);
+#define ioremap_nocache ioremap_nocache
 extern void __iomem * early_ioremap (unsigned long phys_addr, unsigned long size);
 #define early_memremap(phys_addr, size)        early_ioremap(phys_addr, size)
 extern void early_iounmap (volatile void __iomem *addr, unsigned long size);
 #define early_memunmap(addr, size)             early_iounmap(addr, size)
-static inline void __iomem * ioremap_cache (unsigned long phys_addr, unsigned long size)
-{
-	return ioremap(phys_addr, size);
-}
-
 
 /*
  * String version of IO memory access ops:
diff --git a/arch/ia64/mm/ioremap.c b/arch/ia64/mm/ioremap.c
index 43964cde6214..205d71445f06 100644
--- a/arch/ia64/mm/ioremap.c
+++ b/arch/ia64/mm/ioremap.c
@@ -32,7 +32,7 @@ early_ioremap (unsigned long phys_addr, unsigned long size)
 }
 
 void __iomem *
-ioremap (unsigned long phys_addr, unsigned long size)
+ioremap (resource_size_t phys_addr, unsigned long size)
 {
 	void __iomem *addr;
 	struct vm_struct *area;
@@ -102,7 +102,7 @@ ioremap (unsigned long phys_addr, unsigned long size)
 EXPORT_SYMBOL(ioremap);
 
 void __iomem *
-ioremap_nocache (unsigned long phys_addr, unsigned long size)
+ioremap_nocache (resource_size_t phys_addr, unsigned long size)
 {
 	if (kern_mem_attribute(phys_addr, size) & EFI_MEMORY_WB)
 		return NULL;
diff --git a/arch/m32r/include/asm/io.h b/arch/m32r/include/asm/io.h
index 0c3f25ee3381..d7f96a542816 100644
--- a/arch/m32r/include/asm/io.h
+++ b/arch/m32r/include/asm/io.h
@@ -60,15 +60,14 @@ __ioremap(unsigned long offset, unsigned long size, unsigned long flags);
  *	address.
  */
 
-static inline void __iomem *ioremap(unsigned long offset, unsigned long size)
+static inline void __iomem *ioremap(resource_size_t offset, unsigned long size)
 {
 	return __ioremap(offset, size, 0);
 }
+#define ioremap ioremap
 
-extern void iounmap(volatile void __iomem *addr);
-#define ioremap_nocache(off,size) ioremap(off,size)
-#define ioremap_wc ioremap_nocache
-#define ioremap_wt ioremap_nocache
+void iounmap(volatile void __iomem *addr);
+#define iounmap iounmap
 
 /*
  * IO bus memory addresses are also 1:1 with the physical address
diff --git a/arch/m68k/include/asm/io_mm.h b/arch/m68k/include/asm/io_mm.h
index 618c85d3c786..7658252c64ab 100644
--- a/arch/m68k/include/asm/io_mm.h
+++ b/arch/m68k/include/asm/io_mm.h
@@ -20,8 +20,6 @@
 
 #ifdef __KERNEL__
 
-#define ARCH_HAS_IOREMAP_WT
-
 #include <linux/compiler.h>
 #include <asm/raw_io.h>
 #include <asm/virtconvert.h>
@@ -459,25 +457,32 @@ static inline void isa_delay(void)
 
 #define mmiowb()
 
-static inline void __iomem *ioremap(unsigned long physaddr, unsigned long size)
+static inline void __iomem *ioremap(resource_size_t physaddr, unsigned long size)
 {
 	return __ioremap(physaddr, size, IOMAP_NOCACHE_SER);
 }
-static inline void __iomem *ioremap_nocache(unsigned long physaddr, unsigned long size)
-{
-	return __ioremap(physaddr, size, IOMAP_NOCACHE_SER);
-}
-static inline void __iomem *ioremap_wt(unsigned long physaddr,
+#define ioremap ioremap
+
+static inline void __iomem *ioremap_wt(resource_size_t physaddr,
 					 unsigned long size)
 {
 	return __ioremap(physaddr, size, IOMAP_WRITETHROUGH);
 }
+#define ioremap_wt ioremap_wt
+
 static inline void __iomem *ioremap_fullcache(unsigned long physaddr,
 				      unsigned long size)
 {
 	return __ioremap(physaddr, size, IOMAP_FULL_CACHING);
 }
 
+static inline void __iomem *ioremap_cache(resource_size_t physaddr,
+		unsigned long size)
+{
+	return ioremap_fullcache(physaddr, size);
+}
+#define ioremap_cache ioremap_cache
+
 static inline void memset_io(volatile void __iomem *addr, unsigned char val, int count)
 {
 	__builtin_memset((void __force *) addr, val, count);
diff --git a/arch/m68k/include/asm/io_no.h b/arch/m68k/include/asm/io_no.h
index ad7bd40e6742..ea9b280ebc33 100644
--- a/arch/m68k/include/asm/io_no.h
+++ b/arch/m68k/include/asm/io_no.h
@@ -3,8 +3,6 @@
 
 #ifdef __KERNEL__
 
-#define ARCH_HAS_IOREMAP_WT
-
 #include <asm/virtconvert.h>
 #include <asm-generic/iomap.h>
 
@@ -143,28 +141,40 @@ static inline void io_insl(unsigned int addr, void *buf, int len)
 #define IOMAP_NOCACHE_NONSER		2
 #define IOMAP_WRITETHROUGH		3
 
-static inline void *__ioremap(unsigned long physaddr, unsigned long size, int cacheflag)
-{
-	return (void *) physaddr;
-}
-static inline void *ioremap(unsigned long physaddr, unsigned long size)
+static inline void __iomem *__ioremap(unsigned long physaddr,
+		unsigned long size, int cacheflag)
 {
-	return __ioremap(physaddr, size, IOMAP_NOCACHE_SER);
+	return (void __iomem *) physaddr;
 }
-static inline void *ioremap_nocache(unsigned long physaddr, unsigned long size)
+static inline void __iomem *ioremap(resource_size_t physaddr, unsigned long size)
 {
 	return __ioremap(physaddr, size, IOMAP_NOCACHE_SER);
 }
-static inline void *ioremap_wt(unsigned long physaddr, unsigned long size)
+#define ioremap ioremap
+
+static inline void __iomem *ioremap_wt(resource_size_t physaddr, unsigned long size)
 {
 	return __ioremap(physaddr, size, IOMAP_WRITETHROUGH);
 }
-static inline void *ioremap_fullcache(unsigned long physaddr, unsigned long size)
+#define ioremap_wt ioremap_wt
+
+static inline void __iomem *ioremap_fullcache(unsigned long physaddr,
+		unsigned long size)
 {
 	return __ioremap(physaddr, size, IOMAP_FULL_CACHING);
 }
 
-#define	iounmap(addr)	do { } while(0)
+static inline void __iomem *ioremap_cache(resource_size_t physaddr,
+		unsigned long size)
+{
+	return ioremap_fullcache(physaddr, size);
+}
+#define ioremap_cache ioremap_cache
+
+static inline void iounmap(volatile void __iomem *addr)
+{
+}
+#define iounmap iounmap
 
 /*
  * Convert a physical pointer to a virtual kernel pointer for /dev/mem
diff --git a/arch/m68k/include/asm/raw_io.h b/arch/m68k/include/asm/raw_io.h
index 932faa35655b..abb7708f02ed 100644
--- a/arch/m68k/include/asm/raw_io.h
+++ b/arch/m68k/include/asm/raw_io.h
@@ -19,7 +19,8 @@
 #define IOMAP_NOCACHE_NONSER		2
 #define IOMAP_WRITETHROUGH		3
 
-extern void iounmap(void __iomem *addr);
+extern void iounmap(volatile void __iomem *addr);
+#define iounmap iounmap
 
 extern void __iomem *__ioremap(unsigned long physaddr, unsigned long size,
 		       int cacheflag);
diff --git a/arch/m68k/mm/kmap.c b/arch/m68k/mm/kmap.c
index 6e4955bc542b..f0d76d9f0643 100644
--- a/arch/m68k/mm/kmap.c
+++ b/arch/m68k/mm/kmap.c
@@ -226,7 +226,7 @@ EXPORT_SYMBOL(__ioremap);
 /*
  * Unmap an ioremap()ed region again
  */
-void iounmap(void __iomem *addr)
+void iounmap(volatile void __iomem *addr)
 {
 #ifdef CONFIG_AMIGA
 	if ((!MACH_IS_AMIGA) ||
diff --git a/arch/metag/include/asm/io.h b/arch/metag/include/asm/io.h
index 9890f21eadbe..50e95ecb4bc2 100644
--- a/arch/metag/include/asm/io.h
+++ b/arch/metag/include/asm/io.h
@@ -148,22 +148,29 @@ extern void __iounmap(void __iomem *addr);
  *	address is not guaranteed to be usable directly as a virtual
  *	address.
  */
-#define ioremap(offset, size)                   \
-	__ioremap((offset), (size), 0)
-
-#define ioremap_nocache(offset, size)           \
-	__ioremap((offset), (size), 0)
-
-#define ioremap_cached(offset, size)            \
-	__ioremap((offset), (size), _PAGE_CACHEABLE)
+static inline void __iomem *ioremap(resource_size_t offset, unsigned long size)
+{
+	return __ioremap(offset, size, 0);
+}
+#define ioremap ioremap
 
-#define ioremap_wc(offset, size)                \
-	__ioremap((offset), (size), _PAGE_WR_COMBINE)
+static inline void __iomem *ioremap_cache(resource_size_t offset, unsigned long size)
+{
+	return __ioremap(offset, size, _PAGE_CACHEABLE);
+}
+#define ioremap_cache ioremap_cache
+#define ioremap_cached ioremap_cache
 
-#define ioremap_wt(offset, size)                \
-	__ioremap((offset), (size), 0)
+static inline void __iomem *ioremap_wc(resource_size_t offset, unsigned long size)
+{
+	return __ioremap(offset, size, _PAGE_WR_COMBINE);
+}
+#define ioremap_wc ioremap_wc
 
-#define iounmap(addr)                           \
-	__iounmap(addr)
+static inline void iounmap(volatile void __iomem *addr)
+{
+	return __iounmap(addr);
+}
+#define iounmap iounmap
 
 #endif  /* _ASM_METAG_IO_H */
diff --git a/arch/microblaze/include/asm/io.h b/arch/microblaze/include/asm/io.h
index 39b6315db82e..60ca27d7dd1f 100644
--- a/arch/microblaze/include/asm/io.h
+++ b/arch/microblaze/include/asm/io.h
@@ -36,13 +36,7 @@ extern resource_size_t isa_mem_base;
 #ifdef CONFIG_MMU
 #define page_to_bus(page)	(page_to_phys(page))
 
-extern void iounmap(void __iomem *addr);
-
-extern void __iomem *ioremap(phys_addr_t address, unsigned long size);
-#define ioremap_nocache(addr, size)		ioremap((addr), (size))
 #define ioremap_fullcache(addr, size)		ioremap((addr), (size))
-#define ioremap_wc(addr, size)			ioremap((addr), (size))
-#define ioremap_wt(addr, size)			ioremap((addr), (size))
 
 #endif /* CONFIG_MMU */
 
diff --git a/arch/microblaze/mm/pgtable.c b/arch/microblaze/mm/pgtable.c
index 4f4520e779a5..2b47b34ff26c 100644
--- a/arch/microblaze/mm/pgtable.c
+++ b/arch/microblaze/mm/pgtable.c
@@ -126,7 +126,7 @@ void __iomem *ioremap(phys_addr_t addr, unsigned long size)
 }
 EXPORT_SYMBOL(ioremap);
 
-void iounmap(void __iomem *addr)
+void iounmap(volatile void __iomem *addr)
 {
 	if ((__force void *)addr > high_memory &&
 					(unsigned long) addr < ioremap_bot)
diff --git a/arch/mips/include/asm/io.h b/arch/mips/include/asm/io.h
index 9e777cd42b67..a907e634f914 100644
--- a/arch/mips/include/asm/io.h
+++ b/arch/mips/include/asm/io.h
@@ -232,30 +232,11 @@ static inline void __iomem * __ioremap_mode(phys_addr_t offset, unsigned long si
  * address is not guaranteed to be usable directly as a virtual
  * address.
  */
-#define ioremap(offset, size)						\
-	__ioremap_mode((offset), (size), _CACHE_UNCACHED)
-
-/*
- * ioremap_nocache     -   map bus memory into CPU space
- * @offset:    bus address of the memory
- * @size:      size of the resource to map
- *
- * ioremap_nocache performs a platform specific sequence of operations to
- * make bus memory CPU accessible via the readb/readw/readl/writeb/
- * writew/writel functions and the other mmio helpers. The returned
- * address is not guaranteed to be usable directly as a virtual
- * address.
- *
- * This version of ioremap ensures that the memory is marked uncachable
- * on the CPU as well as honouring existing caching rules from things like
- * the PCI bus. Note that there are other caches and buffers on many
- * busses. In particular driver authors should read up on PCI writes
- *
- * It's useful if some control registers are in such an area and
- * write combining or read caching is not desirable:
- */
-#define ioremap_nocache(offset, size)					\
-	__ioremap_mode((offset), (size), _CACHE_UNCACHED)
+static inline void __iomem *ioremap(resource_size_t offset, unsigned long size)
+{
+	return __ioremap_mode(offset, size, _CACHE_UNCACHED);
+}
+#define ioremap ioremap
 
 /*
  * ioremap_cachable -	map bus memory into CPU space
@@ -272,8 +253,14 @@ static inline void __iomem * __ioremap_mode(phys_addr_t offset, unsigned long si
  * the CPU.  Also enables full write-combining.	 Useful for some
  * memory-like regions on I/O busses.
  */
-#define ioremap_cachable(offset, size)					\
-	__ioremap_mode((offset), (size), _page_cachable_default)
+#define ioremap_cachable ioremap_cache
+extern unsigned long _page_cachable_default;
+static inline void __iomem *ioremap_cache(resource_size_t offset,
+		unsigned long size)
+{
+	return __ioremap_mode(offset, size, _page_cachable_default);
+}
+#define ioremap_cache ioremap_cache
 
 /*
  * These two are MIPS specific ioremap variant.	 ioremap_cacheable_cow
@@ -286,7 +273,7 @@ static inline void __iomem * __ioremap_mode(phys_addr_t offset, unsigned long si
 #define ioremap_uncached_accelerated(offset, size)			\
 	__ioremap_mode((offset), (size), _CACHE_UNCACHED_ACCELERATED)
 
-static inline void iounmap(const volatile void __iomem *addr)
+static inline void iounmap(volatile void __iomem *addr)
 {
 	if (plat_iounmap(addr))
 		return;
@@ -301,6 +288,7 @@ static inline void iounmap(const volatile void __iomem *addr)
 
 #undef __IS_KSEG1
 }
+#define iounmap iounmap
 
 #ifdef CONFIG_CPU_CAVIUM_OCTEON
 #define war_octeon_io_reorder_wmb()		wmb()
diff --git a/arch/mn10300/include/asm/io.h b/arch/mn10300/include/asm/io.h
index 07c5b4a3903b..48629631f718 100644
--- a/arch/mn10300/include/asm/io.h
+++ b/arch/mn10300/include/asm/io.h
@@ -266,27 +266,29 @@ static inline void __iomem *__ioremap(unsigned long offset, unsigned long size,
 	return (void __iomem *) offset;
 }
 
-static inline void __iomem *ioremap(unsigned long offset, unsigned long size)
+static inline void __iomem *ioremap(resource_size_t offset, unsigned long size)
 {
 	return (void __iomem *)(offset & ~0x20000000);
 }
+#define ioremap ioremap
 
 /*
  * This one maps high address device memory and turns off caching for that
  * area.  it's useful if some control registers are in such an area and write
  * combining or read caching is not desirable:
  */
-static inline void __iomem *ioremap_nocache(unsigned long offset, unsigned long size)
+static inline void __iomem *ioremap_nocache(resource_size_t offset, unsigned long size)
 {
 	return (void __iomem *) (offset | 0x20000000);
 }
-
+#define ioremap_nocache ioremap_nocache
 #define ioremap_wc ioremap_nocache
 #define ioremap_wt ioremap_nocache
 
-static inline void iounmap(void __iomem *addr)
+static inline void iounmap(volatile void __iomem *addr)
 {
 }
+#define iounmap iounmap
 
 static inline void __iomem *ioport_map(unsigned long port, unsigned int nr)
 {
diff --git a/arch/nios2/include/asm/io.h b/arch/nios2/include/asm/io.h
index c5a62da22cd2..161a63265813 100644
--- a/arch/nios2/include/asm/io.h
+++ b/arch/nios2/include/asm/io.h
@@ -29,24 +29,17 @@ extern void __iomem *__ioremap(unsigned long physaddr, unsigned long size,
 			unsigned long cacheflag);
 extern void __iounmap(void __iomem *addr);
 
-static inline void __iomem *ioremap(unsigned long physaddr, unsigned long size)
+static inline void __iomem *ioremap(resource_size_t physaddr, unsigned long size)
 {
 	return __ioremap(physaddr, size, 0);
 }
+#define ioremap ioremap
 
-static inline void __iomem *ioremap_nocache(unsigned long physaddr,
-						unsigned long size)
-{
-	return __ioremap(physaddr, size, 0);
-}
-
-static inline void iounmap(void __iomem *addr)
+static inline void iounmap(volatile void __iomem *addr)
 {
 	__iounmap(addr);
 }
-
-#define ioremap_wc ioremap_nocache
-#define ioremap_wt ioremap_nocache
+#define iounmap iounmap
 
 /* Pages to physical address... */
 #define page_to_phys(page)	virt_to_phys(page_to_virt(page))
diff --git a/arch/openrisc/include/asm/io.h b/arch/openrisc/include/asm/io.h
index 7c691399da3f..4f7636e7901d 100644
--- a/arch/openrisc/include/asm/io.h
+++ b/arch/openrisc/include/asm/io.h
@@ -39,6 +39,7 @@ static inline void __iomem *ioremap(phys_addr_t offset, unsigned long size)
 {
 	return __ioremap(offset, size, PAGE_KERNEL);
 }
+#define ioremap ioremap
 
 /* #define _PAGE_CI       0x002 */
 static inline void __iomem *ioremap_nocache(phys_addr_t offset,
@@ -47,6 +48,6 @@ static inline void __iomem *ioremap_nocache(phys_addr_t offset,
 	return __ioremap(offset, size,
 			 __pgprot(pgprot_val(PAGE_KERNEL) | _PAGE_CI));
 }
+#define ioremap_nocache ioremap_nocache
 
-extern void iounmap(void *addr);
 #endif
diff --git a/arch/openrisc/mm/ioremap.c b/arch/openrisc/mm/ioremap.c
index 62b08ef392be..2af1bbe5f80c 100644
--- a/arch/openrisc/mm/ioremap.c
+++ b/arch/openrisc/mm/ioremap.c
@@ -81,7 +81,7 @@ __ioremap(phys_addr_t addr, unsigned long size, pgprot_t prot)
 	return (void __iomem *)(offset + (char *)v);
 }
 
-void iounmap(void *addr)
+void iounmap(volatile void __iomem *addr)
 {
 	/* If the page is from the fixmap pool then we just clear out
 	 * the fixmap mapping.
diff --git a/arch/parisc/include/asm/io.h b/arch/parisc/include/asm/io.h
index 8cd0abf28ffb..8a4ecb47f960 100644
--- a/arch/parisc/include/asm/io.h
+++ b/arch/parisc/include/asm/io.h
@@ -132,13 +132,11 @@ extern void __iomem * __ioremap(unsigned long offset, unsigned long size, unsign
 /* Most machines react poorly to I/O-space being cacheable... Instead let's
  * define ioremap() in terms of ioremap_nocache().
  */
-static inline void __iomem * ioremap(unsigned long offset, unsigned long size)
+static inline void __iomem * ioremap(resource_size_t offset, unsigned long size)
 {
 	return __ioremap(offset, size, _PAGE_NO_CACHE);
 }
-#define ioremap_nocache(off, sz)	ioremap((off), (sz))
-
-extern void iounmap(const volatile void __iomem *addr);
+#define ioremap ioremap
 
 static inline unsigned char __raw_readb(const volatile void __iomem *addr)
 {
diff --git a/arch/parisc/mm/ioremap.c b/arch/parisc/mm/ioremap.c
index 838d0259cd27..3830d8af80a4 100644
--- a/arch/parisc/mm/ioremap.c
+++ b/arch/parisc/mm/ioremap.c
@@ -91,7 +91,7 @@ void __iomem * __ioremap(unsigned long phys_addr, unsigned long size, unsigned l
 }
 EXPORT_SYMBOL(__ioremap);
 
-void iounmap(const volatile void __iomem *addr)
+void iounmap(volatile void __iomem *addr)
 {
 	if (addr > high_memory)
 		return vfree((void *) (PAGE_MASK & (unsigned long __force) addr));
diff --git a/arch/powerpc/include/asm/io.h b/arch/powerpc/include/asm/io.h
index a8d2ef30d473..081f7d3d8913 100644
--- a/arch/powerpc/include/asm/io.h
+++ b/arch/powerpc/include/asm/io.h
@@ -2,8 +2,6 @@
 #define _ASM_POWERPC_IO_H
 #ifdef __KERNEL__
 
-#define ARCH_HAS_IOREMAP_WC
-
 /*
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License
@@ -25,7 +23,6 @@ extern struct pci_dev *isa_bridge_pcidev;
 #endif
 
 #include <linux/device.h>
-#include <linux/io.h>
 
 #include <linux/compiler.h>
 #include <asm/page.h>
@@ -717,12 +714,14 @@ static inline void iosync(void)
  *
  */
 extern void __iomem *ioremap(phys_addr_t address, unsigned long size);
+#define ioremap ioremap
 extern void __iomem *ioremap_prot(phys_addr_t address, unsigned long size,
 				  unsigned long flags);
 extern void __iomem *ioremap_wc(phys_addr_t address, unsigned long size);
-#define ioremap_nocache(addr, size)	ioremap((addr), (size))
+#define ioremap_wc ioremap_wc
 
 extern void iounmap(volatile void __iomem *addr);
+#define iounmap iounmap
 
 extern void __iomem *__ioremap(phys_addr_t, unsigned long size,
 			       unsigned long flags);
diff --git a/arch/s390/include/asm/io.h b/arch/s390/include/asm/io.h
index cb5fdf3a78fc..1cb32250d12b 100644
--- a/arch/s390/include/asm/io.h
+++ b/arch/s390/include/asm/io.h
@@ -27,18 +27,16 @@ void unxlate_dev_mem_ptr(phys_addr_t phys, void *addr);
 
 #ifdef CONFIG_PCI
 
-#define ioremap_nocache(addr, size)	ioremap(addr, size)
-#define ioremap_wc			ioremap_nocache
-#define ioremap_wt			ioremap_nocache
-
-static inline void __iomem *ioremap(unsigned long offset, unsigned long size)
+static inline void __iomem *ioremap(resource_size_t offset, unsigned long size)
 {
 	return (void __iomem *) offset;
 }
+#define ioremap ioremap
 
 static inline void iounmap(volatile void __iomem *addr)
 {
 }
+#define iounmap iounmap
 
 static inline void __iomem *ioport_map(unsigned long port, unsigned int nr)
 {
diff --git a/arch/sh/include/asm/io.h b/arch/sh/include/asm/io.h
index 728c4c571f40..5fd16fe8ecc9 100644
--- a/arch/sh/include/asm/io.h
+++ b/arch/sh/include/asm/io.h
@@ -336,12 +336,14 @@ static inline void __iomem *ioremap(phys_addr_t offset, unsigned long size)
 {
 	return __ioremap_mode(offset, size, PAGE_KERNEL_NOCACHE);
 }
+#define ioremap ioremap
 
 static inline void __iomem *
 ioremap_cache(phys_addr_t offset, unsigned long size)
 {
 	return __ioremap_mode(offset, size, PAGE_KERNEL);
 }
+#define ioremap_cache ioremap_cache
 
 #ifdef CONFIG_HAVE_IOREMAP_PROT
 static inline void __iomem *
@@ -367,8 +369,11 @@ static inline void ioremap_fixed_init(void) { }
 static inline int iounmap_fixed(void __iomem *addr) { return -EINVAL; }
 #endif
 
-#define ioremap_nocache	ioremap
-#define iounmap		__iounmap
+static inline void iounmap(volatile void __iomem *addr)
+{
+	__iounmap(addr);
+}
+#define iounmap	iounmap
 
 /*
  * Convert a physical pointer to a virtual kernel pointer for /dev/mem
diff --git a/arch/sparc/include/asm/io_32.h b/arch/sparc/include/asm/io_32.h
index 57f26c398dc9..138e47e0c7d2 100644
--- a/arch/sparc/include/asm/io_32.h
+++ b/arch/sparc/include/asm/io_32.h
@@ -126,11 +126,8 @@ static inline void sbus_memcpy_toio(volatile void __iomem *dst,
  * Bus number may be embedded in the higher bits of the physical address.
  * This is why we have no bus number argument to ioremap().
  */
-void __iomem *ioremap(unsigned long offset, unsigned long size);
-#define ioremap_nocache(X,Y)	ioremap((X),(Y))
-#define ioremap_wc(X,Y)		ioremap((X),(Y))
-#define ioremap_wt(X,Y)		ioremap((X),(Y))
-void iounmap(volatile void __iomem *addr);
+void __iomem *ioremap(resource_size_t offset, unsigned long size);
+#define ioremap ioremap
 
 /* Create a virtual mapping cookie for an IO port range */
 void __iomem *ioport_map(unsigned long port, unsigned int nr);
diff --git a/arch/sparc/include/asm/io_64.h b/arch/sparc/include/asm/io_64.h
index c32fa3f752c8..47e90988b562 100644
--- a/arch/sparc/include/asm/io_64.h
+++ b/arch/sparc/include/asm/io_64.h
@@ -395,18 +395,16 @@ static inline void memcpy_toio(volatile void __iomem *dst, const void *src,
 /* On sparc64 we have the whole physical IO address space accessible
  * using physically addressed loads and stores, so this does nothing.
  */
-static inline void __iomem *ioremap(unsigned long offset, unsigned long size)
+static inline void __iomem *ioremap(resource_size_t offset, unsigned long size)
 {
 	return (void __iomem *)offset;
 }
-
-#define ioremap_nocache(X,Y)		ioremap((X),(Y))
-#define ioremap_wc(X,Y)			ioremap((X),(Y))
-#define ioremap_wt(X,Y)			ioremap((X),(Y))
+#define ioremap ioremap
 
 static inline void iounmap(volatile void __iomem *addr)
 {
 }
+#define iounmap iounmap
 
 #define ioread8			readb
 #define ioread16		readw
diff --git a/arch/sparc/kernel/ioport.c b/arch/sparc/kernel/ioport.c
index 28fed53b13a0..b8c999f5b821 100644
--- a/arch/sparc/kernel/ioport.c
+++ b/arch/sparc/kernel/ioport.c
@@ -121,7 +121,7 @@ static void xres_free(struct xresource *xrp) {
  *
  * Bus type is always zero on IIep.
  */
-void __iomem *ioremap(unsigned long offset, unsigned long size)
+void __iomem *ioremap(resource_size_t offset, unsigned long size)
 {
 	char name[14];
 
diff --git a/arch/tile/include/asm/io.h b/arch/tile/include/asm/io.h
index dc61de15c1f9..bf7f0fffb8db 100644
--- a/arch/tile/include/asm/io.h
+++ b/arch/tile/include/asm/io.h
@@ -48,14 +48,19 @@ extern void __iomem *ioremap_prot(resource_size_t offset, unsigned long size,
 	pgprot_t pgprot);
 extern void iounmap(volatile void __iomem *addr);
 #else
-#define ioremap(physaddr, size)	((void __iomem *)(unsigned long)(physaddr))
-#define iounmap(addr)		((void)0)
+static inline void __iomem *ioremap(resource_size_t offset, unsigned long size)
+{
+	return (void __force __iomem *) offset;
+}
+
+static inline void iounmap(volatile void __iomem *addr)
+{
+}
 #endif
+#define ioremap ioremap
+#define iounmap iounmap
 
-#define ioremap_nocache(physaddr, size)		ioremap(physaddr, size)
-#define ioremap_wc(physaddr, size)		ioremap(physaddr, size)
-#define ioremap_wt(physaddr, size)		ioremap(physaddr, size)
-#define ioremap_fullcache(physaddr, size)	ioremap(physaddr, size)
+#define ioremap_fullcache ioremap
 
 #define mmiowb()
 
diff --git a/arch/unicore32/include/asm/io.h b/arch/unicore32/include/asm/io.h
index cb1d8fd2b16b..1088450fabfd 100644
--- a/arch/unicore32/include/asm/io.h
+++ b/arch/unicore32/include/asm/io.h
@@ -18,7 +18,6 @@
 #include <asm/memory.h>
 
 #define PCI_IOBASE	PKUNITY_PCILIO_BASE
-#include <asm-generic/io.h>
 
 /*
  * __uc32_ioremap and __uc32_ioremap_cached takes CPU physical address.
@@ -34,10 +33,26 @@ extern void __uc32_iounmap(volatile void __iomem *addr);
  * Documentation/io-mapping.txt.
  *
  */
-#define ioremap(cookie, size)		__uc32_ioremap(cookie, size)
-#define ioremap_cached(cookie, size)	__uc32_ioremap_cached(cookie, size)
-#define ioremap_nocache(cookie, size)	__uc32_ioremap(cookie, size)
-#define iounmap(cookie)			__uc32_iounmap(cookie)
+static inline void __iomem *ioremap(resource_size_t cookie, unsigned long size)
+{
+	return __uc32_ioremap(cookie, size);
+}
+#define ioremap ioremap
+
+static inline void __iomem *ioremap_cache(resource_size_t cookie, unsigned long size)
+{
+	return __uc32_ioremap_cached(cookie, size);
+}
+#define ioremap_cache ioremap_cache
+#define ioremap_cached ioremap_cached
+
+static inline void iounmap(volatile void __iomem *addr)
+{
+	return __uc32_iounmap(addr);
+}
+#define iounmap iounmap
+
+#include <asm-generic/io.h>
 
 #define readb_relaxed readb
 #define readw_relaxed readw
diff --git a/arch/x86/include/asm/io.h b/arch/x86/include/asm/io.h
index 83ec9b1d77cc..97ae3b748d9e 100644
--- a/arch/x86/include/asm/io.h
+++ b/arch/x86/include/asm/io.h
@@ -34,9 +34,6 @@
   *  - Arnaldo Carvalho de Melo <acme@conectiva.com.br>
   */
 
-#define ARCH_HAS_IOREMAP_WC
-#define ARCH_HAS_IOREMAP_WT
-
 #include <linux/string.h>
 #include <linux/compiler.h>
 #include <asm/page.h>
@@ -179,8 +176,10 @@ static inline unsigned int isa_virt_to_bus(volatile void *address)
  * look at pci_iomap().
  */
 extern void __iomem *ioremap_nocache(resource_size_t offset, unsigned long size);
+#define ioremap_nocache ioremap_nocache
 extern void __iomem *ioremap_uc(resource_size_t offset, unsigned long size);
 extern void __iomem *ioremap_cache(resource_size_t offset, unsigned long size);
+#define ioremap_cache ioremap_cache
 extern void __iomem *ioremap_prot(resource_size_t offset, unsigned long size,
 				unsigned long prot_val);
 
@@ -191,8 +190,10 @@ static inline void __iomem *ioremap(resource_size_t offset, unsigned long size)
 {
 	return ioremap_nocache(offset, size);
 }
+#define ioremap ioremap
 
 extern void iounmap(volatile void __iomem *addr);
+#define iounmap iounmap
 
 extern void set_iounmap_nonlazy(void);
 
@@ -321,7 +322,9 @@ extern void unxlate_dev_mem_ptr(phys_addr_t phys, void *addr);
 extern int ioremap_change_attr(unsigned long vaddr, unsigned long size,
 				enum page_cache_mode pcm);
 extern void __iomem *ioremap_wc(resource_size_t offset, unsigned long size);
+#define ioremap_wc ioremap_wc
 extern void __iomem *ioremap_wt(resource_size_t offset, unsigned long size);
+#define ioremap_wt ioremap_wt
 
 extern bool is_early_ioremap_ptep(pte_t *ptep);
 
diff --git a/arch/xtensa/include/asm/io.h b/arch/xtensa/include/asm/io.h
index c39bb6e61911..ae20fc5a1b5f 100644
--- a/arch/xtensa/include/asm/io.h
+++ b/arch/xtensa/include/asm/io.h
@@ -38,7 +38,7 @@ static inline unsigned long xtensa_get_kio_paddr(void)
  * Return the virtual address for the specified bus memory.
  * Note that we currently don't support any address outside the KIO segment.
  */
-static inline void __iomem *ioremap_nocache(unsigned long offset,
+static inline void __iomem *ioremap_nocache(resource_size_t offset,
 		unsigned long size)
 {
 	if (offset >= XCHAL_KIO_PADDR
@@ -47,8 +47,9 @@ static inline void __iomem *ioremap_nocache(unsigned long offset,
 	else
 		BUG();
 }
+#define ioremap_nocache ioremap_nocache
 
-static inline void __iomem *ioremap_cache(unsigned long offset,
+static inline void __iomem *ioremap_cache(resource_size_t offset,
 		unsigned long size)
 {
 	if (offset >= XCHAL_KIO_PADDR
@@ -57,18 +58,18 @@ static inline void __iomem *ioremap_cache(unsigned long offset,
 	else
 		BUG();
 }
+#define ioremap_cache ioremap_cache
 
-#define ioremap_wc ioremap_nocache
-#define ioremap_wt ioremap_nocache
-
-static inline void __iomem *ioremap(unsigned long offset, unsigned long size)
+static inline void __iomem *ioremap(resource_size_t offset, unsigned long size)
 {
 	return ioremap_nocache(offset, size);
 }
+#define ioremap ioremap
 
 static inline void iounmap(volatile void __iomem *addr)
 {
 }
+#define iounmap iounmap
 
 #define virt_to_bus     virt_to_phys
 #define bus_to_virt     phys_to_virt
diff --git a/drivers/net/ethernet/sfc/io.h b/drivers/net/ethernet/sfc/io.h
index afb94aa2c15e..9d54dd7f4c72 100644
--- a/drivers/net/ethernet/sfc/io.h
+++ b/drivers/net/ethernet/sfc/io.h
@@ -73,7 +73,7 @@
  */
 #ifdef CONFIG_X86_64
 /* PIO is a win only if write-combining is possible */
-#ifdef ARCH_HAS_IOREMAP_WC
+#ifdef ioremap_wc
 #define EFX_USE_PIO 1
 #endif
 #endif
diff --git a/include/asm-generic/iomap.h b/include/asm-generic/iomap.h
index d8f8622fa044..4789b1cec313 100644
--- a/include/asm-generic/iomap.h
+++ b/include/asm-generic/iomap.h
@@ -62,14 +62,6 @@ extern void __iomem *ioport_map(unsigned long port, unsigned int nr);
 extern void ioport_unmap(void __iomem *);
 #endif
 
-#ifndef ARCH_HAS_IOREMAP_WC
-#define ioremap_wc ioremap_nocache
-#endif
-
-#ifndef ARCH_HAS_IOREMAP_WT
-#define ioremap_wt ioremap_nocache
-#endif
-
 #ifdef CONFIG_PCI
 /* Destroy a virtual mapping cookie for a PCI BAR (memory or IO) */
 struct pci_dev;
diff --git a/include/linux/io.h b/include/linux/io.h
index fb5a99800e77..41e93fe14b3c 100644
--- a/include/linux/io.h
+++ b/include/linux/io.h
@@ -80,6 +80,64 @@ int check_signature(const volatile void __iomem *io_addr,
 			const unsigned char *signature, int length);
 void devm_ioremap_release(struct device *dev, void *res);
 
+#ifndef ioremap
+void __iomem *ioremap(resource_size_t offset, unsigned long size);
+#endif
+
+#ifndef iounmap
+void iounmap(volatile void __iomem *addr);
+#endif
+
+#ifndef ioremap_nocache
+static inline void __iomem *ioremap_nocache(resource_size_t offset,
+		unsigned long size)
+{
+	return ioremap(offset, size);
+}
+#endif
+
+#ifndef ioremap_wc
+static inline void __iomem *ioremap_wc(resource_size_t offset,
+		unsigned long size)
+{
+	return ioremap(offset, size);
+}
+#endif
+
+#ifndef ioremap_wt
+static inline void __iomem *ioremap_wt(resource_size_t offset,
+		unsigned long size)
+{
+	return ioremap(offset, size);
+}
+#endif
+
+#ifndef ioremap_cache
+static inline void __iomem *ioremap_cache(resource_size_t offset,
+		unsigned long size)
+{
+	return ioremap(offset, size);
+}
+#endif
+
+/*
+ * Throw warnings if an arch fails to define or uses unexpected data
+ * types in its ioremap implementations.
+ */
+static inline void ioremap_test(void)
+{
+	void __iomem *(*map)(resource_size_t offset, unsigned long size)
+		__always_unused;
+	void (*unmap)(volatile void __iomem *addr) __always_unused;
+
+	map = ioremap;
+	map = ioremap_nocache;
+	map = ioremap_cache;
+	map = ioremap_wc;
+	map = ioremap_wt;
+	unmap = iounmap;
+}
+
 /*
  * Some systems do not have legacy ISA devices.
  * /dev/port is not a valid interface on these systems.

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org.  For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>

^ permalink raw reply related	[flat|nested] 85+ messages in thread

* [PATCH v5 2/6] arch: unify ioremap prototypes and macro aliases
@ 2015-06-22  8:24   ` Dan Williams
  0 siblings, 0 replies; 85+ messages in thread
From: Dan Williams @ 2015-06-22  8:24 UTC (permalink / raw)
  To: arnd, mingo, bp, hpa, tglx, ross.zwisler, akpm
  Cc: jgross, x86, toshi.kani, linux-nvdimm, benh, mcgrof, konrad.wilk,
	linux-kernel, stefan.bader, luto, linux-mm, geert, ralf, hmh,
	mpe, tj, paulus, hch

Some archs define the first parameter to ioremap() as unsigned long,
while the balance define it as resource_size_t.  Unify on
resource_size_t to enable passing ioremap function pointers.  Also, some
archs use function-like macros for defining ioremap aliases, but
asm-generic/io.h expects object-like macros, unify on the latter.

Move all handling of ioremap aliasing (i.e. ioremap_wt => ioremap) to
include/linux/io.h.  Add a check to include/linux/io.h to warn at
compile time if an arch violates expectations.

Kill ARCH_HAS_IOREMAP_WC and ARCH_HAS_IOREMAP_WT in favor of just
testing for ioremap_wc, and ioremap_wt being defined.  This arrangement
allows drivers to know when ioremap_<foo> are being re-directed to plain
ioremap.

Reported-by: kbuild test robot <fengguang.wu@intel.com>
Signed-off-by: Dan Williams <dan.j.williams@intel.com>
---
 arch/alpha/include/asm/io.h      |    7 +++--
 arch/arc/include/asm/io.h        |    6 ----
 arch/arm/include/asm/io.h        |   31 ++++++++++++++++----
 arch/arm64/include/asm/io.h      |   23 ++++++++++++---
 arch/avr32/include/asm/io.h      |   22 +++++++-------
 arch/avr32/mm/ioremap.c          |    2 +
 arch/cris/include/asm/io.h       |    8 +++--
 arch/cris/mm/ioremap.c           |    2 +
 arch/frv/include/asm/io.h        |   23 +++++++--------
 arch/hexagon/include/asm/io.h    |    5 +++
 arch/ia64/include/asm/io.h       |   10 +------
 arch/ia64/mm/ioremap.c           |    4 +--
 arch/m32r/include/asm/io.h       |    9 +++---
 arch/m68k/include/asm/io_mm.h    |   21 +++++++++-----
 arch/m68k/include/asm/io_no.h    |   34 ++++++++++++++--------
 arch/m68k/include/asm/raw_io.h   |    3 +-
 arch/m68k/mm/kmap.c              |    2 +
 arch/metag/include/asm/io.h      |   35 ++++++++++++++---------
 arch/microblaze/include/asm/io.h |    6 ----
 arch/microblaze/mm/pgtable.c     |    2 +
 arch/mips/include/asm/io.h       |   42 ++++++++++------------------
 arch/mn10300/include/asm/io.h    |   10 ++++---
 arch/nios2/include/asm/io.h      |   15 +++-------
 arch/openrisc/include/asm/io.h   |    3 +-
 arch/openrisc/mm/ioremap.c       |    2 +
 arch/parisc/include/asm/io.h     |    6 +---
 arch/parisc/mm/ioremap.c         |    2 +
 arch/powerpc/include/asm/io.h    |    7 ++---
 arch/s390/include/asm/io.h       |    8 ++---
 arch/sh/include/asm/io.h         |    9 +++++-
 arch/sparc/include/asm/io_32.h   |    7 +----
 arch/sparc/include/asm/io_64.h   |    8 ++---
 arch/sparc/kernel/ioport.c       |    2 +
 arch/tile/include/asm/io.h       |   17 +++++++----
 arch/unicore32/include/asm/io.h  |   25 +++++++++++++---
 arch/x86/include/asm/io.h        |    9 ++++--
 arch/xtensa/include/asm/io.h     |   13 +++++----
 drivers/net/ethernet/sfc/io.h    |    2 +
 include/asm-generic/iomap.h      |    8 -----
 include/linux/io.h               |   58 ++++++++++++++++++++++++++++++++++++++
 40 files changed, 300 insertions(+), 208 deletions(-)

diff --git a/arch/alpha/include/asm/io.h b/arch/alpha/include/asm/io.h
index f05bdb4b1cb9..6b63689c27a6 100644
--- a/arch/alpha/include/asm/io.h
+++ b/arch/alpha/include/asm/io.h
@@ -282,10 +282,11 @@ extern inline void ioport_unmap(void __iomem *addr)
 {
 }
 
-static inline void __iomem *ioremap(unsigned long port, unsigned long size)
+static inline void __iomem *ioremap(resource_size_t port, unsigned long size)
 {
 	return IO_CONCAT(__IO_PREFIX,ioremap) (port, size);
 }
+#define ioremap ioremap
 
 static inline void __iomem *__ioremap(unsigned long port, unsigned long size,
 				      unsigned long flags)
@@ -293,16 +294,18 @@ static inline void __iomem *__ioremap(unsigned long port, unsigned long size,
 	return ioremap(port, size);
 }
 
-static inline void __iomem * ioremap_nocache(unsigned long offset,
+static inline void __iomem * ioremap_nocache(resource_size_t offset,
 					     unsigned long size)
 {
 	return ioremap(offset, size);
 } 
+#define ioremap_nocache ioremap_nocache
 
 static inline void iounmap(volatile void __iomem *addr)
 {
 	IO_CONCAT(__IO_PREFIX,iounmap)(addr);
 }
+#define iounmap iounmap
 
 static inline int __is_ioaddr(unsigned long addr)
 {
diff --git a/arch/arc/include/asm/io.h b/arch/arc/include/asm/io.h
index 7cc4ced5dbf4..e6f782863026 100644
--- a/arch/arc/include/asm/io.h
+++ b/arch/arc/include/asm/io.h
@@ -13,14 +13,8 @@
 #include <asm/byteorder.h>
 #include <asm/page.h>
 
-extern void __iomem *ioremap(unsigned long physaddr, unsigned long size);
 extern void __iomem *ioremap_prot(phys_addr_t offset, unsigned long size,
 				  unsigned long flags);
-extern void iounmap(const void __iomem *addr);
-
-#define ioremap_nocache(phy, sz)	ioremap(phy, sz)
-#define ioremap_wc(phy, sz)		ioremap(phy, sz)
-#define ioremap_wt(phy, sz)		ioremap(phy, sz)
 
 /* Change struct page to physical address */
 #define page_to_phys(page)		(page_to_pfn(page) << PAGE_SHIFT)
diff --git a/arch/arm/include/asm/io.h b/arch/arm/include/asm/io.h
index 1b7677d1e5e1..ecd410c716d8 100644
--- a/arch/arm/include/asm/io.h
+++ b/arch/arm/include/asm/io.h
@@ -332,12 +332,31 @@ extern void _memset_io(volatile void __iomem *, int, size_t);
  * Documentation/io-mapping.txt.
  *
  */
-#define ioremap(cookie,size)		__arm_ioremap((cookie), (size), MT_DEVICE)
-#define ioremap_nocache(cookie,size)	__arm_ioremap((cookie), (size), MT_DEVICE)
-#define ioremap_cache(cookie,size)	__arm_ioremap((cookie), (size), MT_DEVICE_CACHED)
-#define ioremap_wc(cookie,size)		__arm_ioremap((cookie), (size), MT_DEVICE_WC)
-#define ioremap_wt(cookie,size)		__arm_ioremap((cookie), (size), MT_DEVICE)
-#define iounmap				__arm_iounmap
+static inline void __iomem *ioremap(resource_size_t cookie, unsigned long size)
+{
+	return __arm_ioremap(cookie, size, MT_DEVICE);
+}
+#define ioremap ioremap
+
+static inline void __iomem *ioremap_cache(resource_size_t cookie,
+		unsigned long size)
+{
+	return __arm_ioremap(cookie, size, MT_DEVICE_CACHED);
+}
+#define ioremap_cache ioremap_cache
+
+static inline void __iomem *ioremap_wc(resource_size_t cookie,
+		unsigned long size)
+{
+	return __arm_ioremap(cookie, size, MT_DEVICE_WC);
+}
+#define ioremap_wc ioremap_wc
+
+static inline void iounmap(volatile void __iomem *addr)
+{
+	__arm_iounmap(addr);
+}
+#define iounmap iounmap
 
 /*
  * io{read,write}{16,32}be() macros
diff --git a/arch/arm64/include/asm/io.h b/arch/arm64/include/asm/io.h
index 7116d3973058..56782487bf3c 100644
--- a/arch/arm64/include/asm/io.h
+++ b/arch/arm64/include/asm/io.h
@@ -166,12 +166,25 @@ extern void __memset_io(volatile void __iomem *, int, size_t);
 extern void __iomem *__ioremap(phys_addr_t phys_addr, size_t size, pgprot_t prot);
 extern void __iounmap(volatile void __iomem *addr);
 extern void __iomem *ioremap_cache(phys_addr_t phys_addr, size_t size);
+#define ioremap_cache ioremap_cache
 
-#define ioremap(addr, size)		__ioremap((addr), (size), __pgprot(PROT_DEVICE_nGnRE))
-#define ioremap_nocache(addr, size)	__ioremap((addr), (size), __pgprot(PROT_DEVICE_nGnRE))
-#define ioremap_wc(addr, size)		__ioremap((addr), (size), __pgprot(PROT_NORMAL_NC))
-#define ioremap_wt(addr, size)		__ioremap((addr), (size), __pgprot(PROT_DEVICE_nGnRE))
-#define iounmap				__iounmap
+static inline void __iomem *ioremap(resource_size_t addr, unsigned long size)
+{
+	return __ioremap(addr, size, __pgprot(PROT_DEVICE_nGnRE));
+}
+#define ioremap ioremap
+
+static inline void __iomem *ioremap_wc(resource_size_t addr, unsigned long size)
+{
+	return __ioremap(addr, size, __pgprot(PROT_NORMAL_NC));
+}
+#define ioremap_wc ioremap_wc
+
+static inline void iounmap(volatile void __iomem *addr)
+{
+	return __iounmap(addr);
+}
+#define iounmap iounmap
 
 /*
  * io{read,write}{16,32}be() macros
diff --git a/arch/avr32/include/asm/io.h b/arch/avr32/include/asm/io.h
index e998ff5d8e1a..80af4cb6c5b6 100644
--- a/arch/avr32/include/asm/io.h
+++ b/arch/avr32/include/asm/io.h
@@ -274,7 +274,7 @@ static inline void memset_io(volatile void __iomem *addr, unsigned char val,
 
 extern void __iomem *__ioremap(unsigned long offset, size_t size,
 			       unsigned long flags);
-extern void __iounmap(void __iomem *addr);
+extern void __iounmap(volatile void __iomem *addr);
 
 /*
  * ioremap	-   map bus memory into CPU space
@@ -286,17 +286,17 @@ extern void __iounmap(void __iomem *addr);
  * the other mmio helpers. The returned address is not guaranteed to
  * be usable directly as a virtual address.
  */
-#define ioremap(offset, size)			\
-	__ioremap((offset), (size), 0)
-
-#define ioremap_nocache(offset, size)		\
-	__ioremap((offset), (size), 0)
-
-#define iounmap(addr)				\
-	__iounmap(addr)
+static inline void __iomem *ioremap(resource_size_t offset, unsigned long size)
+{
+	return __ioremap(offset, size, 0);
+}
+#define ioremap ioremap
 
-#define ioremap_wc ioremap_nocache
-#define ioremap_wt ioremap_nocache
+static inline void iounmap(volatile void __iomem *addr)
+{
+	return __iounmap(addr);
+}
+#define iounmap iounmap
 
 #define cached(addr) P1SEGADDR(addr)
 #define uncached(addr) P2SEGADDR(addr)
diff --git a/arch/avr32/mm/ioremap.c b/arch/avr32/mm/ioremap.c
index 7def0d84cec6..f3eacbe5dff6 100644
--- a/arch/avr32/mm/ioremap.c
+++ b/arch/avr32/mm/ioremap.c
@@ -73,7 +73,7 @@ void __iomem *__ioremap(unsigned long phys_addr, size_t size,
 }
 EXPORT_SYMBOL(__ioremap);
 
-void __iounmap(void __iomem *addr)
+void __iounmap(volatile void __iomem *addr)
 {
 	struct vm_struct *p;
 
diff --git a/arch/cris/include/asm/io.h b/arch/cris/include/asm/io.h
index 752a3f45df60..cd55a5709433 100644
--- a/arch/cris/include/asm/io.h
+++ b/arch/cris/include/asm/io.h
@@ -37,14 +37,14 @@ static inline void * phys_to_virt(unsigned long address)
 extern void __iomem * __ioremap(unsigned long offset, unsigned long size, unsigned long flags);
 extern void __iomem * __ioremap_prot(unsigned long phys_addr, unsigned long size, pgprot_t prot);
 
-static inline void __iomem * ioremap (unsigned long offset, unsigned long size)
+static inline void __iomem * ioremap(resource_size_t offset, unsigned long size)
 {
 	return __ioremap(offset, size, 0);
 }
+#define ioremap ioremap
 
-extern void iounmap(volatile void * __iomem addr);
-
-extern void __iomem * ioremap_nocache(unsigned long offset, unsigned long size);
+extern void __iomem * ioremap_nocache(resource_size_t offset, unsigned long size);
+#define ioremap_nocache ioremap_nocache
 
 /*
  * IO bus memory addresses are also 1:1 with the physical address
diff --git a/arch/cris/mm/ioremap.c b/arch/cris/mm/ioremap.c
index 80fdb995a8ce..13cef92df503 100644
--- a/arch/cris/mm/ioremap.c
+++ b/arch/cris/mm/ioremap.c
@@ -76,7 +76,7 @@ void __iomem * __ioremap(unsigned long phys_addr, unsigned long size, unsigned l
  * Must be freed with iounmap.
  */
 
-void __iomem *ioremap_nocache(unsigned long phys_addr, unsigned long size)
+void __iomem *ioremap_nocache(resource_size_t phys_addr, unsigned long size)
 {
         return __ioremap(phys_addr | MEM_NON_CACHEABLE, size, 0);
 }
diff --git a/arch/frv/include/asm/io.h b/arch/frv/include/asm/io.h
index a31b63ec4930..bde570d29c89 100644
--- a/arch/frv/include/asm/io.h
+++ b/arch/frv/include/asm/io.h
@@ -17,8 +17,6 @@
 
 #ifdef __KERNEL__
 
-#define ARCH_HAS_IOREMAP_WT
-
 #include <linux/types.h>
 #include <asm/virtconvert.h>
 #include <asm/string.h>
@@ -257,29 +255,28 @@ static inline void writel(uint32_t datum, volatile void __iomem *addr)
 
 extern void __iomem *__ioremap(unsigned long physaddr, unsigned long size, int cacheflag);
 
-static inline void __iomem *ioremap(unsigned long physaddr, unsigned long size)
-{
-	return __ioremap(physaddr, size, IOMAP_NOCACHE_SER);
-}
-
-static inline void __iomem *ioremap_nocache(unsigned long physaddr, unsigned long size)
+static inline void __iomem *ioremap(resource_size_t physaddr, unsigned long size)
 {
 	return __ioremap(physaddr, size, IOMAP_NOCACHE_SER);
 }
+#define ioremap ioremap
 
-static inline void __iomem *ioremap_wt(unsigned long physaddr, unsigned long size)
+static inline void __iomem *ioremap_wt(resource_size_t physaddr, unsigned long size)
 {
 	return __ioremap(physaddr, size, IOMAP_WRITETHROUGH);
 }
+#define ioremap_wt ioremap_wt
 
-static inline void __iomem *ioremap_fullcache(unsigned long physaddr, unsigned long size)
+static inline void __iomem *ioremap_fullcache(resource_size_t physaddr, unsigned long size)
 {
 	return __ioremap(physaddr, size, IOMAP_FULL_CACHING);
 }
 
-#define ioremap_wc ioremap_nocache
-
-extern void iounmap(void volatile __iomem *addr);
+static inline void __iomem *ioremap_cache(resource_size_t physaddr, unsigned long size)
+{
+	return ioremap_fullcache(physaddr, size);
+}
+#define ioremap_cache ioremap_cache
 
 static inline void __iomem *ioport_map(unsigned long port, unsigned int nr)
 {
diff --git a/arch/hexagon/include/asm/io.h b/arch/hexagon/include/asm/io.h
index 66f5e9a61efc..e5ecc08b7627 100644
--- a/arch/hexagon/include/asm/io.h
+++ b/arch/hexagon/include/asm/io.h
@@ -191,16 +191,19 @@ static inline void writel(u32 data, volatile void __iomem *addr)
  * This is probably too long for an inline.
  */
 void __iomem *ioremap_nocache(unsigned long phys_addr, unsigned long size);
+#define ioremap_nocache ioremap_nocache
 
-static inline void __iomem *ioremap(unsigned long phys_addr, unsigned long size)
+static inline void __iomem *ioremap(resouce_size_t phys_addr, unsigned long size)
 {
 	return ioremap_nocache(phys_addr, size);
 }
+#define ioremap ioremap
 
 static inline void iounmap(volatile void __iomem *addr)
 {
 	__iounmap(addr);
 }
+#define iounmap iounmap
 
 #define __raw_writel writel
 
diff --git a/arch/ia64/include/asm/io.h b/arch/ia64/include/asm/io.h
index 80a7e34be009..ea4c7a243973 100644
--- a/arch/ia64/include/asm/io.h
+++ b/arch/ia64/include/asm/io.h
@@ -424,18 +424,12 @@ __writeq (unsigned long val, volatile void __iomem *addr)
 
 # ifdef __KERNEL__
 
-extern void __iomem * ioremap(unsigned long offset, unsigned long size);
-extern void __iomem * ioremap_nocache (unsigned long offset, unsigned long size);
-extern void iounmap (volatile void __iomem *addr);
+extern void __iomem * ioremap_nocache (resource_size_t offset, unsigned long size);
+#define ioremap_nocache ioremap_nocache
 extern void __iomem * early_ioremap (unsigned long phys_addr, unsigned long size);
 #define early_memremap(phys_addr, size)        early_ioremap(phys_addr, size)
 extern void early_iounmap (volatile void __iomem *addr, unsigned long size);
 #define early_memunmap(addr, size)             early_iounmap(addr, size)
-static inline void __iomem * ioremap_cache (unsigned long phys_addr, unsigned long size)
-{
-	return ioremap(phys_addr, size);
-}
-
 
 /*
  * String version of IO memory access ops:
diff --git a/arch/ia64/mm/ioremap.c b/arch/ia64/mm/ioremap.c
index 43964cde6214..205d71445f06 100644
--- a/arch/ia64/mm/ioremap.c
+++ b/arch/ia64/mm/ioremap.c
@@ -32,7 +32,7 @@ early_ioremap (unsigned long phys_addr, unsigned long size)
 }
 
 void __iomem *
-ioremap (unsigned long phys_addr, unsigned long size)
+ioremap (resource_size_t phys_addr, unsigned long size)
 {
 	void __iomem *addr;
 	struct vm_struct *area;
@@ -102,7 +102,7 @@ ioremap (unsigned long phys_addr, unsigned long size)
 EXPORT_SYMBOL(ioremap);
 
 void __iomem *
-ioremap_nocache (unsigned long phys_addr, unsigned long size)
+ioremap_nocache (resource_size_t phys_addr, unsigned long size)
 {
 	if (kern_mem_attribute(phys_addr, size) & EFI_MEMORY_WB)
 		return NULL;
diff --git a/arch/m32r/include/asm/io.h b/arch/m32r/include/asm/io.h
index 0c3f25ee3381..d7f96a542816 100644
--- a/arch/m32r/include/asm/io.h
+++ b/arch/m32r/include/asm/io.h
@@ -60,15 +60,14 @@ __ioremap(unsigned long offset, unsigned long size, unsigned long flags);
  *	address.
  */
 
-static inline void __iomem *ioremap(unsigned long offset, unsigned long size)
+static inline void __iomem *ioremap(resource_size_t offset, unsigned long size)
 {
 	return __ioremap(offset, size, 0);
 }
+#define ioremap ioremap
 
-extern void iounmap(volatile void __iomem *addr);
-#define ioremap_nocache(off,size) ioremap(off,size)
-#define ioremap_wc ioremap_nocache
-#define ioremap_wt ioremap_nocache
+void iounmap(volatile void __iomem *addr);
+#define iounmap iounmap
 
 /*
  * IO bus memory addresses are also 1:1 with the physical address
diff --git a/arch/m68k/include/asm/io_mm.h b/arch/m68k/include/asm/io_mm.h
index 618c85d3c786..7658252c64ab 100644
--- a/arch/m68k/include/asm/io_mm.h
+++ b/arch/m68k/include/asm/io_mm.h
@@ -20,8 +20,6 @@
 
 #ifdef __KERNEL__
 
-#define ARCH_HAS_IOREMAP_WT
-
 #include <linux/compiler.h>
 #include <asm/raw_io.h>
 #include <asm/virtconvert.h>
@@ -459,25 +457,32 @@ static inline void isa_delay(void)
 
 #define mmiowb()
 
-static inline void __iomem *ioremap(unsigned long physaddr, unsigned long size)
+static inline void __iomem *ioremap(resource_size_t physaddr, unsigned long size)
 {
 	return __ioremap(physaddr, size, IOMAP_NOCACHE_SER);
 }
-static inline void __iomem *ioremap_nocache(unsigned long physaddr, unsigned long size)
-{
-	return __ioremap(physaddr, size, IOMAP_NOCACHE_SER);
-}
-static inline void __iomem *ioremap_wt(unsigned long physaddr,
+#define ioremap ioremap
+
+static inline void __iomem *ioremap_wt(resource_size_t physaddr,
 					 unsigned long size)
 {
 	return __ioremap(physaddr, size, IOMAP_WRITETHROUGH);
 }
+#define ioremap_wt ioremap_wt
+
 static inline void __iomem *ioremap_fullcache(unsigned long physaddr,
 				      unsigned long size)
 {
 	return __ioremap(physaddr, size, IOMAP_FULL_CACHING);
 }
 
+static inline void __iomem *ioremap_cache(resource_size_t physaddr,
+		unsigned long size)
+{
+	return ioremap_fullcache(physaddr, size);
+}
+#define ioremap_cache ioremap_cache
+
 static inline void memset_io(volatile void __iomem *addr, unsigned char val, int count)
 {
 	__builtin_memset((void __force *) addr, val, count);
diff --git a/arch/m68k/include/asm/io_no.h b/arch/m68k/include/asm/io_no.h
index ad7bd40e6742..ea9b280ebc33 100644
--- a/arch/m68k/include/asm/io_no.h
+++ b/arch/m68k/include/asm/io_no.h
@@ -3,8 +3,6 @@
 
 #ifdef __KERNEL__
 
-#define ARCH_HAS_IOREMAP_WT
-
 #include <asm/virtconvert.h>
 #include <asm-generic/iomap.h>
 
@@ -143,28 +141,40 @@ static inline void io_insl(unsigned int addr, void *buf, int len)
 #define IOMAP_NOCACHE_NONSER		2
 #define IOMAP_WRITETHROUGH		3
 
-static inline void *__ioremap(unsigned long physaddr, unsigned long size, int cacheflag)
-{
-	return (void *) physaddr;
-}
-static inline void *ioremap(unsigned long physaddr, unsigned long size)
+static inline void __iomem *__ioremap(unsigned long physaddr,
+		unsigned long size, int cacheflag)
 {
-	return __ioremap(physaddr, size, IOMAP_NOCACHE_SER);
+	return (void __iomem *) physaddr;
 }
-static inline void *ioremap_nocache(unsigned long physaddr, unsigned long size)
+static inline void __iomem *ioremap(resource_size_t physaddr, unsigned long size)
 {
 	return __ioremap(physaddr, size, IOMAP_NOCACHE_SER);
 }
-static inline void *ioremap_wt(unsigned long physaddr, unsigned long size)
+#define ioremap ioremap
+
+static inline void __iomem *ioremap_wt(resource_size_t physaddr, unsigned long size)
 {
 	return __ioremap(physaddr, size, IOMAP_WRITETHROUGH);
 }
-static inline void *ioremap_fullcache(unsigned long physaddr, unsigned long size)
+#define ioremap_wt ioremap_wt
+
+static inline void __iomem *ioremap_fullcache(unsigned long physaddr,
+		unsigned long size)
 {
 	return __ioremap(physaddr, size, IOMAP_FULL_CACHING);
 }
 
-#define	iounmap(addr)	do { } while(0)
+static inline void __iomem *ioremap_cache(resource_size_t physaddr,
+		unsigned long size)
+{
+	return ioremap_fullcache(physaddr, size);
+}
+#define ioremap_cache ioremap_cache
+
+static inline void iounmap(volatile void __iomem *addr)
+{
+}
+#define iounmap iounmap
 
 /*
  * Convert a physical pointer to a virtual kernel pointer for /dev/mem
diff --git a/arch/m68k/include/asm/raw_io.h b/arch/m68k/include/asm/raw_io.h
index 932faa35655b..abb7708f02ed 100644
--- a/arch/m68k/include/asm/raw_io.h
+++ b/arch/m68k/include/asm/raw_io.h
@@ -19,7 +19,8 @@
 #define IOMAP_NOCACHE_NONSER		2
 #define IOMAP_WRITETHROUGH		3
 
-extern void iounmap(void __iomem *addr);
+extern void iounmap(volatile void __iomem *addr);
+#define iounmap iounmap
 
 extern void __iomem *__ioremap(unsigned long physaddr, unsigned long size,
 		       int cacheflag);
diff --git a/arch/m68k/mm/kmap.c b/arch/m68k/mm/kmap.c
index 6e4955bc542b..f0d76d9f0643 100644
--- a/arch/m68k/mm/kmap.c
+++ b/arch/m68k/mm/kmap.c
@@ -226,7 +226,7 @@ EXPORT_SYMBOL(__ioremap);
 /*
  * Unmap an ioremap()ed region again
  */
-void iounmap(void __iomem *addr)
+void iounmap(volatile void __iomem *addr)
 {
 #ifdef CONFIG_AMIGA
 	if ((!MACH_IS_AMIGA) ||
diff --git a/arch/metag/include/asm/io.h b/arch/metag/include/asm/io.h
index 9890f21eadbe..50e95ecb4bc2 100644
--- a/arch/metag/include/asm/io.h
+++ b/arch/metag/include/asm/io.h
@@ -148,22 +148,29 @@ extern void __iounmap(void __iomem *addr);
  *	address is not guaranteed to be usable directly as a virtual
  *	address.
  */
-#define ioremap(offset, size)                   \
-	__ioremap((offset), (size), 0)
-
-#define ioremap_nocache(offset, size)           \
-	__ioremap((offset), (size), 0)
-
-#define ioremap_cached(offset, size)            \
-	__ioremap((offset), (size), _PAGE_CACHEABLE)
+static inline void __iomem *ioremap(resource_size_t offset, unsigned long size)
+{
+	return __ioremap(offset, size, 0);
+}
+#define ioremap ioremap
 
-#define ioremap_wc(offset, size)                \
-	__ioremap((offset), (size), _PAGE_WR_COMBINE)
+static inline void __iomem *ioremap_cache(resource_size_t offset, unsigned long size)
+{
+	return __ioremap(offset, size, _PAGE_CACHEABLE);
+}
+#define ioremap_cache ioremap_cache
+#define ioremap_cached ioremap_cache
 
-#define ioremap_wt(offset, size)                \
-	__ioremap((offset), (size), 0)
+static inline void __iomem *ioremap_wc(resource_size_t offset, unsigned long size)
+{
+	return __ioremap(offset, size, _PAGE_WR_COMBINE);
+}
+#define ioremap_wc ioremap_wc
 
-#define iounmap(addr)                           \
-	__iounmap(addr)
+static inline void iounmap(volatile void __iomem *addr)
+{
+	return __iounmap(addr);
+}
+#define iounmap iounmap
 
 #endif  /* _ASM_METAG_IO_H */
diff --git a/arch/microblaze/include/asm/io.h b/arch/microblaze/include/asm/io.h
index 39b6315db82e..60ca27d7dd1f 100644
--- a/arch/microblaze/include/asm/io.h
+++ b/arch/microblaze/include/asm/io.h
@@ -36,13 +36,7 @@ extern resource_size_t isa_mem_base;
 #ifdef CONFIG_MMU
 #define page_to_bus(page)	(page_to_phys(page))
 
-extern void iounmap(void __iomem *addr);
-
-extern void __iomem *ioremap(phys_addr_t address, unsigned long size);
-#define ioremap_nocache(addr, size)		ioremap((addr), (size))
 #define ioremap_fullcache(addr, size)		ioremap((addr), (size))
-#define ioremap_wc(addr, size)			ioremap((addr), (size))
-#define ioremap_wt(addr, size)			ioremap((addr), (size))
 
 #endif /* CONFIG_MMU */
 
diff --git a/arch/microblaze/mm/pgtable.c b/arch/microblaze/mm/pgtable.c
index 4f4520e779a5..2b47b34ff26c 100644
--- a/arch/microblaze/mm/pgtable.c
+++ b/arch/microblaze/mm/pgtable.c
@@ -126,7 +126,7 @@ void __iomem *ioremap(phys_addr_t addr, unsigned long size)
 }
 EXPORT_SYMBOL(ioremap);
 
-void iounmap(void __iomem *addr)
+void iounmap(volatile void __iomem *addr)
 {
 	if ((__force void *)addr > high_memory &&
 					(unsigned long) addr < ioremap_bot)
diff --git a/arch/mips/include/asm/io.h b/arch/mips/include/asm/io.h
index 9e777cd42b67..a907e634f914 100644
--- a/arch/mips/include/asm/io.h
+++ b/arch/mips/include/asm/io.h
@@ -232,30 +232,11 @@ static inline void __iomem * __ioremap_mode(phys_addr_t offset, unsigned long si
  * address is not guaranteed to be usable directly as a virtual
  * address.
  */
-#define ioremap(offset, size)						\
-	__ioremap_mode((offset), (size), _CACHE_UNCACHED)
-
-/*
- * ioremap_nocache     -   map bus memory into CPU space
- * @offset:    bus address of the memory
- * @size:      size of the resource to map
- *
- * ioremap_nocache performs a platform specific sequence of operations to
- * make bus memory CPU accessible via the readb/readw/readl/writeb/
- * writew/writel functions and the other mmio helpers. The returned
- * address is not guaranteed to be usable directly as a virtual
- * address.
- *
- * This version of ioremap ensures that the memory is marked uncachable
- * on the CPU as well as honouring existing caching rules from things like
- * the PCI bus. Note that there are other caches and buffers on many
- * busses. In particular driver authors should read up on PCI writes
- *
- * It's useful if some control registers are in such an area and
- * write combining or read caching is not desirable:
- */
-#define ioremap_nocache(offset, size)					\
-	__ioremap_mode((offset), (size), _CACHE_UNCACHED)
+static inline void __iomem *ioremap(resource_size_t offset, unsigned long size)
+{
+	return __ioremap_mode(offset, size, _CACHE_UNCACHED);
+}
+#define ioremap ioremap
 
 /*
  * ioremap_cachable -	map bus memory into CPU space
@@ -272,8 +253,14 @@ static inline void __iomem * __ioremap_mode(phys_addr_t offset, unsigned long si
  * the CPU.  Also enables full write-combining.	 Useful for some
  * memory-like regions on I/O busses.
  */
-#define ioremap_cachable(offset, size)					\
-	__ioremap_mode((offset), (size), _page_cachable_default)
+#define ioremap_cachable ioremap_cache
+extern unsigned long _page_cachable_default;
+static inline void __iomem *ioremap_cache(resource_size_t offset,
+		unsigned long size)
+{
+	return __ioremap_mode(offset, size, _page_cachable_default);
+}
+#define ioremap_cache ioremap_cache
 
 /*
  * These two are MIPS specific ioremap variant.	 ioremap_cacheable_cow
@@ -286,7 +273,7 @@ static inline void __iomem * __ioremap_mode(phys_addr_t offset, unsigned long si
 #define ioremap_uncached_accelerated(offset, size)			\
 	__ioremap_mode((offset), (size), _CACHE_UNCACHED_ACCELERATED)
 
-static inline void iounmap(const volatile void __iomem *addr)
+static inline void iounmap(volatile void __iomem *addr)
 {
 	if (plat_iounmap(addr))
 		return;
@@ -301,6 +288,7 @@ static inline void iounmap(const volatile void __iomem *addr)
 
 #undef __IS_KSEG1
 }
+#define iounmap iounmap
 
 #ifdef CONFIG_CPU_CAVIUM_OCTEON
 #define war_octeon_io_reorder_wmb()		wmb()
diff --git a/arch/mn10300/include/asm/io.h b/arch/mn10300/include/asm/io.h
index 07c5b4a3903b..48629631f718 100644
--- a/arch/mn10300/include/asm/io.h
+++ b/arch/mn10300/include/asm/io.h
@@ -266,27 +266,29 @@ static inline void __iomem *__ioremap(unsigned long offset, unsigned long size,
 	return (void __iomem *) offset;
 }
 
-static inline void __iomem *ioremap(unsigned long offset, unsigned long size)
+static inline void __iomem *ioremap(resource_size_t offset, unsigned long size)
 {
 	return (void __iomem *)(offset & ~0x20000000);
 }
+#define ioremap ioremap
 
 /*
  * This one maps high address device memory and turns off caching for that
  * area.  it's useful if some control registers are in such an area and write
  * combining or read caching is not desirable:
  */
-static inline void __iomem *ioremap_nocache(unsigned long offset, unsigned long size)
+static inline void __iomem *ioremap_nocache(resource_size_t offset, unsigned long size)
 {
 	return (void __iomem *) (offset | 0x20000000);
 }
-
+#define ioremap_nocache ioremap_nocache
 #define ioremap_wc ioremap_nocache
 #define ioremap_wt ioremap_nocache
 
-static inline void iounmap(void __iomem *addr)
+static inline void iounmap(volatile void __iomem *addr)
 {
 }
+#define iounmap iounmap
 
 static inline void __iomem *ioport_map(unsigned long port, unsigned int nr)
 {
diff --git a/arch/nios2/include/asm/io.h b/arch/nios2/include/asm/io.h
index c5a62da22cd2..161a63265813 100644
--- a/arch/nios2/include/asm/io.h
+++ b/arch/nios2/include/asm/io.h
@@ -29,24 +29,17 @@ extern void __iomem *__ioremap(unsigned long physaddr, unsigned long size,
 			unsigned long cacheflag);
 extern void __iounmap(void __iomem *addr);
 
-static inline void __iomem *ioremap(unsigned long physaddr, unsigned long size)
+static inline void __iomem *ioremap(resource_size_t physaddr, unsigned long size)
 {
 	return __ioremap(physaddr, size, 0);
 }
+#define ioremap ioremap
 
-static inline void __iomem *ioremap_nocache(unsigned long physaddr,
-						unsigned long size)
-{
-	return __ioremap(physaddr, size, 0);
-}
-
-static inline void iounmap(void __iomem *addr)
+static inline void iounmap(volatile void __iomem *addr)
 {
 	__iounmap(addr);
 }
-
-#define ioremap_wc ioremap_nocache
-#define ioremap_wt ioremap_nocache
+#define iounmap iounmap
 
 /* Pages to physical address... */
 #define page_to_phys(page)	virt_to_phys(page_to_virt(page))
diff --git a/arch/openrisc/include/asm/io.h b/arch/openrisc/include/asm/io.h
index 7c691399da3f..4f7636e7901d 100644
--- a/arch/openrisc/include/asm/io.h
+++ b/arch/openrisc/include/asm/io.h
@@ -39,6 +39,7 @@ static inline void __iomem *ioremap(phys_addr_t offset, unsigned long size)
 {
 	return __ioremap(offset, size, PAGE_KERNEL);
 }
+#define ioremap ioremap
 
 /* #define _PAGE_CI       0x002 */
 static inline void __iomem *ioremap_nocache(phys_addr_t offset,
@@ -47,6 +48,6 @@ static inline void __iomem *ioremap_nocache(phys_addr_t offset,
 	return __ioremap(offset, size,
 			 __pgprot(pgprot_val(PAGE_KERNEL) | _PAGE_CI));
 }
+#define ioremap_nocache ioremap_nocache
 
-extern void iounmap(void *addr);
 #endif
diff --git a/arch/openrisc/mm/ioremap.c b/arch/openrisc/mm/ioremap.c
index 62b08ef392be..2af1bbe5f80c 100644
--- a/arch/openrisc/mm/ioremap.c
+++ b/arch/openrisc/mm/ioremap.c
@@ -81,7 +81,7 @@ __ioremap(phys_addr_t addr, unsigned long size, pgprot_t prot)
 	return (void __iomem *)(offset + (char *)v);
 }
 
-void iounmap(void *addr)
+void iounmap(volatile void __iomem *addr)
 {
 	/* If the page is from the fixmap pool then we just clear out
 	 * the fixmap mapping.
diff --git a/arch/parisc/include/asm/io.h b/arch/parisc/include/asm/io.h
index 8cd0abf28ffb..8a4ecb47f960 100644
--- a/arch/parisc/include/asm/io.h
+++ b/arch/parisc/include/asm/io.h
@@ -132,13 +132,11 @@ extern void __iomem * __ioremap(unsigned long offset, unsigned long size, unsign
 /* Most machines react poorly to I/O-space being cacheable... Instead let's
  * define ioremap() in terms of ioremap_nocache().
  */
-static inline void __iomem * ioremap(unsigned long offset, unsigned long size)
+static inline void __iomem * ioremap(resource_size_t offset, unsigned long size)
 {
 	return __ioremap(offset, size, _PAGE_NO_CACHE);
 }
-#define ioremap_nocache(off, sz)	ioremap((off), (sz))
-
-extern void iounmap(const volatile void __iomem *addr);
+#define ioremap ioremap
 
 static inline unsigned char __raw_readb(const volatile void __iomem *addr)
 {
diff --git a/arch/parisc/mm/ioremap.c b/arch/parisc/mm/ioremap.c
index 838d0259cd27..3830d8af80a4 100644
--- a/arch/parisc/mm/ioremap.c
+++ b/arch/parisc/mm/ioremap.c
@@ -91,7 +91,7 @@ void __iomem * __ioremap(unsigned long phys_addr, unsigned long size, unsigned l
 }
 EXPORT_SYMBOL(__ioremap);
 
-void iounmap(const volatile void __iomem *addr)
+void iounmap(volatile void __iomem *addr)
 {
 	if (addr > high_memory)
 		return vfree((void *) (PAGE_MASK & (unsigned long __force) addr));
diff --git a/arch/powerpc/include/asm/io.h b/arch/powerpc/include/asm/io.h
index a8d2ef30d473..081f7d3d8913 100644
--- a/arch/powerpc/include/asm/io.h
+++ b/arch/powerpc/include/asm/io.h
@@ -2,8 +2,6 @@
 #define _ASM_POWERPC_IO_H
 #ifdef __KERNEL__
 
-#define ARCH_HAS_IOREMAP_WC
-
 /*
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License
@@ -25,7 +23,6 @@ extern struct pci_dev *isa_bridge_pcidev;
 #endif
 
 #include <linux/device.h>
-#include <linux/io.h>
 
 #include <linux/compiler.h>
 #include <asm/page.h>
@@ -717,12 +714,14 @@ static inline void iosync(void)
  *
  */
 extern void __iomem *ioremap(phys_addr_t address, unsigned long size);
+#define ioremap ioremap
 extern void __iomem *ioremap_prot(phys_addr_t address, unsigned long size,
 				  unsigned long flags);
 extern void __iomem *ioremap_wc(phys_addr_t address, unsigned long size);
-#define ioremap_nocache(addr, size)	ioremap((addr), (size))
+#define ioremap_wc ioremap_wc
 
 extern void iounmap(volatile void __iomem *addr);
+#define iounmap iounmap
 
 extern void __iomem *__ioremap(phys_addr_t, unsigned long size,
 			       unsigned long flags);
diff --git a/arch/s390/include/asm/io.h b/arch/s390/include/asm/io.h
index cb5fdf3a78fc..1cb32250d12b 100644
--- a/arch/s390/include/asm/io.h
+++ b/arch/s390/include/asm/io.h
@@ -27,18 +27,16 @@ void unxlate_dev_mem_ptr(phys_addr_t phys, void *addr);
 
 #ifdef CONFIG_PCI
 
-#define ioremap_nocache(addr, size)	ioremap(addr, size)
-#define ioremap_wc			ioremap_nocache
-#define ioremap_wt			ioremap_nocache
-
-static inline void __iomem *ioremap(unsigned long offset, unsigned long size)
+static inline void __iomem *ioremap(resource_size_t offset, unsigned long size)
 {
 	return (void __iomem *) offset;
 }
+#define ioremap ioremap
 
 static inline void iounmap(volatile void __iomem *addr)
 {
 }
+#define iounmap iounmap
 
 static inline void __iomem *ioport_map(unsigned long port, unsigned int nr)
 {
diff --git a/arch/sh/include/asm/io.h b/arch/sh/include/asm/io.h
index 728c4c571f40..5fd16fe8ecc9 100644
--- a/arch/sh/include/asm/io.h
+++ b/arch/sh/include/asm/io.h
@@ -336,12 +336,14 @@ static inline void __iomem *ioremap(phys_addr_t offset, unsigned long size)
 {
 	return __ioremap_mode(offset, size, PAGE_KERNEL_NOCACHE);
 }
+#define ioremap ioremap
 
 static inline void __iomem *
 ioremap_cache(phys_addr_t offset, unsigned long size)
 {
 	return __ioremap_mode(offset, size, PAGE_KERNEL);
 }
+#define ioremap_cache ioremap_cache
 
 #ifdef CONFIG_HAVE_IOREMAP_PROT
 static inline void __iomem *
@@ -367,8 +369,11 @@ static inline void ioremap_fixed_init(void) { }
 static inline int iounmap_fixed(void __iomem *addr) { return -EINVAL; }
 #endif
 
-#define ioremap_nocache	ioremap
-#define iounmap		__iounmap
+static inline void iounmap(volatile void __iomem *addr)
+{
+	__iounmap(addr);
+}
+#define iounmap	iounmap
 
 /*
  * Convert a physical pointer to a virtual kernel pointer for /dev/mem
diff --git a/arch/sparc/include/asm/io_32.h b/arch/sparc/include/asm/io_32.h
index 57f26c398dc9..138e47e0c7d2 100644
--- a/arch/sparc/include/asm/io_32.h
+++ b/arch/sparc/include/asm/io_32.h
@@ -126,11 +126,8 @@ static inline void sbus_memcpy_toio(volatile void __iomem *dst,
  * Bus number may be embedded in the higher bits of the physical address.
  * This is why we have no bus number argument to ioremap().
  */
-void __iomem *ioremap(unsigned long offset, unsigned long size);
-#define ioremap_nocache(X,Y)	ioremap((X),(Y))
-#define ioremap_wc(X,Y)		ioremap((X),(Y))
-#define ioremap_wt(X,Y)		ioremap((X),(Y))
-void iounmap(volatile void __iomem *addr);
+void __iomem *ioremap(resource_size_t offset, unsigned long size);
+#define ioremap ioremap
 
 /* Create a virtual mapping cookie for an IO port range */
 void __iomem *ioport_map(unsigned long port, unsigned int nr);
diff --git a/arch/sparc/include/asm/io_64.h b/arch/sparc/include/asm/io_64.h
index c32fa3f752c8..47e90988b562 100644
--- a/arch/sparc/include/asm/io_64.h
+++ b/arch/sparc/include/asm/io_64.h
@@ -395,18 +395,16 @@ static inline void memcpy_toio(volatile void __iomem *dst, const void *src,
 /* On sparc64 we have the whole physical IO address space accessible
  * using physically addressed loads and stores, so this does nothing.
  */
-static inline void __iomem *ioremap(unsigned long offset, unsigned long size)
+static inline void __iomem *ioremap(resource_size_t offset, unsigned long size)
 {
 	return (void __iomem *)offset;
 }
-
-#define ioremap_nocache(X,Y)		ioremap((X),(Y))
-#define ioremap_wc(X,Y)			ioremap((X),(Y))
-#define ioremap_wt(X,Y)			ioremap((X),(Y))
+#define ioremap ioremap
 
 static inline void iounmap(volatile void __iomem *addr)
 {
 }
+#define iounmap iounmap
 
 #define ioread8			readb
 #define ioread16		readw
diff --git a/arch/sparc/kernel/ioport.c b/arch/sparc/kernel/ioport.c
index 28fed53b13a0..b8c999f5b821 100644
--- a/arch/sparc/kernel/ioport.c
+++ b/arch/sparc/kernel/ioport.c
@@ -121,7 +121,7 @@ static void xres_free(struct xresource *xrp) {
  *
  * Bus type is always zero on IIep.
  */
-void __iomem *ioremap(unsigned long offset, unsigned long size)
+void __iomem *ioremap(resource_size_t offset, unsigned long size)
 {
 	char name[14];
 
diff --git a/arch/tile/include/asm/io.h b/arch/tile/include/asm/io.h
index dc61de15c1f9..bf7f0fffb8db 100644
--- a/arch/tile/include/asm/io.h
+++ b/arch/tile/include/asm/io.h
@@ -48,14 +48,19 @@ extern void __iomem *ioremap_prot(resource_size_t offset, unsigned long size,
 	pgprot_t pgprot);
 extern void iounmap(volatile void __iomem *addr);
 #else
-#define ioremap(physaddr, size)	((void __iomem *)(unsigned long)(physaddr))
-#define iounmap(addr)		((void)0)
+static inline void __iomem *ioremap(resource_size_t offset, unsigned long size)
+{
+	return (void __force __iomem *) offset;
+}
+
+static inline void iounmap(volatile void __iomem *addr)
+{
+}
 #endif
+#define ioremap ioremap
+#define iounmap iounmap
 
-#define ioremap_nocache(physaddr, size)		ioremap(physaddr, size)
-#define ioremap_wc(physaddr, size)		ioremap(physaddr, size)
-#define ioremap_wt(physaddr, size)		ioremap(physaddr, size)
-#define ioremap_fullcache(physaddr, size)	ioremap(physaddr, size)
+#define ioremap_fullcache ioremap
 
 #define mmiowb()
 
diff --git a/arch/unicore32/include/asm/io.h b/arch/unicore32/include/asm/io.h
index cb1d8fd2b16b..1088450fabfd 100644
--- a/arch/unicore32/include/asm/io.h
+++ b/arch/unicore32/include/asm/io.h
@@ -18,7 +18,6 @@
 #include <asm/memory.h>
 
 #define PCI_IOBASE	PKUNITY_PCILIO_BASE
-#include <asm-generic/io.h>
 
 /*
  * __uc32_ioremap and __uc32_ioremap_cached takes CPU physical address.
@@ -34,10 +33,26 @@ extern void __uc32_iounmap(volatile void __iomem *addr);
  * Documentation/io-mapping.txt.
  *
  */
-#define ioremap(cookie, size)		__uc32_ioremap(cookie, size)
-#define ioremap_cached(cookie, size)	__uc32_ioremap_cached(cookie, size)
-#define ioremap_nocache(cookie, size)	__uc32_ioremap(cookie, size)
-#define iounmap(cookie)			__uc32_iounmap(cookie)
+static inline void __iomem *ioremap(resource_size_t cookie, unsigned long size)
+{
+	return __uc32_ioremap(cookie, size);
+}
+#define ioremap ioremap
+
+static inline void __iomem *ioremap_cache(resource_size_t cookie, unsigned long size)
+{
+	return __uc32_ioremap_cached(cookie, size);
+}
+#define ioremap_cache ioremap_cache
+#define ioremap_cached ioremap_cached
+
+static inline void iounmap(volatile void __iomem *addr)
+{
+	return __uc32_iounmap(addr);
+}
+#define iounmap iounmap
+
+#include <asm-generic/io.h>
 
 #define readb_relaxed readb
 #define readw_relaxed readw
diff --git a/arch/x86/include/asm/io.h b/arch/x86/include/asm/io.h
index 83ec9b1d77cc..97ae3b748d9e 100644
--- a/arch/x86/include/asm/io.h
+++ b/arch/x86/include/asm/io.h
@@ -34,9 +34,6 @@
   *  - Arnaldo Carvalho de Melo <acme@conectiva.com.br>
   */
 
-#define ARCH_HAS_IOREMAP_WC
-#define ARCH_HAS_IOREMAP_WT
-
 #include <linux/string.h>
 #include <linux/compiler.h>
 #include <asm/page.h>
@@ -179,8 +176,10 @@ static inline unsigned int isa_virt_to_bus(volatile void *address)
  * look at pci_iomap().
  */
 extern void __iomem *ioremap_nocache(resource_size_t offset, unsigned long size);
+#define ioremap_nocache ioremap_nocache
 extern void __iomem *ioremap_uc(resource_size_t offset, unsigned long size);
 extern void __iomem *ioremap_cache(resource_size_t offset, unsigned long size);
+#define ioremap_cache ioremap_cache
 extern void __iomem *ioremap_prot(resource_size_t offset, unsigned long size,
 				unsigned long prot_val);
 
@@ -191,8 +190,10 @@ static inline void __iomem *ioremap(resource_size_t offset, unsigned long size)
 {
 	return ioremap_nocache(offset, size);
 }
+#define ioremap ioremap
 
 extern void iounmap(volatile void __iomem *addr);
+#define iounmap iounmap
 
 extern void set_iounmap_nonlazy(void);
 
@@ -321,7 +322,9 @@ extern void unxlate_dev_mem_ptr(phys_addr_t phys, void *addr);
 extern int ioremap_change_attr(unsigned long vaddr, unsigned long size,
 				enum page_cache_mode pcm);
 extern void __iomem *ioremap_wc(resource_size_t offset, unsigned long size);
+#define ioremap_wc ioremap_wc
 extern void __iomem *ioremap_wt(resource_size_t offset, unsigned long size);
+#define ioremap_wt ioremap_wt
 
 extern bool is_early_ioremap_ptep(pte_t *ptep);
 
diff --git a/arch/xtensa/include/asm/io.h b/arch/xtensa/include/asm/io.h
index c39bb6e61911..ae20fc5a1b5f 100644
--- a/arch/xtensa/include/asm/io.h
+++ b/arch/xtensa/include/asm/io.h
@@ -38,7 +38,7 @@ static inline unsigned long xtensa_get_kio_paddr(void)
  * Return the virtual address for the specified bus memory.
  * Note that we currently don't support any address outside the KIO segment.
  */
-static inline void __iomem *ioremap_nocache(unsigned long offset,
+static inline void __iomem *ioremap_nocache(resource_size_t offset,
 		unsigned long size)
 {
 	if (offset >= XCHAL_KIO_PADDR
@@ -47,8 +47,9 @@ static inline void __iomem *ioremap_nocache(unsigned long offset,
 	else
 		BUG();
 }
+#define ioremap_nocache ioremap_nocache
 
-static inline void __iomem *ioremap_cache(unsigned long offset,
+static inline void __iomem *ioremap_cache(resource_size_t offset,
 		unsigned long size)
 {
 	if (offset >= XCHAL_KIO_PADDR
@@ -57,18 +58,18 @@ static inline void __iomem *ioremap_cache(unsigned long offset,
 	else
 		BUG();
 }
+#define ioremap_cache ioremap_cache
 
-#define ioremap_wc ioremap_nocache
-#define ioremap_wt ioremap_nocache
-
-static inline void __iomem *ioremap(unsigned long offset, unsigned long size)
+static inline void __iomem *ioremap(resource_size_t offset, unsigned long size)
 {
 	return ioremap_nocache(offset, size);
 }
+#define ioremap ioremap
 
 static inline void iounmap(volatile void __iomem *addr)
 {
 }
+#define iounmap iounmap
 
 #define virt_to_bus     virt_to_phys
 #define bus_to_virt     phys_to_virt
diff --git a/drivers/net/ethernet/sfc/io.h b/drivers/net/ethernet/sfc/io.h
index afb94aa2c15e..9d54dd7f4c72 100644
--- a/drivers/net/ethernet/sfc/io.h
+++ b/drivers/net/ethernet/sfc/io.h
@@ -73,7 +73,7 @@
  */
 #ifdef CONFIG_X86_64
 /* PIO is a win only if write-combining is possible */
-#ifdef ARCH_HAS_IOREMAP_WC
+#ifdef ioremap_wc
 #define EFX_USE_PIO 1
 #endif
 #endif
diff --git a/include/asm-generic/iomap.h b/include/asm-generic/iomap.h
index d8f8622fa044..4789b1cec313 100644
--- a/include/asm-generic/iomap.h
+++ b/include/asm-generic/iomap.h
@@ -62,14 +62,6 @@ extern void __iomem *ioport_map(unsigned long port, unsigned int nr);
 extern void ioport_unmap(void __iomem *);
 #endif
 
-#ifndef ARCH_HAS_IOREMAP_WC
-#define ioremap_wc ioremap_nocache
-#endif
-
-#ifndef ARCH_HAS_IOREMAP_WT
-#define ioremap_wt ioremap_nocache
-#endif
-
 #ifdef CONFIG_PCI
 /* Destroy a virtual mapping cookie for a PCI BAR (memory or IO) */
 struct pci_dev;
diff --git a/include/linux/io.h b/include/linux/io.h
index fb5a99800e77..41e93fe14b3c 100644
--- a/include/linux/io.h
+++ b/include/linux/io.h
@@ -80,6 +80,64 @@ int check_signature(const volatile void __iomem *io_addr,
 			const unsigned char *signature, int length);
 void devm_ioremap_release(struct device *dev, void *res);
 
+#ifndef ioremap
+void __iomem *ioremap(resource_size_t offset, unsigned long size);
+#endif
+
+#ifndef iounmap
+void iounmap(volatile void __iomem *addr);
+#endif
+
+#ifndef ioremap_nocache
+static inline void __iomem *ioremap_nocache(resource_size_t offset,
+		unsigned long size)
+{
+	return ioremap(offset, size);
+}
+#endif
+
+#ifndef ioremap_wc
+static inline void __iomem *ioremap_wc(resource_size_t offset,
+		unsigned long size)
+{
+	return ioremap(offset, size);
+}
+#endif
+
+#ifndef ioremap_wt
+static inline void __iomem *ioremap_wt(resource_size_t offset,
+		unsigned long size)
+{
+	return ioremap(offset, size);
+}
+#endif
+
+#ifndef ioremap_cache
+static inline void __iomem *ioremap_cache(resource_size_t offset,
+		unsigned long size)
+{
+	return ioremap(offset, size);
+}
+#endif
+
+/*
+ * Throw warnings if an arch fails to define or uses unexpected data
+ * types in its ioremap implementations.
+ */
+static inline void ioremap_test(void)
+{
+	void __iomem *(*map)(resource_size_t offset, unsigned long size)
+		__always_unused;
+	void (*unmap)(volatile void __iomem *addr) __always_unused;
+
+	map = ioremap;
+	map = ioremap_nocache;
+	map = ioremap_cache;
+	map = ioremap_wc;
+	map = ioremap_wt;
+	unmap = iounmap;
+}
+
 /*
  * Some systems do not have legacy ISA devices.
  * /dev/port is not a valid interface on these systems.

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
Please read the FAQ at  http://www.tux.org/lkml/

^ permalink raw reply related	[flat|nested] 85+ messages in thread

* [PATCH v5 3/6] cleanup IORESOURCE_CACHEABLE vs ioremap()
  2015-06-22  8:24 ` Dan Williams
@ 2015-06-22  8:24   ` Dan Williams
  -1 siblings, 0 replies; 85+ messages in thread
From: Dan Williams @ 2015-06-22  8:24 UTC (permalink / raw)
  To: arnd, mingo, bp, hpa, tglx, ross.zwisler, akpm
  Cc: jgross, x86, toshi.kani, linux-nvdimm, benh, mcgrof, konrad.wilk,
	linux-kernel, stefan.bader, luto, linux-mm, geert, ralf, hmh,
	mpe, tj, paulus, hch

Quoting Arnd:
    I was thinking the opposite approach and basically removing all uses
    of IORESOURCE_CACHEABLE from the kernel. There are only a handful of
    them.and we can probably replace them all with hardcoded
    ioremap_cached() calls in the cases they are actually useful.

All existing usages of IORESOURCE_CACHEABLE call ioremap() instead of
ioremap_nocache() if the resource is cacheable, however ioremap() is
uncached by default.  Clearly none of the existing usages care about the
cacheability, so let's clean that up before introducing generic
ioremap_cache() support across architectures.

Suggested-by: Arnd Bergmann <arnd@arndb.de>
Signed-off-by: Dan Williams <dan.j.williams@intel.com>
---
 arch/arm/mach-clps711x/board-cdb89712.c |    2 +-
 arch/powerpc/kernel/pci_of_scan.c       |    2 +-
 arch/sparc/kernel/pci.c                 |    3 +--
 drivers/pci/probe.c                     |    3 +--
 drivers/pnp/manager.c                   |    2 --
 drivers/scsi/aic94xx/aic94xx_init.c     |    7 +------
 drivers/scsi/arcmsr/arcmsr_hba.c        |    5 +----
 drivers/scsi/mvsas/mv_init.c            |   15 ++++-----------
 drivers/video/fbdev/ocfb.c              |    1 -
 lib/devres.c                            |    7 ++-----
 lib/pci_iomap.c                         |    7 ++-----
 11 files changed, 14 insertions(+), 40 deletions(-)

diff --git a/arch/arm/mach-clps711x/board-cdb89712.c b/arch/arm/mach-clps711x/board-cdb89712.c
index 1ec378c334e5..972abdb10028 100644
--- a/arch/arm/mach-clps711x/board-cdb89712.c
+++ b/arch/arm/mach-clps711x/board-cdb89712.c
@@ -95,7 +95,7 @@ static struct physmap_flash_data cdb89712_bootrom_pdata __initdata = {
 
 static struct resource cdb89712_bootrom_resources[] __initdata = {
 	DEFINE_RES_NAMED(CS7_PHYS_BASE, SZ_128, "BOOTROM", IORESOURCE_MEM |
-			 IORESOURCE_CACHEABLE | IORESOURCE_READONLY),
+			 IORESOURCE_READONLY),
 };
 
 static struct platform_device cdb89712_bootrom_pdev __initdata = {
diff --git a/arch/powerpc/kernel/pci_of_scan.c b/arch/powerpc/kernel/pci_of_scan.c
index 42e02a2d570b..d4726addff0b 100644
--- a/arch/powerpc/kernel/pci_of_scan.c
+++ b/arch/powerpc/kernel/pci_of_scan.c
@@ -102,7 +102,7 @@ static void of_pci_parse_addrs(struct device_node *node, struct pci_dev *dev)
 			res = &dev->resource[(i - PCI_BASE_ADDRESS_0) >> 2];
 		} else if (i == dev->rom_base_reg) {
 			res = &dev->resource[PCI_ROM_RESOURCE];
-			flags |= IORESOURCE_READONLY | IORESOURCE_CACHEABLE;
+			flags |= IORESOURCE_READONLY;
 		} else {
 			printk(KERN_ERR "PCI: bad cfg reg num 0x%x\n", i);
 			continue;
diff --git a/arch/sparc/kernel/pci.c b/arch/sparc/kernel/pci.c
index c928bc64b4ba..04da147e0712 100644
--- a/arch/sparc/kernel/pci.c
+++ b/arch/sparc/kernel/pci.c
@@ -231,8 +231,7 @@ static void pci_parse_of_addrs(struct platform_device *op,
 			res = &dev->resource[(i - PCI_BASE_ADDRESS_0) >> 2];
 		} else if (i == dev->rom_base_reg) {
 			res = &dev->resource[PCI_ROM_RESOURCE];
-			flags |= IORESOURCE_READONLY | IORESOURCE_CACHEABLE
-			      | IORESOURCE_SIZEALIGN;
+			flags |= IORESOURCE_READONLY | IORESOURCE_SIZEALIGN;
 		} else {
 			printk(KERN_ERR "PCI: bad cfg reg num 0x%x\n", i);
 			continue;
diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c
index 6675a7a1b9fc..bbc7f8f86051 100644
--- a/drivers/pci/probe.c
+++ b/drivers/pci/probe.c
@@ -326,8 +326,7 @@ static void pci_read_bases(struct pci_dev *dev, unsigned int howmany, int rom)
 		struct resource *res = &dev->resource[PCI_ROM_RESOURCE];
 		dev->rom_base_reg = rom;
 		res->flags = IORESOURCE_MEM | IORESOURCE_PREFETCH |
-				IORESOURCE_READONLY | IORESOURCE_CACHEABLE |
-				IORESOURCE_SIZEALIGN;
+				IORESOURCE_READONLY | IORESOURCE_SIZEALIGN;
 		__pci_read_base(dev, pci_bar_mem32, res, rom);
 	}
 }
diff --git a/drivers/pnp/manager.c b/drivers/pnp/manager.c
index 9357aa779048..7ad3295752ef 100644
--- a/drivers/pnp/manager.c
+++ b/drivers/pnp/manager.c
@@ -97,8 +97,6 @@ static int pnp_assign_mem(struct pnp_dev *dev, struct pnp_mem *rule, int idx)
 	/* ??? rule->flags restricted to 8 bits, all tests bogus ??? */
 	if (!(rule->flags & IORESOURCE_MEM_WRITEABLE))
 		res->flags |= IORESOURCE_READONLY;
-	if (rule->flags & IORESOURCE_MEM_CACHEABLE)
-		res->flags |= IORESOURCE_CACHEABLE;
 	if (rule->flags & IORESOURCE_MEM_RANGELENGTH)
 		res->flags |= IORESOURCE_RANGELENGTH;
 	if (rule->flags & IORESOURCE_MEM_SHADOWABLE)
diff --git a/drivers/scsi/aic94xx/aic94xx_init.c b/drivers/scsi/aic94xx/aic94xx_init.c
index 02a2512b76a8..1058a7b1e334 100644
--- a/drivers/scsi/aic94xx/aic94xx_init.c
+++ b/drivers/scsi/aic94xx/aic94xx_init.c
@@ -101,12 +101,7 @@ static int asd_map_memio(struct asd_ha_struct *asd_ha)
 				   pci_name(asd_ha->pcidev));
 			goto Err;
 		}
-		if (io_handle->flags & IORESOURCE_CACHEABLE)
-			io_handle->addr = ioremap(io_handle->start,
-						  io_handle->len);
-		else
-			io_handle->addr = ioremap_nocache(io_handle->start,
-							  io_handle->len);
+		io_handle->addr = ioremap(io_handle->start, io_handle->len);
 		if (!io_handle->addr) {
 			asd_printk("couldn't map MBAR%d of %s\n", i==0?0:1,
 				   pci_name(asd_ha->pcidev));
diff --git a/drivers/scsi/arcmsr/arcmsr_hba.c b/drivers/scsi/arcmsr/arcmsr_hba.c
index 914c39f9f388..e4f77cad9fd8 100644
--- a/drivers/scsi/arcmsr/arcmsr_hba.c
+++ b/drivers/scsi/arcmsr/arcmsr_hba.c
@@ -259,10 +259,7 @@ static bool arcmsr_remap_pciregion(struct AdapterControlBlock *acb)
 		addr = (unsigned long)pci_resource_start(pdev, 0);
 		range = pci_resource_len(pdev, 0);
 		flags = pci_resource_flags(pdev, 0);
-		if (flags & IORESOURCE_CACHEABLE)
-			mem_base0 = ioremap(addr, range);
-		else
-			mem_base0 = ioremap_nocache(addr, range);
+		mem_base0 = ioremap(addr, range);
 		if (!mem_base0) {
 			pr_notice("arcmsr%d: memory mapping region fail\n",
 				acb->host->host_no);
diff --git a/drivers/scsi/mvsas/mv_init.c b/drivers/scsi/mvsas/mv_init.c
index 53030b0e8015..c01ef5f538b1 100644
--- a/drivers/scsi/mvsas/mv_init.c
+++ b/drivers/scsi/mvsas/mv_init.c
@@ -325,13 +325,9 @@ int mvs_ioremap(struct mvs_info *mvi, int bar, int bar_ex)
 			goto err_out;
 
 		res_flag_ex = pci_resource_flags(pdev, bar_ex);
-		if (res_flag_ex & IORESOURCE_MEM) {
-			if (res_flag_ex & IORESOURCE_CACHEABLE)
-				mvi->regs_ex = ioremap(res_start, res_len);
-			else
-				mvi->regs_ex = ioremap_nocache(res_start,
-						res_len);
-		} else
+		if (res_flag_ex & IORESOURCE_MEM)
+			mvi->regs_ex = ioremap(res_start, res_len);
+		else
 			mvi->regs_ex = (void *)res_start;
 		if (!mvi->regs_ex)
 			goto err_out;
@@ -343,10 +339,7 @@ int mvs_ioremap(struct mvs_info *mvi, int bar, int bar_ex)
 		goto err_out;
 
 	res_flag = pci_resource_flags(pdev, bar);
-	if (res_flag & IORESOURCE_CACHEABLE)
-		mvi->regs = ioremap(res_start, res_len);
-	else
-		mvi->regs = ioremap_nocache(res_start, res_len);
+	mvi->regs = ioremap(res_start, res_len);
 
 	if (!mvi->regs) {
 		if (mvi->regs_ex && (res_flag_ex & IORESOURCE_MEM))
diff --git a/drivers/video/fbdev/ocfb.c b/drivers/video/fbdev/ocfb.c
index de9819660ca0..c9293aea8ec3 100644
--- a/drivers/video/fbdev/ocfb.c
+++ b/drivers/video/fbdev/ocfb.c
@@ -325,7 +325,6 @@ static int ocfb_probe(struct platform_device *pdev)
 		dev_err(&pdev->dev, "I/O resource request failed\n");
 		return -ENXIO;
 	}
-	res->flags &= ~IORESOURCE_CACHEABLE;
 	fbdev->regs = devm_ioremap_resource(&pdev->dev, res);
 	if (IS_ERR(fbdev->regs))
 		return PTR_ERR(fbdev->regs);
diff --git a/lib/devres.c b/lib/devres.c
index fbe2aac522e6..f4001d90d24d 100644
--- a/lib/devres.c
+++ b/lib/devres.c
@@ -153,11 +153,8 @@ void __iomem *devm_ioremap_resource(struct device *dev, struct resource *res)
 		return IOMEM_ERR_PTR(-EBUSY);
 	}
 
-	if (res->flags & IORESOURCE_CACHEABLE)
-		dest_ptr = devm_ioremap(dev, res->start, size);
-	else
-		dest_ptr = devm_ioremap_nocache(dev, res->start, size);
-
+	/* FIXME: add devm_ioremap_cache support */
+	dest_ptr = devm_ioremap(dev, res->start, size);
 	if (!dest_ptr) {
 		dev_err(dev, "ioremap failed for resource %pR\n", res);
 		devm_release_mem_region(dev, res->start, size);
diff --git a/lib/pci_iomap.c b/lib/pci_iomap.c
index bcce5f149310..e1930dbab2da 100644
--- a/lib/pci_iomap.c
+++ b/lib/pci_iomap.c
@@ -41,11 +41,8 @@ void __iomem *pci_iomap_range(struct pci_dev *dev,
 		len = maxlen;
 	if (flags & IORESOURCE_IO)
 		return __pci_ioport_map(dev, start, len);
-	if (flags & IORESOURCE_MEM) {
-		if (flags & IORESOURCE_CACHEABLE)
-			return ioremap(start, len);
-		return ioremap_nocache(start, len);
-	}
+	if (flags & IORESOURCE_MEM)
+		return ioremap(start, len);
 	/* What? */
 	return NULL;
 }

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org.  For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>

^ permalink raw reply related	[flat|nested] 85+ messages in thread

* [PATCH v5 3/6] cleanup IORESOURCE_CACHEABLE vs ioremap()
@ 2015-06-22  8:24   ` Dan Williams
  0 siblings, 0 replies; 85+ messages in thread
From: Dan Williams @ 2015-06-22  8:24 UTC (permalink / raw)
  To: arnd, mingo, bp, hpa, tglx, ross.zwisler, akpm
  Cc: jgross, x86, toshi.kani, linux-nvdimm, benh, mcgrof, konrad.wilk,
	linux-kernel, stefan.bader, luto, linux-mm, geert, ralf, hmh,
	mpe, tj, paulus, hch

Quoting Arnd:
    I was thinking the opposite approach and basically removing all uses
    of IORESOURCE_CACHEABLE from the kernel. There are only a handful of
    them.and we can probably replace them all with hardcoded
    ioremap_cached() calls in the cases they are actually useful.

All existing usages of IORESOURCE_CACHEABLE call ioremap() instead of
ioremap_nocache() if the resource is cacheable, however ioremap() is
uncached by default.  Clearly none of the existing usages care about the
cacheability, so let's clean that up before introducing generic
ioremap_cache() support across architectures.

Suggested-by: Arnd Bergmann <arnd@arndb.de>
Signed-off-by: Dan Williams <dan.j.williams@intel.com>
---
 arch/arm/mach-clps711x/board-cdb89712.c |    2 +-
 arch/powerpc/kernel/pci_of_scan.c       |    2 +-
 arch/sparc/kernel/pci.c                 |    3 +--
 drivers/pci/probe.c                     |    3 +--
 drivers/pnp/manager.c                   |    2 --
 drivers/scsi/aic94xx/aic94xx_init.c     |    7 +------
 drivers/scsi/arcmsr/arcmsr_hba.c        |    5 +----
 drivers/scsi/mvsas/mv_init.c            |   15 ++++-----------
 drivers/video/fbdev/ocfb.c              |    1 -
 lib/devres.c                            |    7 ++-----
 lib/pci_iomap.c                         |    7 ++-----
 11 files changed, 14 insertions(+), 40 deletions(-)

diff --git a/arch/arm/mach-clps711x/board-cdb89712.c b/arch/arm/mach-clps711x/board-cdb89712.c
index 1ec378c334e5..972abdb10028 100644
--- a/arch/arm/mach-clps711x/board-cdb89712.c
+++ b/arch/arm/mach-clps711x/board-cdb89712.c
@@ -95,7 +95,7 @@ static struct physmap_flash_data cdb89712_bootrom_pdata __initdata = {
 
 static struct resource cdb89712_bootrom_resources[] __initdata = {
 	DEFINE_RES_NAMED(CS7_PHYS_BASE, SZ_128, "BOOTROM", IORESOURCE_MEM |
-			 IORESOURCE_CACHEABLE | IORESOURCE_READONLY),
+			 IORESOURCE_READONLY),
 };
 
 static struct platform_device cdb89712_bootrom_pdev __initdata = {
diff --git a/arch/powerpc/kernel/pci_of_scan.c b/arch/powerpc/kernel/pci_of_scan.c
index 42e02a2d570b..d4726addff0b 100644
--- a/arch/powerpc/kernel/pci_of_scan.c
+++ b/arch/powerpc/kernel/pci_of_scan.c
@@ -102,7 +102,7 @@ static void of_pci_parse_addrs(struct device_node *node, struct pci_dev *dev)
 			res = &dev->resource[(i - PCI_BASE_ADDRESS_0) >> 2];
 		} else if (i == dev->rom_base_reg) {
 			res = &dev->resource[PCI_ROM_RESOURCE];
-			flags |= IORESOURCE_READONLY | IORESOURCE_CACHEABLE;
+			flags |= IORESOURCE_READONLY;
 		} else {
 			printk(KERN_ERR "PCI: bad cfg reg num 0x%x\n", i);
 			continue;
diff --git a/arch/sparc/kernel/pci.c b/arch/sparc/kernel/pci.c
index c928bc64b4ba..04da147e0712 100644
--- a/arch/sparc/kernel/pci.c
+++ b/arch/sparc/kernel/pci.c
@@ -231,8 +231,7 @@ static void pci_parse_of_addrs(struct platform_device *op,
 			res = &dev->resource[(i - PCI_BASE_ADDRESS_0) >> 2];
 		} else if (i == dev->rom_base_reg) {
 			res = &dev->resource[PCI_ROM_RESOURCE];
-			flags |= IORESOURCE_READONLY | IORESOURCE_CACHEABLE
-			      | IORESOURCE_SIZEALIGN;
+			flags |= IORESOURCE_READONLY | IORESOURCE_SIZEALIGN;
 		} else {
 			printk(KERN_ERR "PCI: bad cfg reg num 0x%x\n", i);
 			continue;
diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c
index 6675a7a1b9fc..bbc7f8f86051 100644
--- a/drivers/pci/probe.c
+++ b/drivers/pci/probe.c
@@ -326,8 +326,7 @@ static void pci_read_bases(struct pci_dev *dev, unsigned int howmany, int rom)
 		struct resource *res = &dev->resource[PCI_ROM_RESOURCE];
 		dev->rom_base_reg = rom;
 		res->flags = IORESOURCE_MEM | IORESOURCE_PREFETCH |
-				IORESOURCE_READONLY | IORESOURCE_CACHEABLE |
-				IORESOURCE_SIZEALIGN;
+				IORESOURCE_READONLY | IORESOURCE_SIZEALIGN;
 		__pci_read_base(dev, pci_bar_mem32, res, rom);
 	}
 }
diff --git a/drivers/pnp/manager.c b/drivers/pnp/manager.c
index 9357aa779048..7ad3295752ef 100644
--- a/drivers/pnp/manager.c
+++ b/drivers/pnp/manager.c
@@ -97,8 +97,6 @@ static int pnp_assign_mem(struct pnp_dev *dev, struct pnp_mem *rule, int idx)
 	/* ??? rule->flags restricted to 8 bits, all tests bogus ??? */
 	if (!(rule->flags & IORESOURCE_MEM_WRITEABLE))
 		res->flags |= IORESOURCE_READONLY;
-	if (rule->flags & IORESOURCE_MEM_CACHEABLE)
-		res->flags |= IORESOURCE_CACHEABLE;
 	if (rule->flags & IORESOURCE_MEM_RANGELENGTH)
 		res->flags |= IORESOURCE_RANGELENGTH;
 	if (rule->flags & IORESOURCE_MEM_SHADOWABLE)
diff --git a/drivers/scsi/aic94xx/aic94xx_init.c b/drivers/scsi/aic94xx/aic94xx_init.c
index 02a2512b76a8..1058a7b1e334 100644
--- a/drivers/scsi/aic94xx/aic94xx_init.c
+++ b/drivers/scsi/aic94xx/aic94xx_init.c
@@ -101,12 +101,7 @@ static int asd_map_memio(struct asd_ha_struct *asd_ha)
 				   pci_name(asd_ha->pcidev));
 			goto Err;
 		}
-		if (io_handle->flags & IORESOURCE_CACHEABLE)
-			io_handle->addr = ioremap(io_handle->start,
-						  io_handle->len);
-		else
-			io_handle->addr = ioremap_nocache(io_handle->start,
-							  io_handle->len);
+		io_handle->addr = ioremap(io_handle->start, io_handle->len);
 		if (!io_handle->addr) {
 			asd_printk("couldn't map MBAR%d of %s\n", i==0?0:1,
 				   pci_name(asd_ha->pcidev));
diff --git a/drivers/scsi/arcmsr/arcmsr_hba.c b/drivers/scsi/arcmsr/arcmsr_hba.c
index 914c39f9f388..e4f77cad9fd8 100644
--- a/drivers/scsi/arcmsr/arcmsr_hba.c
+++ b/drivers/scsi/arcmsr/arcmsr_hba.c
@@ -259,10 +259,7 @@ static bool arcmsr_remap_pciregion(struct AdapterControlBlock *acb)
 		addr = (unsigned long)pci_resource_start(pdev, 0);
 		range = pci_resource_len(pdev, 0);
 		flags = pci_resource_flags(pdev, 0);
-		if (flags & IORESOURCE_CACHEABLE)
-			mem_base0 = ioremap(addr, range);
-		else
-			mem_base0 = ioremap_nocache(addr, range);
+		mem_base0 = ioremap(addr, range);
 		if (!mem_base0) {
 			pr_notice("arcmsr%d: memory mapping region fail\n",
 				acb->host->host_no);
diff --git a/drivers/scsi/mvsas/mv_init.c b/drivers/scsi/mvsas/mv_init.c
index 53030b0e8015..c01ef5f538b1 100644
--- a/drivers/scsi/mvsas/mv_init.c
+++ b/drivers/scsi/mvsas/mv_init.c
@@ -325,13 +325,9 @@ int mvs_ioremap(struct mvs_info *mvi, int bar, int bar_ex)
 			goto err_out;
 
 		res_flag_ex = pci_resource_flags(pdev, bar_ex);
-		if (res_flag_ex & IORESOURCE_MEM) {
-			if (res_flag_ex & IORESOURCE_CACHEABLE)
-				mvi->regs_ex = ioremap(res_start, res_len);
-			else
-				mvi->regs_ex = ioremap_nocache(res_start,
-						res_len);
-		} else
+		if (res_flag_ex & IORESOURCE_MEM)
+			mvi->regs_ex = ioremap(res_start, res_len);
+		else
 			mvi->regs_ex = (void *)res_start;
 		if (!mvi->regs_ex)
 			goto err_out;
@@ -343,10 +339,7 @@ int mvs_ioremap(struct mvs_info *mvi, int bar, int bar_ex)
 		goto err_out;
 
 	res_flag = pci_resource_flags(pdev, bar);
-	if (res_flag & IORESOURCE_CACHEABLE)
-		mvi->regs = ioremap(res_start, res_len);
-	else
-		mvi->regs = ioremap_nocache(res_start, res_len);
+	mvi->regs = ioremap(res_start, res_len);
 
 	if (!mvi->regs) {
 		if (mvi->regs_ex && (res_flag_ex & IORESOURCE_MEM))
diff --git a/drivers/video/fbdev/ocfb.c b/drivers/video/fbdev/ocfb.c
index de9819660ca0..c9293aea8ec3 100644
--- a/drivers/video/fbdev/ocfb.c
+++ b/drivers/video/fbdev/ocfb.c
@@ -325,7 +325,6 @@ static int ocfb_probe(struct platform_device *pdev)
 		dev_err(&pdev->dev, "I/O resource request failed\n");
 		return -ENXIO;
 	}
-	res->flags &= ~IORESOURCE_CACHEABLE;
 	fbdev->regs = devm_ioremap_resource(&pdev->dev, res);
 	if (IS_ERR(fbdev->regs))
 		return PTR_ERR(fbdev->regs);
diff --git a/lib/devres.c b/lib/devres.c
index fbe2aac522e6..f4001d90d24d 100644
--- a/lib/devres.c
+++ b/lib/devres.c
@@ -153,11 +153,8 @@ void __iomem *devm_ioremap_resource(struct device *dev, struct resource *res)
 		return IOMEM_ERR_PTR(-EBUSY);
 	}
 
-	if (res->flags & IORESOURCE_CACHEABLE)
-		dest_ptr = devm_ioremap(dev, res->start, size);
-	else
-		dest_ptr = devm_ioremap_nocache(dev, res->start, size);
-
+	/* FIXME: add devm_ioremap_cache support */
+	dest_ptr = devm_ioremap(dev, res->start, size);
 	if (!dest_ptr) {
 		dev_err(dev, "ioremap failed for resource %pR\n", res);
 		devm_release_mem_region(dev, res->start, size);
diff --git a/lib/pci_iomap.c b/lib/pci_iomap.c
index bcce5f149310..e1930dbab2da 100644
--- a/lib/pci_iomap.c
+++ b/lib/pci_iomap.c
@@ -41,11 +41,8 @@ void __iomem *pci_iomap_range(struct pci_dev *dev,
 		len = maxlen;
 	if (flags & IORESOURCE_IO)
 		return __pci_ioport_map(dev, start, len);
-	if (flags & IORESOURCE_MEM) {
-		if (flags & IORESOURCE_CACHEABLE)
-			return ioremap(start, len);
-		return ioremap_nocache(start, len);
-	}
+	if (flags & IORESOURCE_MEM)
+		return ioremap(start, len);
 	/* What? */
 	return NULL;
 }

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
Please read the FAQ at  http://www.tux.org/lkml/

^ permalink raw reply related	[flat|nested] 85+ messages in thread

* [PATCH v5 4/6] devm: fix ioremap_cache() usage
  2015-06-22  8:24 ` Dan Williams
@ 2015-06-22  8:24   ` Dan Williams
  -1 siblings, 0 replies; 85+ messages in thread
From: Dan Williams @ 2015-06-22  8:24 UTC (permalink / raw)
  To: arnd, mingo, bp, hpa, tglx, ross.zwisler, akpm
  Cc: jgross, x86, toshi.kani, linux-nvdimm, benh, mcgrof, konrad.wilk,
	linux-kernel, stefan.bader, luto, linux-mm, geert, ralf, hmh,
	mpe, tj, paulus, hch

Provide devm_ioremap_cache() and fix up devm_ioremap_resource() to
actually provide cacheable mappings.  On archs that implement
ioremap_cache() devm_ioremap_resource() is always silently falling back
to uncached when IORESOURCE_CACHEABLE is specified.

Cc: Toshi Kani <toshi.kani@hp.com>
Cc: Arnd Bergmann <arnd@arndb.de>
Signed-off-by: Dan Williams <dan.j.williams@intel.com>
---
 include/linux/io.h |    2 ++
 lib/devres.c       |   53 +++++++++++++++++++++++++---------------------------
 2 files changed, 27 insertions(+), 28 deletions(-)

diff --git a/include/linux/io.h b/include/linux/io.h
index 41e93fe14b3c..8789a114f37c 100644
--- a/include/linux/io.h
+++ b/include/linux/io.h
@@ -71,6 +71,8 @@ static inline void devm_ioport_unmap(struct device *dev, void __iomem *addr)
 
 void __iomem *devm_ioremap(struct device *dev, resource_size_t offset,
 			   resource_size_t size);
+void __iomem *devm_ioremap_cache(struct device *dev, resource_size_t offset,
+			   resource_size_t size);
 void __iomem *devm_ioremap_nocache(struct device *dev, resource_size_t offset,
 				   resource_size_t size);
 void __iomem *devm_ioremap_wc(struct device *dev, resource_size_t offset,
diff --git a/lib/devres.c b/lib/devres.c
index f4001d90d24d..c8e75cdaf816 100644
--- a/lib/devres.c
+++ b/lib/devres.c
@@ -14,6 +14,8 @@ static int devm_ioremap_match(struct device *dev, void *res, void *match_data)
 	return *(void **)res == match_data;
 }
 
+typedef void __iomem *(*ioremap_fn)(resource_size_t offset, unsigned long size);
+
 /**
  * devm_ioremap - Managed ioremap()
  * @dev: Generic device to remap IO address for
@@ -22,8 +24,9 @@ static int devm_ioremap_match(struct device *dev, void *res, void *match_data)
  *
  * Managed ioremap().  Map is automatically unmapped on driver detach.
  */
-void __iomem *devm_ioremap(struct device *dev, resource_size_t offset,
-			   resource_size_t size)
+static void __iomem *devm_ioremap_type(struct device *dev,
+		resource_size_t offset, resource_size_t size,
+		ioremap_fn ioremap_type)
 {
 	void __iomem **ptr, *addr;
 
@@ -31,7 +34,7 @@ void __iomem *devm_ioremap(struct device *dev, resource_size_t offset,
 	if (!ptr)
 		return NULL;
 
-	addr = ioremap(offset, size);
+	addr = ioremap_type(offset, size);
 	if (addr) {
 		*ptr = addr;
 		devres_add(dev, ptr);
@@ -40,34 +43,25 @@ void __iomem *devm_ioremap(struct device *dev, resource_size_t offset,
 
 	return addr;
 }
+
+void __iomem *devm_ioremap(struct device *dev, resource_size_t offset,
+			   resource_size_t size)
+{
+	return devm_ioremap_type(dev, offset, size, ioremap);
+}
 EXPORT_SYMBOL(devm_ioremap);
 
-/**
- * devm_ioremap_nocache - Managed ioremap_nocache()
- * @dev: Generic device to remap IO address for
- * @offset: BUS offset to map
- * @size: Size of map
- *
- * Managed ioremap_nocache().  Map is automatically unmapped on driver
- * detach.
- */
+void __iomem *devm_ioremap_cache(struct device *dev, resource_size_t offset,
+			   resource_size_t size)
+{
+	return devm_ioremap_type(dev, offset, size, ioremap_cache);
+}
+EXPORT_SYMBOL(devm_ioremap_cache);
+
 void __iomem *devm_ioremap_nocache(struct device *dev, resource_size_t offset,
 				   resource_size_t size)
 {
-	void __iomem **ptr, *addr;
-
-	ptr = devres_alloc(devm_ioremap_release, sizeof(*ptr), GFP_KERNEL);
-	if (!ptr)
-		return NULL;
-
-	addr = ioremap_nocache(offset, size);
-	if (addr) {
-		*ptr = addr;
-		devres_add(dev, ptr);
-	} else
-		devres_free(ptr);
-
-	return addr;
+	return devm_ioremap_type(dev, offset, size, ioremap_nocache);
 }
 EXPORT_SYMBOL(devm_ioremap_nocache);
 
@@ -153,8 +147,11 @@ void __iomem *devm_ioremap_resource(struct device *dev, struct resource *res)
 		return IOMEM_ERR_PTR(-EBUSY);
 	}
 
-	/* FIXME: add devm_ioremap_cache support */
-	dest_ptr = devm_ioremap(dev, res->start, size);
+	if (res->flags & IORESOURCE_CACHEABLE)
+		dest_ptr = devm_ioremap_cache(dev, res->start, size);
+	else
+		dest_ptr = devm_ioremap_nocache(dev, res->start, size);
+
 	if (!dest_ptr) {
 		dev_err(dev, "ioremap failed for resource %pR\n", res);
 		devm_release_mem_region(dev, res->start, size);

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org.  For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>

^ permalink raw reply related	[flat|nested] 85+ messages in thread

* [PATCH v5 4/6] devm: fix ioremap_cache() usage
@ 2015-06-22  8:24   ` Dan Williams
  0 siblings, 0 replies; 85+ messages in thread
From: Dan Williams @ 2015-06-22  8:24 UTC (permalink / raw)
  To: arnd, mingo, bp, hpa, tglx, ross.zwisler, akpm
  Cc: jgross, x86, toshi.kani, linux-nvdimm, benh, mcgrof, konrad.wilk,
	linux-kernel, stefan.bader, luto, linux-mm, geert, ralf, hmh,
	mpe, tj, paulus, hch

Provide devm_ioremap_cache() and fix up devm_ioremap_resource() to
actually provide cacheable mappings.  On archs that implement
ioremap_cache() devm_ioremap_resource() is always silently falling back
to uncached when IORESOURCE_CACHEABLE is specified.

Cc: Toshi Kani <toshi.kani@hp.com>
Cc: Arnd Bergmann <arnd@arndb.de>
Signed-off-by: Dan Williams <dan.j.williams@intel.com>
---
 include/linux/io.h |    2 ++
 lib/devres.c       |   53 +++++++++++++++++++++++++---------------------------
 2 files changed, 27 insertions(+), 28 deletions(-)

diff --git a/include/linux/io.h b/include/linux/io.h
index 41e93fe14b3c..8789a114f37c 100644
--- a/include/linux/io.h
+++ b/include/linux/io.h
@@ -71,6 +71,8 @@ static inline void devm_ioport_unmap(struct device *dev, void __iomem *addr)
 
 void __iomem *devm_ioremap(struct device *dev, resource_size_t offset,
 			   resource_size_t size);
+void __iomem *devm_ioremap_cache(struct device *dev, resource_size_t offset,
+			   resource_size_t size);
 void __iomem *devm_ioremap_nocache(struct device *dev, resource_size_t offset,
 				   resource_size_t size);
 void __iomem *devm_ioremap_wc(struct device *dev, resource_size_t offset,
diff --git a/lib/devres.c b/lib/devres.c
index f4001d90d24d..c8e75cdaf816 100644
--- a/lib/devres.c
+++ b/lib/devres.c
@@ -14,6 +14,8 @@ static int devm_ioremap_match(struct device *dev, void *res, void *match_data)
 	return *(void **)res == match_data;
 }
 
+typedef void __iomem *(*ioremap_fn)(resource_size_t offset, unsigned long size);
+
 /**
  * devm_ioremap - Managed ioremap()
  * @dev: Generic device to remap IO address for
@@ -22,8 +24,9 @@ static int devm_ioremap_match(struct device *dev, void *res, void *match_data)
  *
  * Managed ioremap().  Map is automatically unmapped on driver detach.
  */
-void __iomem *devm_ioremap(struct device *dev, resource_size_t offset,
-			   resource_size_t size)
+static void __iomem *devm_ioremap_type(struct device *dev,
+		resource_size_t offset, resource_size_t size,
+		ioremap_fn ioremap_type)
 {
 	void __iomem **ptr, *addr;
 
@@ -31,7 +34,7 @@ void __iomem *devm_ioremap(struct device *dev, resource_size_t offset,
 	if (!ptr)
 		return NULL;
 
-	addr = ioremap(offset, size);
+	addr = ioremap_type(offset, size);
 	if (addr) {
 		*ptr = addr;
 		devres_add(dev, ptr);
@@ -40,34 +43,25 @@ void __iomem *devm_ioremap(struct device *dev, resource_size_t offset,
 
 	return addr;
 }
+
+void __iomem *devm_ioremap(struct device *dev, resource_size_t offset,
+			   resource_size_t size)
+{
+	return devm_ioremap_type(dev, offset, size, ioremap);
+}
 EXPORT_SYMBOL(devm_ioremap);
 
-/**
- * devm_ioremap_nocache - Managed ioremap_nocache()
- * @dev: Generic device to remap IO address for
- * @offset: BUS offset to map
- * @size: Size of map
- *
- * Managed ioremap_nocache().  Map is automatically unmapped on driver
- * detach.
- */
+void __iomem *devm_ioremap_cache(struct device *dev, resource_size_t offset,
+			   resource_size_t size)
+{
+	return devm_ioremap_type(dev, offset, size, ioremap_cache);
+}
+EXPORT_SYMBOL(devm_ioremap_cache);
+
 void __iomem *devm_ioremap_nocache(struct device *dev, resource_size_t offset,
 				   resource_size_t size)
 {
-	void __iomem **ptr, *addr;
-
-	ptr = devres_alloc(devm_ioremap_release, sizeof(*ptr), GFP_KERNEL);
-	if (!ptr)
-		return NULL;
-
-	addr = ioremap_nocache(offset, size);
-	if (addr) {
-		*ptr = addr;
-		devres_add(dev, ptr);
-	} else
-		devres_free(ptr);
-
-	return addr;
+	return devm_ioremap_type(dev, offset, size, ioremap_nocache);
 }
 EXPORT_SYMBOL(devm_ioremap_nocache);
 
@@ -153,8 +147,11 @@ void __iomem *devm_ioremap_resource(struct device *dev, struct resource *res)
 		return IOMEM_ERR_PTR(-EBUSY);
 	}
 
-	/* FIXME: add devm_ioremap_cache support */
-	dest_ptr = devm_ioremap(dev, res->start, size);
+	if (res->flags & IORESOURCE_CACHEABLE)
+		dest_ptr = devm_ioremap_cache(dev, res->start, size);
+	else
+		dest_ptr = devm_ioremap_nocache(dev, res->start, size);
+
 	if (!dest_ptr) {
 		dev_err(dev, "ioremap failed for resource %pR\n", res);
 		devm_release_mem_region(dev, res->start, size);

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
Please read the FAQ at  http://www.tux.org/lkml/

^ permalink raw reply related	[flat|nested] 85+ messages in thread

* [PATCH v5 5/6] arch: introduce memremap_cache() and memremap_wt()
  2015-06-22  8:24 ` Dan Williams
@ 2015-06-22  8:24   ` Dan Williams
  -1 siblings, 0 replies; 85+ messages in thread
From: Dan Williams @ 2015-06-22  8:24 UTC (permalink / raw)
  To: arnd, mingo, bp, hpa, tglx, ross.zwisler, akpm
  Cc: jgross, x86, toshi.kani, linux-nvdimm, benh, mcgrof, konrad.wilk,
	linux-kernel, stefan.bader, luto, linux-mm, geert, ralf, hmh,
	mpe, tj, paulus, hch

Existing users of ioremap_cache() are mapping memory that is known in
advance to not have i/o side effects.  These users are forced to cast
away the __iomem annotation, or otherwise neglect to fix the sparse
errors thrown when dereferencing pointers to this memory.  Provide
memremap_*() as a non __iomem annotated ioremap_*().

The ARCH_HAS_MEMREMAP kconfig symbol is introduced for archs to assert
that it is safe to recast / reuse the return value from ioremap as a
normal pointer to memory.  In other words, archs that mandate specific
accessors for __iomem are not memremap() capable and drivers that care,
like pmem, can add a dependency to disable themselves on these archs.

Cc: Arnd Bergmann <arnd@arndb.de>
Acked-by: Andy Shevchenko <andy.shevchenko@gmail.com>
Signed-off-by: Dan Williams <dan.j.williams@intel.com>
---
 arch/arm/Kconfig                     |    1 +
 arch/arm64/Kconfig                   |    1 +
 arch/arm64/kernel/efi.c              |    4 ++-
 arch/arm64/kernel/smp_spin_table.c   |   10 ++++----
 arch/frv/Kconfig                     |    1 +
 arch/m68k/Kconfig                    |    1 +
 arch/metag/Kconfig                   |    1 +
 arch/mips/Kconfig                    |    1 +
 arch/powerpc/Kconfig                 |    1 +
 arch/x86/Kconfig                     |    1 +
 arch/x86/kernel/crash_dump_64.c      |    6 ++---
 arch/x86/kernel/kdebugfs.c           |    8 +++----
 arch/x86/kernel/ksysfs.c             |   28 ++++++++++++-----------
 arch/x86/mm/ioremap.c                |   10 +++-----
 arch/xtensa/Kconfig                  |    1 +
 drivers/acpi/apei/einj.c             |    8 +++----
 drivers/acpi/apei/erst.c             |    4 ++-
 drivers/block/Kconfig                |    1 +
 drivers/block/pmem.c                 |    7 +++---
 drivers/firmware/google/memconsole.c |    4 ++-
 include/linux/device.h               |    5 ++++
 include/linux/io.h                   |    4 +++
 kernel/resource.c                    |   41 +++++++++++++++++++++++++++++++++-
 lib/Kconfig                          |    5 +++-
 24 files changed, 107 insertions(+), 47 deletions(-)

diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 45df48ba0b12..397426f8ca37 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -3,6 +3,7 @@ config ARM
 	default y
 	select ARCH_HAS_ATOMIC64_DEC_IF_POSITIVE
 	select ARCH_HAS_ELF_RANDOMIZE
+	select ARCH_HAS_MEMREMAP
 	select ARCH_HAS_TICK_BROADCAST if GENERIC_CLOCKEVENTS_BROADCAST
 	select ARCH_HAVE_CUSTOM_GPIO_H
 	select ARCH_HAS_GCOV_PROFILE_ALL
diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
index 7796af4b1d6f..f07a9a5af61e 100644
--- a/arch/arm64/Kconfig
+++ b/arch/arm64/Kconfig
@@ -5,6 +5,7 @@ config ARM64
 	select ARCH_HAS_ATOMIC64_DEC_IF_POSITIVE
 	select ARCH_HAS_ELF_RANDOMIZE
 	select ARCH_HAS_GCOV_PROFILE_ALL
+	select ARCH_HAS_MEMREMAP
 	select ARCH_HAS_SG_CHAIN
 	select ARCH_HAS_TICK_BROADCAST if GENERIC_CLOCKEVENTS_BROADCAST
 	select ARCH_USE_CMPXCHG_LOCKREF
diff --git a/arch/arm64/kernel/efi.c b/arch/arm64/kernel/efi.c
index ab21e0d58278..b672ef33f08b 100644
--- a/arch/arm64/kernel/efi.c
+++ b/arch/arm64/kernel/efi.c
@@ -289,7 +289,7 @@ static int __init arm64_enable_runtime_services(void)
 	pr_info("Remapping and enabling EFI services.\n");
 
 	mapsize = memmap.map_end - memmap.map;
-	memmap.map = (__force void *)ioremap_cache((phys_addr_t)memmap.phys_map,
+	memmap.map = memremap_cache((phys_addr_t)memmap.phys_map,
 						   mapsize);
 	if (!memmap.map) {
 		pr_err("Failed to remap EFI memory map\n");
@@ -298,7 +298,7 @@ static int __init arm64_enable_runtime_services(void)
 	memmap.map_end = memmap.map + mapsize;
 	efi.memmap = &memmap;
 
-	efi.systab = (__force void *)ioremap_cache(efi_system_table,
+	efi.systab = memremap_cache(efi_system_table,
 						   sizeof(efi_system_table_t));
 	if (!efi.systab) {
 		pr_err("Failed to remap EFI System Table\n");
diff --git a/arch/arm64/kernel/smp_spin_table.c b/arch/arm64/kernel/smp_spin_table.c
index 14944e5b28da..893c8586e20f 100644
--- a/arch/arm64/kernel/smp_spin_table.c
+++ b/arch/arm64/kernel/smp_spin_table.c
@@ -67,18 +67,18 @@ static int smp_spin_table_cpu_init(struct device_node *dn, unsigned int cpu)
 
 static int smp_spin_table_cpu_prepare(unsigned int cpu)
 {
-	__le64 __iomem *release_addr;
+	__le64 *release_addr;
 
 	if (!cpu_release_addr[cpu])
 		return -ENODEV;
 
 	/*
 	 * The cpu-release-addr may or may not be inside the linear mapping.
-	 * As ioremap_cache will either give us a new mapping or reuse the
+	 * As memremap_cache will either give us a new mapping or reuse the
 	 * existing linear mapping, we can use it to cover both cases. In
 	 * either case the memory will be MT_NORMAL.
 	 */
-	release_addr = ioremap_cache(cpu_release_addr[cpu],
+	release_addr = memremap_cache(cpu_release_addr[cpu],
 				     sizeof(*release_addr));
 	if (!release_addr)
 		return -ENOMEM;
@@ -91,7 +91,7 @@ static int smp_spin_table_cpu_prepare(unsigned int cpu)
 	 * the boot protocol.
 	 */
 	writeq_relaxed(__pa(secondary_holding_pen), release_addr);
-	__flush_dcache_area((__force void *)release_addr,
+	__flush_dcache_area(release_addr,
 			    sizeof(*release_addr));
 
 	/*
@@ -99,7 +99,7 @@ static int smp_spin_table_cpu_prepare(unsigned int cpu)
 	 */
 	sev();
 
-	iounmap(release_addr);
+	memunmap(release_addr);
 
 	return 0;
 }
diff --git a/arch/frv/Kconfig b/arch/frv/Kconfig
index 34aa19352dc1..2373bf183527 100644
--- a/arch/frv/Kconfig
+++ b/arch/frv/Kconfig
@@ -14,6 +14,7 @@ config FRV
 	select OLD_SIGSUSPEND3
 	select OLD_SIGACTION
 	select HAVE_DEBUG_STACKOVERFLOW
+	select ARCH_HAS_MEMREMAP
 
 config ZONE_DMA
 	bool
diff --git a/arch/m68k/Kconfig b/arch/m68k/Kconfig
index 2dd8f63bfbbb..831b1be8c43d 100644
--- a/arch/m68k/Kconfig
+++ b/arch/m68k/Kconfig
@@ -23,6 +23,7 @@ config M68K
 	select MODULES_USE_ELF_RELA
 	select OLD_SIGSUSPEND3
 	select OLD_SIGACTION
+	select ARCH_HAS_MEMREMAP
 
 config RWSEM_GENERIC_SPINLOCK
 	bool
diff --git a/arch/metag/Kconfig b/arch/metag/Kconfig
index 0b389a81c43a..5669fe3eb807 100644
--- a/arch/metag/Kconfig
+++ b/arch/metag/Kconfig
@@ -24,6 +24,7 @@ config METAG
 	select HAVE_PERF_EVENTS
 	select HAVE_SYSCALL_TRACEPOINTS
 	select HAVE_UNDERSCORE_SYMBOL_PREFIX
+	select ARCH_HAS_MEMREMAP
 	select IRQ_DOMAIN
 	select MODULES_USE_ELF_RELA
 	select OF
diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig
index f5016656494f..9ee35e615c0d 100644
--- a/arch/mips/Kconfig
+++ b/arch/mips/Kconfig
@@ -58,6 +58,7 @@ config MIPS
 	select SYSCTL_EXCEPTION_TRACE
 	select HAVE_VIRT_CPU_ACCOUNTING_GEN
 	select HAVE_IRQ_TIME_ACCOUNTING
+	select ARCH_HAS_MEMREMAP
 
 menu "Machine selection"
 
diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig
index 190cc48abc0c..73c1f8b1f022 100644
--- a/arch/powerpc/Kconfig
+++ b/arch/powerpc/Kconfig
@@ -153,6 +153,7 @@ config PPC
 	select NO_BOOTMEM
 	select HAVE_GENERIC_RCU_GUP
 	select HAVE_PERF_EVENTS_NMI if PPC64
+	select ARCH_HAS_MEMREMAP
 
 config GENERIC_CSUM
 	def_bool CPU_LITTLE_ENDIAN
diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
index 228aa35d7e89..f16caf7eac27 100644
--- a/arch/x86/Kconfig
+++ b/arch/x86/Kconfig
@@ -27,6 +27,7 @@ config X86
 	select ARCH_HAS_ELF_RANDOMIZE
 	select ARCH_HAS_FAST_MULTIPLIER
 	select ARCH_HAS_GCOV_PROFILE_ALL
+	select ARCH_HAS_MEMREMAP
 	select ARCH_HAS_SG_CHAIN
 	select ARCH_HAVE_NMI_SAFE_CMPXCHG
 	select ARCH_MIGHT_HAVE_ACPI_PDC		if ACPI
diff --git a/arch/x86/kernel/crash_dump_64.c b/arch/x86/kernel/crash_dump_64.c
index afa64adb75ee..8e04011665fd 100644
--- a/arch/x86/kernel/crash_dump_64.c
+++ b/arch/x86/kernel/crash_dump_64.c
@@ -31,19 +31,19 @@ ssize_t copy_oldmem_page(unsigned long pfn, char *buf,
 	if (!csize)
 		return 0;
 
-	vaddr = ioremap_cache(pfn << PAGE_SHIFT, PAGE_SIZE);
+	vaddr = memremap_cache(pfn << PAGE_SHIFT, PAGE_SIZE);
 	if (!vaddr)
 		return -ENOMEM;
 
 	if (userbuf) {
 		if (copy_to_user(buf, vaddr + offset, csize)) {
-			iounmap(vaddr);
+			memunmap(vaddr);
 			return -EFAULT;
 		}
 	} else
 		memcpy(buf, vaddr + offset, csize);
 
 	set_iounmap_nonlazy();
-	iounmap(vaddr);
+	memunmap(vaddr);
 	return csize;
 }
diff --git a/arch/x86/kernel/kdebugfs.c b/arch/x86/kernel/kdebugfs.c
index dc1404bf8e4b..731b10e2814f 100644
--- a/arch/x86/kernel/kdebugfs.c
+++ b/arch/x86/kernel/kdebugfs.c
@@ -49,7 +49,7 @@ static ssize_t setup_data_read(struct file *file, char __user *user_buf,
 	pa = node->paddr + sizeof(struct setup_data) + pos;
 	pg = pfn_to_page((pa + count - 1) >> PAGE_SHIFT);
 	if (PageHighMem(pg)) {
-		p = ioremap_cache(pa, count);
+		p = memremap_cache(pa, count);
 		if (!p)
 			return -ENXIO;
 	} else
@@ -58,7 +58,7 @@ static ssize_t setup_data_read(struct file *file, char __user *user_buf,
 	remain = copy_to_user(user_buf, p, count);
 
 	if (PageHighMem(pg))
-		iounmap(p);
+		memunmap(p);
 
 	if (remain)
 		return -EFAULT;
@@ -128,7 +128,7 @@ static int __init create_setup_data_nodes(struct dentry *parent)
 
 		pg = pfn_to_page((pa_data+sizeof(*data)-1) >> PAGE_SHIFT);
 		if (PageHighMem(pg)) {
-			data = ioremap_cache(pa_data, sizeof(*data));
+			data = memremap_cache(pa_data, sizeof(*data));
 			if (!data) {
 				kfree(node);
 				error = -ENXIO;
@@ -144,7 +144,7 @@ static int __init create_setup_data_nodes(struct dentry *parent)
 		pa_data = data->next;
 
 		if (PageHighMem(pg))
-			iounmap(data);
+			memunmap(data);
 		if (error)
 			goto err_dir;
 		no++;
diff --git a/arch/x86/kernel/ksysfs.c b/arch/x86/kernel/ksysfs.c
index c2bedaea11f7..2fbc62886eae 100644
--- a/arch/x86/kernel/ksysfs.c
+++ b/arch/x86/kernel/ksysfs.c
@@ -16,8 +16,8 @@
 #include <linux/stat.h>
 #include <linux/slab.h>
 #include <linux/mm.h>
+#include <linux/io.h>
 
-#include <asm/io.h>
 #include <asm/setup.h>
 
 static ssize_t version_show(struct kobject *kobj,
@@ -79,12 +79,12 @@ static int get_setup_data_paddr(int nr, u64 *paddr)
 			*paddr = pa_data;
 			return 0;
 		}
-		data = ioremap_cache(pa_data, sizeof(*data));
+		data = memremap_cache(pa_data, sizeof(*data));
 		if (!data)
 			return -ENOMEM;
 
 		pa_data = data->next;
-		iounmap(data);
+		memunmap(data);
 		i++;
 	}
 	return -EINVAL;
@@ -97,17 +97,17 @@ static int __init get_setup_data_size(int nr, size_t *size)
 	u64 pa_data = boot_params.hdr.setup_data;
 
 	while (pa_data) {
-		data = ioremap_cache(pa_data, sizeof(*data));
+		data = memremap_cache(pa_data, sizeof(*data));
 		if (!data)
 			return -ENOMEM;
 		if (nr == i) {
 			*size = data->len;
-			iounmap(data);
+			memunmap(data);
 			return 0;
 		}
 
 		pa_data = data->next;
-		iounmap(data);
+		memunmap(data);
 		i++;
 	}
 	return -EINVAL;
@@ -127,12 +127,12 @@ static ssize_t type_show(struct kobject *kobj,
 	ret = get_setup_data_paddr(nr, &paddr);
 	if (ret)
 		return ret;
-	data = ioremap_cache(paddr, sizeof(*data));
+	data = memremap_cache(paddr, sizeof(*data));
 	if (!data)
 		return -ENOMEM;
 
 	ret = sprintf(buf, "0x%x\n", data->type);
-	iounmap(data);
+	memunmap(data);
 	return ret;
 }
 
@@ -154,7 +154,7 @@ static ssize_t setup_data_data_read(struct file *fp,
 	ret = get_setup_data_paddr(nr, &paddr);
 	if (ret)
 		return ret;
-	data = ioremap_cache(paddr, sizeof(*data));
+	data = memremap_cache(paddr, sizeof(*data));
 	if (!data)
 		return -ENOMEM;
 
@@ -170,15 +170,15 @@ static ssize_t setup_data_data_read(struct file *fp,
 		goto out;
 
 	ret = count;
-	p = ioremap_cache(paddr + sizeof(*data), data->len);
+	p = memremap_cache(paddr + sizeof(*data), data->len);
 	if (!p) {
 		ret = -ENOMEM;
 		goto out;
 	}
 	memcpy(buf, p + off, count);
-	iounmap(p);
+	memunmap(p);
 out:
-	iounmap(data);
+	memunmap(data);
 	return ret;
 }
 
@@ -250,13 +250,13 @@ static int __init get_setup_data_total_num(u64 pa_data, int *nr)
 	*nr = 0;
 	while (pa_data) {
 		*nr += 1;
-		data = ioremap_cache(pa_data, sizeof(*data));
+		data = memremap_cache(pa_data, sizeof(*data));
 		if (!data) {
 			ret = -ENOMEM;
 			goto out;
 		}
 		pa_data = data->next;
-		iounmap(data);
+		memunmap(data);
 	}
 
 out:
diff --git a/arch/x86/mm/ioremap.c b/arch/x86/mm/ioremap.c
index cc5ccc415cc0..7f087cb793fa 100644
--- a/arch/x86/mm/ioremap.c
+++ b/arch/x86/mm/ioremap.c
@@ -414,12 +414,10 @@ void *xlate_dev_mem_ptr(phys_addr_t phys)
 	if (page_is_ram(start >> PAGE_SHIFT))
 		return __va(phys);
 
-	vaddr = ioremap_cache(start, PAGE_SIZE);
-	/* Only add the offset on success and return NULL if the ioremap() failed: */
+	vaddr = memremap_cache(start, PAGE_SIZE);
 	if (vaddr)
-		vaddr += offset;
-
-	return vaddr;
+		return vaddr + offset;
+	return NULL;
 }
 
 void unxlate_dev_mem_ptr(phys_addr_t phys, void *addr)
@@ -427,7 +425,7 @@ void unxlate_dev_mem_ptr(phys_addr_t phys, void *addr)
 	if (page_is_ram(phys >> PAGE_SHIFT))
 		return;
 
-	iounmap((void __iomem *)((unsigned long)addr & PAGE_MASK));
+	memunmap((void *)((unsigned long)addr & PAGE_MASK));
 }
 
 static pte_t bm_pte[PAGE_SIZE/sizeof(pte_t)] __page_aligned_bss;
diff --git a/arch/xtensa/Kconfig b/arch/xtensa/Kconfig
index 87be10e8b57a..e601faf87cee 100644
--- a/arch/xtensa/Kconfig
+++ b/arch/xtensa/Kconfig
@@ -3,6 +3,7 @@ config ZONE_DMA
 
 config XTENSA
 	def_bool y
+	select ARCH_HAS_MEMREMAP
 	select ARCH_WANT_FRAME_POINTERS
 	select ARCH_WANT_IPC_PARSE_VERSION
 	select ARCH_WANT_OPTIONAL_GPIOLIB
diff --git a/drivers/acpi/apei/einj.c b/drivers/acpi/apei/einj.c
index a095d4f858da..2ec9006cfb6c 100644
--- a/drivers/acpi/apei/einj.c
+++ b/drivers/acpi/apei/einj.c
@@ -318,7 +318,7 @@ static int __einj_error_trigger(u64 trigger_paddr, u32 type,
 			    sizeof(*trigger_tab) - 1);
 		goto out;
 	}
-	trigger_tab = ioremap_cache(trigger_paddr, sizeof(*trigger_tab));
+	trigger_tab = memremap_cache(trigger_paddr, sizeof(*trigger_tab));
 	if (!trigger_tab) {
 		pr_err(EINJ_PFX "Failed to map trigger table!\n");
 		goto out_rel_header;
@@ -346,8 +346,8 @@ static int __einj_error_trigger(u64 trigger_paddr, u32 type,
 		       (unsigned long long)trigger_paddr + table_size - 1);
 		goto out_rel_header;
 	}
-	iounmap(trigger_tab);
-	trigger_tab = ioremap_cache(trigger_paddr, table_size);
+	memunmap(trigger_tab);
+	trigger_tab = memremap_cache(trigger_paddr, table_size);
 	if (!trigger_tab) {
 		pr_err(EINJ_PFX "Failed to map trigger table!\n");
 		goto out_rel_entry;
@@ -409,7 +409,7 @@ out_rel_header:
 	release_mem_region(trigger_paddr, sizeof(*trigger_tab));
 out:
 	if (trigger_tab)
-		iounmap(trigger_tab);
+		memunmap(trigger_tab);
 
 	return rc;
 }
diff --git a/drivers/acpi/apei/erst.c b/drivers/acpi/apei/erst.c
index 3670bbab57a3..6b95066da51d 100644
--- a/drivers/acpi/apei/erst.c
+++ b/drivers/acpi/apei/erst.c
@@ -77,7 +77,7 @@ static struct acpi_table_erst *erst_tab;
 static struct erst_erange {
 	u64 base;
 	u64 size;
-	void __iomem *vaddr;
+	void *vaddr;
 	u32 attr;
 } erst_erange;
 
@@ -1185,7 +1185,7 @@ static int __init erst_init(void)
 		goto err_unmap_reg;
 	}
 	rc = -ENOMEM;
-	erst_erange.vaddr = ioremap_cache(erst_erange.base,
+	erst_erange.vaddr = memremap_cache(erst_erange.base,
 					  erst_erange.size);
 	if (!erst_erange.vaddr)
 		goto err_release_erange;
diff --git a/drivers/block/Kconfig b/drivers/block/Kconfig
index eb1fed5bd516..98418fc330ae 100644
--- a/drivers/block/Kconfig
+++ b/drivers/block/Kconfig
@@ -406,6 +406,7 @@ config BLK_DEV_RAM_DAX
 
 config BLK_DEV_PMEM
 	tristate "Persistent memory block device support"
+	depends on ARCH_HAS_MEMREMAP
 	help
 	  Saying Y here will allow you to use a contiguous range of reserved
 	  memory as one or more persistent block devices.
diff --git a/drivers/block/pmem.c b/drivers/block/pmem.c
index 095dfaadcaa5..b00b97314b57 100644
--- a/drivers/block/pmem.c
+++ b/drivers/block/pmem.c
@@ -23,6 +23,7 @@
 #include <linux/module.h>
 #include <linux/moduleparam.h>
 #include <linux/slab.h>
+#include <linux/io.h>
 
 #define PMEM_MINORS		16
 
@@ -143,7 +144,7 @@ static struct pmem_device *pmem_alloc(struct device *dev, struct resource *res)
 	 * of the CPU caches in case of a crash.
 	 */
 	err = -ENOMEM;
-	pmem->virt_addr = ioremap_wt(pmem->phys_addr, pmem->size);
+	pmem->virt_addr = memremap_wt(pmem->phys_addr, pmem->size);
 	if (!pmem->virt_addr)
 		goto out_release_region;
 
@@ -179,7 +180,7 @@ static struct pmem_device *pmem_alloc(struct device *dev, struct resource *res)
 out_free_queue:
 	blk_cleanup_queue(pmem->pmem_queue);
 out_unmap:
-	iounmap(pmem->virt_addr);
+	memunmap(pmem->virt_addr);
 out_release_region:
 	release_mem_region(pmem->phys_addr, pmem->size);
 out_free_dev:
@@ -193,7 +194,7 @@ static void pmem_free(struct pmem_device *pmem)
 	del_gendisk(pmem->pmem_disk);
 	put_disk(pmem->pmem_disk);
 	blk_cleanup_queue(pmem->pmem_queue);
-	iounmap(pmem->virt_addr);
+	memunmap(pmem->virt_addr);
 	release_mem_region(pmem->phys_addr, pmem->size);
 	kfree(pmem);
 }
diff --git a/drivers/firmware/google/memconsole.c b/drivers/firmware/google/memconsole.c
index 2f569aaed4c7..877433dc8297 100644
--- a/drivers/firmware/google/memconsole.c
+++ b/drivers/firmware/google/memconsole.c
@@ -52,14 +52,14 @@ static ssize_t memconsole_read(struct file *filp, struct kobject *kobp,
 	char *memconsole;
 	ssize_t ret;
 
-	memconsole = ioremap_cache(memconsole_baseaddr, memconsole_length);
+	memconsole = memremap_cache(memconsole_baseaddr, memconsole_length);
 	if (!memconsole) {
 		pr_err("memconsole: ioremap_cache failed\n");
 		return -ENOMEM;
 	}
 	ret = memory_read_from_buffer(buf, count, &pos, memconsole,
 				      memconsole_length);
-	iounmap(memconsole);
+	memunmap(memconsole);
 	return ret;
 }
 
diff --git a/include/linux/device.h b/include/linux/device.h
index 6558af90c8fe..518f49c5d596 100644
--- a/include/linux/device.h
+++ b/include/linux/device.h
@@ -638,6 +638,11 @@ extern void devm_free_pages(struct device *dev, unsigned long addr);
 
 void __iomem *devm_ioremap_resource(struct device *dev, struct resource *res);
 
+static inline void *devm_memremap_resource(struct device *dev, struct resource *res)
+{
+	return (void __force *) devm_ioremap_resource(dev, res);
+}
+
 /* allows to add/remove a custom action to devres stack */
 int devm_add_action(struct device *dev, void (*action)(void *), void *data);
 void devm_remove_action(struct device *dev, void (*action)(void *), void *data);
diff --git a/include/linux/io.h b/include/linux/io.h
index 8789a114f37c..21dc5de483f6 100644
--- a/include/linux/io.h
+++ b/include/linux/io.h
@@ -181,4 +181,8 @@ static inline int arch_phys_wc_index(int handle)
 #endif
 #endif
 
+extern void *memremap_cache(resource_size_t offset, size_t size);
+extern void *memremap_wt(resource_size_t offset, size_t size);
+extern void memunmap(void *addr);
+
 #endif /* _LINUX_IO_H */
diff --git a/kernel/resource.c b/kernel/resource.c
index 90552aab5f2d..2f8aca09da52 100644
--- a/kernel/resource.c
+++ b/kernel/resource.c
@@ -23,7 +23,7 @@
 #include <linux/pfn.h>
 #include <linux/mm.h>
 #include <linux/resource_ext.h>
-#include <asm/io.h>
+#include <linux/io.h>
 
 
 struct resource ioport_resource = {
@@ -528,6 +528,45 @@ int region_is_ram(resource_size_t start, unsigned long size)
 	return ret;
 }
 
+#ifdef CONFIG_ARCH_HAS_MEMREMAP
+/*
+ * memremap() is "ioremap" for cases where it is known that the resource
+ * being mapped does not have i/o side effects and the __iomem
+ * annotation is not applicable.
+ */
+static bool memremap_valid(resource_size_t offset, size_t size)
+{
+	if (region_is_ram(offset, size) != 0) {
+		WARN_ONCE(1, "memremap attempted on ram %pa size: %zu\n",
+				&offset, size);
+		return false;
+	}
+	return true;
+}
+
+void *memremap_cache(resource_size_t offset, size_t size)
+{
+	if (!memremap_valid(offset, size))
+		return NULL;
+	return (void __force *) ioremap_cache(offset, size);
+}
+EXPORT_SYMBOL(memremap_cache);
+
+void *memremap_wt(resource_size_t offset, size_t size)
+{
+	if (!memremap_valid(offset, size))
+		return NULL;
+	return (void __force *) ioremap_wt(offset, size);
+}
+EXPORT_SYMBOL(memremap_wt);
+
+void memunmap(void *addr)
+{
+	iounmap((void __iomem __force *) addr);
+}
+EXPORT_SYMBOL(memunmap);
+#endif /* CONFIG_ARCH_HAS_MEMREMAP */
+
 void __weak arch_remove_reservations(struct resource *avail)
 {
 }
diff --git a/lib/Kconfig b/lib/Kconfig
index 601965a948e8..bc7bc0278921 100644
--- a/lib/Kconfig
+++ b/lib/Kconfig
@@ -520,6 +520,9 @@ source "lib/fonts/Kconfig"
 #
 
 config ARCH_HAS_SG_CHAIN
-	def_bool n
+	bool
+
+config ARCH_HAS_MEMREMAP
+	bool
 
 endmenu

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org.  For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>

^ permalink raw reply related	[flat|nested] 85+ messages in thread

* [PATCH v5 5/6] arch: introduce memremap_cache() and memremap_wt()
@ 2015-06-22  8:24   ` Dan Williams
  0 siblings, 0 replies; 85+ messages in thread
From: Dan Williams @ 2015-06-22  8:24 UTC (permalink / raw)
  To: arnd, mingo, bp, hpa, tglx, ross.zwisler, akpm
  Cc: jgross, x86, toshi.kani, linux-nvdimm, benh, mcgrof, konrad.wilk,
	linux-kernel, stefan.bader, luto, linux-mm, geert, ralf, hmh,
	mpe, tj, paulus, hch

Existing users of ioremap_cache() are mapping memory that is known in
advance to not have i/o side effects.  These users are forced to cast
away the __iomem annotation, or otherwise neglect to fix the sparse
errors thrown when dereferencing pointers to this memory.  Provide
memremap_*() as a non __iomem annotated ioremap_*().

The ARCH_HAS_MEMREMAP kconfig symbol is introduced for archs to assert
that it is safe to recast / reuse the return value from ioremap as a
normal pointer to memory.  In other words, archs that mandate specific
accessors for __iomem are not memremap() capable and drivers that care,
like pmem, can add a dependency to disable themselves on these archs.

Cc: Arnd Bergmann <arnd@arndb.de>
Acked-by: Andy Shevchenko <andy.shevchenko@gmail.com>
Signed-off-by: Dan Williams <dan.j.williams@intel.com>
---
 arch/arm/Kconfig                     |    1 +
 arch/arm64/Kconfig                   |    1 +
 arch/arm64/kernel/efi.c              |    4 ++-
 arch/arm64/kernel/smp_spin_table.c   |   10 ++++----
 arch/frv/Kconfig                     |    1 +
 arch/m68k/Kconfig                    |    1 +
 arch/metag/Kconfig                   |    1 +
 arch/mips/Kconfig                    |    1 +
 arch/powerpc/Kconfig                 |    1 +
 arch/x86/Kconfig                     |    1 +
 arch/x86/kernel/crash_dump_64.c      |    6 ++---
 arch/x86/kernel/kdebugfs.c           |    8 +++----
 arch/x86/kernel/ksysfs.c             |   28 ++++++++++++-----------
 arch/x86/mm/ioremap.c                |   10 +++-----
 arch/xtensa/Kconfig                  |    1 +
 drivers/acpi/apei/einj.c             |    8 +++----
 drivers/acpi/apei/erst.c             |    4 ++-
 drivers/block/Kconfig                |    1 +
 drivers/block/pmem.c                 |    7 +++---
 drivers/firmware/google/memconsole.c |    4 ++-
 include/linux/device.h               |    5 ++++
 include/linux/io.h                   |    4 +++
 kernel/resource.c                    |   41 +++++++++++++++++++++++++++++++++-
 lib/Kconfig                          |    5 +++-
 24 files changed, 107 insertions(+), 47 deletions(-)

diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 45df48ba0b12..397426f8ca37 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -3,6 +3,7 @@ config ARM
 	default y
 	select ARCH_HAS_ATOMIC64_DEC_IF_POSITIVE
 	select ARCH_HAS_ELF_RANDOMIZE
+	select ARCH_HAS_MEMREMAP
 	select ARCH_HAS_TICK_BROADCAST if GENERIC_CLOCKEVENTS_BROADCAST
 	select ARCH_HAVE_CUSTOM_GPIO_H
 	select ARCH_HAS_GCOV_PROFILE_ALL
diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
index 7796af4b1d6f..f07a9a5af61e 100644
--- a/arch/arm64/Kconfig
+++ b/arch/arm64/Kconfig
@@ -5,6 +5,7 @@ config ARM64
 	select ARCH_HAS_ATOMIC64_DEC_IF_POSITIVE
 	select ARCH_HAS_ELF_RANDOMIZE
 	select ARCH_HAS_GCOV_PROFILE_ALL
+	select ARCH_HAS_MEMREMAP
 	select ARCH_HAS_SG_CHAIN
 	select ARCH_HAS_TICK_BROADCAST if GENERIC_CLOCKEVENTS_BROADCAST
 	select ARCH_USE_CMPXCHG_LOCKREF
diff --git a/arch/arm64/kernel/efi.c b/arch/arm64/kernel/efi.c
index ab21e0d58278..b672ef33f08b 100644
--- a/arch/arm64/kernel/efi.c
+++ b/arch/arm64/kernel/efi.c
@@ -289,7 +289,7 @@ static int __init arm64_enable_runtime_services(void)
 	pr_info("Remapping and enabling EFI services.\n");
 
 	mapsize = memmap.map_end - memmap.map;
-	memmap.map = (__force void *)ioremap_cache((phys_addr_t)memmap.phys_map,
+	memmap.map = memremap_cache((phys_addr_t)memmap.phys_map,
 						   mapsize);
 	if (!memmap.map) {
 		pr_err("Failed to remap EFI memory map\n");
@@ -298,7 +298,7 @@ static int __init arm64_enable_runtime_services(void)
 	memmap.map_end = memmap.map + mapsize;
 	efi.memmap = &memmap;
 
-	efi.systab = (__force void *)ioremap_cache(efi_system_table,
+	efi.systab = memremap_cache(efi_system_table,
 						   sizeof(efi_system_table_t));
 	if (!efi.systab) {
 		pr_err("Failed to remap EFI System Table\n");
diff --git a/arch/arm64/kernel/smp_spin_table.c b/arch/arm64/kernel/smp_spin_table.c
index 14944e5b28da..893c8586e20f 100644
--- a/arch/arm64/kernel/smp_spin_table.c
+++ b/arch/arm64/kernel/smp_spin_table.c
@@ -67,18 +67,18 @@ static int smp_spin_table_cpu_init(struct device_node *dn, unsigned int cpu)
 
 static int smp_spin_table_cpu_prepare(unsigned int cpu)
 {
-	__le64 __iomem *release_addr;
+	__le64 *release_addr;
 
 	if (!cpu_release_addr[cpu])
 		return -ENODEV;
 
 	/*
 	 * The cpu-release-addr may or may not be inside the linear mapping.
-	 * As ioremap_cache will either give us a new mapping or reuse the
+	 * As memremap_cache will either give us a new mapping or reuse the
 	 * existing linear mapping, we can use it to cover both cases. In
 	 * either case the memory will be MT_NORMAL.
 	 */
-	release_addr = ioremap_cache(cpu_release_addr[cpu],
+	release_addr = memremap_cache(cpu_release_addr[cpu],
 				     sizeof(*release_addr));
 	if (!release_addr)
 		return -ENOMEM;
@@ -91,7 +91,7 @@ static int smp_spin_table_cpu_prepare(unsigned int cpu)
 	 * the boot protocol.
 	 */
 	writeq_relaxed(__pa(secondary_holding_pen), release_addr);
-	__flush_dcache_area((__force void *)release_addr,
+	__flush_dcache_area(release_addr,
 			    sizeof(*release_addr));
 
 	/*
@@ -99,7 +99,7 @@ static int smp_spin_table_cpu_prepare(unsigned int cpu)
 	 */
 	sev();
 
-	iounmap(release_addr);
+	memunmap(release_addr);
 
 	return 0;
 }
diff --git a/arch/frv/Kconfig b/arch/frv/Kconfig
index 34aa19352dc1..2373bf183527 100644
--- a/arch/frv/Kconfig
+++ b/arch/frv/Kconfig
@@ -14,6 +14,7 @@ config FRV
 	select OLD_SIGSUSPEND3
 	select OLD_SIGACTION
 	select HAVE_DEBUG_STACKOVERFLOW
+	select ARCH_HAS_MEMREMAP
 
 config ZONE_DMA
 	bool
diff --git a/arch/m68k/Kconfig b/arch/m68k/Kconfig
index 2dd8f63bfbbb..831b1be8c43d 100644
--- a/arch/m68k/Kconfig
+++ b/arch/m68k/Kconfig
@@ -23,6 +23,7 @@ config M68K
 	select MODULES_USE_ELF_RELA
 	select OLD_SIGSUSPEND3
 	select OLD_SIGACTION
+	select ARCH_HAS_MEMREMAP
 
 config RWSEM_GENERIC_SPINLOCK
 	bool
diff --git a/arch/metag/Kconfig b/arch/metag/Kconfig
index 0b389a81c43a..5669fe3eb807 100644
--- a/arch/metag/Kconfig
+++ b/arch/metag/Kconfig
@@ -24,6 +24,7 @@ config METAG
 	select HAVE_PERF_EVENTS
 	select HAVE_SYSCALL_TRACEPOINTS
 	select HAVE_UNDERSCORE_SYMBOL_PREFIX
+	select ARCH_HAS_MEMREMAP
 	select IRQ_DOMAIN
 	select MODULES_USE_ELF_RELA
 	select OF
diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig
index f5016656494f..9ee35e615c0d 100644
--- a/arch/mips/Kconfig
+++ b/arch/mips/Kconfig
@@ -58,6 +58,7 @@ config MIPS
 	select SYSCTL_EXCEPTION_TRACE
 	select HAVE_VIRT_CPU_ACCOUNTING_GEN
 	select HAVE_IRQ_TIME_ACCOUNTING
+	select ARCH_HAS_MEMREMAP
 
 menu "Machine selection"
 
diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig
index 190cc48abc0c..73c1f8b1f022 100644
--- a/arch/powerpc/Kconfig
+++ b/arch/powerpc/Kconfig
@@ -153,6 +153,7 @@ config PPC
 	select NO_BOOTMEM
 	select HAVE_GENERIC_RCU_GUP
 	select HAVE_PERF_EVENTS_NMI if PPC64
+	select ARCH_HAS_MEMREMAP
 
 config GENERIC_CSUM
 	def_bool CPU_LITTLE_ENDIAN
diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
index 228aa35d7e89..f16caf7eac27 100644
--- a/arch/x86/Kconfig
+++ b/arch/x86/Kconfig
@@ -27,6 +27,7 @@ config X86
 	select ARCH_HAS_ELF_RANDOMIZE
 	select ARCH_HAS_FAST_MULTIPLIER
 	select ARCH_HAS_GCOV_PROFILE_ALL
+	select ARCH_HAS_MEMREMAP
 	select ARCH_HAS_SG_CHAIN
 	select ARCH_HAVE_NMI_SAFE_CMPXCHG
 	select ARCH_MIGHT_HAVE_ACPI_PDC		if ACPI
diff --git a/arch/x86/kernel/crash_dump_64.c b/arch/x86/kernel/crash_dump_64.c
index afa64adb75ee..8e04011665fd 100644
--- a/arch/x86/kernel/crash_dump_64.c
+++ b/arch/x86/kernel/crash_dump_64.c
@@ -31,19 +31,19 @@ ssize_t copy_oldmem_page(unsigned long pfn, char *buf,
 	if (!csize)
 		return 0;
 
-	vaddr = ioremap_cache(pfn << PAGE_SHIFT, PAGE_SIZE);
+	vaddr = memremap_cache(pfn << PAGE_SHIFT, PAGE_SIZE);
 	if (!vaddr)
 		return -ENOMEM;
 
 	if (userbuf) {
 		if (copy_to_user(buf, vaddr + offset, csize)) {
-			iounmap(vaddr);
+			memunmap(vaddr);
 			return -EFAULT;
 		}
 	} else
 		memcpy(buf, vaddr + offset, csize);
 
 	set_iounmap_nonlazy();
-	iounmap(vaddr);
+	memunmap(vaddr);
 	return csize;
 }
diff --git a/arch/x86/kernel/kdebugfs.c b/arch/x86/kernel/kdebugfs.c
index dc1404bf8e4b..731b10e2814f 100644
--- a/arch/x86/kernel/kdebugfs.c
+++ b/arch/x86/kernel/kdebugfs.c
@@ -49,7 +49,7 @@ static ssize_t setup_data_read(struct file *file, char __user *user_buf,
 	pa = node->paddr + sizeof(struct setup_data) + pos;
 	pg = pfn_to_page((pa + count - 1) >> PAGE_SHIFT);
 	if (PageHighMem(pg)) {
-		p = ioremap_cache(pa, count);
+		p = memremap_cache(pa, count);
 		if (!p)
 			return -ENXIO;
 	} else
@@ -58,7 +58,7 @@ static ssize_t setup_data_read(struct file *file, char __user *user_buf,
 	remain = copy_to_user(user_buf, p, count);
 
 	if (PageHighMem(pg))
-		iounmap(p);
+		memunmap(p);
 
 	if (remain)
 		return -EFAULT;
@@ -128,7 +128,7 @@ static int __init create_setup_data_nodes(struct dentry *parent)
 
 		pg = pfn_to_page((pa_data+sizeof(*data)-1) >> PAGE_SHIFT);
 		if (PageHighMem(pg)) {
-			data = ioremap_cache(pa_data, sizeof(*data));
+			data = memremap_cache(pa_data, sizeof(*data));
 			if (!data) {
 				kfree(node);
 				error = -ENXIO;
@@ -144,7 +144,7 @@ static int __init create_setup_data_nodes(struct dentry *parent)
 		pa_data = data->next;
 
 		if (PageHighMem(pg))
-			iounmap(data);
+			memunmap(data);
 		if (error)
 			goto err_dir;
 		no++;
diff --git a/arch/x86/kernel/ksysfs.c b/arch/x86/kernel/ksysfs.c
index c2bedaea11f7..2fbc62886eae 100644
--- a/arch/x86/kernel/ksysfs.c
+++ b/arch/x86/kernel/ksysfs.c
@@ -16,8 +16,8 @@
 #include <linux/stat.h>
 #include <linux/slab.h>
 #include <linux/mm.h>
+#include <linux/io.h>
 
-#include <asm/io.h>
 #include <asm/setup.h>
 
 static ssize_t version_show(struct kobject *kobj,
@@ -79,12 +79,12 @@ static int get_setup_data_paddr(int nr, u64 *paddr)
 			*paddr = pa_data;
 			return 0;
 		}
-		data = ioremap_cache(pa_data, sizeof(*data));
+		data = memremap_cache(pa_data, sizeof(*data));
 		if (!data)
 			return -ENOMEM;
 
 		pa_data = data->next;
-		iounmap(data);
+		memunmap(data);
 		i++;
 	}
 	return -EINVAL;
@@ -97,17 +97,17 @@ static int __init get_setup_data_size(int nr, size_t *size)
 	u64 pa_data = boot_params.hdr.setup_data;
 
 	while (pa_data) {
-		data = ioremap_cache(pa_data, sizeof(*data));
+		data = memremap_cache(pa_data, sizeof(*data));
 		if (!data)
 			return -ENOMEM;
 		if (nr == i) {
 			*size = data->len;
-			iounmap(data);
+			memunmap(data);
 			return 0;
 		}
 
 		pa_data = data->next;
-		iounmap(data);
+		memunmap(data);
 		i++;
 	}
 	return -EINVAL;
@@ -127,12 +127,12 @@ static ssize_t type_show(struct kobject *kobj,
 	ret = get_setup_data_paddr(nr, &paddr);
 	if (ret)
 		return ret;
-	data = ioremap_cache(paddr, sizeof(*data));
+	data = memremap_cache(paddr, sizeof(*data));
 	if (!data)
 		return -ENOMEM;
 
 	ret = sprintf(buf, "0x%x\n", data->type);
-	iounmap(data);
+	memunmap(data);
 	return ret;
 }
 
@@ -154,7 +154,7 @@ static ssize_t setup_data_data_read(struct file *fp,
 	ret = get_setup_data_paddr(nr, &paddr);
 	if (ret)
 		return ret;
-	data = ioremap_cache(paddr, sizeof(*data));
+	data = memremap_cache(paddr, sizeof(*data));
 	if (!data)
 		return -ENOMEM;
 
@@ -170,15 +170,15 @@ static ssize_t setup_data_data_read(struct file *fp,
 		goto out;
 
 	ret = count;
-	p = ioremap_cache(paddr + sizeof(*data), data->len);
+	p = memremap_cache(paddr + sizeof(*data), data->len);
 	if (!p) {
 		ret = -ENOMEM;
 		goto out;
 	}
 	memcpy(buf, p + off, count);
-	iounmap(p);
+	memunmap(p);
 out:
-	iounmap(data);
+	memunmap(data);
 	return ret;
 }
 
@@ -250,13 +250,13 @@ static int __init get_setup_data_total_num(u64 pa_data, int *nr)
 	*nr = 0;
 	while (pa_data) {
 		*nr += 1;
-		data = ioremap_cache(pa_data, sizeof(*data));
+		data = memremap_cache(pa_data, sizeof(*data));
 		if (!data) {
 			ret = -ENOMEM;
 			goto out;
 		}
 		pa_data = data->next;
-		iounmap(data);
+		memunmap(data);
 	}
 
 out:
diff --git a/arch/x86/mm/ioremap.c b/arch/x86/mm/ioremap.c
index cc5ccc415cc0..7f087cb793fa 100644
--- a/arch/x86/mm/ioremap.c
+++ b/arch/x86/mm/ioremap.c
@@ -414,12 +414,10 @@ void *xlate_dev_mem_ptr(phys_addr_t phys)
 	if (page_is_ram(start >> PAGE_SHIFT))
 		return __va(phys);
 
-	vaddr = ioremap_cache(start, PAGE_SIZE);
-	/* Only add the offset on success and return NULL if the ioremap() failed: */
+	vaddr = memremap_cache(start, PAGE_SIZE);
 	if (vaddr)
-		vaddr += offset;
-
-	return vaddr;
+		return vaddr + offset;
+	return NULL;
 }
 
 void unxlate_dev_mem_ptr(phys_addr_t phys, void *addr)
@@ -427,7 +425,7 @@ void unxlate_dev_mem_ptr(phys_addr_t phys, void *addr)
 	if (page_is_ram(phys >> PAGE_SHIFT))
 		return;
 
-	iounmap((void __iomem *)((unsigned long)addr & PAGE_MASK));
+	memunmap((void *)((unsigned long)addr & PAGE_MASK));
 }
 
 static pte_t bm_pte[PAGE_SIZE/sizeof(pte_t)] __page_aligned_bss;
diff --git a/arch/xtensa/Kconfig b/arch/xtensa/Kconfig
index 87be10e8b57a..e601faf87cee 100644
--- a/arch/xtensa/Kconfig
+++ b/arch/xtensa/Kconfig
@@ -3,6 +3,7 @@ config ZONE_DMA
 
 config XTENSA
 	def_bool y
+	select ARCH_HAS_MEMREMAP
 	select ARCH_WANT_FRAME_POINTERS
 	select ARCH_WANT_IPC_PARSE_VERSION
 	select ARCH_WANT_OPTIONAL_GPIOLIB
diff --git a/drivers/acpi/apei/einj.c b/drivers/acpi/apei/einj.c
index a095d4f858da..2ec9006cfb6c 100644
--- a/drivers/acpi/apei/einj.c
+++ b/drivers/acpi/apei/einj.c
@@ -318,7 +318,7 @@ static int __einj_error_trigger(u64 trigger_paddr, u32 type,
 			    sizeof(*trigger_tab) - 1);
 		goto out;
 	}
-	trigger_tab = ioremap_cache(trigger_paddr, sizeof(*trigger_tab));
+	trigger_tab = memremap_cache(trigger_paddr, sizeof(*trigger_tab));
 	if (!trigger_tab) {
 		pr_err(EINJ_PFX "Failed to map trigger table!\n");
 		goto out_rel_header;
@@ -346,8 +346,8 @@ static int __einj_error_trigger(u64 trigger_paddr, u32 type,
 		       (unsigned long long)trigger_paddr + table_size - 1);
 		goto out_rel_header;
 	}
-	iounmap(trigger_tab);
-	trigger_tab = ioremap_cache(trigger_paddr, table_size);
+	memunmap(trigger_tab);
+	trigger_tab = memremap_cache(trigger_paddr, table_size);
 	if (!trigger_tab) {
 		pr_err(EINJ_PFX "Failed to map trigger table!\n");
 		goto out_rel_entry;
@@ -409,7 +409,7 @@ out_rel_header:
 	release_mem_region(trigger_paddr, sizeof(*trigger_tab));
 out:
 	if (trigger_tab)
-		iounmap(trigger_tab);
+		memunmap(trigger_tab);
 
 	return rc;
 }
diff --git a/drivers/acpi/apei/erst.c b/drivers/acpi/apei/erst.c
index 3670bbab57a3..6b95066da51d 100644
--- a/drivers/acpi/apei/erst.c
+++ b/drivers/acpi/apei/erst.c
@@ -77,7 +77,7 @@ static struct acpi_table_erst *erst_tab;
 static struct erst_erange {
 	u64 base;
 	u64 size;
-	void __iomem *vaddr;
+	void *vaddr;
 	u32 attr;
 } erst_erange;
 
@@ -1185,7 +1185,7 @@ static int __init erst_init(void)
 		goto err_unmap_reg;
 	}
 	rc = -ENOMEM;
-	erst_erange.vaddr = ioremap_cache(erst_erange.base,
+	erst_erange.vaddr = memremap_cache(erst_erange.base,
 					  erst_erange.size);
 	if (!erst_erange.vaddr)
 		goto err_release_erange;
diff --git a/drivers/block/Kconfig b/drivers/block/Kconfig
index eb1fed5bd516..98418fc330ae 100644
--- a/drivers/block/Kconfig
+++ b/drivers/block/Kconfig
@@ -406,6 +406,7 @@ config BLK_DEV_RAM_DAX
 
 config BLK_DEV_PMEM
 	tristate "Persistent memory block device support"
+	depends on ARCH_HAS_MEMREMAP
 	help
 	  Saying Y here will allow you to use a contiguous range of reserved
 	  memory as one or more persistent block devices.
diff --git a/drivers/block/pmem.c b/drivers/block/pmem.c
index 095dfaadcaa5..b00b97314b57 100644
--- a/drivers/block/pmem.c
+++ b/drivers/block/pmem.c
@@ -23,6 +23,7 @@
 #include <linux/module.h>
 #include <linux/moduleparam.h>
 #include <linux/slab.h>
+#include <linux/io.h>
 
 #define PMEM_MINORS		16
 
@@ -143,7 +144,7 @@ static struct pmem_device *pmem_alloc(struct device *dev, struct resource *res)
 	 * of the CPU caches in case of a crash.
 	 */
 	err = -ENOMEM;
-	pmem->virt_addr = ioremap_wt(pmem->phys_addr, pmem->size);
+	pmem->virt_addr = memremap_wt(pmem->phys_addr, pmem->size);
 	if (!pmem->virt_addr)
 		goto out_release_region;
 
@@ -179,7 +180,7 @@ static struct pmem_device *pmem_alloc(struct device *dev, struct resource *res)
 out_free_queue:
 	blk_cleanup_queue(pmem->pmem_queue);
 out_unmap:
-	iounmap(pmem->virt_addr);
+	memunmap(pmem->virt_addr);
 out_release_region:
 	release_mem_region(pmem->phys_addr, pmem->size);
 out_free_dev:
@@ -193,7 +194,7 @@ static void pmem_free(struct pmem_device *pmem)
 	del_gendisk(pmem->pmem_disk);
 	put_disk(pmem->pmem_disk);
 	blk_cleanup_queue(pmem->pmem_queue);
-	iounmap(pmem->virt_addr);
+	memunmap(pmem->virt_addr);
 	release_mem_region(pmem->phys_addr, pmem->size);
 	kfree(pmem);
 }
diff --git a/drivers/firmware/google/memconsole.c b/drivers/firmware/google/memconsole.c
index 2f569aaed4c7..877433dc8297 100644
--- a/drivers/firmware/google/memconsole.c
+++ b/drivers/firmware/google/memconsole.c
@@ -52,14 +52,14 @@ static ssize_t memconsole_read(struct file *filp, struct kobject *kobp,
 	char *memconsole;
 	ssize_t ret;
 
-	memconsole = ioremap_cache(memconsole_baseaddr, memconsole_length);
+	memconsole = memremap_cache(memconsole_baseaddr, memconsole_length);
 	if (!memconsole) {
 		pr_err("memconsole: ioremap_cache failed\n");
 		return -ENOMEM;
 	}
 	ret = memory_read_from_buffer(buf, count, &pos, memconsole,
 				      memconsole_length);
-	iounmap(memconsole);
+	memunmap(memconsole);
 	return ret;
 }
 
diff --git a/include/linux/device.h b/include/linux/device.h
index 6558af90c8fe..518f49c5d596 100644
--- a/include/linux/device.h
+++ b/include/linux/device.h
@@ -638,6 +638,11 @@ extern void devm_free_pages(struct device *dev, unsigned long addr);
 
 void __iomem *devm_ioremap_resource(struct device *dev, struct resource *res);
 
+static inline void *devm_memremap_resource(struct device *dev, struct resource *res)
+{
+	return (void __force *) devm_ioremap_resource(dev, res);
+}
+
 /* allows to add/remove a custom action to devres stack */
 int devm_add_action(struct device *dev, void (*action)(void *), void *data);
 void devm_remove_action(struct device *dev, void (*action)(void *), void *data);
diff --git a/include/linux/io.h b/include/linux/io.h
index 8789a114f37c..21dc5de483f6 100644
--- a/include/linux/io.h
+++ b/include/linux/io.h
@@ -181,4 +181,8 @@ static inline int arch_phys_wc_index(int handle)
 #endif
 #endif
 
+extern void *memremap_cache(resource_size_t offset, size_t size);
+extern void *memremap_wt(resource_size_t offset, size_t size);
+extern void memunmap(void *addr);
+
 #endif /* _LINUX_IO_H */
diff --git a/kernel/resource.c b/kernel/resource.c
index 90552aab5f2d..2f8aca09da52 100644
--- a/kernel/resource.c
+++ b/kernel/resource.c
@@ -23,7 +23,7 @@
 #include <linux/pfn.h>
 #include <linux/mm.h>
 #include <linux/resource_ext.h>
-#include <asm/io.h>
+#include <linux/io.h>
 
 
 struct resource ioport_resource = {
@@ -528,6 +528,45 @@ int region_is_ram(resource_size_t start, unsigned long size)
 	return ret;
 }
 
+#ifdef CONFIG_ARCH_HAS_MEMREMAP
+/*
+ * memremap() is "ioremap" for cases where it is known that the resource
+ * being mapped does not have i/o side effects and the __iomem
+ * annotation is not applicable.
+ */
+static bool memremap_valid(resource_size_t offset, size_t size)
+{
+	if (region_is_ram(offset, size) != 0) {
+		WARN_ONCE(1, "memremap attempted on ram %pa size: %zu\n",
+				&offset, size);
+		return false;
+	}
+	return true;
+}
+
+void *memremap_cache(resource_size_t offset, size_t size)
+{
+	if (!memremap_valid(offset, size))
+		return NULL;
+	return (void __force *) ioremap_cache(offset, size);
+}
+EXPORT_SYMBOL(memremap_cache);
+
+void *memremap_wt(resource_size_t offset, size_t size)
+{
+	if (!memremap_valid(offset, size))
+		return NULL;
+	return (void __force *) ioremap_wt(offset, size);
+}
+EXPORT_SYMBOL(memremap_wt);
+
+void memunmap(void *addr)
+{
+	iounmap((void __iomem __force *) addr);
+}
+EXPORT_SYMBOL(memunmap);
+#endif /* CONFIG_ARCH_HAS_MEMREMAP */
+
 void __weak arch_remove_reservations(struct resource *avail)
 {
 }
diff --git a/lib/Kconfig b/lib/Kconfig
index 601965a948e8..bc7bc0278921 100644
--- a/lib/Kconfig
+++ b/lib/Kconfig
@@ -520,6 +520,9 @@ source "lib/fonts/Kconfig"
 #
 
 config ARCH_HAS_SG_CHAIN
-	def_bool n
+	bool
+
+config ARCH_HAS_MEMREMAP
+	bool
 
 endmenu

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
Please read the FAQ at  http://www.tux.org/lkml/

^ permalink raw reply related	[flat|nested] 85+ messages in thread

* [PATCH v5 6/6] arch, x86: pmem api for ensuring durability of persistent memory updates
  2015-06-22  8:24 ` Dan Williams
@ 2015-06-22  8:24   ` Dan Williams
  -1 siblings, 0 replies; 85+ messages in thread
From: Dan Williams @ 2015-06-22  8:24 UTC (permalink / raw)
  To: arnd, mingo, bp, hpa, tglx, ross.zwisler, akpm
  Cc: jgross, x86, toshi.kani, linux-nvdimm, benh, mcgrof, konrad.wilk,
	linux-kernel, stefan.bader, luto, linux-mm, geert, ralf, hmh,
	mpe, tj, paulus, hch

From: Ross Zwisler <ross.zwisler@linux.intel.com>

Based on an original patch by Ross Zwisler [1].

Writes to persistent memory have the potential to be posted to cpu
cache, cpu write buffers, and platform write buffers (memory controller)
before being committed to persistent media.  Provide apis,
memcpy_to_pmem(), wmb_pmem(), and memremap_pmem(), to write data to
pmem and assert that it is durable in PMEM (a persistent linear address
range).  A '__pmem' attribute is added so sparse can track proper usage
of pointers to pmem.

[1]: https://lists.01.org/pipermail/linux-nvdimm/2015-May/000932.html

Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Ingo Molnar <mingo@redhat.com>
Cc: "H. Peter Anvin" <hpa@zytor.com>
Signed-off-by: Ross Zwisler <ross.zwisler@linux.intel.com>
[djbw: various reworks]
Signed-off-by: Dan Williams <dan.j.williams@intel.com>
---
 arch/x86/Kconfig                  |    1 
 arch/x86/include/asm/cacheflush.h |   71 ++++++++++++++++++++++++
 arch/x86/include/asm/io.h         |    6 ++
 drivers/block/pmem.c              |   45 +++++++++++++--
 include/linux/compiler.h          |    2 +
 include/linux/pmem.h              |  110 +++++++++++++++++++++++++++++++++++++
 lib/Kconfig                       |    3 +
 7 files changed, 231 insertions(+), 7 deletions(-)
 create mode 100644 include/linux/pmem.h

diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
index f16caf7eac27..5dfb8f31ac48 100644
--- a/arch/x86/Kconfig
+++ b/arch/x86/Kconfig
@@ -28,6 +28,7 @@ config X86
 	select ARCH_HAS_FAST_MULTIPLIER
 	select ARCH_HAS_GCOV_PROFILE_ALL
 	select ARCH_HAS_MEMREMAP
+	select ARCH_HAS_PMEM_API
 	select ARCH_HAS_SG_CHAIN
 	select ARCH_HAVE_NMI_SAFE_CMPXCHG
 	select ARCH_MIGHT_HAVE_ACPI_PDC		if ACPI
diff --git a/arch/x86/include/asm/cacheflush.h b/arch/x86/include/asm/cacheflush.h
index b6f7457d12e4..2c78c796d679 100644
--- a/arch/x86/include/asm/cacheflush.h
+++ b/arch/x86/include/asm/cacheflush.h
@@ -4,6 +4,7 @@
 /* Caches aren't brain-dead on the intel. */
 #include <asm-generic/cacheflush.h>
 #include <asm/special_insns.h>
+#include <asm/uaccess.h>
 
 /*
  * The set_memory_* API can be used to change various attributes of a virtual
@@ -108,4 +109,74 @@ static inline int rodata_test(void)
 }
 #endif
 
+#ifdef ARCH_HAS_NOCACHE_UACCESS
+
+/**
+ * arch_memcpy_to_pmem - copy data to persistent memory
+ * @dst: destination buffer for the copy
+ * @src: source buffer for the copy
+ * @n: length of the copy in bytes
+ *
+ * Copy data to persistent memory media via non-temporal stores so that
+ * a subsequent arch_wmb_pmem() can flush cpu and memory controller
+ * write buffers to guarantee durability.
+ */
+static inline void arch_memcpy_to_pmem(void __pmem *dst, const void *src, size_t n)
+{
+	int unwritten;
+
+	/*
+	 * We are copying between two kernel buffers, if
+	 * __copy_from_user_inatomic_nocache() returns an error (page
+	 * fault) we would have already reported a general protection fault
+	 * before the WARN+BUG.
+	 */
+	unwritten = __copy_from_user_inatomic_nocache((void __force *) dst,
+			(void __user *) src, n);
+	if (WARN(unwritten, "%s: fault copying %p <- %p unwritten: %d\n",
+				__func__, dst, src, unwritten))
+		BUG();
+}
+
+/**
+ * arch_wmb_pmem - synchronize writes to persistent memory
+ *
+ * After a series of arch_memcpy_to_pmem() operations this drains data
+ * from cpu write buffers and any platform (memory controller) buffers
+ * to ensure that written data is durable on persistent memory media.
+ */
+static inline void arch_wmb_pmem(void)
+{
+	/*
+	 * wmb() to 'sfence' all previous writes such that they are
+	 * architecturally visible to 'pcommit'.  Note, that we've
+	 * already arranged for pmem writes to avoid the cache via
+	 * arch_memcpy_to_pmem().
+	 */
+	wmb();
+	pcommit_sfence();
+}
+
+static inline bool __arch_has_wmb_pmem(void)
+{
+#ifdef CONFIG_X86_64
+	/*
+	 * We require that wmb() be an 'sfence', that is only guaranteed on
+	 * 64-bit builds
+	 */
+	return static_cpu_has(X86_FEATURE_PCOMMIT);
+#else
+	return false;
+#endif
+}
+#else /* ARCH_HAS_NOCACHE_UACCESS i.e. ARCH=um */
+extern void arch_memcpy_to_pmem(void __pmem *dst, const void *src, size_t n);
+extern void arch_wmb_pmem(void);
+
+static inline bool __arch_has_wmb_pmem(void)
+{
+	return false;
+}
+#endif
+
 #endif /* _ASM_X86_CACHEFLUSH_H */
diff --git a/arch/x86/include/asm/io.h b/arch/x86/include/asm/io.h
index 97ae3b748d9e..0d3e43f679aa 100644
--- a/arch/x86/include/asm/io.h
+++ b/arch/x86/include/asm/io.h
@@ -249,6 +249,12 @@ static inline void flush_write_buffers(void)
 #endif
 }
 
+static inline void __pmem *arch_memremap_pmem(resource_size_t offset,
+	unsigned long size)
+{
+	return (void __force __pmem *) ioremap_cache(offset, size);
+}
+
 #endif /* __KERNEL__ */
 
 extern void native_io_delay(void);
diff --git a/drivers/block/pmem.c b/drivers/block/pmem.c
index b00b97314b57..8507a5fff464 100644
--- a/drivers/block/pmem.c
+++ b/drivers/block/pmem.c
@@ -23,6 +23,7 @@
 #include <linux/module.h>
 #include <linux/moduleparam.h>
 #include <linux/slab.h>
+#include <linux/pmem.h>
 #include <linux/io.h>
 
 #define PMEM_MINORS		16
@@ -33,26 +34,47 @@ struct pmem_device {
 
 	/* One contiguous memory region per device */
 	phys_addr_t		phys_addr;
-	void			*virt_addr;
+	void __pmem		*virt_addr;
 	size_t			size;
 };
 
 static int pmem_major;
 static atomic_t pmem_index;
 
+/*
+ * These defaults seek to offer decent performance and minimize the
+ * window between i/o completion and writes being durable on media.
+ * However, it is undefined / architecture specific whether
+ * default_memremap_pmem + default_memcpy_to_pmem is sufficient for
+ * making data durable relative to i/o completion.
+ */
+static void default_memcpy_to_pmem(void __pmem *dst, const void *src, size_t size)
+{
+	memcpy((void __force *) dst, src, size);
+}
+
+static void __pmem *default_memremap_pmem(resource_size_t offset, unsigned long size)
+{
+	return (void __pmem *)memremap_wt(offset, size);
+}
+
 static void pmem_do_bvec(struct pmem_device *pmem, struct page *page,
 			unsigned int len, unsigned int off, int rw,
 			sector_t sector)
 {
 	void *mem = kmap_atomic(page);
 	size_t pmem_off = sector << 9;
+	void __pmem *pmem_addr = pmem->virt_addr + pmem_off;
 
 	if (rw == READ) {
-		memcpy(mem + off, pmem->virt_addr + pmem_off, len);
+		memcpy_from_pmem(mem + off, pmem_addr, len);
 		flush_dcache_page(page);
 	} else {
 		flush_dcache_page(page);
-		memcpy(pmem->virt_addr + pmem_off, mem + off, len);
+		if (arch_has_pmem_api())
+			memcpy_to_pmem(pmem_addr, mem + off, len);
+		else
+			default_memcpy_to_pmem(pmem_addr, mem + off, len);
 	}
 
 	kunmap_atomic(mem);
@@ -83,6 +105,8 @@ static void pmem_make_request(struct request_queue *q, struct bio *bio)
 		sector += bvec.bv_len >> 9;
 	}
 
+	if (rw && arch_has_pmem_api())
+		wmb_pmem();
 out:
 	bio_endio(bio, err);
 }
@@ -107,7 +131,8 @@ static long pmem_direct_access(struct block_device *bdev, sector_t sector,
 	if (!pmem)
 		return -ENODEV;
 
-	*kaddr = pmem->virt_addr + offset;
+	/* FIXME convert DAX to comprehend that this mapping has a lifetime */
+	*kaddr = (void __force *) pmem->virt_addr + offset;
 	*pfn = (pmem->phys_addr + offset) >> PAGE_SHIFT;
 
 	return pmem->size - offset;
@@ -132,6 +157,8 @@ static struct pmem_device *pmem_alloc(struct device *dev, struct resource *res)
 
 	pmem->phys_addr = res->start;
 	pmem->size = resource_size(res);
+	if (!arch_has_pmem_api())
+		dev_warn(dev, "unable to guarantee persistence of writes\n");
 
 	err = -EINVAL;
 	if (!request_mem_region(pmem->phys_addr, pmem->size, "pmem")) {
@@ -144,7 +171,11 @@ static struct pmem_device *pmem_alloc(struct device *dev, struct resource *res)
 	 * of the CPU caches in case of a crash.
 	 */
 	err = -ENOMEM;
-	pmem->virt_addr = memremap_wt(pmem->phys_addr, pmem->size);
+	if (arch_has_pmem_api())
+		pmem->virt_addr = memremap_pmem(pmem->phys_addr, pmem->size);
+	else
+		pmem->virt_addr = default_memremap_pmem(pmem->phys_addr,
+				pmem->size);
 	if (!pmem->virt_addr)
 		goto out_release_region;
 
@@ -180,7 +211,7 @@ static struct pmem_device *pmem_alloc(struct device *dev, struct resource *res)
 out_free_queue:
 	blk_cleanup_queue(pmem->pmem_queue);
 out_unmap:
-	memunmap(pmem->virt_addr);
+	memunmap_pmem(pmem->virt_addr);
 out_release_region:
 	release_mem_region(pmem->phys_addr, pmem->size);
 out_free_dev:
@@ -194,7 +225,7 @@ static void pmem_free(struct pmem_device *pmem)
 	del_gendisk(pmem->pmem_disk);
 	put_disk(pmem->pmem_disk);
 	blk_cleanup_queue(pmem->pmem_queue);
-	memunmap(pmem->virt_addr);
+	memunmap_pmem(pmem->virt_addr);
 	release_mem_region(pmem->phys_addr, pmem->size);
 	kfree(pmem);
 }
diff --git a/include/linux/compiler.h b/include/linux/compiler.h
index 05be2352fef8..26fc8bc77f85 100644
--- a/include/linux/compiler.h
+++ b/include/linux/compiler.h
@@ -21,6 +21,7 @@
 # define __rcu		__attribute__((noderef, address_space(4)))
 #else
 # define __rcu
+# define __pmem		__attribute__((noderef, address_space(5)))
 #endif
 extern void __chk_user_ptr(const volatile void __user *);
 extern void __chk_io_ptr(const volatile void __iomem *);
@@ -42,6 +43,7 @@ extern void __chk_io_ptr(const volatile void __iomem *);
 # define __cond_lock(x,c) (c)
 # define __percpu
 # define __rcu
+# define __pmem
 #endif
 
 /* Indirect macros required for expanded argument pasting, eg. __LINE__. */
diff --git a/include/linux/pmem.h b/include/linux/pmem.h
new file mode 100644
index 000000000000..5575b524c51a
--- /dev/null
+++ b/include/linux/pmem.h
@@ -0,0 +1,110 @@
+/*
+ * Copyright(c) 2015 Intel Corporation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ */
+#ifndef __PMEM_H__
+#define __PMEM_H__
+
+#include <linux/io.h>
+#include <asm/cacheflush.h>
+
+/*
+ * Architectures that define ARCH_HAS_PMEM_API must provide
+ * implementations for arch_memremap_pmem(), arch_memcpy_to_pmem(),
+ * arch_wmb_pmem(), and __arch_has_wmb_pmem().
+ */
+
+#ifdef CONFIG_ARCH_HAS_PMEM_API
+/**
+ * memremap_pmem - map physical persistent memory for pmem api
+ * @offset: physical address of persistent memory
+ * @size: size of the mapping
+ *
+ * Establish a mapping of the architecture specific memory type expected
+ * by memcpy_to_pmem() and wmb_pmem().  For example, it may be
+ * the case that an uncacheable or writethrough mapping is sufficient,
+ * or a writeback mapping provided memcpy_to_pmem() and
+ * wmb_pmem() arrange for the data to be written through the
+ * cache to persistent media.
+ */
+static inline void __pmem *memremap_pmem(resource_size_t offset, unsigned long size)
+{
+	return arch_memremap_pmem(offset, size);
+}
+
+/**
+ * memcpy_to_pmem - copy data to persistent memory
+ * @dst: destination buffer for the copy
+ * @src: source buffer for the copy
+ * @n: length of the copy in bytes
+ *
+ * Perform a memory copy that results in the destination of the copy
+ * being effectively evicted from, or never written to, the processor
+ * cache hierarchy after the copy completes.  After memcpy_to_pmem()
+ * data may still reside in cpu or platform buffers, so this operation
+ * must be followed by a wmb_pmem().
+ */
+static inline void memcpy_to_pmem(void __pmem *dst, const void *src, size_t n)
+{
+	arch_memcpy_to_pmem(dst, src, n);
+}
+
+/**
+ * wmb_pmem - synchronize writes to persistent memory
+ *
+ * After a series of memcpy_to_pmem() operations this drains data from
+ * cpu write buffers and any platform (memory controller) buffers to
+ * ensure that written data is durable on persistent memory media.
+ */
+static inline void wmb_pmem(void)
+{
+	arch_wmb_pmem();
+}
+
+/**
+ * arch_has_wmb_pmem - true if wmb_pmem() ensures durability
+ *
+ * For a given cpu implementation within an architecture it is possible
+ * that wmb_pmem() resolves to a nop.  In the case this returns
+ * false, pmem api users are unable to ensure durability and may want to
+ * fall back to a different data consistency model, or otherwise notify
+ * the user.
+ */
+static inline bool arch_has_wmb_pmem(void)
+{
+	return __arch_has_wmb_pmem();
+}
+#else
+/* undefined symbols */
+extern void __pmem *memremap_pmem(resource_size_t offet, unsigned long size);
+extern void memcpy_to_pmem(void __pmem *dst, const void *src, size_t n);
+extern void wmb_pmem(void);
+static inline bool arch_has_wmb_pmem(void)
+{
+	return false;
+}
+#endif /* CONFIG_ARCH_HAS_PMEM_API */
+
+static inline void memcpy_from_pmem(void *dst, void __pmem const *src, size_t size)
+{
+	memcpy(dst, (void __force const *) src, size);
+}
+
+static inline void memunmap_pmem(void __pmem *addr)
+{
+	memunmap((void __force *) addr);
+}
+
+static inline bool arch_has_pmem_api(void)
+{
+	return IS_ENABLED(CONFIG_ARCH_HAS_PMEM_API) && arch_has_wmb_pmem();
+}
+#endif /* __PMEM_H__ */
diff --git a/lib/Kconfig b/lib/Kconfig
index bc7bc0278921..0d28cc560c6b 100644
--- a/lib/Kconfig
+++ b/lib/Kconfig
@@ -525,4 +525,7 @@ config ARCH_HAS_SG_CHAIN
 config ARCH_HAS_MEMREMAP
 	bool
 
+config ARCH_HAS_PMEM_API
+	bool
+
 endmenu

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org.  For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>

^ permalink raw reply related	[flat|nested] 85+ messages in thread

* [PATCH v5 6/6] arch, x86: pmem api for ensuring durability of persistent memory updates
@ 2015-06-22  8:24   ` Dan Williams
  0 siblings, 0 replies; 85+ messages in thread
From: Dan Williams @ 2015-06-22  8:24 UTC (permalink / raw)
  To: arnd, mingo, bp, hpa, tglx, ross.zwisler, akpm
  Cc: jgross, x86, toshi.kani, linux-nvdimm, benh, mcgrof, konrad.wilk,
	linux-kernel, stefan.bader, luto, linux-mm, geert, ralf, hmh,
	mpe, tj, paulus, hch

From: Ross Zwisler <ross.zwisler@linux.intel.com>

Based on an original patch by Ross Zwisler [1].

Writes to persistent memory have the potential to be posted to cpu
cache, cpu write buffers, and platform write buffers (memory controller)
before being committed to persistent media.  Provide apis,
memcpy_to_pmem(), wmb_pmem(), and memremap_pmem(), to write data to
pmem and assert that it is durable in PMEM (a persistent linear address
range).  A '__pmem' attribute is added so sparse can track proper usage
of pointers to pmem.

[1]: https://lists.01.org/pipermail/linux-nvdimm/2015-May/000932.html

Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Ingo Molnar <mingo@redhat.com>
Cc: "H. Peter Anvin" <hpa@zytor.com>
Signed-off-by: Ross Zwisler <ross.zwisler@linux.intel.com>
[djbw: various reworks]
Signed-off-by: Dan Williams <dan.j.williams@intel.com>
---
 arch/x86/Kconfig                  |    1 
 arch/x86/include/asm/cacheflush.h |   71 ++++++++++++++++++++++++
 arch/x86/include/asm/io.h         |    6 ++
 drivers/block/pmem.c              |   45 +++++++++++++--
 include/linux/compiler.h          |    2 +
 include/linux/pmem.h              |  110 +++++++++++++++++++++++++++++++++++++
 lib/Kconfig                       |    3 +
 7 files changed, 231 insertions(+), 7 deletions(-)
 create mode 100644 include/linux/pmem.h

diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
index f16caf7eac27..5dfb8f31ac48 100644
--- a/arch/x86/Kconfig
+++ b/arch/x86/Kconfig
@@ -28,6 +28,7 @@ config X86
 	select ARCH_HAS_FAST_MULTIPLIER
 	select ARCH_HAS_GCOV_PROFILE_ALL
 	select ARCH_HAS_MEMREMAP
+	select ARCH_HAS_PMEM_API
 	select ARCH_HAS_SG_CHAIN
 	select ARCH_HAVE_NMI_SAFE_CMPXCHG
 	select ARCH_MIGHT_HAVE_ACPI_PDC		if ACPI
diff --git a/arch/x86/include/asm/cacheflush.h b/arch/x86/include/asm/cacheflush.h
index b6f7457d12e4..2c78c796d679 100644
--- a/arch/x86/include/asm/cacheflush.h
+++ b/arch/x86/include/asm/cacheflush.h
@@ -4,6 +4,7 @@
 /* Caches aren't brain-dead on the intel. */
 #include <asm-generic/cacheflush.h>
 #include <asm/special_insns.h>
+#include <asm/uaccess.h>
 
 /*
  * The set_memory_* API can be used to change various attributes of a virtual
@@ -108,4 +109,74 @@ static inline int rodata_test(void)
 }
 #endif
 
+#ifdef ARCH_HAS_NOCACHE_UACCESS
+
+/**
+ * arch_memcpy_to_pmem - copy data to persistent memory
+ * @dst: destination buffer for the copy
+ * @src: source buffer for the copy
+ * @n: length of the copy in bytes
+ *
+ * Copy data to persistent memory media via non-temporal stores so that
+ * a subsequent arch_wmb_pmem() can flush cpu and memory controller
+ * write buffers to guarantee durability.
+ */
+static inline void arch_memcpy_to_pmem(void __pmem *dst, const void *src, size_t n)
+{
+	int unwritten;
+
+	/*
+	 * We are copying between two kernel buffers, if
+	 * __copy_from_user_inatomic_nocache() returns an error (page
+	 * fault) we would have already reported a general protection fault
+	 * before the WARN+BUG.
+	 */
+	unwritten = __copy_from_user_inatomic_nocache((void __force *) dst,
+			(void __user *) src, n);
+	if (WARN(unwritten, "%s: fault copying %p <- %p unwritten: %d\n",
+				__func__, dst, src, unwritten))
+		BUG();
+}
+
+/**
+ * arch_wmb_pmem - synchronize writes to persistent memory
+ *
+ * After a series of arch_memcpy_to_pmem() operations this drains data
+ * from cpu write buffers and any platform (memory controller) buffers
+ * to ensure that written data is durable on persistent memory media.
+ */
+static inline void arch_wmb_pmem(void)
+{
+	/*
+	 * wmb() to 'sfence' all previous writes such that they are
+	 * architecturally visible to 'pcommit'.  Note, that we've
+	 * already arranged for pmem writes to avoid the cache via
+	 * arch_memcpy_to_pmem().
+	 */
+	wmb();
+	pcommit_sfence();
+}
+
+static inline bool __arch_has_wmb_pmem(void)
+{
+#ifdef CONFIG_X86_64
+	/*
+	 * We require that wmb() be an 'sfence', that is only guaranteed on
+	 * 64-bit builds
+	 */
+	return static_cpu_has(X86_FEATURE_PCOMMIT);
+#else
+	return false;
+#endif
+}
+#else /* ARCH_HAS_NOCACHE_UACCESS i.e. ARCH=um */
+extern void arch_memcpy_to_pmem(void __pmem *dst, const void *src, size_t n);
+extern void arch_wmb_pmem(void);
+
+static inline bool __arch_has_wmb_pmem(void)
+{
+	return false;
+}
+#endif
+
 #endif /* _ASM_X86_CACHEFLUSH_H */
diff --git a/arch/x86/include/asm/io.h b/arch/x86/include/asm/io.h
index 97ae3b748d9e..0d3e43f679aa 100644
--- a/arch/x86/include/asm/io.h
+++ b/arch/x86/include/asm/io.h
@@ -249,6 +249,12 @@ static inline void flush_write_buffers(void)
 #endif
 }
 
+static inline void __pmem *arch_memremap_pmem(resource_size_t offset,
+	unsigned long size)
+{
+	return (void __force __pmem *) ioremap_cache(offset, size);
+}
+
 #endif /* __KERNEL__ */
 
 extern void native_io_delay(void);
diff --git a/drivers/block/pmem.c b/drivers/block/pmem.c
index b00b97314b57..8507a5fff464 100644
--- a/drivers/block/pmem.c
+++ b/drivers/block/pmem.c
@@ -23,6 +23,7 @@
 #include <linux/module.h>
 #include <linux/moduleparam.h>
 #include <linux/slab.h>
+#include <linux/pmem.h>
 #include <linux/io.h>
 
 #define PMEM_MINORS		16
@@ -33,26 +34,47 @@ struct pmem_device {
 
 	/* One contiguous memory region per device */
 	phys_addr_t		phys_addr;
-	void			*virt_addr;
+	void __pmem		*virt_addr;
 	size_t			size;
 };
 
 static int pmem_major;
 static atomic_t pmem_index;
 
+/*
+ * These defaults seek to offer decent performance and minimize the
+ * window between i/o completion and writes being durable on media.
+ * However, it is undefined / architecture specific whether
+ * default_memremap_pmem + default_memcpy_to_pmem is sufficient for
+ * making data durable relative to i/o completion.
+ */
+static void default_memcpy_to_pmem(void __pmem *dst, const void *src, size_t size)
+{
+	memcpy((void __force *) dst, src, size);
+}
+
+static void __pmem *default_memremap_pmem(resource_size_t offset, unsigned long size)
+{
+	return (void __pmem *)memremap_wt(offset, size);
+}
+
 static void pmem_do_bvec(struct pmem_device *pmem, struct page *page,
 			unsigned int len, unsigned int off, int rw,
 			sector_t sector)
 {
 	void *mem = kmap_atomic(page);
 	size_t pmem_off = sector << 9;
+	void __pmem *pmem_addr = pmem->virt_addr + pmem_off;
 
 	if (rw == READ) {
-		memcpy(mem + off, pmem->virt_addr + pmem_off, len);
+		memcpy_from_pmem(mem + off, pmem_addr, len);
 		flush_dcache_page(page);
 	} else {
 		flush_dcache_page(page);
-		memcpy(pmem->virt_addr + pmem_off, mem + off, len);
+		if (arch_has_pmem_api())
+			memcpy_to_pmem(pmem_addr, mem + off, len);
+		else
+			default_memcpy_to_pmem(pmem_addr, mem + off, len);
 	}
 
 	kunmap_atomic(mem);
@@ -83,6 +105,8 @@ static void pmem_make_request(struct request_queue *q, struct bio *bio)
 		sector += bvec.bv_len >> 9;
 	}
 
+	if (rw && arch_has_pmem_api())
+		wmb_pmem();
 out:
 	bio_endio(bio, err);
 }
@@ -107,7 +131,8 @@ static long pmem_direct_access(struct block_device *bdev, sector_t sector,
 	if (!pmem)
 		return -ENODEV;
 
-	*kaddr = pmem->virt_addr + offset;
+	/* FIXME convert DAX to comprehend that this mapping has a lifetime */
+	*kaddr = (void __force *) pmem->virt_addr + offset;
 	*pfn = (pmem->phys_addr + offset) >> PAGE_SHIFT;
 
 	return pmem->size - offset;
@@ -132,6 +157,8 @@ static struct pmem_device *pmem_alloc(struct device *dev, struct resource *res)
 
 	pmem->phys_addr = res->start;
 	pmem->size = resource_size(res);
+	if (!arch_has_pmem_api())
+		dev_warn(dev, "unable to guarantee persistence of writes\n");
 
 	err = -EINVAL;
 	if (!request_mem_region(pmem->phys_addr, pmem->size, "pmem")) {
@@ -144,7 +171,11 @@ static struct pmem_device *pmem_alloc(struct device *dev, struct resource *res)
 	 * of the CPU caches in case of a crash.
 	 */
 	err = -ENOMEM;
-	pmem->virt_addr = memremap_wt(pmem->phys_addr, pmem->size);
+	if (arch_has_pmem_api())
+		pmem->virt_addr = memremap_pmem(pmem->phys_addr, pmem->size);
+	else
+		pmem->virt_addr = default_memremap_pmem(pmem->phys_addr,
+				pmem->size);
 	if (!pmem->virt_addr)
 		goto out_release_region;
 
@@ -180,7 +211,7 @@ static struct pmem_device *pmem_alloc(struct device *dev, struct resource *res)
 out_free_queue:
 	blk_cleanup_queue(pmem->pmem_queue);
 out_unmap:
-	memunmap(pmem->virt_addr);
+	memunmap_pmem(pmem->virt_addr);
 out_release_region:
 	release_mem_region(pmem->phys_addr, pmem->size);
 out_free_dev:
@@ -194,7 +225,7 @@ static void pmem_free(struct pmem_device *pmem)
 	del_gendisk(pmem->pmem_disk);
 	put_disk(pmem->pmem_disk);
 	blk_cleanup_queue(pmem->pmem_queue);
-	memunmap(pmem->virt_addr);
+	memunmap_pmem(pmem->virt_addr);
 	release_mem_region(pmem->phys_addr, pmem->size);
 	kfree(pmem);
 }
diff --git a/include/linux/compiler.h b/include/linux/compiler.h
index 05be2352fef8..26fc8bc77f85 100644
--- a/include/linux/compiler.h
+++ b/include/linux/compiler.h
@@ -21,6 +21,7 @@
 # define __rcu		__attribute__((noderef, address_space(4)))
 #else
 # define __rcu
+# define __pmem		__attribute__((noderef, address_space(5)))
 #endif
 extern void __chk_user_ptr(const volatile void __user *);
 extern void __chk_io_ptr(const volatile void __iomem *);
@@ -42,6 +43,7 @@ extern void __chk_io_ptr(const volatile void __iomem *);
 # define __cond_lock(x,c) (c)
 # define __percpu
 # define __rcu
+# define __pmem
 #endif
 
 /* Indirect macros required for expanded argument pasting, eg. __LINE__. */
diff --git a/include/linux/pmem.h b/include/linux/pmem.h
new file mode 100644
index 000000000000..5575b524c51a
--- /dev/null
+++ b/include/linux/pmem.h
@@ -0,0 +1,110 @@
+/*
+ * Copyright(c) 2015 Intel Corporation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ */
+#ifndef __PMEM_H__
+#define __PMEM_H__
+
+#include <linux/io.h>
+#include <asm/cacheflush.h>
+
+/*
+ * Architectures that define ARCH_HAS_PMEM_API must provide
+ * implementations for arch_memremap_pmem(), arch_memcpy_to_pmem(),
+ * arch_wmb_pmem(), and __arch_has_wmb_pmem().
+ */
+
+#ifdef CONFIG_ARCH_HAS_PMEM_API
+/**
+ * memremap_pmem - map physical persistent memory for pmem api
+ * @offset: physical address of persistent memory
+ * @size: size of the mapping
+ *
+ * Establish a mapping of the architecture specific memory type expected
+ * by memcpy_to_pmem() and wmb_pmem().  For example, it may be
+ * the case that an uncacheable or writethrough mapping is sufficient,
+ * or a writeback mapping provided memcpy_to_pmem() and
+ * wmb_pmem() arrange for the data to be written through the
+ * cache to persistent media.
+ */
+static inline void __pmem *memremap_pmem(resource_size_t offset, unsigned long size)
+{
+	return arch_memremap_pmem(offset, size);
+}
+
+/**
+ * memcpy_to_pmem - copy data to persistent memory
+ * @dst: destination buffer for the copy
+ * @src: source buffer for the copy
+ * @n: length of the copy in bytes
+ *
+ * Perform a memory copy that results in the destination of the copy
+ * being effectively evicted from, or never written to, the processor
+ * cache hierarchy after the copy completes.  After memcpy_to_pmem()
+ * data may still reside in cpu or platform buffers, so this operation
+ * must be followed by a wmb_pmem().
+ */
+static inline void memcpy_to_pmem(void __pmem *dst, const void *src, size_t n)
+{
+	arch_memcpy_to_pmem(dst, src, n);
+}
+
+/**
+ * wmb_pmem - synchronize writes to persistent memory
+ *
+ * After a series of memcpy_to_pmem() operations this drains data from
+ * cpu write buffers and any platform (memory controller) buffers to
+ * ensure that written data is durable on persistent memory media.
+ */
+static inline void wmb_pmem(void)
+{
+	arch_wmb_pmem();
+}
+
+/**
+ * arch_has_wmb_pmem - true if wmb_pmem() ensures durability
+ *
+ * For a given cpu implementation within an architecture it is possible
+ * that wmb_pmem() resolves to a nop.  In the case this returns
+ * false, pmem api users are unable to ensure durability and may want to
+ * fall back to a different data consistency model, or otherwise notify
+ * the user.
+ */
+static inline bool arch_has_wmb_pmem(void)
+{
+	return __arch_has_wmb_pmem();
+}
+#else
+/* undefined symbols */
+extern void __pmem *memremap_pmem(resource_size_t offet, unsigned long size);
+extern void memcpy_to_pmem(void __pmem *dst, const void *src, size_t n);
+extern void wmb_pmem(void);
+static inline bool arch_has_wmb_pmem(void)
+{
+	return false;
+}
+#endif /* CONFIG_ARCH_HAS_PMEM_API */
+
+static inline void memcpy_from_pmem(void *dst, void __pmem const *src, size_t size)
+{
+	memcpy(dst, (void __force const *) src, size);
+}
+
+static inline void memunmap_pmem(void __pmem *addr)
+{
+	memunmap((void __force *) addr);
+}
+
+static inline bool arch_has_pmem_api(void)
+{
+	return IS_ENABLED(CONFIG_ARCH_HAS_PMEM_API) && arch_has_wmb_pmem();
+}
+#endif /* __PMEM_H__ */
diff --git a/lib/Kconfig b/lib/Kconfig
index bc7bc0278921..0d28cc560c6b 100644
--- a/lib/Kconfig
+++ b/lib/Kconfig
@@ -525,4 +525,7 @@ config ARCH_HAS_SG_CHAIN
 config ARCH_HAS_MEMREMAP
 	bool
 
+config ARCH_HAS_PMEM_API
+	bool
+
 endmenu

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
Please read the FAQ at  http://www.tux.org/lkml/

^ permalink raw reply related	[flat|nested] 85+ messages in thread

* Re: [PATCH v5 1/6] arch, drivers: don't include <asm/io.h> directly, use <linux/io.h> instead
  2015-06-22  8:24   ` Dan Williams
@ 2015-06-22 16:01     ` Christoph Hellwig
  -1 siblings, 0 replies; 85+ messages in thread
From: Christoph Hellwig @ 2015-06-22 16:01 UTC (permalink / raw)
  To: Dan Williams
  Cc: arnd, mingo, bp, hpa, tglx, ross.zwisler, akpm, jgross, x86,
	toshi.kani, linux-nvdimm, benh, mcgrof, konrad.wilk,
	linux-kernel, stefan.bader, luto, linux-mm, geert, ralf, hmh,
	mpe, tj, paulus

On Mon, Jun 22, 2015 at 04:24:22AM -0400, Dan Williams wrote:
> Preparation for uniform definition of ioremap, ioremap_wc, ioremap_wt,
> and ioremap_cache, tree-wide.
> 
> Signed-off-by: Dan Williams <dan.j.williams@intel.com>

Looks good,

Reviewed-by: Christoph Hellwig <hch@lst.de>

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org.  For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>

^ permalink raw reply	[flat|nested] 85+ messages in thread

* Re: [PATCH v5 1/6] arch, drivers: don't include <asm/io.h> directly, use <linux/io.h> instead
@ 2015-06-22 16:01     ` Christoph Hellwig
  0 siblings, 0 replies; 85+ messages in thread
From: Christoph Hellwig @ 2015-06-22 16:01 UTC (permalink / raw)
  To: Dan Williams
  Cc: arnd, mingo, bp, hpa, tglx, ross.zwisler, akpm, jgross, x86,
	toshi.kani, linux-nvdimm, benh, mcgrof, konrad.wilk,
	linux-kernel, stefan.bader, luto, linux-mm, geert, ralf, hmh,
	mpe, tj, paulus

On Mon, Jun 22, 2015 at 04:24:22AM -0400, Dan Williams wrote:
> Preparation for uniform definition of ioremap, ioremap_wc, ioremap_wt,
> and ioremap_cache, tree-wide.
> 
> Signed-off-by: Dan Williams <dan.j.williams@intel.com>

Looks good,

Reviewed-by: Christoph Hellwig <hch@lst.de>
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
Please read the FAQ at  http://www.tux.org/lkml/

^ permalink raw reply	[flat|nested] 85+ messages in thread

* Re: [PATCH v5 2/6] arch: unify ioremap prototypes and macro aliases
  2015-06-22  8:24   ` Dan Williams
@ 2015-06-22 16:10     ` Christoph Hellwig
  -1 siblings, 0 replies; 85+ messages in thread
From: Christoph Hellwig @ 2015-06-22 16:10 UTC (permalink / raw)
  To: Dan Williams
  Cc: arnd, mingo, bp, hpa, tglx, ross.zwisler, akpm, jgross, x86,
	toshi.kani, linux-nvdimm, benh, mcgrof, konrad.wilk,
	linux-kernel, stefan.bader, luto, linux-mm, geert, ralf, hmh,
	mpe, tj, paulus, hch

On Mon, Jun 22, 2015 at 04:24:27AM -0400, Dan Williams wrote:
> Some archs define the first parameter to ioremap() as unsigned long,
> while the balance define it as resource_size_t.  Unify on
> resource_size_t to enable passing ioremap function pointers.  Also, some
> archs use function-like macros for defining ioremap aliases, but
> asm-generic/io.h expects object-like macros, unify on the latter.
> 
> Move all handling of ioremap aliasing (i.e. ioremap_wt => ioremap) to
> include/linux/io.h.  Add a check to include/linux/io.h to warn at
> compile time if an arch violates expectations.
> 
> Kill ARCH_HAS_IOREMAP_WC and ARCH_HAS_IOREMAP_WT in favor of just
> testing for ioremap_wc, and ioremap_wt being defined.  This arrangement
> allows drivers to know when ioremap_<foo> are being re-directed to plain
> ioremap.
> 
> Reported-by: kbuild test robot <fengguang.wu@intel.com>
> Signed-off-by: Dan Williams <dan.j.williams@intel.com>

Hmm, this is quite a bit of churn, and doesn't make the interface lot
more obvious.

I guess it's enough to get the pmem related bits going, but I'd really
prefer defining the ioremap* prototype in linux/io.h and requiring
and out of line implementation in the architectures, it's not like
it's a fast path.  And to avoid the ifdef mess make it something like:

void __iomem *ioremap_flags(resource_size_t offset, unsigned long size,
			unsigned long prot_val, unsigned flags);

static inline void __iomem *ioremap(resource_size_t offset, unsigned long size)
{
	return ioremap_flags(offset, size, 0, 0);
}

static inline void __iomem *ioremap_prot(resource_size_t offset,
		unsigned long size, unsigned long prot_val)
{
	return ioremap_flags(offset, size, prot_val, 0);
}

static inline void __iomem *ioremap_nocache(resource_size_t offset,
		unsigned long size)
{
	return ioremap_flags(offset, size, 0, IOREMAP_NOCACHE);
}

static inline void __iomem *ioremap_cache(resource_size_t offset,
		unsigned long size)
{
	return ioremap_flags(offset, size, 0, IOREMAP_CACHE);
}

static inline void __iomem *ioremap_uc(resource_size_t offset,
		unsigned long size)
{
	return ioremap_flags(offset, size, 0, IOREMAP_UC);
}

static inline void __iomem *ioremap_wc(resource_size_t offset,
		unsigned long size)
{
	return ioremap_flags(offset, size, 0, IOREMAP_WC);
}

static inline void __iomem *ioremap_wt(resource_size_t offset,
		unsigned long size)
{
	return ioremap_flags(offset, size, 0, IOREMAP_WT);
}

With all wrappers but ioremap() itself deprecated in the long run.

Besides following the one API one prototype guideline this gives
us one proper entry point for all the variants.  Additionally
it can reject non-supported caching modes at run time, e.g. because
different hardware may or may not support it.  Additionally it
avoids the need for all these HAVE_IOREMAP_FOO defines, which need
constant updating.

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org.  For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>

^ permalink raw reply	[flat|nested] 85+ messages in thread

* Re: [PATCH v5 2/6] arch: unify ioremap prototypes and macro aliases
@ 2015-06-22 16:10     ` Christoph Hellwig
  0 siblings, 0 replies; 85+ messages in thread
From: Christoph Hellwig @ 2015-06-22 16:10 UTC (permalink / raw)
  To: Dan Williams
  Cc: arnd, mingo, bp, hpa, tglx, ross.zwisler, akpm, jgross, x86,
	toshi.kani, linux-nvdimm, benh, mcgrof, konrad.wilk,
	linux-kernel, stefan.bader, luto, linux-mm, geert, ralf, hmh,
	mpe, tj, paulus, hch

On Mon, Jun 22, 2015 at 04:24:27AM -0400, Dan Williams wrote:
> Some archs define the first parameter to ioremap() as unsigned long,
> while the balance define it as resource_size_t.  Unify on
> resource_size_t to enable passing ioremap function pointers.  Also, some
> archs use function-like macros for defining ioremap aliases, but
> asm-generic/io.h expects object-like macros, unify on the latter.
> 
> Move all handling of ioremap aliasing (i.e. ioremap_wt => ioremap) to
> include/linux/io.h.  Add a check to include/linux/io.h to warn at
> compile time if an arch violates expectations.
> 
> Kill ARCH_HAS_IOREMAP_WC and ARCH_HAS_IOREMAP_WT in favor of just
> testing for ioremap_wc, and ioremap_wt being defined.  This arrangement
> allows drivers to know when ioremap_<foo> are being re-directed to plain
> ioremap.
> 
> Reported-by: kbuild test robot <fengguang.wu@intel.com>
> Signed-off-by: Dan Williams <dan.j.williams@intel.com>

Hmm, this is quite a bit of churn, and doesn't make the interface lot
more obvious.

I guess it's enough to get the pmem related bits going, but I'd really
prefer defining the ioremap* prototype in linux/io.h and requiring
and out of line implementation in the architectures, it's not like
it's a fast path.  And to avoid the ifdef mess make it something like:

void __iomem *ioremap_flags(resource_size_t offset, unsigned long size,
			unsigned long prot_val, unsigned flags);

static inline void __iomem *ioremap(resource_size_t offset, unsigned long size)
{
	return ioremap_flags(offset, size, 0, 0);
}

static inline void __iomem *ioremap_prot(resource_size_t offset,
		unsigned long size, unsigned long prot_val)
{
	return ioremap_flags(offset, size, prot_val, 0);
}

static inline void __iomem *ioremap_nocache(resource_size_t offset,
		unsigned long size)
{
	return ioremap_flags(offset, size, 0, IOREMAP_NOCACHE);
}

static inline void __iomem *ioremap_cache(resource_size_t offset,
		unsigned long size)
{
	return ioremap_flags(offset, size, 0, IOREMAP_CACHE);
}

static inline void __iomem *ioremap_uc(resource_size_t offset,
		unsigned long size)
{
	return ioremap_flags(offset, size, 0, IOREMAP_UC);
}

static inline void __iomem *ioremap_wc(resource_size_t offset,
		unsigned long size)
{
	return ioremap_flags(offset, size, 0, IOREMAP_WC);
}

static inline void __iomem *ioremap_wt(resource_size_t offset,
		unsigned long size)
{
	return ioremap_flags(offset, size, 0, IOREMAP_WT);
}

With all wrappers but ioremap() itself deprecated in the long run.

Besides following the one API one prototype guideline this gives
us one proper entry point for all the variants.  Additionally
it can reject non-supported caching modes at run time, e.g. because
different hardware may or may not support it.  Additionally it
avoids the need for all these HAVE_IOREMAP_FOO defines, which need
constant updating.
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
Please read the FAQ at  http://www.tux.org/lkml/

^ permalink raw reply	[flat|nested] 85+ messages in thread

* Re: [PATCH v5 6/6] arch, x86: pmem api for ensuring durability of persistent memory updates
  2015-06-22  8:24   ` Dan Williams
@ 2015-06-22 16:17     ` Christoph Hellwig
  -1 siblings, 0 replies; 85+ messages in thread
From: Christoph Hellwig @ 2015-06-22 16:17 UTC (permalink / raw)
  To: Dan Williams
  Cc: arnd, mingo, bp, hpa, tglx, ross.zwisler, akpm, jgross, x86,
	toshi.kani, linux-nvdimm, benh, mcgrof, konrad.wilk,
	linux-kernel, stefan.bader, luto, linux-mm, geert, ralf, hmh,
	mpe, tj, paulus, Richard Weinberger

> +#ifdef ARCH_HAS_NOCACHE_UACCESS

Seems like this is always define for x86 anyway?

> +/**
> + * arch_memcpy_to_pmem - copy data to persistent memory
> + * @dst: destination buffer for the copy
> + * @src: source buffer for the copy
> + * @n: length of the copy in bytes
> + *
> + * Copy data to persistent memory media via non-temporal stores so that
> + * a subsequent arch_wmb_pmem() can flush cpu and memory controller
> + * write buffers to guarantee durability.
> + */
static inline void arch_memcpy_to_pmem(void __pmem *dst, const void *src, size_t n)

Too long line.  Also why not simply arch_copy_{from,to}_pmem?

> +#else /* ARCH_HAS_NOCACHE_UACCESS i.e. ARCH=um */

Oh, UM.  I'd rather see UM fixed to provide these.

Richard, any chance you could look into it?

> diff --git a/arch/x86/include/asm/io.h b/arch/x86/include/asm/io.h
> index 97ae3b748d9e..0d3e43f679aa 100644
> --- a/arch/x86/include/asm/io.h
> +++ b/arch/x86/include/asm/io.h
> @@ -249,6 +249,12 @@ static inline void flush_write_buffers(void)
>  #endif
>  }
>  
> +static inline void __pmem *arch_memremap_pmem(resource_size_t offset,
> +	unsigned long size)
> +{
> +	return (void __force __pmem *) ioremap_cache(offset, size);
> +}

Now with my ioremap_flags proposal we'd just add an IOREMAP_PMEM
flag, which architectures could implement (usually as no-op), and move
the cast into memremap_pmem.

> + * These defaults seek to offer decent performance and minimize the
> + * window between i/o completion and writes being durable on media.
> + * However, it is undefined / architecture specific whether
> + * default_memremap_pmem + default_memcpy_to_pmem is sufficient for
> + * making data durable relative to i/o completion.
> + */
> +static void default_memcpy_to_pmem(void __pmem *dst, const void *src, size_t size)
> +{
> +	memcpy((void __force *) dst, src, size);
> +}

This should really be in asm-generic (or at least your linux/pmem.h for now).

> +static void __pmem *default_memremap_pmem(resource_size_t offset, unsigned long size)
> +{
> +	return (void __pmem *)memremap_wt(offset, size);
> +}

And this as well, unless we can get rid of it entirely with ioremap_flags().

>  	if (rw == READ) {
> -		memcpy(mem + off, pmem->virt_addr + pmem_off, len);
> +		memcpy_from_pmem(mem + off, pmem_addr, len);
>  		flush_dcache_page(page);
>  	} else {
>  		flush_dcache_page(page);
> -		memcpy(pmem->virt_addr + pmem_off, mem + off, len);
> +		if (arch_has_pmem_api())
> +			memcpy_to_pmem(pmem_addr, mem + off, len);
> +		else
> +			default_memcpy_to_pmem(pmem_addr, mem + off, len);

So memcpy_from_pmem hides the different but memcpy_to_pmem doesn't?
That seems pretty awkward.  Please move the check into the helper.

> +	if (rw && arch_has_pmem_api())
> +		wmb_pmem();

And here again make sure wmb_pmem is always available and a no-op if
not supported.

> +	if (arch_has_pmem_api())
> +		pmem->virt_addr = memremap_pmem(pmem->phys_addr, pmem->size);
> +	else
> +		pmem->virt_addr = default_memremap_pmem(pmem->phys_addr,
> +				pmem->size);

All of this should be hidden in memremap_pmem.

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org.  For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>

^ permalink raw reply	[flat|nested] 85+ messages in thread

* Re: [PATCH v5 6/6] arch, x86: pmem api for ensuring durability of persistent memory updates
@ 2015-06-22 16:17     ` Christoph Hellwig
  0 siblings, 0 replies; 85+ messages in thread
From: Christoph Hellwig @ 2015-06-22 16:17 UTC (permalink / raw)
  To: Dan Williams
  Cc: arnd, mingo, bp, hpa, tglx, ross.zwisler, akpm, jgross, x86,
	toshi.kani, linux-nvdimm, benh, mcgrof, konrad.wilk,
	linux-kernel, stefan.bader, luto, linux-mm, geert, ralf, hmh,
	mpe, tj, paulus, Richard Weinberger

> +#ifdef ARCH_HAS_NOCACHE_UACCESS

Seems like this is always define for x86 anyway?

> +/**
> + * arch_memcpy_to_pmem - copy data to persistent memory
> + * @dst: destination buffer for the copy
> + * @src: source buffer for the copy
> + * @n: length of the copy in bytes
> + *
> + * Copy data to persistent memory media via non-temporal stores so that
> + * a subsequent arch_wmb_pmem() can flush cpu and memory controller
> + * write buffers to guarantee durability.
> + */
static inline void arch_memcpy_to_pmem(void __pmem *dst, const void *src, size_t n)

Too long line.  Also why not simply arch_copy_{from,to}_pmem?

> +#else /* ARCH_HAS_NOCACHE_UACCESS i.e. ARCH=um */

Oh, UM.  I'd rather see UM fixed to provide these.

Richard, any chance you could look into it?

> diff --git a/arch/x86/include/asm/io.h b/arch/x86/include/asm/io.h
> index 97ae3b748d9e..0d3e43f679aa 100644
> --- a/arch/x86/include/asm/io.h
> +++ b/arch/x86/include/asm/io.h
> @@ -249,6 +249,12 @@ static inline void flush_write_buffers(void)
>  #endif
>  }
>  
> +static inline void __pmem *arch_memremap_pmem(resource_size_t offset,
> +	unsigned long size)
> +{
> +	return (void __force __pmem *) ioremap_cache(offset, size);
> +}

Now with my ioremap_flags proposal we'd just add an IOREMAP_PMEM
flag, which architectures could implement (usually as no-op), and move
the cast into memremap_pmem.

> + * These defaults seek to offer decent performance and minimize the
> + * window between i/o completion and writes being durable on media.
> + * However, it is undefined / architecture specific whether
> + * default_memremap_pmem + default_memcpy_to_pmem is sufficient for
> + * making data durable relative to i/o completion.
> + */
> +static void default_memcpy_to_pmem(void __pmem *dst, const void *src, size_t size)
> +{
> +	memcpy((void __force *) dst, src, size);
> +}

This should really be in asm-generic (or at least your linux/pmem.h for now).

> +static void __pmem *default_memremap_pmem(resource_size_t offset, unsigned long size)
> +{
> +	return (void __pmem *)memremap_wt(offset, size);
> +}

And this as well, unless we can get rid of it entirely with ioremap_flags().

>  	if (rw == READ) {
> -		memcpy(mem + off, pmem->virt_addr + pmem_off, len);
> +		memcpy_from_pmem(mem + off, pmem_addr, len);
>  		flush_dcache_page(page);
>  	} else {
>  		flush_dcache_page(page);
> -		memcpy(pmem->virt_addr + pmem_off, mem + off, len);
> +		if (arch_has_pmem_api())
> +			memcpy_to_pmem(pmem_addr, mem + off, len);
> +		else
> +			default_memcpy_to_pmem(pmem_addr, mem + off, len);

So memcpy_from_pmem hides the different but memcpy_to_pmem doesn't?
That seems pretty awkward.  Please move the check into the helper.

> +	if (rw && arch_has_pmem_api())
> +		wmb_pmem();

And here again make sure wmb_pmem is always available and a no-op if
not supported.

> +	if (arch_has_pmem_api())
> +		pmem->virt_addr = memremap_pmem(pmem->phys_addr, pmem->size);
> +	else
> +		pmem->virt_addr = default_memremap_pmem(pmem->phys_addr,
> +				pmem->size);

All of this should be hidden in memremap_pmem.
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
Please read the FAQ at  http://www.tux.org/lkml/

^ permalink raw reply	[flat|nested] 85+ messages in thread

* Re: [PATCH v5 2/6] arch: unify ioremap prototypes and macro aliases
  2015-06-22 16:10     ` Christoph Hellwig
@ 2015-06-22 17:12       ` Dan Williams
  -1 siblings, 0 replies; 85+ messages in thread
From: Dan Williams @ 2015-06-22 17:12 UTC (permalink / raw)
  To: Christoph Hellwig
  Cc: Arnd Bergmann, Ingo Molnar, Borislav Petkov, H. Peter Anvin,
	Thomas Gleixner, Ross Zwisler, Andrew Morton, Juergen Gross,
	X86 ML, Kani, Toshimitsu, linux-nvdimm, Benjamin Herrenschmidt,
	Luis Rodriguez, Konrad Rzeszutek Wilk, linux-kernel,
	Stefan Bader, Andy Lutomirski, linux-mm, Geert Uytterhoeven,
	Ralf Baechle, Henrique de Moraes Holschuh, mpe, Tejun Heo,
	Paul Mackerras

On Mon, Jun 22, 2015 at 9:10 AM, Christoph Hellwig <hch@lst.de> wrote:
> On Mon, Jun 22, 2015 at 04:24:27AM -0400, Dan Williams wrote:
>> Some archs define the first parameter to ioremap() as unsigned long,
>> while the balance define it as resource_size_t.  Unify on
>> resource_size_t to enable passing ioremap function pointers.  Also, some
>> archs use function-like macros for defining ioremap aliases, but
>> asm-generic/io.h expects object-like macros, unify on the latter.
>>
>> Move all handling of ioremap aliasing (i.e. ioremap_wt => ioremap) to
>> include/linux/io.h.  Add a check to include/linux/io.h to warn at
>> compile time if an arch violates expectations.
>>
>> Kill ARCH_HAS_IOREMAP_WC and ARCH_HAS_IOREMAP_WT in favor of just
>> testing for ioremap_wc, and ioremap_wt being defined.  This arrangement
>> allows drivers to know when ioremap_<foo> are being re-directed to plain
>> ioremap.
>>
>> Reported-by: kbuild test robot <fengguang.wu@intel.com>
>> Signed-off-by: Dan Williams <dan.j.williams@intel.com>
>
> Hmm, this is quite a bit of churn, and doesn't make the interface lot
> more obvious.
>
> I guess it's enough to get the pmem related bits going

Is that an acked-by for this cycle with a request to go deeper for 4.3?

> but I'd really
> prefer defining the ioremap* prototype in linux/io.h and requiring
> and out of line implementation in the architectures, it's not like
> it's a fast path.  And to avoid the ifdef mess make it something like:
>
> void __iomem *ioremap_flags(resource_size_t offset, unsigned long size,
>                         unsigned long prot_val, unsigned flags);

Yes, I do like this even better.

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org.  For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>

^ permalink raw reply	[flat|nested] 85+ messages in thread

* Re: [PATCH v5 2/6] arch: unify ioremap prototypes and macro aliases
@ 2015-06-22 17:12       ` Dan Williams
  0 siblings, 0 replies; 85+ messages in thread
From: Dan Williams @ 2015-06-22 17:12 UTC (permalink / raw)
  To: Christoph Hellwig
  Cc: Arnd Bergmann, Ingo Molnar, Borislav Petkov, H. Peter Anvin,
	Thomas Gleixner, Ross Zwisler, Andrew Morton, Juergen Gross,
	X86 ML, Kani, Toshimitsu, linux-nvdimm@lists.01.org,
	Benjamin Herrenschmidt, Luis Rodriguez, Konrad Rzeszutek Wilk,
	linux-kernel, Stefan Bader, Andy Lutomirski, linux-mm,
	Geert Uytterhoeven, Ralf Baechle, Henrique de Moraes Holschuh,
	mpe, Tejun Heo, Paul Mackerras

On Mon, Jun 22, 2015 at 9:10 AM, Christoph Hellwig <hch@lst.de> wrote:
> On Mon, Jun 22, 2015 at 04:24:27AM -0400, Dan Williams wrote:
>> Some archs define the first parameter to ioremap() as unsigned long,
>> while the balance define it as resource_size_t.  Unify on
>> resource_size_t to enable passing ioremap function pointers.  Also, some
>> archs use function-like macros for defining ioremap aliases, but
>> asm-generic/io.h expects object-like macros, unify on the latter.
>>
>> Move all handling of ioremap aliasing (i.e. ioremap_wt => ioremap) to
>> include/linux/io.h.  Add a check to include/linux/io.h to warn at
>> compile time if an arch violates expectations.
>>
>> Kill ARCH_HAS_IOREMAP_WC and ARCH_HAS_IOREMAP_WT in favor of just
>> testing for ioremap_wc, and ioremap_wt being defined.  This arrangement
>> allows drivers to know when ioremap_<foo> are being re-directed to plain
>> ioremap.
>>
>> Reported-by: kbuild test robot <fengguang.wu@intel.com>
>> Signed-off-by: Dan Williams <dan.j.williams@intel.com>
>
> Hmm, this is quite a bit of churn, and doesn't make the interface lot
> more obvious.
>
> I guess it's enough to get the pmem related bits going

Is that an acked-by for this cycle with a request to go deeper for 4.3?

> but I'd really
> prefer defining the ioremap* prototype in linux/io.h and requiring
> and out of line implementation in the architectures, it's not like
> it's a fast path.  And to avoid the ifdef mess make it something like:
>
> void __iomem *ioremap_flags(resource_size_t offset, unsigned long size,
>                         unsigned long prot_val, unsigned flags);

Yes, I do like this even better.
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
Please read the FAQ at  http://www.tux.org/lkml/

^ permalink raw reply	[flat|nested] 85+ messages in thread

* Re: [PATCH v5 6/6] arch, x86: pmem api for ensuring durability of persistent memory updates
  2015-06-22 16:17     ` Christoph Hellwig
@ 2015-06-22 17:51       ` Dan Williams
  -1 siblings, 0 replies; 85+ messages in thread
From: Dan Williams @ 2015-06-22 17:51 UTC (permalink / raw)
  To: Christoph Hellwig
  Cc: Arnd Bergmann, Ingo Molnar, Borislav Petkov, H. Peter Anvin,
	Thomas Gleixner, Ross Zwisler, Andrew Morton, Juergen Gross,
	X86 ML, Kani, Toshimitsu, linux-nvdimm, Benjamin Herrenschmidt,
	Luis Rodriguez, Konrad Rzeszutek Wilk, linux-kernel,
	Stefan Bader, Andy Lutomirski, linux-mm, Geert Uytterhoeven,
	Ralf Baechle, Henrique de Moraes Holschuh, mpe, Tejun Heo,
	Paul Mackerras, Richard Weinberger

On Mon, Jun 22, 2015 at 9:17 AM, Christoph Hellwig <hch@lst.de> wrote:
>> +#ifdef ARCH_HAS_NOCACHE_UACCESS
>
> Seems like this is always define for x86 anyway?
>
>> +/**
>> + * arch_memcpy_to_pmem - copy data to persistent memory
>> + * @dst: destination buffer for the copy
>> + * @src: source buffer for the copy
>> + * @n: length of the copy in bytes
>> + *
>> + * Copy data to persistent memory media via non-temporal stores so that
>> + * a subsequent arch_wmb_pmem() can flush cpu and memory controller
>> + * write buffers to guarantee durability.
>> + */
> static inline void arch_memcpy_to_pmem(void __pmem *dst, const void *src, size_t n)
>
> Too long line.  Also why not simply arch_copy_{from,to}_pmem?

I'm following the precedence set by memcpy_{from,to}_io().

>> +static inline void __pmem *arch_memremap_pmem(resource_size_t offset,
>> +     unsigned long size)
>> +{
>> +     return (void __force __pmem *) ioremap_cache(offset, size);
>> +}
>
> Now with my ioremap_flags proposal we'd just add an IOREMAP_PMEM
> flag, which architectures could implement (usually as no-op), and move
> the cast into memremap_pmem.

*nod*

>
>> + * These defaults seek to offer decent performance and minimize the
>> + * window between i/o completion and writes being durable on media.
>> + * However, it is undefined / architecture specific whether
>> + * default_memremap_pmem + default_memcpy_to_pmem is sufficient for
>> + * making data durable relative to i/o completion.
>> + */
>> +static void default_memcpy_to_pmem(void __pmem *dst, const void *src, size_t size)
>> +{
>> +     memcpy((void __force *) dst, src, size);
>> +}
>
> This should really be in asm-generic (or at least your linux/pmem.h for now).

ok.

>> +static void __pmem *default_memremap_pmem(resource_size_t offset, unsigned long size)
>> +{
>> +     return (void __pmem *)memremap_wt(offset, size);
>> +}
>
> And this as well, unless we can get rid of it entirely with ioremap_flags().

I'll move it for now.  ioremap_flags() requires more care than can be
given in the open merge window as far as I can see.

>>       if (rw == READ) {
>> -             memcpy(mem + off, pmem->virt_addr + pmem_off, len);
>> +             memcpy_from_pmem(mem + off, pmem_addr, len);
>>               flush_dcache_page(page);
>>       } else {
>>               flush_dcache_page(page);
>> -             memcpy(pmem->virt_addr + pmem_off, mem + off, len);
>> +             if (arch_has_pmem_api())
>> +                     memcpy_to_pmem(pmem_addr, mem + off, len);
>> +             else
>> +                     default_memcpy_to_pmem(pmem_addr, mem + off, len);
>
> So memcpy_from_pmem hides the different but memcpy_to_pmem doesn't?
> That seems pretty awkward.  Please move the check into the helper.

ok

>> +     if (rw && arch_has_pmem_api())
>> +             wmb_pmem();
>
> And here again make sure wmb_pmem is always available and a no-op if
> not supported.

ok.

>
>> +     if (arch_has_pmem_api())
>> +             pmem->virt_addr = memremap_pmem(pmem->phys_addr, pmem->size);
>> +     else
>> +             pmem->virt_addr = default_memremap_pmem(pmem->phys_addr,
>> +                             pmem->size);
>
> All of this should be hidden in memremap_pmem.

done.

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org.  For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>

^ permalink raw reply	[flat|nested] 85+ messages in thread

* Re: [PATCH v5 6/6] arch, x86: pmem api for ensuring durability of persistent memory updates
@ 2015-06-22 17:51       ` Dan Williams
  0 siblings, 0 replies; 85+ messages in thread
From: Dan Williams @ 2015-06-22 17:51 UTC (permalink / raw)
  To: Christoph Hellwig
  Cc: Arnd Bergmann, Ingo Molnar, Borislav Petkov, H. Peter Anvin,
	Thomas Gleixner, Ross Zwisler, Andrew Morton, Juergen Gross,
	X86 ML, Kani, Toshimitsu, linux-nvdimm@lists.01.org,
	Benjamin Herrenschmidt, Luis Rodriguez, Konrad Rzeszutek Wilk,
	linux-kernel, Stefan Bader, Andy Lutomirski, linux-mm,
	Geert Uytterhoeven, Ralf Baechle, Henrique de Moraes Holschuh,
	mpe, Tejun Heo, Paul Mackerras, Richard Weinberger

On Mon, Jun 22, 2015 at 9:17 AM, Christoph Hellwig <hch@lst.de> wrote:
>> +#ifdef ARCH_HAS_NOCACHE_UACCESS
>
> Seems like this is always define for x86 anyway?
>
>> +/**
>> + * arch_memcpy_to_pmem - copy data to persistent memory
>> + * @dst: destination buffer for the copy
>> + * @src: source buffer for the copy
>> + * @n: length of the copy in bytes
>> + *
>> + * Copy data to persistent memory media via non-temporal stores so that
>> + * a subsequent arch_wmb_pmem() can flush cpu and memory controller
>> + * write buffers to guarantee durability.
>> + */
> static inline void arch_memcpy_to_pmem(void __pmem *dst, const void *src, size_t n)
>
> Too long line.  Also why not simply arch_copy_{from,to}_pmem?

I'm following the precedence set by memcpy_{from,to}_io().

>> +static inline void __pmem *arch_memremap_pmem(resource_size_t offset,
>> +     unsigned long size)
>> +{
>> +     return (void __force __pmem *) ioremap_cache(offset, size);
>> +}
>
> Now with my ioremap_flags proposal we'd just add an IOREMAP_PMEM
> flag, which architectures could implement (usually as no-op), and move
> the cast into memremap_pmem.

*nod*

>
>> + * These defaults seek to offer decent performance and minimize the
>> + * window between i/o completion and writes being durable on media.
>> + * However, it is undefined / architecture specific whether
>> + * default_memremap_pmem + default_memcpy_to_pmem is sufficient for
>> + * making data durable relative to i/o completion.
>> + */
>> +static void default_memcpy_to_pmem(void __pmem *dst, const void *src, size_t size)
>> +{
>> +     memcpy((void __force *) dst, src, size);
>> +}
>
> This should really be in asm-generic (or at least your linux/pmem.h for now).

ok.

>> +static void __pmem *default_memremap_pmem(resource_size_t offset, unsigned long size)
>> +{
>> +     return (void __pmem *)memremap_wt(offset, size);
>> +}
>
> And this as well, unless we can get rid of it entirely with ioremap_flags().

I'll move it for now.  ioremap_flags() requires more care than can be
given in the open merge window as far as I can see.

>>       if (rw == READ) {
>> -             memcpy(mem + off, pmem->virt_addr + pmem_off, len);
>> +             memcpy_from_pmem(mem + off, pmem_addr, len);
>>               flush_dcache_page(page);
>>       } else {
>>               flush_dcache_page(page);
>> -             memcpy(pmem->virt_addr + pmem_off, mem + off, len);
>> +             if (arch_has_pmem_api())
>> +                     memcpy_to_pmem(pmem_addr, mem + off, len);
>> +             else
>> +                     default_memcpy_to_pmem(pmem_addr, mem + off, len);
>
> So memcpy_from_pmem hides the different but memcpy_to_pmem doesn't?
> That seems pretty awkward.  Please move the check into the helper.

ok

>> +     if (rw && arch_has_pmem_api())
>> +             wmb_pmem();
>
> And here again make sure wmb_pmem is always available and a no-op if
> not supported.

ok.

>
>> +     if (arch_has_pmem_api())
>> +             pmem->virt_addr = memremap_pmem(pmem->phys_addr, pmem->size);
>> +     else
>> +             pmem->virt_addr = default_memremap_pmem(pmem->phys_addr,
>> +                             pmem->size);
>
> All of this should be hidden in memremap_pmem.

done.
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
Please read the FAQ at  http://www.tux.org/lkml/

^ permalink raw reply	[flat|nested] 85+ messages in thread

* Re: [PATCH v5 2/6] arch: unify ioremap prototypes and macro aliases
  2015-06-22 17:12       ` Dan Williams
@ 2015-06-23 10:07         ` Christoph Hellwig
  -1 siblings, 0 replies; 85+ messages in thread
From: Christoph Hellwig @ 2015-06-23 10:07 UTC (permalink / raw)
  To: Dan Williams
  Cc: Christoph Hellwig, Arnd Bergmann, Ingo Molnar, Borislav Petkov,
	H. Peter Anvin, Thomas Gleixner, Ross Zwisler, Andrew Morton,
	Juergen Gross, X86 ML, Kani, Toshimitsu, linux-nvdimm,
	Benjamin Herrenschmidt, Luis Rodriguez, Konrad Rzeszutek Wilk,
	linux-kernel, Stefan Bader, Andy Lutomirski, linux-mm,
	Geert Uytterhoeven, Ralf Baechle, Henrique de Moraes Holschuh,
	mpe, Tejun Heo, Paul Mackerras

On Mon, Jun 22, 2015 at 10:12:40AM -0700, Dan Williams wrote:
> Is that an acked-by for this cycle with a request to go deeper for 4.3?

I wouldn't really expect something this wide reaching to be picked up
for this cycle, but if you manage to get it in:

Acked-by: Christoph Hellwig <hch@lst.de>

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org.  For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>

^ permalink raw reply	[flat|nested] 85+ messages in thread

* Re: [PATCH v5 2/6] arch: unify ioremap prototypes and macro aliases
@ 2015-06-23 10:07         ` Christoph Hellwig
  0 siblings, 0 replies; 85+ messages in thread
From: Christoph Hellwig @ 2015-06-23 10:07 UTC (permalink / raw)
  To: Dan Williams
  Cc: Christoph Hellwig, Arnd Bergmann, Ingo Molnar, Borislav Petkov,
	H. Peter Anvin, Thomas Gleixner, Ross Zwisler, Andrew Morton,
	Juergen Gross, X86 ML, Kani, Toshimitsu,
	linux-nvdimm@lists.01.org, Benjamin Herrenschmidt,
	Luis Rodriguez, Konrad Rzeszutek Wilk, linux-kernel,
	Stefan Bader, Andy Lutomirski, linux-mm, Geert Uytterhoeven,
	Ralf Baechle, Henrique de Moraes Holschuh, mpe, Tejun Heo,
	Paul Mackerras

On Mon, Jun 22, 2015 at 10:12:40AM -0700, Dan Williams wrote:
> Is that an acked-by for this cycle with a request to go deeper for 4.3?

I wouldn't really expect something this wide reaching to be picked up
for this cycle, but if you manage to get it in:

Acked-by: Christoph Hellwig <hch@lst.de>

^ permalink raw reply	[flat|nested] 85+ messages in thread

* Re: [PATCH v5 6/6] arch, x86: pmem api for ensuring durability of persistent memory updates
  2015-06-22 17:51       ` Dan Williams
@ 2015-06-23 10:09         ` Christoph Hellwig
  -1 siblings, 0 replies; 85+ messages in thread
From: Christoph Hellwig @ 2015-06-23 10:09 UTC (permalink / raw)
  To: Dan Williams
  Cc: Christoph Hellwig, Arnd Bergmann, Ingo Molnar, Borislav Petkov,
	H. Peter Anvin, Thomas Gleixner, Ross Zwisler, Andrew Morton,
	Juergen Gross, X86 ML, Kani, Toshimitsu, linux-nvdimm,
	Benjamin Herrenschmidt, Luis Rodriguez, Konrad Rzeszutek Wilk,
	linux-kernel, Stefan Bader, Andy Lutomirski, linux-mm,
	Geert Uytterhoeven, Ralf Baechle, Henrique de Moraes Holschuh,
	mpe, Tejun Heo, Paul Mackerras, Richard Weinberger

Oh, and please move the ioremap selftest to a .c file instead of a
header included by almost every driver.

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org.  For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>

^ permalink raw reply	[flat|nested] 85+ messages in thread

* Re: [PATCH v5 6/6] arch, x86: pmem api for ensuring durability of persistent memory updates
@ 2015-06-23 10:09         ` Christoph Hellwig
  0 siblings, 0 replies; 85+ messages in thread
From: Christoph Hellwig @ 2015-06-23 10:09 UTC (permalink / raw)
  To: Dan Williams
  Cc: Christoph Hellwig, Arnd Bergmann, Ingo Molnar, Borislav Petkov,
	H. Peter Anvin, Thomas Gleixner, Ross Zwisler, Andrew Morton,
	Juergen Gross, X86 ML, Kani, Toshimitsu,
	linux-nvdimm@lists.01.org, Benjamin Herrenschmidt,
	Luis Rodriguez, Konrad Rzeszutek Wilk, linux-kernel,
	Stefan Bader, Andy Lutomirski, linux-mm, Geert Uytterhoeven,
	Ralf Baechle, Henrique de Moraes Holschuh, mpe, Tejun Heo,
	Paul Mackerras, Richard Weinberger

Oh, and please move the ioremap selftest to a .c file instead of a
header included by almost every driver.

^ permalink raw reply	[flat|nested] 85+ messages in thread

* Re: [PATCH v5 6/6] arch, x86: pmem api for ensuring durability of persistent memory updates
  2015-06-22 16:17     ` Christoph Hellwig
@ 2015-06-23 10:39       ` Richard Weinberger
  -1 siblings, 0 replies; 85+ messages in thread
From: Richard Weinberger @ 2015-06-23 10:39 UTC (permalink / raw)
  To: Christoph Hellwig, Dan Williams
  Cc: arnd, mingo, bp, hpa, tglx, ross.zwisler, akpm, jgross, x86,
	toshi.kani, linux-nvdimm, benh, mcgrof, konrad.wilk,
	linux-kernel, stefan.bader, luto, linux-mm, geert, ralf, hmh,
	mpe, tj, paulus

Am 22.06.2015 um 18:17 schrieb Christoph Hellwig:
>> +#ifdef ARCH_HAS_NOCACHE_UACCESS
> 
> Seems like this is always define for x86 anyway?
> 
>> +/**
>> + * arch_memcpy_to_pmem - copy data to persistent memory
>> + * @dst: destination buffer for the copy
>> + * @src: source buffer for the copy
>> + * @n: length of the copy in bytes
>> + *
>> + * Copy data to persistent memory media via non-temporal stores so that
>> + * a subsequent arch_wmb_pmem() can flush cpu and memory controller
>> + * write buffers to guarantee durability.
>> + */
> static inline void arch_memcpy_to_pmem(void __pmem *dst, const void *src, size_t n)
> 
> Too long line.  Also why not simply arch_copy_{from,to}_pmem?
> 
>> +#else /* ARCH_HAS_NOCACHE_UACCESS i.e. ARCH=um */
> 
> Oh, UM.  I'd rather see UM fixed to provide these.
> 
> Richard, any chance you could look into it?

Not sure if I understand this correctly, is the plan to support pmem also on UML?
At least drivers/block/pmem.c cannot work on UML as it depends on io memory.

Only x86 seems to have ARCH_HAS_NOCACHE_UACCESS, if UML would offer these methods
what drivers need them? I'm still not sure where it would make sense on UML as
uaccess on UML means ptrace() between host and guest process.

Thanks,
//richard

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org.  For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>

^ permalink raw reply	[flat|nested] 85+ messages in thread

* Re: [PATCH v5 6/6] arch, x86: pmem api for ensuring durability of persistent memory updates
@ 2015-06-23 10:39       ` Richard Weinberger
  0 siblings, 0 replies; 85+ messages in thread
From: Richard Weinberger @ 2015-06-23 10:39 UTC (permalink / raw)
  To: Christoph Hellwig, Dan Williams
  Cc: arnd, mingo, bp, hpa, tglx, ross.zwisler, akpm, jgross, x86,
	toshi.kani, linux-nvdimm, benh, mcgrof, konrad.wilk,
	linux-kernel, stefan.bader, luto, linux-mm, geert, ralf, hmh,
	mpe, tj, paulus

Am 22.06.2015 um 18:17 schrieb Christoph Hellwig:
>> +#ifdef ARCH_HAS_NOCACHE_UACCESS
> 
> Seems like this is always define for x86 anyway?
> 
>> +/**
>> + * arch_memcpy_to_pmem - copy data to persistent memory
>> + * @dst: destination buffer for the copy
>> + * @src: source buffer for the copy
>> + * @n: length of the copy in bytes
>> + *
>> + * Copy data to persistent memory media via non-temporal stores so that
>> + * a subsequent arch_wmb_pmem() can flush cpu and memory controller
>> + * write buffers to guarantee durability.
>> + */
> static inline void arch_memcpy_to_pmem(void __pmem *dst, const void *src, size_t n)
> 
> Too long line.  Also why not simply arch_copy_{from,to}_pmem?
> 
>> +#else /* ARCH_HAS_NOCACHE_UACCESS i.e. ARCH=um */
> 
> Oh, UM.  I'd rather see UM fixed to provide these.
> 
> Richard, any chance you could look into it?

Not sure if I understand this correctly, is the plan to support pmem also on UML?
At least drivers/block/pmem.c cannot work on UML as it depends on io memory.

Only x86 seems to have ARCH_HAS_NOCACHE_UACCESS, if UML would offer these methods
what drivers need them? I'm still not sure where it would make sense on UML as
uaccess on UML means ptrace() between host and guest process.

Thanks,
//richard

^ permalink raw reply	[flat|nested] 85+ messages in thread

* Re: [PATCH v5 2/6] arch: unify ioremap prototypes and macro aliases
  2015-06-23 10:07         ` Christoph Hellwig
@ 2015-06-23 15:04           ` Dan Williams
  -1 siblings, 0 replies; 85+ messages in thread
From: Dan Williams @ 2015-06-23 15:04 UTC (permalink / raw)
  To: Christoph Hellwig
  Cc: Arnd Bergmann, Ingo Molnar, Borislav Petkov, H. Peter Anvin,
	Thomas Gleixner, Ross Zwisler, Andrew Morton, Juergen Gross,
	X86 ML, Kani, Toshimitsu, linux-nvdimm, Benjamin Herrenschmidt,
	Luis Rodriguez, Konrad Rzeszutek Wilk, linux-kernel,
	Stefan Bader, Andy Lutomirski, linux-mm, Geert Uytterhoeven,
	Ralf Baechle, Henrique de Moraes Holschuh, mpe, Tejun Heo,
	Paul Mackerras

On Tue, Jun 23, 2015 at 3:07 AM, Christoph Hellwig <hch@lst.de> wrote:
> On Mon, Jun 22, 2015 at 10:12:40AM -0700, Dan Williams wrote:
>> Is that an acked-by for this cycle with a request to go deeper for 4.3?
>
> I wouldn't really expect something this wide reaching to be picked up
> for this cycle, but if you manage to get it in:
>
> Acked-by: Christoph Hellwig <hch@lst.de>

Thanks, definitely a long shot at this point, but this is what one
gets for fixing rather than working around broken base infrastructure.
It would be unfortunate if we went another cycle with pmem having both
poor performance and broken persistence guarantees.

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org.  For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>

^ permalink raw reply	[flat|nested] 85+ messages in thread

* Re: [PATCH v5 2/6] arch: unify ioremap prototypes and macro aliases
@ 2015-06-23 15:04           ` Dan Williams
  0 siblings, 0 replies; 85+ messages in thread
From: Dan Williams @ 2015-06-23 15:04 UTC (permalink / raw)
  To: Christoph Hellwig
  Cc: Arnd Bergmann, Ingo Molnar, Borislav Petkov, H. Peter Anvin,
	Thomas Gleixner, Ross Zwisler, Andrew Morton, Juergen Gross,
	X86 ML, Kani, Toshimitsu, linux-nvdimm@lists.01.org,
	Benjamin Herrenschmidt, Luis Rodriguez, Konrad Rzeszutek Wilk,
	linux-kernel, Stefan Bader, Andy Lutomirski, linux-mm,
	Geert Uytterhoeven, Ralf Baechle, Henrique de Moraes Holschuh,
	mpe, Tejun Heo, Paul Mackerras

On Tue, Jun 23, 2015 at 3:07 AM, Christoph Hellwig <hch@lst.de> wrote:
> On Mon, Jun 22, 2015 at 10:12:40AM -0700, Dan Williams wrote:
>> Is that an acked-by for this cycle with a request to go deeper for 4.3?
>
> I wouldn't really expect something this wide reaching to be picked up
> for this cycle, but if you manage to get it in:
>
> Acked-by: Christoph Hellwig <hch@lst.de>

Thanks, definitely a long shot at this point, but this is what one
gets for fixing rather than working around broken base infrastructure.
It would be unfortunate if we went another cycle with pmem having both
poor performance and broken persistence guarantees.

^ permalink raw reply	[flat|nested] 85+ messages in thread

* Re: [PATCH v5 6/6] arch, x86: pmem api for ensuring durability of persistent memory updates
  2015-06-23 10:39       ` Richard Weinberger
@ 2015-06-24 12:08         ` Christoph Hellwig
  -1 siblings, 0 replies; 85+ messages in thread
From: Christoph Hellwig @ 2015-06-24 12:08 UTC (permalink / raw)
  To: Richard Weinberger
  Cc: Christoph Hellwig, Dan Williams, arnd, mingo, bp, hpa, tglx,
	ross.zwisler, akpm, jgross, x86, toshi.kani, linux-nvdimm, benh,
	mcgrof, konrad.wilk, linux-kernel, stefan.bader, luto, linux-mm,
	geert, ralf, hmh, mpe, tj, paulus

On Tue, Jun 23, 2015 at 12:39:09PM +0200, Richard Weinberger wrote:
> Not sure if I understand this correctly, is the plan to support pmem also on UML?
> At least drivers/block/pmem.c cannot work on UML as it depends on io memory.
> 
> Only x86 seems to have ARCH_HAS_NOCACHE_UACCESS, if UML would offer these methods
> what drivers need them? I'm still not sure where it would make sense on UML as
> uaccess on UML means ptrace() between host and guest process.

Ok, that makese snese.  Dan, how about just moving the new pmem helpers
from cacheflush.h to a new asm/pmem.h to avoid having them dragged into
the um build?

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org.  For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>

^ permalink raw reply	[flat|nested] 85+ messages in thread

* Re: [PATCH v5 6/6] arch, x86: pmem api for ensuring durability of persistent memory updates
@ 2015-06-24 12:08         ` Christoph Hellwig
  0 siblings, 0 replies; 85+ messages in thread
From: Christoph Hellwig @ 2015-06-24 12:08 UTC (permalink / raw)
  To: Richard Weinberger
  Cc: Christoph Hellwig, Dan Williams, arnd, mingo, bp, hpa, tglx,
	ross.zwisler, akpm, jgross, x86, toshi.kani, linux-nvdimm, benh,
	mcgrof, konrad.wilk, linux-kernel, stefan.bader, luto, linux-mm,
	geert, ralf, hmh, mpe, tj, paulus

On Tue, Jun 23, 2015 at 12:39:09PM +0200, Richard Weinberger wrote:
> Not sure if I understand this correctly, is the plan to support pmem also on UML?
> At least drivers/block/pmem.c cannot work on UML as it depends on io memory.
> 
> Only x86 seems to have ARCH_HAS_NOCACHE_UACCESS, if UML would offer these methods
> what drivers need them? I'm still not sure where it would make sense on UML as
> uaccess on UML means ptrace() between host and guest process.

Ok, that makese snese.  Dan, how about just moving the new pmem helpers
from cacheflush.h to a new asm/pmem.h to avoid having them dragged into
the um build?

^ permalink raw reply	[flat|nested] 85+ messages in thread

* Re: [PATCH v5 2/6] arch: unify ioremap prototypes and macro aliases
  2015-06-23 15:04           ` Dan Williams
@ 2015-06-24 12:24             ` Christoph Hellwig
  -1 siblings, 0 replies; 85+ messages in thread
From: Christoph Hellwig @ 2015-06-24 12:24 UTC (permalink / raw)
  To: Dan Williams
  Cc: Christoph Hellwig, Arnd Bergmann, Ingo Molnar, Borislav Petkov,
	H. Peter Anvin, Thomas Gleixner, Ross Zwisler, Andrew Morton,
	Juergen Gross, X86 ML, Kani, Toshimitsu, linux-nvdimm,
	Benjamin Herrenschmidt, Luis Rodriguez, Konrad Rzeszutek Wilk,
	linux-kernel, Stefan Bader, Andy Lutomirski, linux-mm,
	Geert Uytterhoeven, Ralf Baechle, Henrique de Moraes Holschuh,
	mpe, Tejun Heo, Paul Mackerras

On Tue, Jun 23, 2015 at 08:04:47AM -0700, Dan Williams wrote:
> Thanks, definitely a long shot at this point, but this is what one
> gets for fixing rather than working around broken base infrastructure.
> It would be unfortunate if we went another cycle with pmem having both
> poor performance and broken persistence guarantees.

Maybe we can aim for the minimal fix for 4.2 that just adds meremap
and the accessors for x86 and the do the big scale cleanups for 4.3?

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org.  For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>

^ permalink raw reply	[flat|nested] 85+ messages in thread

* Re: [PATCH v5 2/6] arch: unify ioremap prototypes and macro aliases
@ 2015-06-24 12:24             ` Christoph Hellwig
  0 siblings, 0 replies; 85+ messages in thread
From: Christoph Hellwig @ 2015-06-24 12:24 UTC (permalink / raw)
  To: Dan Williams
  Cc: Christoph Hellwig, Arnd Bergmann, Ingo Molnar, Borislav Petkov,
	H. Peter Anvin, Thomas Gleixner, Ross Zwisler, Andrew Morton,
	Juergen Gross, X86 ML, Kani, Toshimitsu,
	linux-nvdimm@lists.01.org, Benjamin Herrenschmidt,
	Luis Rodriguez, Konrad Rzeszutek Wilk, linux-kernel,
	Stefan Bader, Andy Lutomirski, linux-mm, Geert Uytterhoeven,
	Ralf Baechle, Henrique de Moraes Holschuh, mpe, Tejun Heo,
	Paul Mackerras

On Tue, Jun 23, 2015 at 08:04:47AM -0700, Dan Williams wrote:
> Thanks, definitely a long shot at this point, but this is what one
> gets for fixing rather than working around broken base infrastructure.
> It would be unfortunate if we went another cycle with pmem having both
> poor performance and broken persistence guarantees.

Maybe we can aim for the minimal fix for 4.2 that just adds meremap
and the accessors for x86 and the do the big scale cleanups for 4.3?

^ permalink raw reply	[flat|nested] 85+ messages in thread

* Re: [PATCH v5 6/6] arch, x86: pmem api for ensuring durability of persistent memory updates
  2015-06-24 12:08         ` Christoph Hellwig
@ 2015-06-24 12:35           ` Richard Weinberger
  -1 siblings, 0 replies; 85+ messages in thread
From: Richard Weinberger @ 2015-06-24 12:35 UTC (permalink / raw)
  To: Christoph Hellwig
  Cc: Dan Williams, arnd, mingo, bp, hpa, tglx, ross.zwisler, akpm,
	jgross, x86, toshi.kani, linux-nvdimm, benh, mcgrof, konrad.wilk,
	linux-kernel, stefan.bader, luto, linux-mm, geert, ralf, hmh,
	mpe, tj, paulus

Am 24.06.2015 um 14:08 schrieb Christoph Hellwig:
> On Tue, Jun 23, 2015 at 12:39:09PM +0200, Richard Weinberger wrote:
>> Not sure if I understand this correctly, is the plan to support pmem also on UML?
>> At least drivers/block/pmem.c cannot work on UML as it depends on io memory.
>>
>> Only x86 seems to have ARCH_HAS_NOCACHE_UACCESS, if UML would offer these methods
>> what drivers need them? I'm still not sure where it would make sense on UML as
>> uaccess on UML means ptrace() between host and guest process.
> 
> Ok, that makese snese.  Dan, how about just moving the new pmem helpers
> from cacheflush.h to a new asm/pmem.h to avoid having them dragged into
> the um build?

If UML does not build for whatever reason, please CC me.
I'll happily help out. Historically UML includes a lot stuff
it should not. So, untangling header dependencies does often
wonders. :-)

Thanks,
//richard

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org.  For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>

^ permalink raw reply	[flat|nested] 85+ messages in thread

* Re: [PATCH v5 6/6] arch, x86: pmem api for ensuring durability of persistent memory updates
@ 2015-06-24 12:35           ` Richard Weinberger
  0 siblings, 0 replies; 85+ messages in thread
From: Richard Weinberger @ 2015-06-24 12:35 UTC (permalink / raw)
  To: Christoph Hellwig
  Cc: Dan Williams, arnd, mingo, bp, hpa, tglx, ross.zwisler, akpm,
	jgross, x86, toshi.kani, linux-nvdimm, benh, mcgrof, konrad.wilk,
	linux-kernel, stefan.bader, luto, linux-mm, geert, ralf, hmh,
	mpe, tj, paulus

Am 24.06.2015 um 14:08 schrieb Christoph Hellwig:
> On Tue, Jun 23, 2015 at 12:39:09PM +0200, Richard Weinberger wrote:
>> Not sure if I understand this correctly, is the plan to support pmem also on UML?
>> At least drivers/block/pmem.c cannot work on UML as it depends on io memory.
>>
>> Only x86 seems to have ARCH_HAS_NOCACHE_UACCESS, if UML would offer these methods
>> what drivers need them? I'm still not sure where it would make sense on UML as
>> uaccess on UML means ptrace() between host and guest process.
> 
> Ok, that makese snese.  Dan, how about just moving the new pmem helpers
> from cacheflush.h to a new asm/pmem.h to avoid having them dragged into
> the um build?

If UML does not build for whatever reason, please CC me.
I'll happily help out. Historically UML includes a lot stuff
it should not. So, untangling header dependencies does often
wonders. :-)

Thanks,
//richard

^ permalink raw reply	[flat|nested] 85+ messages in thread

* Re: [PATCH v5 2/6] arch: unify ioremap prototypes and macro aliases
  2015-06-22 16:10     ` Christoph Hellwig
  (?)
@ 2015-06-30 22:57       ` Dan Williams
  -1 siblings, 0 replies; 85+ messages in thread
From: Dan Williams @ 2015-06-30 22:57 UTC (permalink / raw)
  To: Christoph Hellwig
  Cc: Arnd Bergmann, Ingo Molnar, Borislav Petkov, H. Peter Anvin,
	Thomas Gleixner, Ross Zwisler, Andrew Morton, Juergen Gross,
	X86 ML, Kani, Toshimitsu, linux-nvdimm, Benjamin Herrenschmidt,
	Luis Rodriguez, Konrad Rzeszutek Wilk, linux-kernel,
	Stefan Bader, Andy Lutomirski, linux-mm, Geert Uytterhoeven,
	Ralf Baechle, Henrique de Moraes Holschuh, mpe, Tejun Heo,
	Paul Mackerras, Russell King - ARM Linux, linux-arm-kernel

On Mon, Jun 22, 2015 at 9:10 AM, Christoph Hellwig <hch@lst.de> wrote:
> On Mon, Jun 22, 2015 at 04:24:27AM -0400, Dan Williams wrote:
>> Some archs define the first parameter to ioremap() as unsigned long,
>> while the balance define it as resource_size_t.  Unify on
>> resource_size_t to enable passing ioremap function pointers.  Also, some
>> archs use function-like macros for defining ioremap aliases, but
>> asm-generic/io.h expects object-like macros, unify on the latter.
>>
>> Move all handling of ioremap aliasing (i.e. ioremap_wt => ioremap) to
>> include/linux/io.h.  Add a check to include/linux/io.h to warn at
>> compile time if an arch violates expectations.
>>
>> Kill ARCH_HAS_IOREMAP_WC and ARCH_HAS_IOREMAP_WT in favor of just
>> testing for ioremap_wc, and ioremap_wt being defined.  This arrangement
>> allows drivers to know when ioremap_<foo> are being re-directed to plain
>> ioremap.
>>
>> Reported-by: kbuild test robot <fengguang.wu@intel.com>
>> Signed-off-by: Dan Williams <dan.j.williams@intel.com>
>
> Hmm, this is quite a bit of churn, and doesn't make the interface lot
> more obvious.
>
> I guess it's enough to get the pmem related bits going, but I'd really
> prefer defining the ioremap* prototype in linux/io.h and requiring
> and out of line implementation in the architectures, it's not like
> it's a fast path.  And to avoid the ifdef mess make it something like:
>
> void __iomem *ioremap_flags(resource_size_t offset, unsigned long size,
>                         unsigned long prot_val, unsigned flags);

Doesn't 'flags' imply a specific 'prot_val'?

> static inline void __iomem *ioremap(resource_size_t offset, unsigned long size)
> {
>         return ioremap_flags(offset, size, 0, 0);
> }
>
> static inline void __iomem *ioremap_prot(resource_size_t offset,
>                 unsigned long size, unsigned long prot_val)
> {
>         return ioremap_flags(offset, size, prot_val, 0);
> }
>
> static inline void __iomem *ioremap_nocache(resource_size_t offset,
>                 unsigned long size)
> {
>         return ioremap_flags(offset, size, 0, IOREMAP_NOCACHE);
> }
>
> static inline void __iomem *ioremap_cache(resource_size_t offset,
>                 unsigned long size)
> {
>         return ioremap_flags(offset, size, 0, IOREMAP_CACHE);
> }
>
> static inline void __iomem *ioremap_uc(resource_size_t offset,
>                 unsigned long size)
> {
>         return ioremap_flags(offset, size, 0, IOREMAP_UC);
> }
>
> static inline void __iomem *ioremap_wc(resource_size_t offset,
>                 unsigned long size)
> {
>         return ioremap_flags(offset, size, 0, IOREMAP_WC);
> }
>
> static inline void __iomem *ioremap_wt(resource_size_t offset,
>                 unsigned long size)
> {
>         return ioremap_flags(offset, size, 0, IOREMAP_WT);
> }
>
> With all wrappers but ioremap() itself deprecated in the long run.
>
> Besides following the one API one prototype guideline this gives
> us one proper entry point for all the variants.  Additionally
> it can reject non-supported caching modes at run time, e.g. because
> different hardware may or may not support it.  Additionally it
> avoids the need for all these HAVE_IOREMAP_FOO defines, which need
> constant updating.

One useful feature of the ifdef mess as implemented in the patch is
that you could test for whether ioremap_cache() is actually
implemented or falls back to default ioremap().  I think for
completeness archs should publish an ioremap type capabilities mask
for drivers that care... (I can imagine pmem caring), or default to
being permissive if something like IOREMAP_STRICT is not set.  There's
also the wrinkle of archs that can only support certain types of
mappings at a given alignment.

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org.  For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>

^ permalink raw reply	[flat|nested] 85+ messages in thread

* Re: [PATCH v5 2/6] arch: unify ioremap prototypes and macro aliases
@ 2015-06-30 22:57       ` Dan Williams
  0 siblings, 0 replies; 85+ messages in thread
From: Dan Williams @ 2015-06-30 22:57 UTC (permalink / raw)
  To: Christoph Hellwig
  Cc: Arnd Bergmann, Ingo Molnar, Borislav Petkov, H. Peter Anvin,
	Thomas Gleixner, Ross Zwisler, Andrew Morton, Juergen Gross,
	X86 ML, Kani, Toshimitsu, linux-nvdimm@lists.01.org,
	Benjamin Herrenschmidt, Luis Rodriguez, Konrad Rzeszutek Wilk,
	linux-kernel, Stefan Bader, Andy Lutomirski, linux-mm,
	Geert Uytterhoeven, Ralf Baechle, Henrique de Moraes Holschuh,
	mpe, Tejun Heo, Paul Mackerras, Russell King - ARM Linux,
	linux-arm-kernel

On Mon, Jun 22, 2015 at 9:10 AM, Christoph Hellwig <hch@lst.de> wrote:
> On Mon, Jun 22, 2015 at 04:24:27AM -0400, Dan Williams wrote:
>> Some archs define the first parameter to ioremap() as unsigned long,
>> while the balance define it as resource_size_t.  Unify on
>> resource_size_t to enable passing ioremap function pointers.  Also, some
>> archs use function-like macros for defining ioremap aliases, but
>> asm-generic/io.h expects object-like macros, unify on the latter.
>>
>> Move all handling of ioremap aliasing (i.e. ioremap_wt => ioremap) to
>> include/linux/io.h.  Add a check to include/linux/io.h to warn at
>> compile time if an arch violates expectations.
>>
>> Kill ARCH_HAS_IOREMAP_WC and ARCH_HAS_IOREMAP_WT in favor of just
>> testing for ioremap_wc, and ioremap_wt being defined.  This arrangement
>> allows drivers to know when ioremap_<foo> are being re-directed to plain
>> ioremap.
>>
>> Reported-by: kbuild test robot <fengguang.wu@intel.com>
>> Signed-off-by: Dan Williams <dan.j.williams@intel.com>
>
> Hmm, this is quite a bit of churn, and doesn't make the interface lot
> more obvious.
>
> I guess it's enough to get the pmem related bits going, but I'd really
> prefer defining the ioremap* prototype in linux/io.h and requiring
> and out of line implementation in the architectures, it's not like
> it's a fast path.  And to avoid the ifdef mess make it something like:
>
> void __iomem *ioremap_flags(resource_size_t offset, unsigned long size,
>                         unsigned long prot_val, unsigned flags);

Doesn't 'flags' imply a specific 'prot_val'?

> static inline void __iomem *ioremap(resource_size_t offset, unsigned long size)
> {
>         return ioremap_flags(offset, size, 0, 0);
> }
>
> static inline void __iomem *ioremap_prot(resource_size_t offset,
>                 unsigned long size, unsigned long prot_val)
> {
>         return ioremap_flags(offset, size, prot_val, 0);
> }
>
> static inline void __iomem *ioremap_nocache(resource_size_t offset,
>                 unsigned long size)
> {
>         return ioremap_flags(offset, size, 0, IOREMAP_NOCACHE);
> }
>
> static inline void __iomem *ioremap_cache(resource_size_t offset,
>                 unsigned long size)
> {
>         return ioremap_flags(offset, size, 0, IOREMAP_CACHE);
> }
>
> static inline void __iomem *ioremap_uc(resource_size_t offset,
>                 unsigned long size)
> {
>         return ioremap_flags(offset, size, 0, IOREMAP_UC);
> }
>
> static inline void __iomem *ioremap_wc(resource_size_t offset,
>                 unsigned long size)
> {
>         return ioremap_flags(offset, size, 0, IOREMAP_WC);
> }
>
> static inline void __iomem *ioremap_wt(resource_size_t offset,
>                 unsigned long size)
> {
>         return ioremap_flags(offset, size, 0, IOREMAP_WT);
> }
>
> With all wrappers but ioremap() itself deprecated in the long run.
>
> Besides following the one API one prototype guideline this gives
> us one proper entry point for all the variants.  Additionally
> it can reject non-supported caching modes at run time, e.g. because
> different hardware may or may not support it.  Additionally it
> avoids the need for all these HAVE_IOREMAP_FOO defines, which need
> constant updating.

One useful feature of the ifdef mess as implemented in the patch is
that you could test for whether ioremap_cache() is actually
implemented or falls back to default ioremap().  I think for
completeness archs should publish an ioremap type capabilities mask
for drivers that care... (I can imagine pmem caring), or default to
being permissive if something like IOREMAP_STRICT is not set.  There's
also the wrinkle of archs that can only support certain types of
mappings at a given alignment.

^ permalink raw reply	[flat|nested] 85+ messages in thread

* [PATCH v5 2/6] arch: unify ioremap prototypes and macro aliases
@ 2015-06-30 22:57       ` Dan Williams
  0 siblings, 0 replies; 85+ messages in thread
From: Dan Williams @ 2015-06-30 22:57 UTC (permalink / raw)
  To: linux-arm-kernel

On Mon, Jun 22, 2015 at 9:10 AM, Christoph Hellwig <hch@lst.de> wrote:
> On Mon, Jun 22, 2015 at 04:24:27AM -0400, Dan Williams wrote:
>> Some archs define the first parameter to ioremap() as unsigned long,
>> while the balance define it as resource_size_t.  Unify on
>> resource_size_t to enable passing ioremap function pointers.  Also, some
>> archs use function-like macros for defining ioremap aliases, but
>> asm-generic/io.h expects object-like macros, unify on the latter.
>>
>> Move all handling of ioremap aliasing (i.e. ioremap_wt => ioremap) to
>> include/linux/io.h.  Add a check to include/linux/io.h to warn at
>> compile time if an arch violates expectations.
>>
>> Kill ARCH_HAS_IOREMAP_WC and ARCH_HAS_IOREMAP_WT in favor of just
>> testing for ioremap_wc, and ioremap_wt being defined.  This arrangement
>> allows drivers to know when ioremap_<foo> are being re-directed to plain
>> ioremap.
>>
>> Reported-by: kbuild test robot <fengguang.wu@intel.com>
>> Signed-off-by: Dan Williams <dan.j.williams@intel.com>
>
> Hmm, this is quite a bit of churn, and doesn't make the interface lot
> more obvious.
>
> I guess it's enough to get the pmem related bits going, but I'd really
> prefer defining the ioremap* prototype in linux/io.h and requiring
> and out of line implementation in the architectures, it's not like
> it's a fast path.  And to avoid the ifdef mess make it something like:
>
> void __iomem *ioremap_flags(resource_size_t offset, unsigned long size,
>                         unsigned long prot_val, unsigned flags);

Doesn't 'flags' imply a specific 'prot_val'?

> static inline void __iomem *ioremap(resource_size_t offset, unsigned long size)
> {
>         return ioremap_flags(offset, size, 0, 0);
> }
>
> static inline void __iomem *ioremap_prot(resource_size_t offset,
>                 unsigned long size, unsigned long prot_val)
> {
>         return ioremap_flags(offset, size, prot_val, 0);
> }
>
> static inline void __iomem *ioremap_nocache(resource_size_t offset,
>                 unsigned long size)
> {
>         return ioremap_flags(offset, size, 0, IOREMAP_NOCACHE);
> }
>
> static inline void __iomem *ioremap_cache(resource_size_t offset,
>                 unsigned long size)
> {
>         return ioremap_flags(offset, size, 0, IOREMAP_CACHE);
> }
>
> static inline void __iomem *ioremap_uc(resource_size_t offset,
>                 unsigned long size)
> {
>         return ioremap_flags(offset, size, 0, IOREMAP_UC);
> }
>
> static inline void __iomem *ioremap_wc(resource_size_t offset,
>                 unsigned long size)
> {
>         return ioremap_flags(offset, size, 0, IOREMAP_WC);
> }
>
> static inline void __iomem *ioremap_wt(resource_size_t offset,
>                 unsigned long size)
> {
>         return ioremap_flags(offset, size, 0, IOREMAP_WT);
> }
>
> With all wrappers but ioremap() itself deprecated in the long run.
>
> Besides following the one API one prototype guideline this gives
> us one proper entry point for all the variants.  Additionally
> it can reject non-supported caching modes at run time, e.g. because
> different hardware may or may not support it.  Additionally it
> avoids the need for all these HAVE_IOREMAP_FOO defines, which need
> constant updating.

One useful feature of the ifdef mess as implemented in the patch is
that you could test for whether ioremap_cache() is actually
implemented or falls back to default ioremap().  I think for
completeness archs should publish an ioremap type capabilities mask
for drivers that care... (I can imagine pmem caring), or default to
being permissive if something like IOREMAP_STRICT is not set.  There's
also the wrinkle of archs that can only support certain types of
mappings at a given alignment.

^ permalink raw reply	[flat|nested] 85+ messages in thread

* Re: [PATCH v5 2/6] arch: unify ioremap prototypes and macro aliases
  2015-06-30 22:57       ` Dan Williams
  (?)
@ 2015-07-01  6:23         ` Christoph Hellwig
  -1 siblings, 0 replies; 85+ messages in thread
From: Christoph Hellwig @ 2015-07-01  6:23 UTC (permalink / raw)
  To: Dan Williams
  Cc: Christoph Hellwig, Arnd Bergmann, Ingo Molnar, Borislav Petkov,
	H. Peter Anvin, Thomas Gleixner, Ross Zwisler, Andrew Morton,
	Juergen Gross, X86 ML, Kani, Toshimitsu, linux-nvdimm,
	Benjamin Herrenschmidt, Luis Rodriguez, Konrad Rzeszutek Wilk,
	linux-kernel, Stefan Bader, Andy Lutomirski, linux-mm,
	Geert Uytterhoeven, Ralf Baechle, Henrique de Moraes Holschuh,
	mpe, Tejun Heo, Paul Mackerras, Russell King - ARM Linux,
	linux-arm-kernel

On Tue, Jun 30, 2015 at 03:57:16PM -0700, Dan Williams wrote:
> > void __iomem *ioremap_flags(resource_size_t offset, unsigned long size,
> >                         unsigned long prot_val, unsigned flags);
> 
> Doesn't 'flags' imply a specific 'prot_val'?

Looks like the values are arch specific.  So as a first step I'd like
to keep them separate.  As a second step we could look into unifying
the actual ioremap implementations which look mostly the same.  Once
that is done we could look into collapsing the flags and prot_val
arguments.

> One useful feature of the ifdef mess as implemented in the patch is
> that you could test for whether ioremap_cache() is actually
> implemented or falls back to default ioremap().  I think for
> completeness archs should publish an ioremap type capabilities mask
> for drivers that care... (I can imagine pmem caring), or default to
> being permissive if something like IOREMAP_STRICT is not set.  There's
> also the wrinkle of archs that can only support certain types of
> mappings at a given alignment.

I think doing this at runtime might be a better idea.  E.g. a
ioremap_flags with the CACHED argument will return -EOPNOTSUP unless
actually implemented.  On various architectures different CPUs or
boards will have different capabilities in this area.

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org.  For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>

^ permalink raw reply	[flat|nested] 85+ messages in thread

* Re: [PATCH v5 2/6] arch: unify ioremap prototypes and macro aliases
@ 2015-07-01  6:23         ` Christoph Hellwig
  0 siblings, 0 replies; 85+ messages in thread
From: Christoph Hellwig @ 2015-07-01  6:23 UTC (permalink / raw)
  To: Dan Williams
  Cc: Christoph Hellwig, Arnd Bergmann, Ingo Molnar, Borislav Petkov,
	H. Peter Anvin, Thomas Gleixner, Ross Zwisler, Andrew Morton,
	Juergen Gross, X86 ML, Kani, Toshimitsu,
	linux-nvdimm@lists.01.org, Benjamin Herrenschmidt,
	Luis Rodriguez, Konrad Rzeszutek Wilk, linux-kernel,
	Stefan Bader, Andy Lutomirski, linux-mm, Geert Uytterhoeven,
	Ralf Baechle, Henrique de Moraes Holschuh, mpe, Tejun Heo,
	Paul Mackerras, Russell King - ARM Linux, linux-arm-kernel

On Tue, Jun 30, 2015 at 03:57:16PM -0700, Dan Williams wrote:
> > void __iomem *ioremap_flags(resource_size_t offset, unsigned long size,
> >                         unsigned long prot_val, unsigned flags);
> 
> Doesn't 'flags' imply a specific 'prot_val'?

Looks like the values are arch specific.  So as a first step I'd like
to keep them separate.  As a second step we could look into unifying
the actual ioremap implementations which look mostly the same.  Once
that is done we could look into collapsing the flags and prot_val
arguments.

> One useful feature of the ifdef mess as implemented in the patch is
> that you could test for whether ioremap_cache() is actually
> implemented or falls back to default ioremap().  I think for
> completeness archs should publish an ioremap type capabilities mask
> for drivers that care... (I can imagine pmem caring), or default to
> being permissive if something like IOREMAP_STRICT is not set.  There's
> also the wrinkle of archs that can only support certain types of
> mappings at a given alignment.

I think doing this at runtime might be a better idea.  E.g. a
ioremap_flags with the CACHED argument will return -EOPNOTSUP unless
actually implemented.  On various architectures different CPUs or
boards will have different capabilities in this area.

^ permalink raw reply	[flat|nested] 85+ messages in thread

* [PATCH v5 2/6] arch: unify ioremap prototypes and macro aliases
@ 2015-07-01  6:23         ` Christoph Hellwig
  0 siblings, 0 replies; 85+ messages in thread
From: Christoph Hellwig @ 2015-07-01  6:23 UTC (permalink / raw)
  To: linux-arm-kernel

On Tue, Jun 30, 2015 at 03:57:16PM -0700, Dan Williams wrote:
> > void __iomem *ioremap_flags(resource_size_t offset, unsigned long size,
> >                         unsigned long prot_val, unsigned flags);
> 
> Doesn't 'flags' imply a specific 'prot_val'?

Looks like the values are arch specific.  So as a first step I'd like
to keep them separate.  As a second step we could look into unifying
the actual ioremap implementations which look mostly the same.  Once
that is done we could look into collapsing the flags and prot_val
arguments.

> One useful feature of the ifdef mess as implemented in the patch is
> that you could test for whether ioremap_cache() is actually
> implemented or falls back to default ioremap().  I think for
> completeness archs should publish an ioremap type capabilities mask
> for drivers that care... (I can imagine pmem caring), or default to
> being permissive if something like IOREMAP_STRICT is not set.  There's
> also the wrinkle of archs that can only support certain types of
> mappings at a given alignment.

I think doing this at runtime might be a better idea.  E.g. a
ioremap_flags with the CACHED argument will return -EOPNOTSUP unless
actually implemented.  On various architectures different CPUs or
boards will have different capabilities in this area.

^ permalink raw reply	[flat|nested] 85+ messages in thread

* Re: [PATCH v5 2/6] arch: unify ioremap prototypes and macro aliases
  2015-07-01  6:23         ` Christoph Hellwig
  (?)
@ 2015-07-01  6:55           ` Geert Uytterhoeven
  -1 siblings, 0 replies; 85+ messages in thread
From: Geert Uytterhoeven @ 2015-07-01  6:55 UTC (permalink / raw)
  To: Christoph Hellwig
  Cc: Dan Williams, Arnd Bergmann, Ingo Molnar, Borislav Petkov,
	H. Peter Anvin, Thomas Gleixner, Ross Zwisler, Andrew Morton,
	Juergen Gross, X86 ML, Kani, Toshimitsu, linux-nvdimm,
	Benjamin Herrenschmidt, Luis Rodriguez, Konrad Rzeszutek Wilk,
	linux-kernel, Stefan Bader, Andy Lutomirski, Linux MM,
	Ralf Baechle, Henrique de Moraes Holschuh, Michael Ellerman,
	Tejun Heo, Paul Mackerras, Russell King - ARM Linux,
	linux-arm-kernel

On Wed, Jul 1, 2015 at 8:23 AM, Christoph Hellwig <hch@lst.de> wrote:
>> One useful feature of the ifdef mess as implemented in the patch is
>> that you could test for whether ioremap_cache() is actually
>> implemented or falls back to default ioremap().  I think for
>> completeness archs should publish an ioremap type capabilities mask
>> for drivers that care... (I can imagine pmem caring), or default to
>> being permissive if something like IOREMAP_STRICT is not set.  There's
>> also the wrinkle of archs that can only support certain types of
>> mappings at a given alignment.
>
> I think doing this at runtime might be a better idea.  E.g. a
> ioremap_flags with the CACHED argument will return -EOPNOTSUP unless
> actually implemented.  On various architectures different CPUs or
> boards will have different capabilities in this area.

So it would be the responsibility of the caller to fall back from
ioremap(..., CACHED) to ioremap(..., UNCACHED)?
I.e. all drivers using it should be changed...

Gr{oetje,eeting}s,

                        Geert

--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
                                -- Linus Torvalds

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org.  For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>

^ permalink raw reply	[flat|nested] 85+ messages in thread

* Re: [PATCH v5 2/6] arch: unify ioremap prototypes and macro aliases
@ 2015-07-01  6:55           ` Geert Uytterhoeven
  0 siblings, 0 replies; 85+ messages in thread
From: Geert Uytterhoeven @ 2015-07-01  6:55 UTC (permalink / raw)
  To: Christoph Hellwig
  Cc: Dan Williams, Arnd Bergmann, Ingo Molnar, Borislav Petkov,
	H. Peter Anvin, Thomas Gleixner, Ross Zwisler, Andrew Morton,
	Juergen Gross, X86 ML, Kani, Toshimitsu,
	linux-nvdimm@lists.01.org, Benjamin Herrenschmidt,
	Luis Rodriguez, Konrad Rzeszutek Wilk, linux-kernel,
	Stefan Bader, Andy Lutomirski, Linux MM, Ralf Baechle,
	Henrique de Moraes Holschuh, Michael Ellerman, Tejun Heo,
	Paul Mackerras, Russell King - ARM Linux, linux-arm-kernel

On Wed, Jul 1, 2015 at 8:23 AM, Christoph Hellwig <hch@lst.de> wrote:
>> One useful feature of the ifdef mess as implemented in the patch is
>> that you could test for whether ioremap_cache() is actually
>> implemented or falls back to default ioremap().  I think for
>> completeness archs should publish an ioremap type capabilities mask
>> for drivers that care... (I can imagine pmem caring), or default to
>> being permissive if something like IOREMAP_STRICT is not set.  There's
>> also the wrinkle of archs that can only support certain types of
>> mappings at a given alignment.
>
> I think doing this at runtime might be a better idea.  E.g. a
> ioremap_flags with the CACHED argument will return -EOPNOTSUP unless
> actually implemented.  On various architectures different CPUs or
> boards will have different capabilities in this area.

So it would be the responsibility of the caller to fall back from
ioremap(..., CACHED) to ioremap(..., UNCACHED)?
I.e. all drivers using it should be changed...

Gr{oetje,eeting}s,

                        Geert

--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
                                -- Linus Torvalds

^ permalink raw reply	[flat|nested] 85+ messages in thread

* [PATCH v5 2/6] arch: unify ioremap prototypes and macro aliases
@ 2015-07-01  6:55           ` Geert Uytterhoeven
  0 siblings, 0 replies; 85+ messages in thread
From: Geert Uytterhoeven @ 2015-07-01  6:55 UTC (permalink / raw)
  To: linux-arm-kernel

On Wed, Jul 1, 2015 at 8:23 AM, Christoph Hellwig <hch@lst.de> wrote:
>> One useful feature of the ifdef mess as implemented in the patch is
>> that you could test for whether ioremap_cache() is actually
>> implemented or falls back to default ioremap().  I think for
>> completeness archs should publish an ioremap type capabilities mask
>> for drivers that care... (I can imagine pmem caring), or default to
>> being permissive if something like IOREMAP_STRICT is not set.  There's
>> also the wrinkle of archs that can only support certain types of
>> mappings at a given alignment.
>
> I think doing this at runtime might be a better idea.  E.g. a
> ioremap_flags with the CACHED argument will return -EOPNOTSUP unless
> actually implemented.  On various architectures different CPUs or
> boards will have different capabilities in this area.

So it would be the responsibility of the caller to fall back from
ioremap(..., CACHED) to ioremap(..., UNCACHED)?
I.e. all drivers using it should be changed...

Gr{oetje,eeting}s,

                        Geert

--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert at linux-m68k.org

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
                                -- Linus Torvalds

^ permalink raw reply	[flat|nested] 85+ messages in thread

* Re: [PATCH v5 2/6] arch: unify ioremap prototypes and macro aliases
  2015-07-01  6:55           ` Geert Uytterhoeven
  (?)
@ 2015-07-01  6:59             ` Christoph Hellwig
  -1 siblings, 0 replies; 85+ messages in thread
From: Christoph Hellwig @ 2015-07-01  6:59 UTC (permalink / raw)
  To: Geert Uytterhoeven
  Cc: Christoph Hellwig, Dan Williams, Arnd Bergmann, Ingo Molnar,
	Borislav Petkov, H. Peter Anvin, Thomas Gleixner, Ross Zwisler,
	Andrew Morton, Juergen Gross, X86 ML, Kani, Toshimitsu,
	linux-nvdimm, Benjamin Herrenschmidt, Luis Rodriguez,
	Konrad Rzeszutek Wilk, linux-kernel, Stefan Bader,
	Andy Lutomirski, Linux MM, Ralf Baechle,
	Henrique de Moraes Holschuh, Michael Ellerman, Tejun Heo,
	Paul Mackerras, Russell King - ARM Linux, linux-arm-kernel

On Wed, Jul 01, 2015 at 08:55:57AM +0200, Geert Uytterhoeven wrote:
> >
> > I think doing this at runtime might be a better idea.  E.g. a
> > ioremap_flags with the CACHED argument will return -EOPNOTSUP unless
> > actually implemented.  On various architectures different CPUs or
> > boards will have different capabilities in this area.
> 
> So it would be the responsibility of the caller to fall back from
> ioremap(..., CACHED) to ioremap(..., UNCACHED)?
> I.e. all drivers using it should be changed...

All of the zero users we currently have will need to be changed, yes.

Note that I propose to leave ioremap(), aka ioremap_flags(..., 0) as
a default that always has to work, -EOPNOTSUP is only a valid return
value for non-default flaga.

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org.  For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>

^ permalink raw reply	[flat|nested] 85+ messages in thread

* Re: [PATCH v5 2/6] arch: unify ioremap prototypes and macro aliases
@ 2015-07-01  6:59             ` Christoph Hellwig
  0 siblings, 0 replies; 85+ messages in thread
From: Christoph Hellwig @ 2015-07-01  6:59 UTC (permalink / raw)
  To: Geert Uytterhoeven
  Cc: Christoph Hellwig, Dan Williams, Arnd Bergmann, Ingo Molnar,
	Borislav Petkov, H. Peter Anvin, Thomas Gleixner, Ross Zwisler,
	Andrew Morton, Juergen Gross, X86 ML, Kani, Toshimitsu,
	linux-nvdimm@lists.01.org, Benjamin Herrenschmidt,
	Luis Rodriguez, Konrad Rzeszutek Wilk, linux-kernel,
	Stefan Bader, Andy Lutomirski, Linux MM, Ralf Baechle,
	Henrique de Moraes Holschuh, Michael Ellerman, Tejun Heo,
	Paul Mackerras, Russell King - ARM Linux, linux-arm-kernel

On Wed, Jul 01, 2015 at 08:55:57AM +0200, Geert Uytterhoeven wrote:
> >
> > I think doing this at runtime might be a better idea.  E.g. a
> > ioremap_flags with the CACHED argument will return -EOPNOTSUP unless
> > actually implemented.  On various architectures different CPUs or
> > boards will have different capabilities in this area.
> 
> So it would be the responsibility of the caller to fall back from
> ioremap(..., CACHED) to ioremap(..., UNCACHED)?
> I.e. all drivers using it should be changed...

All of the zero users we currently have will need to be changed, yes.

Note that I propose to leave ioremap(), aka ioremap_flags(..., 0) as
a default that always has to work, -EOPNOTSUP is only a valid return
value for non-default flaga.

^ permalink raw reply	[flat|nested] 85+ messages in thread

* [PATCH v5 2/6] arch: unify ioremap prototypes and macro aliases
@ 2015-07-01  6:59             ` Christoph Hellwig
  0 siblings, 0 replies; 85+ messages in thread
From: Christoph Hellwig @ 2015-07-01  6:59 UTC (permalink / raw)
  To: linux-arm-kernel

On Wed, Jul 01, 2015 at 08:55:57AM +0200, Geert Uytterhoeven wrote:
> >
> > I think doing this at runtime might be a better idea.  E.g. a
> > ioremap_flags with the CACHED argument will return -EOPNOTSUP unless
> > actually implemented.  On various architectures different CPUs or
> > boards will have different capabilities in this area.
> 
> So it would be the responsibility of the caller to fall back from
> ioremap(..., CACHED) to ioremap(..., UNCACHED)?
> I.e. all drivers using it should be changed...

All of the zero users we currently have will need to be changed, yes.

Note that I propose to leave ioremap(), aka ioremap_flags(..., 0) as
a default that always has to work, -EOPNOTSUP is only a valid return
value for non-default flaga.

^ permalink raw reply	[flat|nested] 85+ messages in thread

* Re: [PATCH v5 2/6] arch: unify ioremap prototypes and macro aliases
  2015-07-01  6:59             ` Christoph Hellwig
  (?)
@ 2015-07-01  7:19               ` Geert Uytterhoeven
  -1 siblings, 0 replies; 85+ messages in thread
From: Geert Uytterhoeven @ 2015-07-01  7:19 UTC (permalink / raw)
  To: Christoph Hellwig
  Cc: Dan Williams, Arnd Bergmann, Ingo Molnar, Borislav Petkov,
	H. Peter Anvin, Thomas Gleixner, Ross Zwisler, Andrew Morton,
	Juergen Gross, X86 ML, Kani, Toshimitsu, linux-nvdimm,
	Benjamin Herrenschmidt, Luis Rodriguez, Konrad Rzeszutek Wilk,
	linux-kernel, Stefan Bader, Andy Lutomirski, Linux MM,
	Ralf Baechle, Henrique de Moraes Holschuh, Michael Ellerman,
	Tejun Heo, Paul Mackerras, Russell King - ARM Linux,
	linux-arm-kernel

On Wed, Jul 1, 2015 at 8:59 AM, Christoph Hellwig <hch@lst.de> wrote:
> On Wed, Jul 01, 2015 at 08:55:57AM +0200, Geert Uytterhoeven wrote:
>> >
>> > I think doing this at runtime might be a better idea.  E.g. a
>> > ioremap_flags with the CACHED argument will return -EOPNOTSUP unless
>> > actually implemented.  On various architectures different CPUs or
>> > boards will have different capabilities in this area.
>>
>> So it would be the responsibility of the caller to fall back from
>> ioremap(..., CACHED) to ioremap(..., UNCACHED)?
>> I.e. all drivers using it should be changed...
>
> All of the zero users we currently have will need to be changed, yes.

Good. Less work to convert all of these ;-)

> Note that I propose to leave ioremap(), aka ioremap_flags(..., 0) as
> a default that always has to work, -EOPNOTSUP is only a valid return
> value for non-default flaga.

OK.

Gr{oetje,eeting}s,

                        Geert

--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
                                -- Linus Torvalds

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org.  For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>

^ permalink raw reply	[flat|nested] 85+ messages in thread

* Re: [PATCH v5 2/6] arch: unify ioremap prototypes and macro aliases
@ 2015-07-01  7:19               ` Geert Uytterhoeven
  0 siblings, 0 replies; 85+ messages in thread
From: Geert Uytterhoeven @ 2015-07-01  7:19 UTC (permalink / raw)
  To: Christoph Hellwig
  Cc: Dan Williams, Arnd Bergmann, Ingo Molnar, Borislav Petkov,
	H. Peter Anvin, Thomas Gleixner, Ross Zwisler, Andrew Morton,
	Juergen Gross, X86 ML, Kani, Toshimitsu,
	linux-nvdimm@lists.01.org, Benjamin Herrenschmidt,
	Luis Rodriguez, Konrad Rzeszutek Wilk, linux-kernel,
	Stefan Bader, Andy Lutomirski, Linux MM, Ralf Baechle,
	Henrique de Moraes Holschuh, Michael Ellerman, Tejun Heo,
	Paul Mackerras, Russell King - ARM Linux, linux-arm-kernel

On Wed, Jul 1, 2015 at 8:59 AM, Christoph Hellwig <hch@lst.de> wrote:
> On Wed, Jul 01, 2015 at 08:55:57AM +0200, Geert Uytterhoeven wrote:
>> >
>> > I think doing this at runtime might be a better idea.  E.g. a
>> > ioremap_flags with the CACHED argument will return -EOPNOTSUP unless
>> > actually implemented.  On various architectures different CPUs or
>> > boards will have different capabilities in this area.
>>
>> So it would be the responsibility of the caller to fall back from
>> ioremap(..., CACHED) to ioremap(..., UNCACHED)?
>> I.e. all drivers using it should be changed...
>
> All of the zero users we currently have will need to be changed, yes.

Good. Less work to convert all of these ;-)

> Note that I propose to leave ioremap(), aka ioremap_flags(..., 0) as
> a default that always has to work, -EOPNOTSUP is only a valid return
> value for non-default flaga.

OK.

Gr{oetje,eeting}s,

                        Geert

--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
                                -- Linus Torvalds

^ permalink raw reply	[flat|nested] 85+ messages in thread

* [PATCH v5 2/6] arch: unify ioremap prototypes and macro aliases
@ 2015-07-01  7:19               ` Geert Uytterhoeven
  0 siblings, 0 replies; 85+ messages in thread
From: Geert Uytterhoeven @ 2015-07-01  7:19 UTC (permalink / raw)
  To: linux-arm-kernel

On Wed, Jul 1, 2015 at 8:59 AM, Christoph Hellwig <hch@lst.de> wrote:
> On Wed, Jul 01, 2015 at 08:55:57AM +0200, Geert Uytterhoeven wrote:
>> >
>> > I think doing this at runtime might be a better idea.  E.g. a
>> > ioremap_flags with the CACHED argument will return -EOPNOTSUP unless
>> > actually implemented.  On various architectures different CPUs or
>> > boards will have different capabilities in this area.
>>
>> So it would be the responsibility of the caller to fall back from
>> ioremap(..., CACHED) to ioremap(..., UNCACHED)?
>> I.e. all drivers using it should be changed...
>
> All of the zero users we currently have will need to be changed, yes.

Good. Less work to convert all of these ;-)

> Note that I propose to leave ioremap(), aka ioremap_flags(..., 0) as
> a default that always has to work, -EOPNOTSUP is only a valid return
> value for non-default flaga.

OK.

Gr{oetje,eeting}s,

                        Geert

--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert at linux-m68k.org

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
                                -- Linus Torvalds

^ permalink raw reply	[flat|nested] 85+ messages in thread

* Re: [PATCH v5 2/6] arch: unify ioremap prototypes and macro aliases
  2015-07-01  7:19               ` Geert Uytterhoeven
  (?)
@ 2015-07-01  7:28                 ` Christoph Hellwig
  -1 siblings, 0 replies; 85+ messages in thread
From: Christoph Hellwig @ 2015-07-01  7:28 UTC (permalink / raw)
  To: Geert Uytterhoeven
  Cc: Christoph Hellwig, Dan Williams, Arnd Bergmann, Ingo Molnar,
	Borislav Petkov, H. Peter Anvin, Thomas Gleixner, Ross Zwisler,
	Andrew Morton, Juergen Gross, X86 ML, Kani, Toshimitsu,
	linux-nvdimm, Benjamin Herrenschmidt, Luis Rodriguez,
	Konrad Rzeszutek Wilk, linux-kernel, Stefan Bader,
	Andy Lutomirski, Linux MM, Ralf Baechle,
	Henrique de Moraes Holschuh, Michael Ellerman, Tejun Heo,
	Paul Mackerras, Russell King - ARM Linux, linux-arm-kernel

On Wed, Jul 01, 2015 at 09:19:29AM +0200, Geert Uytterhoeven wrote:
> >> So it would be the responsibility of the caller to fall back from
> >> ioremap(..., CACHED) to ioremap(..., UNCACHED)?
> >> I.e. all drivers using it should be changed...
> >
> > All of the zero users we currently have will need to be changed, yes.
> 
> Good. Less work to convert all of these ;-)

And I didn't have enough coffee yet.  We of course have a few users of
ioremap_cache(), and two implememantions but no users of ioremap_cached().
Looks like the implementations can't even agree on the name.

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org.  For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>

^ permalink raw reply	[flat|nested] 85+ messages in thread

* Re: [PATCH v5 2/6] arch: unify ioremap prototypes and macro aliases
@ 2015-07-01  7:28                 ` Christoph Hellwig
  0 siblings, 0 replies; 85+ messages in thread
From: Christoph Hellwig @ 2015-07-01  7:28 UTC (permalink / raw)
  To: Geert Uytterhoeven
  Cc: Christoph Hellwig, Dan Williams, Arnd Bergmann, Ingo Molnar,
	Borislav Petkov, H. Peter Anvin, Thomas Gleixner, Ross Zwisler,
	Andrew Morton, Juergen Gross, X86 ML, Kani, Toshimitsu,
	linux-nvdimm@lists.01.org, Benjamin Herrenschmidt,
	Luis Rodriguez, Konrad Rzeszutek Wilk, linux-kernel,
	Stefan Bader, Andy Lutomirski, Linux MM, Ralf Baechle,
	Henrique de Moraes Holschuh, Michael Ellerman, Tejun Heo,
	Paul Mackerras, Russell King - ARM Linux, linux-arm-kernel

On Wed, Jul 01, 2015 at 09:19:29AM +0200, Geert Uytterhoeven wrote:
> >> So it would be the responsibility of the caller to fall back from
> >> ioremap(..., CACHED) to ioremap(..., UNCACHED)?
> >> I.e. all drivers using it should be changed...
> >
> > All of the zero users we currently have will need to be changed, yes.
> 
> Good. Less work to convert all of these ;-)

And I didn't have enough coffee yet.  We of course have a few users of
ioremap_cache(), and two implememantions but no users of ioremap_cached().
Looks like the implementations can't even agree on the name.

^ permalink raw reply	[flat|nested] 85+ messages in thread

* [PATCH v5 2/6] arch: unify ioremap prototypes and macro aliases
@ 2015-07-01  7:28                 ` Christoph Hellwig
  0 siblings, 0 replies; 85+ messages in thread
From: Christoph Hellwig @ 2015-07-01  7:28 UTC (permalink / raw)
  To: linux-arm-kernel

On Wed, Jul 01, 2015 at 09:19:29AM +0200, Geert Uytterhoeven wrote:
> >> So it would be the responsibility of the caller to fall back from
> >> ioremap(..., CACHED) to ioremap(..., UNCACHED)?
> >> I.e. all drivers using it should be changed...
> >
> > All of the zero users we currently have will need to be changed, yes.
> 
> Good. Less work to convert all of these ;-)

And I didn't have enough coffee yet.  We of course have a few users of
ioremap_cache(), and two implememantions but no users of ioremap_cached().
Looks like the implementations can't even agree on the name.

^ permalink raw reply	[flat|nested] 85+ messages in thread

* Re: [PATCH v5 2/6] arch: unify ioremap prototypes and macro aliases
  2015-07-01  6:55           ` Geert Uytterhoeven
  (?)
@ 2015-07-01  8:09             ` Russell King - ARM Linux
  -1 siblings, 0 replies; 85+ messages in thread
From: Russell King - ARM Linux @ 2015-07-01  8:09 UTC (permalink / raw)
  To: Geert Uytterhoeven
  Cc: Christoph Hellwig, Dan Williams, Arnd Bergmann, Ingo Molnar,
	Borislav Petkov, H. Peter Anvin, Thomas Gleixner, Ross Zwisler,
	Andrew Morton, Juergen Gross, X86 ML, Kani, Toshimitsu,
	linux-nvdimm@lists.01.org, Benjamin Herrenschmidt,
	Luis Rodriguez, Konrad Rzeszutek Wilk, linux-kernel,
	Stefan Bader, Andy Lutomirski, Linux MM, Ralf Baechle,
	Henrique de Moraes Holschuh, Michael Ellerman, Tejun Heo,
	Paul Mackerras, linux-arm-kernel

On Wed, Jul 01, 2015 at 08:55:57AM +0200, Geert Uytterhoeven wrote:
> On Wed, Jul 1, 2015 at 8:23 AM, Christoph Hellwig <hch@lst.de> wrote:
> >> One useful feature of the ifdef mess as implemented in the patch is
> >> that you could test for whether ioremap_cache() is actually
> >> implemented or falls back to default ioremap().  I think for
> >> completeness archs should publish an ioremap type capabilities mask
> >> for drivers that care... (I can imagine pmem caring), or default to
> >> being permissive if something like IOREMAP_STRICT is not set.  There's
> >> also the wrinkle of archs that can only support certain types of
> >> mappings at a given alignment.
> >
> > I think doing this at runtime might be a better idea.  E.g. a
> > ioremap_flags with the CACHED argument will return -EOPNOTSUP unless
> > actually implemented.  On various architectures different CPUs or
> > boards will have different capabilities in this area.
> 
> So it would be the responsibility of the caller to fall back from
> ioremap(..., CACHED) to ioremap(..., UNCACHED)?
> I.e. all drivers using it should be changed...

Another important point here is to define what the properties of the
mappings are.  It's no good just saying "uncached".

We've recently been around this over the PMEM driver and the broken
addition of ioremap_wt() on ARM...

By "properties" I mean stuff like whether unaligned accesses permitted,
any kind of atomic access (eg, xchg, cmpxchg, etc).

This matters: on ARM, a mapping suitable for a device does not support
unaligned accesses or atomic accesses - only "memory-like" mappings
support those.  However, memory-like mappings are not required to
preserve access size, number of accesses, etc which makes them unsuitable
for device registers.

The problem with ioremap_uncached() in particular is that we have LDD
and other documentation telling people to use it to map device registers,
so we can't define ioremap_uncached() on ARM to have memory-like
properties, and it doesn't support unaligned accesses.

I have a series of patches which fix up 32-bit ARM for the broken
ioremap_wt() stuff that was merged during this merge window, which I
intend to push out into linux-next at some point (possibly during the
merge window, if not after -rc1) which also move ioremap*() out of line
on ARM but more importantly, adds a load of documentation about the
properties of the resulting mapping on ARM.

-- 
FTTC broadband for 0.8mile line: currently at 10.5Mbps down 400kbps up
according to speedtest.net.

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org.  For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>

^ permalink raw reply	[flat|nested] 85+ messages in thread

* Re: [PATCH v5 2/6] arch: unify ioremap prototypes and macro aliases
@ 2015-07-01  8:09             ` Russell King - ARM Linux
  0 siblings, 0 replies; 85+ messages in thread
From: Russell King - ARM Linux @ 2015-07-01  8:09 UTC (permalink / raw)
  To: Geert Uytterhoeven
  Cc: Christoph Hellwig, Dan Williams, Arnd Bergmann, Ingo Molnar,
	Borislav Petkov, H. Peter Anvin, Thomas Gleixner, Ross Zwisler,
	Andrew Morton, Juergen Gross, X86 ML, Kani, Toshimitsu,
	linux-nvdimm@lists.01.org, Benjamin Herrenschmidt,
	Luis Rodriguez, Konrad Rzeszutek Wilk, linux-kernel,
	Stefan Bader, Andy Lutomirski, Linux MM, Ralf Baechle,
	Henrique de Moraes Holschuh, Michael Ellerman, Tejun Heo,
	Paul Mackerras, linux-arm-kernel

On Wed, Jul 01, 2015 at 08:55:57AM +0200, Geert Uytterhoeven wrote:
> On Wed, Jul 1, 2015 at 8:23 AM, Christoph Hellwig <hch@lst.de> wrote:
> >> One useful feature of the ifdef mess as implemented in the patch is
> >> that you could test for whether ioremap_cache() is actually
> >> implemented or falls back to default ioremap().  I think for
> >> completeness archs should publish an ioremap type capabilities mask
> >> for drivers that care... (I can imagine pmem caring), or default to
> >> being permissive if something like IOREMAP_STRICT is not set.  There's
> >> also the wrinkle of archs that can only support certain types of
> >> mappings at a given alignment.
> >
> > I think doing this at runtime might be a better idea.  E.g. a
> > ioremap_flags with the CACHED argument will return -EOPNOTSUP unless
> > actually implemented.  On various architectures different CPUs or
> > boards will have different capabilities in this area.
> 
> So it would be the responsibility of the caller to fall back from
> ioremap(..., CACHED) to ioremap(..., UNCACHED)?
> I.e. all drivers using it should be changed...

Another important point here is to define what the properties of the
mappings are.  It's no good just saying "uncached".

We've recently been around this over the PMEM driver and the broken
addition of ioremap_wt() on ARM...

By "properties" I mean stuff like whether unaligned accesses permitted,
any kind of atomic access (eg, xchg, cmpxchg, etc).

This matters: on ARM, a mapping suitable for a device does not support
unaligned accesses or atomic accesses - only "memory-like" mappings
support those.  However, memory-like mappings are not required to
preserve access size, number of accesses, etc which makes them unsuitable
for device registers.

The problem with ioremap_uncached() in particular is that we have LDD
and other documentation telling people to use it to map device registers,
so we can't define ioremap_uncached() on ARM to have memory-like
properties, and it doesn't support unaligned accesses.

I have a series of patches which fix up 32-bit ARM for the broken
ioremap_wt() stuff that was merged during this merge window, which I
intend to push out into linux-next at some point (possibly during the
merge window, if not after -rc1) which also move ioremap*() out of line
on ARM but more importantly, adds a load of documentation about the
properties of the resulting mapping on ARM.

-- 
FTTC broadband for 0.8mile line: currently at 10.5Mbps down 400kbps up
according to speedtest.net.

^ permalink raw reply	[flat|nested] 85+ messages in thread

* [PATCH v5 2/6] arch: unify ioremap prototypes and macro aliases
@ 2015-07-01  8:09             ` Russell King - ARM Linux
  0 siblings, 0 replies; 85+ messages in thread
From: Russell King - ARM Linux @ 2015-07-01  8:09 UTC (permalink / raw)
  To: linux-arm-kernel

On Wed, Jul 01, 2015 at 08:55:57AM +0200, Geert Uytterhoeven wrote:
> On Wed, Jul 1, 2015 at 8:23 AM, Christoph Hellwig <hch@lst.de> wrote:
> >> One useful feature of the ifdef mess as implemented in the patch is
> >> that you could test for whether ioremap_cache() is actually
> >> implemented or falls back to default ioremap().  I think for
> >> completeness archs should publish an ioremap type capabilities mask
> >> for drivers that care... (I can imagine pmem caring), or default to
> >> being permissive if something like IOREMAP_STRICT is not set.  There's
> >> also the wrinkle of archs that can only support certain types of
> >> mappings at a given alignment.
> >
> > I think doing this at runtime might be a better idea.  E.g. a
> > ioremap_flags with the CACHED argument will return -EOPNOTSUP unless
> > actually implemented.  On various architectures different CPUs or
> > boards will have different capabilities in this area.
> 
> So it would be the responsibility of the caller to fall back from
> ioremap(..., CACHED) to ioremap(..., UNCACHED)?
> I.e. all drivers using it should be changed...

Another important point here is to define what the properties of the
mappings are.  It's no good just saying "uncached".

We've recently been around this over the PMEM driver and the broken
addition of ioremap_wt() on ARM...

By "properties" I mean stuff like whether unaligned accesses permitted,
any kind of atomic access (eg, xchg, cmpxchg, etc).

This matters: on ARM, a mapping suitable for a device does not support
unaligned accesses or atomic accesses - only "memory-like" mappings
support those.  However, memory-like mappings are not required to
preserve access size, number of accesses, etc which makes them unsuitable
for device registers.

The problem with ioremap_uncached() in particular is that we have LDD
and other documentation telling people to use it to map device registers,
so we can't define ioremap_uncached() on ARM to have memory-like
properties, and it doesn't support unaligned accesses.

I have a series of patches which fix up 32-bit ARM for the broken
ioremap_wt() stuff that was merged during this merge window, which I
intend to push out into linux-next at some point (possibly during the
merge window, if not after -rc1) which also move ioremap*() out of line
on ARM but more importantly, adds a load of documentation about the
properties of the resulting mapping on ARM.

-- 
FTTC broadband for 0.8mile line: currently at 10.5Mbps down 400kbps up
according to speedtest.net.

^ permalink raw reply	[flat|nested] 85+ messages in thread

* Re: [PATCH v5 2/6] arch: unify ioremap prototypes and macro aliases
  2015-07-01  8:09             ` Russell King - ARM Linux
  (?)
@ 2015-07-01 16:47               ` Dan Williams
  -1 siblings, 0 replies; 85+ messages in thread
From: Dan Williams @ 2015-07-01 16:47 UTC (permalink / raw)
  To: Russell King - ARM Linux
  Cc: Geert Uytterhoeven, Christoph Hellwig, Arnd Bergmann,
	Ingo Molnar, Borislav Petkov, H. Peter Anvin, Thomas Gleixner,
	Ross Zwisler, Andrew Morton, Juergen Gross, X86 ML, Kani,
	Toshimitsu, linux-nvdimm@lists.01.org, Benjamin Herrenschmidt,
	Luis Rodriguez, Konrad Rzeszutek Wilk, linux-kernel,
	Stefan Bader, Andy Lutomirski, Linux MM, Ralf Baechle,
	Henrique de Moraes Holschuh, Michael Ellerman, Tejun Heo,
	Paul Mackerras, linux-arm-kernel

On Wed, Jul 1, 2015 at 1:09 AM, Russell King - ARM Linux
<linux@arm.linux.org.uk> wrote:
> On Wed, Jul 01, 2015 at 08:55:57AM +0200, Geert Uytterhoeven wrote:
>> On Wed, Jul 1, 2015 at 8:23 AM, Christoph Hellwig <hch@lst.de> wrote:
>> >> One useful feature of the ifdef mess as implemented in the patch is
>> >> that you could test for whether ioremap_cache() is actually
>> >> implemented or falls back to default ioremap().  I think for
>> >> completeness archs should publish an ioremap type capabilities mask
>> >> for drivers that care... (I can imagine pmem caring), or default to
>> >> being permissive if something like IOREMAP_STRICT is not set.  There's
>> >> also the wrinkle of archs that can only support certain types of
>> >> mappings at a given alignment.
>> >
>> > I think doing this at runtime might be a better idea.  E.g. a
>> > ioremap_flags with the CACHED argument will return -EOPNOTSUP unless
>> > actually implemented.  On various architectures different CPUs or
>> > boards will have different capabilities in this area.
>>
>> So it would be the responsibility of the caller to fall back from
>> ioremap(..., CACHED) to ioremap(..., UNCACHED)?
>> I.e. all drivers using it should be changed...
>
> Another important point here is to define what the properties of the
> mappings are.  It's no good just saying "uncached".
>
> We've recently been around this over the PMEM driver and the broken
> addition of ioremap_wt() on ARM...
>
> By "properties" I mean stuff like whether unaligned accesses permitted,
> any kind of atomic access (eg, xchg, cmpxchg, etc).
>
> This matters: on ARM, a mapping suitable for a device does not support
> unaligned accesses or atomic accesses - only "memory-like" mappings
> support those.  However, memory-like mappings are not required to
> preserve access size, number of accesses, etc which makes them unsuitable
> for device registers.

I'm proposing that we explicitly switch "memory-like" use cases over
to a separate set of "memremap()" apis, as these are no longer
"__iomem" [1].

> The problem with ioremap_uncached() in particular is that we have LDD
> and other documentation telling people to use it to map device registers,
> so we can't define ioremap_uncached() on ARM to have memory-like
> properties, and it doesn't support unaligned accesses.
>
> I have a series of patches which fix up 32-bit ARM for the broken
> ioremap_wt() stuff that was merged during this merge window, which I
> intend to push out into linux-next at some point (possibly during the
> merge window, if not after -rc1) which also move ioremap*() out of line
> on ARM but more importantly, adds a load of documentation about the
> properties of the resulting mapping on ARM.

Sounds good, I'll look for that before proceeding on this clean up.

[1]: https://lists.01.org/pipermail/linux-nvdimm/2015-June/001331.html

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org.  For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>

^ permalink raw reply	[flat|nested] 85+ messages in thread

* Re: [PATCH v5 2/6] arch: unify ioremap prototypes and macro aliases
@ 2015-07-01 16:47               ` Dan Williams
  0 siblings, 0 replies; 85+ messages in thread
From: Dan Williams @ 2015-07-01 16:47 UTC (permalink / raw)
  To: Russell King - ARM Linux
  Cc: Geert Uytterhoeven, Christoph Hellwig, Arnd Bergmann,
	Ingo Molnar, Borislav Petkov, H. Peter Anvin, Thomas Gleixner,
	Ross Zwisler, Andrew Morton, Juergen Gross, X86 ML, Kani,
	Toshimitsu, linux-nvdimm@lists.01.org, Benjamin Herrenschmidt,
	Luis Rodriguez, Konrad Rzeszutek Wilk, linux-kernel,
	Stefan Bader, Andy Lutomirski, Linux MM, Ralf Baechle,
	Henrique de Moraes Holschuh, Michael Ellerman, Tejun Heo,
	Paul Mackerras, linux-arm-kernel

On Wed, Jul 1, 2015 at 1:09 AM, Russell King - ARM Linux
<linux@arm.linux.org.uk> wrote:
> On Wed, Jul 01, 2015 at 08:55:57AM +0200, Geert Uytterhoeven wrote:
>> On Wed, Jul 1, 2015 at 8:23 AM, Christoph Hellwig <hch@lst.de> wrote:
>> >> One useful feature of the ifdef mess as implemented in the patch is
>> >> that you could test for whether ioremap_cache() is actually
>> >> implemented or falls back to default ioremap().  I think for
>> >> completeness archs should publish an ioremap type capabilities mask
>> >> for drivers that care... (I can imagine pmem caring), or default to
>> >> being permissive if something like IOREMAP_STRICT is not set.  There's
>> >> also the wrinkle of archs that can only support certain types of
>> >> mappings at a given alignment.
>> >
>> > I think doing this at runtime might be a better idea.  E.g. a
>> > ioremap_flags with the CACHED argument will return -EOPNOTSUP unless
>> > actually implemented.  On various architectures different CPUs or
>> > boards will have different capabilities in this area.
>>
>> So it would be the responsibility of the caller to fall back from
>> ioremap(..., CACHED) to ioremap(..., UNCACHED)?
>> I.e. all drivers using it should be changed...
>
> Another important point here is to define what the properties of the
> mappings are.  It's no good just saying "uncached".
>
> We've recently been around this over the PMEM driver and the broken
> addition of ioremap_wt() on ARM...
>
> By "properties" I mean stuff like whether unaligned accesses permitted,
> any kind of atomic access (eg, xchg, cmpxchg, etc).
>
> This matters: on ARM, a mapping suitable for a device does not support
> unaligned accesses or atomic accesses - only "memory-like" mappings
> support those.  However, memory-like mappings are not required to
> preserve access size, number of accesses, etc which makes them unsuitable
> for device registers.

I'm proposing that we explicitly switch "memory-like" use cases over
to a separate set of "memremap()" apis, as these are no longer
"__iomem" [1].

> The problem with ioremap_uncached() in particular is that we have LDD
> and other documentation telling people to use it to map device registers,
> so we can't define ioremap_uncached() on ARM to have memory-like
> properties, and it doesn't support unaligned accesses.
>
> I have a series of patches which fix up 32-bit ARM for the broken
> ioremap_wt() stuff that was merged during this merge window, which I
> intend to push out into linux-next at some point (possibly during the
> merge window, if not after -rc1) which also move ioremap*() out of line
> on ARM but more importantly, adds a load of documentation about the
> properties of the resulting mapping on ARM.

Sounds good, I'll look for that before proceeding on this clean up.

[1]: https://lists.01.org/pipermail/linux-nvdimm/2015-June/001331.html

^ permalink raw reply	[flat|nested] 85+ messages in thread

* [PATCH v5 2/6] arch: unify ioremap prototypes and macro aliases
@ 2015-07-01 16:47               ` Dan Williams
  0 siblings, 0 replies; 85+ messages in thread
From: Dan Williams @ 2015-07-01 16:47 UTC (permalink / raw)
  To: linux-arm-kernel

On Wed, Jul 1, 2015 at 1:09 AM, Russell King - ARM Linux
<linux@arm.linux.org.uk> wrote:
> On Wed, Jul 01, 2015 at 08:55:57AM +0200, Geert Uytterhoeven wrote:
>> On Wed, Jul 1, 2015 at 8:23 AM, Christoph Hellwig <hch@lst.de> wrote:
>> >> One useful feature of the ifdef mess as implemented in the patch is
>> >> that you could test for whether ioremap_cache() is actually
>> >> implemented or falls back to default ioremap().  I think for
>> >> completeness archs should publish an ioremap type capabilities mask
>> >> for drivers that care... (I can imagine pmem caring), or default to
>> >> being permissive if something like IOREMAP_STRICT is not set.  There's
>> >> also the wrinkle of archs that can only support certain types of
>> >> mappings at a given alignment.
>> >
>> > I think doing this at runtime might be a better idea.  E.g. a
>> > ioremap_flags with the CACHED argument will return -EOPNOTSUP unless
>> > actually implemented.  On various architectures different CPUs or
>> > boards will have different capabilities in this area.
>>
>> So it would be the responsibility of the caller to fall back from
>> ioremap(..., CACHED) to ioremap(..., UNCACHED)?
>> I.e. all drivers using it should be changed...
>
> Another important point here is to define what the properties of the
> mappings are.  It's no good just saying "uncached".
>
> We've recently been around this over the PMEM driver and the broken
> addition of ioremap_wt() on ARM...
>
> By "properties" I mean stuff like whether unaligned accesses permitted,
> any kind of atomic access (eg, xchg, cmpxchg, etc).
>
> This matters: on ARM, a mapping suitable for a device does not support
> unaligned accesses or atomic accesses - only "memory-like" mappings
> support those.  However, memory-like mappings are not required to
> preserve access size, number of accesses, etc which makes them unsuitable
> for device registers.

I'm proposing that we explicitly switch "memory-like" use cases over
to a separate set of "memremap()" apis, as these are no longer
"__iomem" [1].

> The problem with ioremap_uncached() in particular is that we have LDD
> and other documentation telling people to use it to map device registers,
> so we can't define ioremap_uncached() on ARM to have memory-like
> properties, and it doesn't support unaligned accesses.
>
> I have a series of patches which fix up 32-bit ARM for the broken
> ioremap_wt() stuff that was merged during this merge window, which I
> intend to push out into linux-next at some point (possibly during the
> merge window, if not after -rc1) which also move ioremap*() out of line
> on ARM but more importantly, adds a load of documentation about the
> properties of the resulting mapping on ARM.

Sounds good, I'll look for that before proceeding on this clean up.

[1]: https://lists.01.org/pipermail/linux-nvdimm/2015-June/001331.html

^ permalink raw reply	[flat|nested] 85+ messages in thread

* Re: [PATCH v5 2/6] arch: unify ioremap prototypes and macro aliases
  2015-07-01  7:28                 ` Christoph Hellwig
  (?)
@ 2015-07-07  9:50                   ` Luis R. Rodriguez
  -1 siblings, 0 replies; 85+ messages in thread
From: Luis R. Rodriguez @ 2015-07-07  9:50 UTC (permalink / raw)
  To: Christoph Hellwig, Andy Lutomirski, Benjamin Herrenschmidt
  Cc: Geert Uytterhoeven, Julia Lawall, Dan Williams, Arnd Bergmann,
	Ingo Molnar, Borislav Petkov, H. Peter Anvin, Thomas Gleixner,
	Ross Zwisler, Andrew Morton, Juergen Gross, X86 ML, Kani,
	Toshimitsu, linux-nvdimm, Konrad Rzeszutek Wilk, linux-kernel,
	Stefan Bader, Linux MM, Ralf Baechle,
	Henrique de Moraes Holschuh, Michael Ellerman, Tejun Heo,
	Paul Mackerras, Russell King - ARM Linux, mcgrof,
	linux-arm-kernel

On Wed, Jul 01, 2015 at 09:28:28AM +0200, Christoph Hellwig wrote:
> On Wed, Jul 01, 2015 at 09:19:29AM +0200, Geert Uytterhoeven wrote:
> > >> So it would be the responsibility of the caller to fall back from
> > >> ioremap(..., CACHED) to ioremap(..., UNCACHED)?
> > >> I.e. all drivers using it should be changed...
> > >
> > > All of the zero users we currently have will need to be changed, yes.
> > 
> > Good. Less work to convert all of these ;-)
> 
> And I didn't have enough coffee yet.  We of course have a few users of
> ioremap_cache(), and two implememantions but no users of ioremap_cached().
> Looks like the implementations can't even agree on the name.

Yies, that naming is icky... we also have quite a bit of ioremap_nocache() users:

mcgrof@ergon ~/linux-next (git::kill-mtrr)$ git grep ioremap_nocache drivers/| wc -l
359

On x86 the default ioremap() happens to map to ioremap_nocache() anyway as well.

This is on purpose, there is an ongoing effort to streamline ioremap_nocache()
for registers on the x86 front with the long term goal then of making PAT
strong UC the default preference for both ioremap() and ioremap_nocache() for
PAT enabled systems. This would prevent things like write-combining modifiers
from having any effect on the area. This comes with a small architectural
driver cost, it means all write-combining desired areas must be split out in
drivers properly.  This is part of the work I've been doing lately. The
eventual goal once we have the write-combing areas properly split with
ioremap_wc() and using the new proper preferred architecture agnostic modifier
(arch_phys_wc_add()) is to change the default ioremap behaviour on x86 to use
strong UC for PAT enabled systems for *both* ioremap() and ioremap_nocache().

This was aleady done once but reverted later due to the regression issues on
video drivers not haveing the right ioremap_wc() calls. I'm finishing this
effort and am about a few patches away...

Once done and once things cool down we should go back and may consider flipping
the switch again to make strong UC default. For details refer to commit
de33c442ed2a465 ("x86 PAT: fix performance drop for glx, use UC minus
for ioremap(), ioremap_nocache() and pci_mmap_page_range()").

All this is fine in theory -- but Benjamin Herrenschmidt recently also
noted that on powerpc the write-combining may end up requiring each
register read/write with its own specific API. That is, we'd lose the
magic of having things being done behind the scenes, and that would
also mean tons of reads/writes may need to be converted over to be
explicit about write-combining preferences...

I will note that upon discussions it seems that the above requirement
may have been a slight mishap on not being explicit about our semantics
and requirements on ioremap() variants, technically it may be possible
that effectively PowerPC may not get any write-combining effects on
infiniband / networking / anything not doing write-combining on
userspace such as framebuffer... from what I gather that needs to
be fixed. Because of these grammatical issues and the issues with
unaligned access with ARM I think its important we put some effort
to care a bit more about defining clear semantics through grammar
for new APIs or as we rewrite APIs. We have tools to do this these
days, best make use of them.

While we're at it and reconsidering all this, a few items I wish for
us to address as well then, most of them related to grammar, some
procedural clarification:

  * Document it as not supported to have overlapping ioremap() calls.
    No one seems to have a clue if this should work, but clearly this
    is just a bad idea. I don't see why we should support the complexity
    of having this. It seems we can write grammar rules to prevent this.

  * We seem to care about device drivers / kernel code doing unaligned
    accesses with certain ioremap() variants. At least for ARM you should
    not do unaligned accesses on ioremap_nocache() areas. I am not sure
    if we can come up with grammar to vet for / warn for unaligned access
    type of code in driver code on some memory area when some ioremap()
    variant is used, but this could be looked into. I believe we may
    want rules for unaligned access maybe in general, and not attached
    to certain calls due to performance considerations, so this work
    may be welcomed regardless (refer to
    Documentation/unaligned-memory-access.txt)
    
  * We seem to want to be pedantic about adding new ioremap() variants, the
    unaligned issue on ARM is one reason, do we ideally then want *all*
    architecture maintainers to provide an Acked-by for any new ioremap
    variants ? Are we going to have to sit and wait for a kumbaya every time
    a helper comes along to see how it all fits well for all architectures?
    The asm-generic io.h seemed to have set in place the ability to let
    architectures define things *when* they get to it, that seems like a much
    more fair approach *if* and *when possible*.  Can we not have and define
    a *safe* ioremap() call to fall under ?  The unaligned access concerns seem
    fair but.. again it seems we generally care about unaligned access anyway,
    so the concern really should be to fix all driver code to not do unaligned
    access, if possible no?

  * There are helpers such as set_memory_wc() which should not be used
    on IO memory, we should define grammar rules for these.

  * There are ioremap() variants which may require helpers for architectures.
    The only example I am aware of is ioremap_wc() requires arch_phys_wc_add()
    so that on x86 PAT enabled systems this does nothing, but on x86 non-PAT
    systems this will use MTRRs. The arch_phys_wc_add() API can be re-purposed
    for other architectures if needed, maybe benh can look at this for powerpc?
    But it seems those helpers were added mostly with a bias towards x86
    requirements, do we again expect all architecture maintainers to provide
    an Acked-by for ioremap() variants helpers ?

  Luis

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org.  For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>

^ permalink raw reply	[flat|nested] 85+ messages in thread

* Re: [PATCH v5 2/6] arch: unify ioremap prototypes and macro aliases
@ 2015-07-07  9:50                   ` Luis R. Rodriguez
  0 siblings, 0 replies; 85+ messages in thread
From: Luis R. Rodriguez @ 2015-07-07  9:50 UTC (permalink / raw)
  To: Christoph Hellwig, Andy Lutomirski, Benjamin Herrenschmidt
  Cc: Geert Uytterhoeven, Julia Lawall, Dan Williams, Arnd Bergmann,
	Ingo Molnar, Borislav Petkov, H. Peter Anvin, Thomas Gleixner,
	Ross Zwisler, Andrew Morton, Juergen Gross, X86 ML, Kani,
	Toshimitsu, linux-nvdimm@lists.01.org, Konrad Rzeszutek Wilk,
	linux-kernel, Stefan Bader, Linux MM, Ralf Baechle,
	Henrique de Moraes Holschuh, Michael Ellerman, Tejun Heo,
	Paul Mackerras, Russell King - ARM Linux, mcgrof,
	linux-arm-kernel

On Wed, Jul 01, 2015 at 09:28:28AM +0200, Christoph Hellwig wrote:
> On Wed, Jul 01, 2015 at 09:19:29AM +0200, Geert Uytterhoeven wrote:
> > >> So it would be the responsibility of the caller to fall back from
> > >> ioremap(..., CACHED) to ioremap(..., UNCACHED)?
> > >> I.e. all drivers using it should be changed...
> > >
> > > All of the zero users we currently have will need to be changed, yes.
> > 
> > Good. Less work to convert all of these ;-)
> 
> And I didn't have enough coffee yet.  We of course have a few users of
> ioremap_cache(), and two implememantions but no users of ioremap_cached().
> Looks like the implementations can't even agree on the name.

Yies, that naming is icky... we also have quite a bit of ioremap_nocache() users:

mcgrof@ergon ~/linux-next (git::kill-mtrr)$ git grep ioremap_nocache drivers/| wc -l
359

On x86 the default ioremap() happens to map to ioremap_nocache() anyway as well.

This is on purpose, there is an ongoing effort to streamline ioremap_nocache()
for registers on the x86 front with the long term goal then of making PAT
strong UC the default preference for both ioremap() and ioremap_nocache() for
PAT enabled systems. This would prevent things like write-combining modifiers
from having any effect on the area. This comes with a small architectural
driver cost, it means all write-combining desired areas must be split out in
drivers properly.  This is part of the work I've been doing lately. The
eventual goal once we have the write-combing areas properly split with
ioremap_wc() and using the new proper preferred architecture agnostic modifier
(arch_phys_wc_add()) is to change the default ioremap behaviour on x86 to use
strong UC for PAT enabled systems for *both* ioremap() and ioremap_nocache().

This was aleady done once but reverted later due to the regression issues on
video drivers not haveing the right ioremap_wc() calls. I'm finishing this
effort and am about a few patches away...

Once done and once things cool down we should go back and may consider flipping
the switch again to make strong UC default. For details refer to commit
de33c442ed2a465 ("x86 PAT: fix performance drop for glx, use UC minus
for ioremap(), ioremap_nocache() and pci_mmap_page_range()").

All this is fine in theory -- but Benjamin Herrenschmidt recently also
noted that on powerpc the write-combining may end up requiring each
register read/write with its own specific API. That is, we'd lose the
magic of having things being done behind the scenes, and that would
also mean tons of reads/writes may need to be converted over to be
explicit about write-combining preferences...

I will note that upon discussions it seems that the above requirement
may have been a slight mishap on not being explicit about our semantics
and requirements on ioremap() variants, technically it may be possible
that effectively PowerPC may not get any write-combining effects on
infiniband / networking / anything not doing write-combining on
userspace such as framebuffer... from what I gather that needs to
be fixed. Because of these grammatical issues and the issues with
unaligned access with ARM I think its important we put some effort
to care a bit more about defining clear semantics through grammar
for new APIs or as we rewrite APIs. We have tools to do this these
days, best make use of them.

While we're at it and reconsidering all this, a few items I wish for
us to address as well then, most of them related to grammar, some
procedural clarification:

  * Document it as not supported to have overlapping ioremap() calls.
    No one seems to have a clue if this should work, but clearly this
    is just a bad idea. I don't see why we should support the complexity
    of having this. It seems we can write grammar rules to prevent this.

  * We seem to care about device drivers / kernel code doing unaligned
    accesses with certain ioremap() variants. At least for ARM you should
    not do unaligned accesses on ioremap_nocache() areas. I am not sure
    if we can come up with grammar to vet for / warn for unaligned access
    type of code in driver code on some memory area when some ioremap()
    variant is used, but this could be looked into. I believe we may
    want rules for unaligned access maybe in general, and not attached
    to certain calls due to performance considerations, so this work
    may be welcomed regardless (refer to
    Documentation/unaligned-memory-access.txt)
    
  * We seem to want to be pedantic about adding new ioremap() variants, the
    unaligned issue on ARM is one reason, do we ideally then want *all*
    architecture maintainers to provide an Acked-by for any new ioremap
    variants ? Are we going to have to sit and wait for a kumbaya every time
    a helper comes along to see how it all fits well for all architectures?
    The asm-generic io.h seemed to have set in place the ability to let
    architectures define things *when* they get to it, that seems like a much
    more fair approach *if* and *when possible*.  Can we not have and define
    a *safe* ioremap() call to fall under ?  The unaligned access concerns seem
    fair but.. again it seems we generally care about unaligned access anyway,
    so the concern really should be to fix all driver code to not do unaligned
    access, if possible no?

  * There are helpers such as set_memory_wc() which should not be used
    on IO memory, we should define grammar rules for these.

  * There are ioremap() variants which may require helpers for architectures.
    The only example I am aware of is ioremap_wc() requires arch_phys_wc_add()
    so that on x86 PAT enabled systems this does nothing, but on x86 non-PAT
    systems this will use MTRRs. The arch_phys_wc_add() API can be re-purposed
    for other architectures if needed, maybe benh can look at this for powerpc?
    But it seems those helpers were added mostly with a bias towards x86
    requirements, do we again expect all architecture maintainers to provide
    an Acked-by for ioremap() variants helpers ?

  Luis

^ permalink raw reply	[flat|nested] 85+ messages in thread

* [PATCH v5 2/6] arch: unify ioremap prototypes and macro aliases
@ 2015-07-07  9:50                   ` Luis R. Rodriguez
  0 siblings, 0 replies; 85+ messages in thread
From: Luis R. Rodriguez @ 2015-07-07  9:50 UTC (permalink / raw)
  To: linux-arm-kernel

On Wed, Jul 01, 2015 at 09:28:28AM +0200, Christoph Hellwig wrote:
> On Wed, Jul 01, 2015 at 09:19:29AM +0200, Geert Uytterhoeven wrote:
> > >> So it would be the responsibility of the caller to fall back from
> > >> ioremap(..., CACHED) to ioremap(..., UNCACHED)?
> > >> I.e. all drivers using it should be changed...
> > >
> > > All of the zero users we currently have will need to be changed, yes.
> > 
> > Good. Less work to convert all of these ;-)
> 
> And I didn't have enough coffee yet.  We of course have a few users of
> ioremap_cache(), and two implememantions but no users of ioremap_cached().
> Looks like the implementations can't even agree on the name.

Yies, that naming is icky... we also have quite a bit of ioremap_nocache() users:

mcgrof at ergon ~/linux-next (git::kill-mtrr)$ git grep ioremap_nocache drivers/| wc -l
359

On x86 the default ioremap() happens to map to ioremap_nocache() anyway as well.

This is on purpose, there is an ongoing effort to streamline ioremap_nocache()
for registers on the x86 front with the long term goal then of making PAT
strong UC the default preference for both ioremap() and ioremap_nocache() for
PAT enabled systems. This would prevent things like write-combining modifiers
from having any effect on the area. This comes with a small architectural
driver cost, it means all write-combining desired areas must be split out in
drivers properly.  This is part of the work I've been doing lately. The
eventual goal once we have the write-combing areas properly split with
ioremap_wc() and using the new proper preferred architecture agnostic modifier
(arch_phys_wc_add()) is to change the default ioremap behaviour on x86 to use
strong UC for PAT enabled systems for *both* ioremap() and ioremap_nocache().

This was aleady done once but reverted later due to the regression issues on
video drivers not haveing the right ioremap_wc() calls. I'm finishing this
effort and am about a few patches away...

Once done and once things cool down we should go back and may consider flipping
the switch again to make strong UC default. For details refer to commit
de33c442ed2a465 ("x86 PAT: fix performance drop for glx, use UC minus
for ioremap(), ioremap_nocache() and pci_mmap_page_range()").

All this is fine in theory -- but Benjamin Herrenschmidt recently also
noted that on powerpc the write-combining may end up requiring each
register read/write with its own specific API. That is, we'd lose the
magic of having things being done behind the scenes, and that would
also mean tons of reads/writes may need to be converted over to be
explicit about write-combining preferences...

I will note that upon discussions it seems that the above requirement
may have been a slight mishap on not being explicit about our semantics
and requirements on ioremap() variants, technically it may be possible
that effectively PowerPC may not get any write-combining effects on
infiniband / networking / anything not doing write-combining on
userspace such as framebuffer... from what I gather that needs to
be fixed. Because of these grammatical issues and the issues with
unaligned access with ARM I think its important we put some effort
to care a bit more about defining clear semantics through grammar
for new APIs or as we rewrite APIs. We have tools to do this these
days, best make use of them.

While we're at it and reconsidering all this, a few items I wish for
us to address as well then, most of them related to grammar, some
procedural clarification:

  * Document it as not supported to have overlapping ioremap() calls.
    No one seems to have a clue if this should work, but clearly this
    is just a bad idea. I don't see why we should support the complexity
    of having this. It seems we can write grammar rules to prevent this.

  * We seem to care about device drivers / kernel code doing unaligned
    accesses with certain ioremap() variants. At least for ARM you should
    not do unaligned accesses on ioremap_nocache() areas. I am not sure
    if we can come up with grammar to vet for / warn for unaligned access
    type of code in driver code on some memory area when some ioremap()
    variant is used, but this could be looked into. I believe we may
    want rules for unaligned access maybe in general, and not attached
    to certain calls due to performance considerations, so this work
    may be welcomed regardless (refer to
    Documentation/unaligned-memory-access.txt)
    
  * We seem to want to be pedantic about adding new ioremap() variants, the
    unaligned issue on ARM is one reason, do we ideally then want *all*
    architecture maintainers to provide an Acked-by for any new ioremap
    variants ? Are we going to have to sit and wait for a kumbaya every time
    a helper comes along to see how it all fits well for all architectures?
    The asm-generic io.h seemed to have set in place the ability to let
    architectures define things *when* they get to it, that seems like a much
    more fair approach *if* and *when possible*.  Can we not have and define
    a *safe* ioremap() call to fall under ?  The unaligned access concerns seem
    fair but.. again it seems we generally care about unaligned access anyway,
    so the concern really should be to fix all driver code to not do unaligned
    access, if possible no?

  * There are helpers such as set_memory_wc() which should not be used
    on IO memory, we should define grammar rules for these.

  * There are ioremap() variants which may require helpers for architectures.
    The only example I am aware of is ioremap_wc() requires arch_phys_wc_add()
    so that on x86 PAT enabled systems this does nothing, but on x86 non-PAT
    systems this will use MTRRs. The arch_phys_wc_add() API can be re-purposed
    for other architectures if needed, maybe benh can look at this for powerpc?
    But it seems those helpers were added mostly with a bias towards x86
    requirements, do we again expect all architecture maintainers to provide
    an Acked-by for ioremap() variants helpers ?

  Luis

^ permalink raw reply	[flat|nested] 85+ messages in thread

* Re: [PATCH v5 2/6] arch: unify ioremap prototypes and macro aliases
  2015-07-07  9:50                   ` Luis R. Rodriguez
  (?)
@ 2015-07-07 10:13                     ` Russell King - ARM Linux
  -1 siblings, 0 replies; 85+ messages in thread
From: Russell King - ARM Linux @ 2015-07-07 10:13 UTC (permalink / raw)
  To: Luis R. Rodriguez
  Cc: Christoph Hellwig, Andy Lutomirski, Benjamin Herrenschmidt,
	Geert Uytterhoeven, Julia Lawall, Dan Williams, Arnd Bergmann,
	Ingo Molnar, Borislav Petkov, H. Peter Anvin, Thomas Gleixner,
	Ross Zwisler, Andrew Morton, Juergen Gross, X86 ML, Kani,
	Toshimitsu, linux-nvdimm@lists.01.org, Konrad Rzeszutek Wilk,
	linux-kernel, Stefan Bader, Linux MM, Ralf Baechle,
	Henrique de Moraes Holschuh, Michael Ellerman, Tejun Heo,
	Paul Mackerras, mcgrof, linux-arm-kernel

On Tue, Jul 07, 2015 at 11:50:12AM +0200, Luis R. Rodriguez wrote:
> mcgrof@ergon ~/linux-next (git::kill-mtrr)$ git grep ioremap_nocache drivers/| wc -l
> 359

Yes, it's because we have:
(a) LDD telling people they should be using ioremap_nocache() for mapping
    devices.
(b) We have documentation in the Documentation/ subdirectory telling people
    to use ioremap_nocache() for the same.

> This is part of the work I've been doing lately. The
> eventual goal once we have the write-combing areas properly split with
> ioremap_wc() and using the new proper preferred architecture agnostic modifier
> (arch_phys_wc_add()) is to change the default ioremap behaviour on x86 to use
> strong UC for PAT enabled systems for *both* ioremap() and ioremap_nocache().

Please note that on ARM, ioremap_wc() gives what's termed in ARM ARM
speak "normal memory, non-cacheable" - which can be subject to speculation,
write combining, multiple accesses, etc.  The important point is that
such mapping is not suitable for device registers, but is suitable for
device regions that have "memory like" properties (iow, a chunk of RAM,
like video drivers.)  It does support unaligned accesses.

> Because of these grammatical issues and the issues with
> unaligned access with ARM I think its important we put some effort
> to care a bit more about defining clear semantics through grammar
> for new APIs or as we rewrite APIs. We have tools to do this these
> days, best make use of them.

I'm in support of anything which more clearly specifies the requirements
for these APIs.

> While we're at it and reconsidering all this, a few items I wish for
> us to address as well then, most of them related to grammar, some
> procedural clarification:
> 
>   * Document it as not supported to have overlapping ioremap() calls.
>     No one seems to have a clue if this should work, but clearly this
>     is just a bad idea. I don't see why we should support the complexity
>     of having this. It seems we can write grammar rules to prevent this.

On ARM, we (probably) have a lot of cases where ioremap() is used multiple
times for the same physical address space, so we shouldn't rule out having
multiple mappings of the same type.  However, differing types would be a
problem on ARM.

>   * We seem to care about device drivers / kernel code doing unaligned
>     accesses with certain ioremap() variants. At least for ARM you should
>     not do unaligned accesses on ioremap_nocache() areas.

... and ioremap() areas.

If we can stop the "abuse" of ioremap_nocache() to map device registers,
then we could potentially switch ioremap_nocache() to be a normal-memory
like mapping, which would allow it to support unaligned accesses.

>     I am not sure
>     if we can come up with grammar to vet for / warn for unaligned access
>     type of code in driver code on some memory area when some ioremap()
>     variant is used, but this could be looked into. I believe we may
>     want rules for unaligned access maybe in general, and not attached
>     to certain calls due to performance considerations, so this work
>     may be welcomed regardless (refer to
>     Documentation/unaligned-memory-access.txt)
>     
>   * We seem to want to be pedantic about adding new ioremap() variants, the
>     unaligned issue on ARM is one reason, do we ideally then want *all*
>     architecture maintainers to provide an Acked-by for any new ioremap
>     variants ?

/If/ we get the current mess sorted out so that we have a safe fallback,
and we have understanding of the different architecture variants (iow,
documented what the safe fallback is) I don't see any reason why we'd
need acks from arch maintainers.  Unfortunately, we're not in that
situation today, because of the poorly documented mess that ioremap*()
currently is (and yes, I'm partly to blame for that too by not documenting
ARMs behaviour here.)

I have some patches (prepared last week, I was going to push them out
towards the end of the merge window) which address that, but unfortunately
the ARM autobuilders have been giving a number of seemingly random boot
failures, and I'm not yet sure what's going on... so I'm holding that
back until stuff has settled down.

Another issue is... the use of memcpy()/memset() directly on memory
returned from ioremap*().  The pmem driver does this.  This fails sparse
checks.  However, years ago, x86 invented the memcpy_fromio()/memcpy_toio()
memset_io() functions, which took a __iomem pointer (which /presumably/
means they're supposed to operate on the memory associated with an
ioremap'd region.)

Should these functions always be used for mappings via ioremap*(), and
the standard memcpy()/memset() be avoided?  To me, that sounds like a
very good thing, because that gives us more control over the
implementation of the functions used to access ioremap'd regions,
and the arch can decide to prevent GCC inlining its own memset() or
memcpy() code if desired.

Note that on x86, these three functions are merely wrappers around
standard memcpy()/memset(), so there should be no reason why pmem.c
couldn't be updated to use these accessors instead.

-- 
FTTC broadband for 0.8mile line: currently at 10.5Mbps down 400kbps up
according to speedtest.net.

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org.  For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>

^ permalink raw reply	[flat|nested] 85+ messages in thread

* Re: [PATCH v5 2/6] arch: unify ioremap prototypes and macro aliases
@ 2015-07-07 10:13                     ` Russell King - ARM Linux
  0 siblings, 0 replies; 85+ messages in thread
From: Russell King - ARM Linux @ 2015-07-07 10:13 UTC (permalink / raw)
  To: Luis R. Rodriguez
  Cc: Christoph Hellwig, Andy Lutomirski, Benjamin Herrenschmidt,
	Geert Uytterhoeven, Julia Lawall, Dan Williams, Arnd Bergmann,
	Ingo Molnar, Borislav Petkov, H. Peter Anvin, Thomas Gleixner,
	Ross Zwisler, Andrew Morton, Juergen Gross, X86 ML, Kani,
	Toshimitsu, linux-nvdimm@lists.01.org, Konrad Rzeszutek Wilk,
	linux-kernel, Stefan Bader, Linux MM, Ralf Baechle,
	Henrique de Moraes Holschuh, Michael Ellerman, Tejun Heo,
	Paul Mackerras, mcgrof, linux-arm-kernel

On Tue, Jul 07, 2015 at 11:50:12AM +0200, Luis R. Rodriguez wrote:
> mcgrof@ergon ~/linux-next (git::kill-mtrr)$ git grep ioremap_nocache drivers/| wc -l
> 359

Yes, it's because we have:
(a) LDD telling people they should be using ioremap_nocache() for mapping
    devices.
(b) We have documentation in the Documentation/ subdirectory telling people
    to use ioremap_nocache() for the same.

> This is part of the work I've been doing lately. The
> eventual goal once we have the write-combing areas properly split with
> ioremap_wc() and using the new proper preferred architecture agnostic modifier
> (arch_phys_wc_add()) is to change the default ioremap behaviour on x86 to use
> strong UC for PAT enabled systems for *both* ioremap() and ioremap_nocache().

Please note that on ARM, ioremap_wc() gives what's termed in ARM ARM
speak "normal memory, non-cacheable" - which can be subject to speculation,
write combining, multiple accesses, etc.  The important point is that
such mapping is not suitable for device registers, but is suitable for
device regions that have "memory like" properties (iow, a chunk of RAM,
like video drivers.)  It does support unaligned accesses.

> Because of these grammatical issues and the issues with
> unaligned access with ARM I think its important we put some effort
> to care a bit more about defining clear semantics through grammar
> for new APIs or as we rewrite APIs. We have tools to do this these
> days, best make use of them.

I'm in support of anything which more clearly specifies the requirements
for these APIs.

> While we're at it and reconsidering all this, a few items I wish for
> us to address as well then, most of them related to grammar, some
> procedural clarification:
> 
>   * Document it as not supported to have overlapping ioremap() calls.
>     No one seems to have a clue if this should work, but clearly this
>     is just a bad idea. I don't see why we should support the complexity
>     of having this. It seems we can write grammar rules to prevent this.

On ARM, we (probably) have a lot of cases where ioremap() is used multiple
times for the same physical address space, so we shouldn't rule out having
multiple mappings of the same type.  However, differing types would be a
problem on ARM.

>   * We seem to care about device drivers / kernel code doing unaligned
>     accesses with certain ioremap() variants. At least for ARM you should
>     not do unaligned accesses on ioremap_nocache() areas.

... and ioremap() areas.

If we can stop the "abuse" of ioremap_nocache() to map device registers,
then we could potentially switch ioremap_nocache() to be a normal-memory
like mapping, which would allow it to support unaligned accesses.

>     I am not sure
>     if we can come up with grammar to vet for / warn for unaligned access
>     type of code in driver code on some memory area when some ioremap()
>     variant is used, but this could be looked into. I believe we may
>     want rules for unaligned access maybe in general, and not attached
>     to certain calls due to performance considerations, so this work
>     may be welcomed regardless (refer to
>     Documentation/unaligned-memory-access.txt)
>     
>   * We seem to want to be pedantic about adding new ioremap() variants, the
>     unaligned issue on ARM is one reason, do we ideally then want *all*
>     architecture maintainers to provide an Acked-by for any new ioremap
>     variants ?

/If/ we get the current mess sorted out so that we have a safe fallback,
and we have understanding of the different architecture variants (iow,
documented what the safe fallback is) I don't see any reason why we'd
need acks from arch maintainers.  Unfortunately, we're not in that
situation today, because of the poorly documented mess that ioremap*()
currently is (and yes, I'm partly to blame for that too by not documenting
ARMs behaviour here.)

I have some patches (prepared last week, I was going to push them out
towards the end of the merge window) which address that, but unfortunately
the ARM autobuilders have been giving a number of seemingly random boot
failures, and I'm not yet sure what's going on... so I'm holding that
back until stuff has settled down.

Another issue is... the use of memcpy()/memset() directly on memory
returned from ioremap*().  The pmem driver does this.  This fails sparse
checks.  However, years ago, x86 invented the memcpy_fromio()/memcpy_toio()
memset_io() functions, which took a __iomem pointer (which /presumably/
means they're supposed to operate on the memory associated with an
ioremap'd region.)

Should these functions always be used for mappings via ioremap*(), and
the standard memcpy()/memset() be avoided?  To me, that sounds like a
very good thing, because that gives us more control over the
implementation of the functions used to access ioremap'd regions,
and the arch can decide to prevent GCC inlining its own memset() or
memcpy() code if desired.

Note that on x86, these three functions are merely wrappers around
standard memcpy()/memset(), so there should be no reason why pmem.c
couldn't be updated to use these accessors instead.

-- 
FTTC broadband for 0.8mile line: currently at 10.5Mbps down 400kbps up
according to speedtest.net.

^ permalink raw reply	[flat|nested] 85+ messages in thread

* [PATCH v5 2/6] arch: unify ioremap prototypes and macro aliases
@ 2015-07-07 10:13                     ` Russell King - ARM Linux
  0 siblings, 0 replies; 85+ messages in thread
From: Russell King - ARM Linux @ 2015-07-07 10:13 UTC (permalink / raw)
  To: linux-arm-kernel

On Tue, Jul 07, 2015 at 11:50:12AM +0200, Luis R. Rodriguez wrote:
> mcgrof at ergon ~/linux-next (git::kill-mtrr)$ git grep ioremap_nocache drivers/| wc -l
> 359

Yes, it's because we have:
(a) LDD telling people they should be using ioremap_nocache() for mapping
    devices.
(b) We have documentation in the Documentation/ subdirectory telling people
    to use ioremap_nocache() for the same.

> This is part of the work I've been doing lately. The
> eventual goal once we have the write-combing areas properly split with
> ioremap_wc() and using the new proper preferred architecture agnostic modifier
> (arch_phys_wc_add()) is to change the default ioremap behaviour on x86 to use
> strong UC for PAT enabled systems for *both* ioremap() and ioremap_nocache().

Please note that on ARM, ioremap_wc() gives what's termed in ARM ARM
speak "normal memory, non-cacheable" - which can be subject to speculation,
write combining, multiple accesses, etc.  The important point is that
such mapping is not suitable for device registers, but is suitable for
device regions that have "memory like" properties (iow, a chunk of RAM,
like video drivers.)  It does support unaligned accesses.

> Because of these grammatical issues and the issues with
> unaligned access with ARM I think its important we put some effort
> to care a bit more about defining clear semantics through grammar
> for new APIs or as we rewrite APIs. We have tools to do this these
> days, best make use of them.

I'm in support of anything which more clearly specifies the requirements
for these APIs.

> While we're at it and reconsidering all this, a few items I wish for
> us to address as well then, most of them related to grammar, some
> procedural clarification:
> 
>   * Document it as not supported to have overlapping ioremap() calls.
>     No one seems to have a clue if this should work, but clearly this
>     is just a bad idea. I don't see why we should support the complexity
>     of having this. It seems we can write grammar rules to prevent this.

On ARM, we (probably) have a lot of cases where ioremap() is used multiple
times for the same physical address space, so we shouldn't rule out having
multiple mappings of the same type.  However, differing types would be a
problem on ARM.

>   * We seem to care about device drivers / kernel code doing unaligned
>     accesses with certain ioremap() variants. At least for ARM you should
>     not do unaligned accesses on ioremap_nocache() areas.

... and ioremap() areas.

If we can stop the "abuse" of ioremap_nocache() to map device registers,
then we could potentially switch ioremap_nocache() to be a normal-memory
like mapping, which would allow it to support unaligned accesses.

>     I am not sure
>     if we can come up with grammar to vet for / warn for unaligned access
>     type of code in driver code on some memory area when some ioremap()
>     variant is used, but this could be looked into. I believe we may
>     want rules for unaligned access maybe in general, and not attached
>     to certain calls due to performance considerations, so this work
>     may be welcomed regardless (refer to
>     Documentation/unaligned-memory-access.txt)
>     
>   * We seem to want to be pedantic about adding new ioremap() variants, the
>     unaligned issue on ARM is one reason, do we ideally then want *all*
>     architecture maintainers to provide an Acked-by for any new ioremap
>     variants ?

/If/ we get the current mess sorted out so that we have a safe fallback,
and we have understanding of the different architecture variants (iow,
documented what the safe fallback is) I don't see any reason why we'd
need acks from arch maintainers.  Unfortunately, we're not in that
situation today, because of the poorly documented mess that ioremap*()
currently is (and yes, I'm partly to blame for that too by not documenting
ARMs behaviour here.)

I have some patches (prepared last week, I was going to push them out
towards the end of the merge window) which address that, but unfortunately
the ARM autobuilders have been giving a number of seemingly random boot
failures, and I'm not yet sure what's going on... so I'm holding that
back until stuff has settled down.

Another issue is... the use of memcpy()/memset() directly on memory
returned from ioremap*().  The pmem driver does this.  This fails sparse
checks.  However, years ago, x86 invented the memcpy_fromio()/memcpy_toio()
memset_io() functions, which took a __iomem pointer (which /presumably/
means they're supposed to operate on the memory associated with an
ioremap'd region.)

Should these functions always be used for mappings via ioremap*(), and
the standard memcpy()/memset() be avoided?  To me, that sounds like a
very good thing, because that gives us more control over the
implementation of the functions used to access ioremap'd regions,
and the arch can decide to prevent GCC inlining its own memset() or
memcpy() code if desired.

Note that on x86, these three functions are merely wrappers around
standard memcpy()/memset(), so there should be no reason why pmem.c
couldn't be updated to use these accessors instead.

-- 
FTTC broadband for 0.8mile line: currently at 10.5Mbps down 400kbps up
according to speedtest.net.

^ permalink raw reply	[flat|nested] 85+ messages in thread

* Re: [PATCH v5 2/6] arch: unify ioremap prototypes and macro aliases
  2015-07-07 10:13                     ` Russell King - ARM Linux
  (?)
@ 2015-07-07 10:27                       ` Geert Uytterhoeven
  -1 siblings, 0 replies; 85+ messages in thread
From: Geert Uytterhoeven @ 2015-07-07 10:27 UTC (permalink / raw)
  To: Russell King - ARM Linux
  Cc: Luis R. Rodriguez, Christoph Hellwig, Andy Lutomirski,
	Benjamin Herrenschmidt, Julia Lawall, Dan Williams,
	Arnd Bergmann, Ingo Molnar, Borislav Petkov, H. Peter Anvin,
	Thomas Gleixner, Ross Zwisler, Andrew Morton, Juergen Gross,
	X86 ML, Kani, Toshimitsu, linux-nvdimm@lists.01.org,
	Konrad Rzeszutek Wilk, linux-kernel, Stefan Bader, Linux MM,
	Ralf Baechle, Henrique de Moraes Holschuh, Michael Ellerman,
	Tejun Heo, Paul Mackerras, Luis R. Rodriguez, linux-arm-kernel

On Tue, Jul 7, 2015 at 12:13 PM, Russell King - ARM Linux
<linux@arm.linux.org.uk> wrote:
> Another issue is... the use of memcpy()/memset() directly on memory
> returned from ioremap*().  The pmem driver does this.  This fails sparse
> checks.  However, years ago, x86 invented the memcpy_fromio()/memcpy_toio()
> memset_io() functions, which took a __iomem pointer (which /presumably/
> means they're supposed to operate on the memory associated with an
> ioremap'd region.)
>
> Should these functions always be used for mappings via ioremap*(), and
> the standard memcpy()/memset() be avoided?  To me, that sounds like a
> very good thing, because that gives us more control over the
> implementation of the functions used to access ioremap'd regions,
> and the arch can decide to prevent GCC inlining its own memset() or
> memcpy() code if desired.

Yes they should. Not doing that is a typical portability bug (works on x86,
not everywhere).

Gr{oetje,eeting}s,

                        Geert

--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
                                -- Linus Torvalds

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org.  For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>

^ permalink raw reply	[flat|nested] 85+ messages in thread

* Re: [PATCH v5 2/6] arch: unify ioremap prototypes and macro aliases
@ 2015-07-07 10:27                       ` Geert Uytterhoeven
  0 siblings, 0 replies; 85+ messages in thread
From: Geert Uytterhoeven @ 2015-07-07 10:27 UTC (permalink / raw)
  To: Russell King - ARM Linux
  Cc: Luis R. Rodriguez, Christoph Hellwig, Andy Lutomirski,
	Benjamin Herrenschmidt, Julia Lawall, Dan Williams,
	Arnd Bergmann, Ingo Molnar, Borislav Petkov, H. Peter Anvin,
	Thomas Gleixner, Ross Zwisler, Andrew Morton, Juergen Gross,
	X86 ML, Kani, Toshimitsu, linux-nvdimm@lists.01.org,
	Konrad Rzeszutek Wilk, linux-kernel, Stefan Bader, Linux MM,
	Ralf Baechle, Henrique de Moraes Holschuh, Michael Ellerman,
	Tejun Heo, Paul Mackerras, Luis R. Rodriguez, linux-arm-kernel

On Tue, Jul 7, 2015 at 12:13 PM, Russell King - ARM Linux
<linux@arm.linux.org.uk> wrote:
> Another issue is... the use of memcpy()/memset() directly on memory
> returned from ioremap*().  The pmem driver does this.  This fails sparse
> checks.  However, years ago, x86 invented the memcpy_fromio()/memcpy_toio()
> memset_io() functions, which took a __iomem pointer (which /presumably/
> means they're supposed to operate on the memory associated with an
> ioremap'd region.)
>
> Should these functions always be used for mappings via ioremap*(), and
> the standard memcpy()/memset() be avoided?  To me, that sounds like a
> very good thing, because that gives us more control over the
> implementation of the functions used to access ioremap'd regions,
> and the arch can decide to prevent GCC inlining its own memset() or
> memcpy() code if desired.

Yes they should. Not doing that is a typical portability bug (works on x86,
not everywhere).

Gr{oetje,eeting}s,

                        Geert

--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
                                -- Linus Torvalds

^ permalink raw reply	[flat|nested] 85+ messages in thread

* [PATCH v5 2/6] arch: unify ioremap prototypes and macro aliases
@ 2015-07-07 10:27                       ` Geert Uytterhoeven
  0 siblings, 0 replies; 85+ messages in thread
From: Geert Uytterhoeven @ 2015-07-07 10:27 UTC (permalink / raw)
  To: linux-arm-kernel

On Tue, Jul 7, 2015 at 12:13 PM, Russell King - ARM Linux
<linux@arm.linux.org.uk> wrote:
> Another issue is... the use of memcpy()/memset() directly on memory
> returned from ioremap*().  The pmem driver does this.  This fails sparse
> checks.  However, years ago, x86 invented the memcpy_fromio()/memcpy_toio()
> memset_io() functions, which took a __iomem pointer (which /presumably/
> means they're supposed to operate on the memory associated with an
> ioremap'd region.)
>
> Should these functions always be used for mappings via ioremap*(), and
> the standard memcpy()/memset() be avoided?  To me, that sounds like a
> very good thing, because that gives us more control over the
> implementation of the functions used to access ioremap'd regions,
> and the arch can decide to prevent GCC inlining its own memset() or
> memcpy() code if desired.

Yes they should. Not doing that is a typical portability bug (works on x86,
not everywhere).

Gr{oetje,eeting}s,

                        Geert

--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert at linux-m68k.org

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
                                -- Linus Torvalds

^ permalink raw reply	[flat|nested] 85+ messages in thread

* Re: [PATCH v5 2/6] arch: unify ioremap prototypes and macro aliases
  2015-07-07 10:13                     ` Russell King - ARM Linux
  (?)
@ 2015-07-07 16:07                       ` Luis R. Rodriguez
  -1 siblings, 0 replies; 85+ messages in thread
From: Luis R. Rodriguez @ 2015-07-07 16:07 UTC (permalink / raw)
  To: Russell King - ARM Linux
  Cc: Christoph Hellwig, Andy Lutomirski, Benjamin Herrenschmidt,
	Geert Uytterhoeven, Julia Lawall, Dan Williams, Arnd Bergmann,
	Ingo Molnar, Borislav Petkov, H. Peter Anvin, Thomas Gleixner,
	Ross Zwisler, Andrew Morton, Juergen Gross, X86 ML, Kani,
	Toshimitsu, linux-nvdimm@lists.01.org, Konrad Rzeszutek Wilk,
	linux-kernel, Stefan Bader, Linux MM, Ralf Baechle,
	Henrique de Moraes Holschuh, Michael Ellerman, Tejun Heo,
	Paul Mackerras, mcgrof, linux-arm-kernel

On Tue, Jul 07, 2015 at 11:13:30AM +0100, Russell King - ARM Linux wrote:
> On Tue, Jul 07, 2015 at 11:50:12AM +0200, Luis R. Rodriguez wrote:
> > mcgrof@ergon ~/linux-next (git::kill-mtrr)$ git grep ioremap_nocache drivers/| wc -l
> > 359
> 
> Yes, it's because we have:
> (a) LDD telling people they should be using ioremap_nocache() for mapping
>     devices.

Sounds like LDD could use some love from ARM folks. Not a requirement if we
set out on this semantics / grammar / documentation crusade appropriatley.

> (b) We have documentation in the Documentation/ subdirectory telling people
>     to use ioremap_nocache() for the same.

That obviously needs to be fixed, I take it you're on it.

> > This is part of the work I've been doing lately. The
> > eventual goal once we have the write-combing areas properly split with
> > ioremap_wc() and using the new proper preferred architecture agnostic modifier
> > (arch_phys_wc_add()) is to change the default ioremap behaviour on x86 to use
> > strong UC for PAT enabled systems for *both* ioremap() and ioremap_nocache().
> 
> Please note that on ARM, ioremap_wc() gives what's termed in ARM ARM
> speak "normal memory, non-cacheable" - which can be subject to speculation,
> write combining, multiple accesses, etc.  The important point is that
> such mapping is not suitable for device registers, but is suitable for
> device regions that have "memory like" properties (iow, a chunk of RAM,
> like video drivers.)  It does support unaligned accesses.

Thanks that helps.

> > Because of these grammatical issues and the issues with
> > unaligned access with ARM I think its important we put some effort
> > to care a bit more about defining clear semantics through grammar
> > for new APIs or as we rewrite APIs. We have tools to do this these
> > days, best make use of them.
> 
> I'm in support of anything which more clearly specifies the requirements
> for these APIs.

Great!

> > While we're at it and reconsidering all this, a few items I wish for
> > us to address as well then, most of them related to grammar, some
> > procedural clarification:
> > 
> >   * Document it as not supported to have overlapping ioremap() calls.
> >     No one seems to have a clue if this should work, but clearly this
> >     is just a bad idea. I don't see why we should support the complexity
> >     of having this. It seems we can write grammar rules to prevent this.
> 
> On ARM, we (probably) have a lot of cases where ioremap() is used multiple
> times for the same physical address space, so we shouldn't rule out having
> multiple mappings of the same type.

Why is that done? Don't worry if you are not sure why but only speculate of the
practice's existence (sloppy drivers or lazy driver developers). FWIW for x86
IIRC I ended up concluding that overlapping ioremap() calls with the same type
would work but not if they differ in type.  Although I haven't written a
grammer rule to hunt down overlapping ioremap() I suspected its use was likely
odd and likely should be reconsidered. Would this be true for ARM too ? Or are
you saying this should be a feature ? I don't expect an answer now but I'm
saying we *should* all together decide on this, and if you're inclined to
believe that this should ideally be avoided I'd like to hear that. If you feel
strongly though this should be a feature I would like to know why.

> However, differing types would be a problem on ARM.

Great.

> >   * We seem to care about device drivers / kernel code doing unaligned
> >     accesses with certain ioremap() variants. At least for ARM you should
> >     not do unaligned accesses on ioremap_nocache() areas.
> 
> ... and ioremap() areas.
> 
> If we can stop the "abuse" of ioremap_nocache() to map device registers,

OK when *should* ioremap_nocache() be used then ? That is, we can easily write
a rule to go and switch drivers away from ioremap_nocache() but do we have a
grammatical white-list for when its intended goal was appropriate ?  For x86
the goal is to use it for MMIO registers, keep in mind we'd ideally want an
effective ioremap_uc() on those long term, we just can't go flipping the switch
just yet unless we get all the write-combined areas right first and smake sure
that we split them out. That's the effort I've been working on lately.

> then we could potentially switch ioremap_nocache() to be a normal-memory
> like mapping, which would allow it to support unaligned accesses.

Great. Can you elaborate on why that could happen *iff* the abuse stops ?

> >     I am not sure
> >     if we can come up with grammar to vet for / warn for unaligned access
> >     type of code in driver code on some memory area when some ioremap()
> >     variant is used, but this could be looked into. I believe we may
> >     want rules for unaligned access maybe in general, and not attached
> >     to certain calls due to performance considerations, so this work
> >     may be welcomed regardless (refer to
> >     Documentation/unaligned-memory-access.txt)
> >     
> >   * We seem to want to be pedantic about adding new ioremap() variants, the
> >     unaligned issue on ARM is one reason, do we ideally then want *all*
> >     architecture maintainers to provide an Acked-by for any new ioremap
> >     variants ?
> 
> /If/ we get the current mess sorted out so that we have a safe fallback,
> and we have understanding of the different architecture variants (iow,
> documented what the safe fallback is) I don't see any reason why we'd
> need acks from arch maintainers. 

Great, that's the scalable solution so we should strive for this then as
it seems attainable.

> Unfortunately, we're not in that
> situation today, because of the poorly documented mess that ioremap*()
> currently is (and yes, I'm partly to blame for that too by not documenting
> ARMs behaviour here.)

So you're saying the mess is yours to begin with :) ?

> I have some patches (prepared last week, I was going to push them out
> towards the end of the merge window) which address that, but unfortunately
> the ARM autobuilders have been giving a number of seemingly random boot
> failures, and I'm not yet sure what's going on... so I'm holding that
> back until stuff has settled down.

OK sounds like sorting that out will take some time. What are we to do
in the meantime ? Would a default safe return -EOPNOTSUPP be a good
deafult for variants until we get the semantics all settled out ?

> Another issue is... the use of memcpy()/memset() directly on memory
> returned from ioremap*().  The pmem driver does this.  This fails sparse
> checks.  However, years ago, x86 invented the memcpy_fromio()/memcpy_toio()
> memset_io() functions, which took a __iomem pointer (which /presumably/
> means they're supposed to operate on the memory associated with an
> ioremap'd region.)
> 
> Should these functions always be used for mappings via ioremap*(), and
> the standard memcpy()/memset() be avoided?  To me, that sounds like a
> very good thing, because that gives us more control over the
> implementation of the functions used to access ioremap'd regions,
> and the arch can decide to prevent GCC inlining its own memset() or
> memcpy() code if desired.

I think Ben might like this for PowerPC as well, although the atomic
read / write thing would also require revising. I'm pretty confident
we can use grammar to go and fix these offenders if we deem this as
desirable.

Lastly, a small point I'd like to make is that in my ioremap_wc() crusade to
vet for things I found that the drivers that I had the biggest amount of issue
with were ancient and decrepit, perhaps now staging material drivers. Of 4
drivers that I had issues with two had code commented out (now removed, the
fusion driver), one driver was deprecated and we now reached the decision to
remove it from Linux (outbound via staging for ~2 releases as an accepted
driver removal policy, as Greg clarified) this is the ipath driver, another had
some oddball firmware which didn't even allow to expose the write-combined
address offset and was used for some old DVR setup maybe only some folks in
India are using, and lastly atyfb for which we ended up adding ioremap_uc() for
to help work around some MTRR corner case use cases to match a suitable
replacement with PAT.

This is a long winded way of saying that old crappy drivers had an impact on
setting the pace for sane semantics and collateral evolutions (in the form of
accepted required grammatical changes, to use ioremap_uc() with
arch_phys_wc_add()) to clean things up, and I think that if we want to grow
faster and leaner we must grow with grammar but that also should likely mean
more readily accepting removal of ancient crappy drivers. If folks agree
one way to make this explicit is for example to send to staging drivers
which are enabled for all architectures which do tons of unaligned accesses,
and for staging drivers to be only enabled via Kconfig for architectures
which are known to work.

If we want clear semantics / grammar rules / checks defined for a set of
ioremap() calls and family of calls having a clean slate of drivers should make
defining semantics, grammer rules and enforcing them much easier, just as
then maing collateral evolutions to then go out and fix only a set of drivers.
Moore's law should have implications not only on accepted growth but also
on deprecation, if we haven't been deprecating hardware fast enough and
not giving old drivers major love it should only affect us, specially as
our hardware evolves even faster.

So if we want to be pedantic about semantics / grammar lets flush down the
toilet more drivers and faster and if we're iffy about them we can put them on
the staging corner.

> Note that on x86, these three functions are merely wrappers around
> standard memcpy()/memset(), so there should be no reason why pmem.c
> couldn't be updated to use these accessors instead.

Great.

  Luis

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org.  For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>

^ permalink raw reply	[flat|nested] 85+ messages in thread

* Re: [PATCH v5 2/6] arch: unify ioremap prototypes and macro aliases
@ 2015-07-07 16:07                       ` Luis R. Rodriguez
  0 siblings, 0 replies; 85+ messages in thread
From: Luis R. Rodriguez @ 2015-07-07 16:07 UTC (permalink / raw)
  To: Russell King - ARM Linux
  Cc: Christoph Hellwig, Andy Lutomirski, Benjamin Herrenschmidt,
	Geert Uytterhoeven, Julia Lawall, Dan Williams, Arnd Bergmann,
	Ingo Molnar, Borislav Petkov, H. Peter Anvin, Thomas Gleixner,
	Ross Zwisler, Andrew Morton, Juergen Gross, X86 ML, Kani,
	Toshimitsu, linux-nvdimm@lists.01.org, Konrad Rzeszutek Wilk,
	linux-kernel, Stefan Bader, Linux MM, Ralf Baechle,
	Henrique de Moraes Holschuh, Michael Ellerman, Tejun Heo,
	Paul Mackerras, mcgrof, linux-arm-kernel

On Tue, Jul 07, 2015 at 11:13:30AM +0100, Russell King - ARM Linux wrote:
> On Tue, Jul 07, 2015 at 11:50:12AM +0200, Luis R. Rodriguez wrote:
> > mcgrof@ergon ~/linux-next (git::kill-mtrr)$ git grep ioremap_nocache drivers/| wc -l
> > 359
> 
> Yes, it's because we have:
> (a) LDD telling people they should be using ioremap_nocache() for mapping
>     devices.

Sounds like LDD could use some love from ARM folks. Not a requirement if we
set out on this semantics / grammar / documentation crusade appropriatley.

> (b) We have documentation in the Documentation/ subdirectory telling people
>     to use ioremap_nocache() for the same.

That obviously needs to be fixed, I take it you're on it.

> > This is part of the work I've been doing lately. The
> > eventual goal once we have the write-combing areas properly split with
> > ioremap_wc() and using the new proper preferred architecture agnostic modifier
> > (arch_phys_wc_add()) is to change the default ioremap behaviour on x86 to use
> > strong UC for PAT enabled systems for *both* ioremap() and ioremap_nocache().
> 
> Please note that on ARM, ioremap_wc() gives what's termed in ARM ARM
> speak "normal memory, non-cacheable" - which can be subject to speculation,
> write combining, multiple accesses, etc.  The important point is that
> such mapping is not suitable for device registers, but is suitable for
> device regions that have "memory like" properties (iow, a chunk of RAM,
> like video drivers.)  It does support unaligned accesses.

Thanks that helps.

> > Because of these grammatical issues and the issues with
> > unaligned access with ARM I think its important we put some effort
> > to care a bit more about defining clear semantics through grammar
> > for new APIs or as we rewrite APIs. We have tools to do this these
> > days, best make use of them.
> 
> I'm in support of anything which more clearly specifies the requirements
> for these APIs.

Great!

> > While we're at it and reconsidering all this, a few items I wish for
> > us to address as well then, most of them related to grammar, some
> > procedural clarification:
> > 
> >   * Document it as not supported to have overlapping ioremap() calls.
> >     No one seems to have a clue if this should work, but clearly this
> >     is just a bad idea. I don't see why we should support the complexity
> >     of having this. It seems we can write grammar rules to prevent this.
> 
> On ARM, we (probably) have a lot of cases where ioremap() is used multiple
> times for the same physical address space, so we shouldn't rule out having
> multiple mappings of the same type.

Why is that done? Don't worry if you are not sure why but only speculate of the
practice's existence (sloppy drivers or lazy driver developers). FWIW for x86
IIRC I ended up concluding that overlapping ioremap() calls with the same type
would work but not if they differ in type.  Although I haven't written a
grammer rule to hunt down overlapping ioremap() I suspected its use was likely
odd and likely should be reconsidered. Would this be true for ARM too ? Or are
you saying this should be a feature ? I don't expect an answer now but I'm
saying we *should* all together decide on this, and if you're inclined to
believe that this should ideally be avoided I'd like to hear that. If you feel
strongly though this should be a feature I would like to know why.

> However, differing types would be a problem on ARM.

Great.

> >   * We seem to care about device drivers / kernel code doing unaligned
> >     accesses with certain ioremap() variants. At least for ARM you should
> >     not do unaligned accesses on ioremap_nocache() areas.
> 
> ... and ioremap() areas.
> 
> If we can stop the "abuse" of ioremap_nocache() to map device registers,

OK when *should* ioremap_nocache() be used then ? That is, we can easily write
a rule to go and switch drivers away from ioremap_nocache() but do we have a
grammatical white-list for when its intended goal was appropriate ?  For x86
the goal is to use it for MMIO registers, keep in mind we'd ideally want an
effective ioremap_uc() on those long term, we just can't go flipping the switch
just yet unless we get all the write-combined areas right first and smake sure
that we split them out. That's the effort I've been working on lately.

> then we could potentially switch ioremap_nocache() to be a normal-memory
> like mapping, which would allow it to support unaligned accesses.

Great. Can you elaborate on why that could happen *iff* the abuse stops ?

> >     I am not sure
> >     if we can come up with grammar to vet for / warn for unaligned access
> >     type of code in driver code on some memory area when some ioremap()
> >     variant is used, but this could be looked into. I believe we may
> >     want rules for unaligned access maybe in general, and not attached
> >     to certain calls due to performance considerations, so this work
> >     may be welcomed regardless (refer to
> >     Documentation/unaligned-memory-access.txt)
> >     
> >   * We seem to want to be pedantic about adding new ioremap() variants, the
> >     unaligned issue on ARM is one reason, do we ideally then want *all*
> >     architecture maintainers to provide an Acked-by for any new ioremap
> >     variants ?
> 
> /If/ we get the current mess sorted out so that we have a safe fallback,
> and we have understanding of the different architecture variants (iow,
> documented what the safe fallback is) I don't see any reason why we'd
> need acks from arch maintainers. 

Great, that's the scalable solution so we should strive for this then as
it seems attainable.

> Unfortunately, we're not in that
> situation today, because of the poorly documented mess that ioremap*()
> currently is (and yes, I'm partly to blame for that too by not documenting
> ARMs behaviour here.)

So you're saying the mess is yours to begin with :) ?

> I have some patches (prepared last week, I was going to push them out
> towards the end of the merge window) which address that, but unfortunately
> the ARM autobuilders have been giving a number of seemingly random boot
> failures, and I'm not yet sure what's going on... so I'm holding that
> back until stuff has settled down.

OK sounds like sorting that out will take some time. What are we to do
in the meantime ? Would a default safe return -EOPNOTSUPP be a good
deafult for variants until we get the semantics all settled out ?

> Another issue is... the use of memcpy()/memset() directly on memory
> returned from ioremap*().  The pmem driver does this.  This fails sparse
> checks.  However, years ago, x86 invented the memcpy_fromio()/memcpy_toio()
> memset_io() functions, which took a __iomem pointer (which /presumably/
> means they're supposed to operate on the memory associated with an
> ioremap'd region.)
> 
> Should these functions always be used for mappings via ioremap*(), and
> the standard memcpy()/memset() be avoided?  To me, that sounds like a
> very good thing, because that gives us more control over the
> implementation of the functions used to access ioremap'd regions,
> and the arch can decide to prevent GCC inlining its own memset() or
> memcpy() code if desired.

I think Ben might like this for PowerPC as well, although the atomic
read / write thing would also require revising. I'm pretty confident
we can use grammar to go and fix these offenders if we deem this as
desirable.

Lastly, a small point I'd like to make is that in my ioremap_wc() crusade to
vet for things I found that the drivers that I had the biggest amount of issue
with were ancient and decrepit, perhaps now staging material drivers. Of 4
drivers that I had issues with two had code commented out (now removed, the
fusion driver), one driver was deprecated and we now reached the decision to
remove it from Linux (outbound via staging for ~2 releases as an accepted
driver removal policy, as Greg clarified) this is the ipath driver, another had
some oddball firmware which didn't even allow to expose the write-combined
address offset and was used for some old DVR setup maybe only some folks in
India are using, and lastly atyfb for which we ended up adding ioremap_uc() for
to help work around some MTRR corner case use cases to match a suitable
replacement with PAT.

This is a long winded way of saying that old crappy drivers had an impact on
setting the pace for sane semantics and collateral evolutions (in the form of
accepted required grammatical changes, to use ioremap_uc() with
arch_phys_wc_add()) to clean things up, and I think that if we want to grow
faster and leaner we must grow with grammar but that also should likely mean
more readily accepting removal of ancient crappy drivers. If folks agree
one way to make this explicit is for example to send to staging drivers
which are enabled for all architectures which do tons of unaligned accesses,
and for staging drivers to be only enabled via Kconfig for architectures
which are known to work.

If we want clear semantics / grammar rules / checks defined for a set of
ioremap() calls and family of calls having a clean slate of drivers should make
defining semantics, grammer rules and enforcing them much easier, just as
then maing collateral evolutions to then go out and fix only a set of drivers.
Moore's law should have implications not only on accepted growth but also
on deprecation, if we haven't been deprecating hardware fast enough and
not giving old drivers major love it should only affect us, specially as
our hardware evolves even faster.

So if we want to be pedantic about semantics / grammar lets flush down the
toilet more drivers and faster and if we're iffy about them we can put them on
the staging corner.

> Note that on x86, these three functions are merely wrappers around
> standard memcpy()/memset(), so there should be no reason why pmem.c
> couldn't be updated to use these accessors instead.

Great.

  Luis

^ permalink raw reply	[flat|nested] 85+ messages in thread

* [PATCH v5 2/6] arch: unify ioremap prototypes and macro aliases
@ 2015-07-07 16:07                       ` Luis R. Rodriguez
  0 siblings, 0 replies; 85+ messages in thread
From: Luis R. Rodriguez @ 2015-07-07 16:07 UTC (permalink / raw)
  To: linux-arm-kernel

On Tue, Jul 07, 2015 at 11:13:30AM +0100, Russell King - ARM Linux wrote:
> On Tue, Jul 07, 2015 at 11:50:12AM +0200, Luis R. Rodriguez wrote:
> > mcgrof at ergon ~/linux-next (git::kill-mtrr)$ git grep ioremap_nocache drivers/| wc -l
> > 359
> 
> Yes, it's because we have:
> (a) LDD telling people they should be using ioremap_nocache() for mapping
>     devices.

Sounds like LDD could use some love from ARM folks. Not a requirement if we
set out on this semantics / grammar / documentation crusade appropriatley.

> (b) We have documentation in the Documentation/ subdirectory telling people
>     to use ioremap_nocache() for the same.

That obviously needs to be fixed, I take it you're on it.

> > This is part of the work I've been doing lately. The
> > eventual goal once we have the write-combing areas properly split with
> > ioremap_wc() and using the new proper preferred architecture agnostic modifier
> > (arch_phys_wc_add()) is to change the default ioremap behaviour on x86 to use
> > strong UC for PAT enabled systems for *both* ioremap() and ioremap_nocache().
> 
> Please note that on ARM, ioremap_wc() gives what's termed in ARM ARM
> speak "normal memory, non-cacheable" - which can be subject to speculation,
> write combining, multiple accesses, etc.  The important point is that
> such mapping is not suitable for device registers, but is suitable for
> device regions that have "memory like" properties (iow, a chunk of RAM,
> like video drivers.)  It does support unaligned accesses.

Thanks that helps.

> > Because of these grammatical issues and the issues with
> > unaligned access with ARM I think its important we put some effort
> > to care a bit more about defining clear semantics through grammar
> > for new APIs or as we rewrite APIs. We have tools to do this these
> > days, best make use of them.
> 
> I'm in support of anything which more clearly specifies the requirements
> for these APIs.

Great!

> > While we're at it and reconsidering all this, a few items I wish for
> > us to address as well then, most of them related to grammar, some
> > procedural clarification:
> > 
> >   * Document it as not supported to have overlapping ioremap() calls.
> >     No one seems to have a clue if this should work, but clearly this
> >     is just a bad idea. I don't see why we should support the complexity
> >     of having this. It seems we can write grammar rules to prevent this.
> 
> On ARM, we (probably) have a lot of cases where ioremap() is used multiple
> times for the same physical address space, so we shouldn't rule out having
> multiple mappings of the same type.

Why is that done? Don't worry if you are not sure why but only speculate of the
practice's existence (sloppy drivers or lazy driver developers). FWIW for x86
IIRC I ended up concluding that overlapping ioremap() calls with the same type
would work but not if they differ in type.  Although I haven't written a
grammer rule to hunt down overlapping ioremap() I suspected its use was likely
odd and likely should be reconsidered. Would this be true for ARM too ? Or are
you saying this should be a feature ? I don't expect an answer now but I'm
saying we *should* all together decide on this, and if you're inclined to
believe that this should ideally be avoided I'd like to hear that. If you feel
strongly though this should be a feature I would like to know why.

> However, differing types would be a problem on ARM.

Great.

> >   * We seem to care about device drivers / kernel code doing unaligned
> >     accesses with certain ioremap() variants. At least for ARM you should
> >     not do unaligned accesses on ioremap_nocache() areas.
> 
> ... and ioremap() areas.
> 
> If we can stop the "abuse" of ioremap_nocache() to map device registers,

OK when *should* ioremap_nocache() be used then ? That is, we can easily write
a rule to go and switch drivers away from ioremap_nocache() but do we have a
grammatical white-list for when its intended goal was appropriate ?  For x86
the goal is to use it for MMIO registers, keep in mind we'd ideally want an
effective ioremap_uc() on those long term, we just can't go flipping the switch
just yet unless we get all the write-combined areas right first and smake sure
that we split them out. That's the effort I've been working on lately.

> then we could potentially switch ioremap_nocache() to be a normal-memory
> like mapping, which would allow it to support unaligned accesses.

Great. Can you elaborate on why that could happen *iff* the abuse stops ?

> >     I am not sure
> >     if we can come up with grammar to vet for / warn for unaligned access
> >     type of code in driver code on some memory area when some ioremap()
> >     variant is used, but this could be looked into. I believe we may
> >     want rules for unaligned access maybe in general, and not attached
> >     to certain calls due to performance considerations, so this work
> >     may be welcomed regardless (refer to
> >     Documentation/unaligned-memory-access.txt)
> >     
> >   * We seem to want to be pedantic about adding new ioremap() variants, the
> >     unaligned issue on ARM is one reason, do we ideally then want *all*
> >     architecture maintainers to provide an Acked-by for any new ioremap
> >     variants ?
> 
> /If/ we get the current mess sorted out so that we have a safe fallback,
> and we have understanding of the different architecture variants (iow,
> documented what the safe fallback is) I don't see any reason why we'd
> need acks from arch maintainers. 

Great, that's the scalable solution so we should strive for this then as
it seems attainable.

> Unfortunately, we're not in that
> situation today, because of the poorly documented mess that ioremap*()
> currently is (and yes, I'm partly to blame for that too by not documenting
> ARMs behaviour here.)

So you're saying the mess is yours to begin with :) ?

> I have some patches (prepared last week, I was going to push them out
> towards the end of the merge window) which address that, but unfortunately
> the ARM autobuilders have been giving a number of seemingly random boot
> failures, and I'm not yet sure what's going on... so I'm holding that
> back until stuff has settled down.

OK sounds like sorting that out will take some time. What are we to do
in the meantime ? Would a default safe return -EOPNOTSUPP be a good
deafult for variants until we get the semantics all settled out ?

> Another issue is... the use of memcpy()/memset() directly on memory
> returned from ioremap*().  The pmem driver does this.  This fails sparse
> checks.  However, years ago, x86 invented the memcpy_fromio()/memcpy_toio()
> memset_io() functions, which took a __iomem pointer (which /presumably/
> means they're supposed to operate on the memory associated with an
> ioremap'd region.)
> 
> Should these functions always be used for mappings via ioremap*(), and
> the standard memcpy()/memset() be avoided?  To me, that sounds like a
> very good thing, because that gives us more control over the
> implementation of the functions used to access ioremap'd regions,
> and the arch can decide to prevent GCC inlining its own memset() or
> memcpy() code if desired.

I think Ben might like this for PowerPC as well, although the atomic
read / write thing would also require revising. I'm pretty confident
we can use grammar to go and fix these offenders if we deem this as
desirable.

Lastly, a small point I'd like to make is that in my ioremap_wc() crusade to
vet for things I found that the drivers that I had the biggest amount of issue
with were ancient and decrepit, perhaps now staging material drivers. Of 4
drivers that I had issues with two had code commented out (now removed, the
fusion driver), one driver was deprecated and we now reached the decision to
remove it from Linux (outbound via staging for ~2 releases as an accepted
driver removal policy, as Greg clarified) this is the ipath driver, another had
some oddball firmware which didn't even allow to expose the write-combined
address offset and was used for some old DVR setup maybe only some folks in
India are using, and lastly atyfb for which we ended up adding ioremap_uc() for
to help work around some MTRR corner case use cases to match a suitable
replacement with PAT.

This is a long winded way of saying that old crappy drivers had an impact on
setting the pace for sane semantics and collateral evolutions (in the form of
accepted required grammatical changes, to use ioremap_uc() with
arch_phys_wc_add()) to clean things up, and I think that if we want to grow
faster and leaner we must grow with grammar but that also should likely mean
more readily accepting removal of ancient crappy drivers. If folks agree
one way to make this explicit is for example to send to staging drivers
which are enabled for all architectures which do tons of unaligned accesses,
and for staging drivers to be only enabled via Kconfig for architectures
which are known to work.

If we want clear semantics / grammar rules / checks defined for a set of
ioremap() calls and family of calls having a clean slate of drivers should make
defining semantics, grammer rules and enforcing them much easier, just as
then maing collateral evolutions to then go out and fix only a set of drivers.
Moore's law should have implications not only on accepted growth but also
on deprecation, if we haven't been deprecating hardware fast enough and
not giving old drivers major love it should only affect us, specially as
our hardware evolves even faster.

So if we want to be pedantic about semantics / grammar lets flush down the
toilet more drivers and faster and if we're iffy about them we can put them on
the staging corner.

> Note that on x86, these three functions are merely wrappers around
> standard memcpy()/memset(), so there should be no reason why pmem.c
> couldn't be updated to use these accessors instead.

Great.

  Luis

^ permalink raw reply	[flat|nested] 85+ messages in thread

* Re: [PATCH v5 2/6] arch: unify ioremap prototypes and macro aliases
  2015-07-07 16:07                       ` Luis R. Rodriguez
  (?)
@ 2015-07-07 23:10                         ` Toshi Kani
  -1 siblings, 0 replies; 85+ messages in thread
From: Toshi Kani @ 2015-07-07 23:10 UTC (permalink / raw)
  To: Luis R. Rodriguez, Russell King - ARM Linux
  Cc: Christoph Hellwig, Andy Lutomirski, Benjamin Herrenschmidt,
	Geert Uytterhoeven, Julia Lawall, Dan Williams, Arnd Bergmann,
	Ingo Molnar, Borislav Petkov, H. Peter Anvin, Thomas Gleixner,
	Ross Zwisler, Andrew Morton, Juergen Gross, X86 ML,
	linux-nvdimm@lists.01.org, Konrad Rzeszutek Wilk, linux-kernel,
	Stefan Bader, Linux MM, Ralf Baechle,
	Henrique de Moraes Holschuh, Michael Ellerman, Tejun Heo,
	Paul Mackerras, mcgrof, linux-arm-kernel

On Tue, 2015-07-07 at 18:07 +0200, Luis R. Rodriguez wrote:
> On Tue, Jul 07, 2015 at 11:13:30AM +0100, Russell King - ARM Linux 
> wrote:
  :
> > On ARM, we (probably) have a lot of cases where ioremap() is used 
> > multiple
> > times for the same physical address space, so we shouldn't rule out 
> > having
> > multiple mappings of the same type.
> 
> Why is that done? Don't worry if you are not sure why but only 
> speculate of the
> practice's existence (sloppy drivers or lazy driver developers). FWIW 
> for x86
> IIRC I ended up concluding that overlapping ioremap() calls with the 
> same type
> would work but not if they differ in type.  Although I haven't 
> written a
> grammer rule to hunt down overlapping ioremap() I suspected its use 
> was likely
> odd and likely should be reconsidered. Would this be true for ARM too 
> ? Or are
> you saying this should be a feature ? I don't expect an answer now 
> but I'm
> saying we *should* all together decide on this, and if you're 
> inclined to
> believe that this should ideally be avoided I'd like to hear that. If 
> you feel
> strongly though this should be a feature I would like to know why.

There are multiple mapping interfaces, and overlapping can happen among
them as well.  For instance, remap_pfn_range() (and 
io_remap_pfn_range(), which is the same as remap_pfn_range() on x86)
creates a mapping to user space.  The same physical ranges may be
mapped to kernel and user spaces.  /dev/mem is one example that may
create a user space mapping to a physical address that is already
mapped with ioremap() by other module.  pmem and DAX also create
mappings to the same NVDIMM ranges.  DAX calls vm_insert_mixed(), which
is particularly a problematic since vm_insert_mixed() does not verify
aliasing.  ioremap() and remap_pfn_range() call reserve_memtype() to
verify aliasing on x86.  reserve_memtype() is x86-specific and there is
no arch-generic wrapper for such check.  I think DAX could get a cache
type from pmem to keep them in sync, though.

Thanks,
-Toshi


 


--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org.  For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>

^ permalink raw reply	[flat|nested] 85+ messages in thread

* Re: [PATCH v5 2/6] arch: unify ioremap prototypes and macro aliases
@ 2015-07-07 23:10                         ` Toshi Kani
  0 siblings, 0 replies; 85+ messages in thread
From: Toshi Kani @ 2015-07-07 23:10 UTC (permalink / raw)
  To: Luis R. Rodriguez, Russell King - ARM Linux
  Cc: Christoph Hellwig, Andy Lutomirski, Benjamin Herrenschmidt,
	Geert Uytterhoeven, Julia Lawall, Dan Williams, Arnd Bergmann,
	Ingo Molnar, Borislav Petkov, H. Peter Anvin, Thomas Gleixner,
	Ross Zwisler, Andrew Morton, Juergen Gross, X86 ML,
	linux-nvdimm@lists.01.org, Konrad Rzeszutek Wilk, linux-kernel,
	Stefan Bader, Linux MM, Ralf Baechle,
	Henrique de Moraes Holschuh, Michael Ellerman, Tejun Heo,
	Paul Mackerras, mcgrof, linux-arm-kernel

On Tue, 2015-07-07 at 18:07 +0200, Luis R. Rodriguez wrote:
> On Tue, Jul 07, 2015 at 11:13:30AM +0100, Russell King - ARM Linux 
> wrote:
  :
> > On ARM, we (probably) have a lot of cases where ioremap() is used 
> > multiple
> > times for the same physical address space, so we shouldn't rule out 
> > having
> > multiple mappings of the same type.
> 
> Why is that done? Don't worry if you are not sure why but only 
> speculate of the
> practice's existence (sloppy drivers or lazy driver developers). FWIW 
> for x86
> IIRC I ended up concluding that overlapping ioremap() calls with the 
> same type
> would work but not if they differ in type.  Although I haven't 
> written a
> grammer rule to hunt down overlapping ioremap() I suspected its use 
> was likely
> odd and likely should be reconsidered. Would this be true for ARM too 
> ? Or are
> you saying this should be a feature ? I don't expect an answer now 
> but I'm
> saying we *should* all together decide on this, and if you're 
> inclined to
> believe that this should ideally be avoided I'd like to hear that. If 
> you feel
> strongly though this should be a feature I would like to know why.

There are multiple mapping interfaces, and overlapping can happen among
them as well.  For instance, remap_pfn_range() (and 
io_remap_pfn_range(), which is the same as remap_pfn_range() on x86)
creates a mapping to user space.  The same physical ranges may be
mapped to kernel and user spaces.  /dev/mem is one example that may
create a user space mapping to a physical address that is already
mapped with ioremap() by other module.  pmem and DAX also create
mappings to the same NVDIMM ranges.  DAX calls vm_insert_mixed(), which
is particularly a problematic since vm_insert_mixed() does not verify
aliasing.  ioremap() and remap_pfn_range() call reserve_memtype() to
verify aliasing on x86.  reserve_memtype() is x86-specific and there is
no arch-generic wrapper for such check.  I think DAX could get a cache
type from pmem to keep them in sync, though.

Thanks,
-Toshi


 



^ permalink raw reply	[flat|nested] 85+ messages in thread

* [PATCH v5 2/6] arch: unify ioremap prototypes and macro aliases
@ 2015-07-07 23:10                         ` Toshi Kani
  0 siblings, 0 replies; 85+ messages in thread
From: Toshi Kani @ 2015-07-07 23:10 UTC (permalink / raw)
  To: linux-arm-kernel

On Tue, 2015-07-07 at 18:07 +0200, Luis R. Rodriguez wrote:
> On Tue, Jul 07, 2015 at 11:13:30AM +0100, Russell King - ARM Linux 
> wrote:
  :
> > On ARM, we (probably) have a lot of cases where ioremap() is used 
> > multiple
> > times for the same physical address space, so we shouldn't rule out 
> > having
> > multiple mappings of the same type.
> 
> Why is that done? Don't worry if you are not sure why but only 
> speculate of the
> practice's existence (sloppy drivers or lazy driver developers). FWIW 
> for x86
> IIRC I ended up concluding that overlapping ioremap() calls with the 
> same type
> would work but not if they differ in type.  Although I haven't 
> written a
> grammer rule to hunt down overlapping ioremap() I suspected its use 
> was likely
> odd and likely should be reconsidered. Would this be true for ARM too 
> ? Or are
> you saying this should be a feature ? I don't expect an answer now 
> but I'm
> saying we *should* all together decide on this, and if you're 
> inclined to
> believe that this should ideally be avoided I'd like to hear that. If 
> you feel
> strongly though this should be a feature I would like to know why.

There are multiple mapping interfaces, and overlapping can happen among
them as well.  For instance, remap_pfn_range() (and 
io_remap_pfn_range(), which is the same as remap_pfn_range() on x86)
creates a mapping to user space.  The same physical ranges may be
mapped to kernel and user spaces.  /dev/mem is one example that may
create a user space mapping to a physical address that is already
mapped with ioremap() by other module.  pmem and DAX also create
mappings to the same NVDIMM ranges.  DAX calls vm_insert_mixed(), which
is particularly a problematic since vm_insert_mixed() does not verify
aliasing.  ioremap() and remap_pfn_range() call reserve_memtype() to
verify aliasing on x86.  reserve_memtype() is x86-specific and there is
no arch-generic wrapper for such check.  I think DAX could get a cache
type from pmem to keep them in sync, though.

Thanks,
-Toshi


 

^ permalink raw reply	[flat|nested] 85+ messages in thread

* Re: [PATCH v5 2/6] arch: unify ioremap prototypes and macro aliases
  2015-07-07 23:10                         ` Toshi Kani
  (?)
@ 2015-07-09  1:40                           ` Luis R. Rodriguez
  -1 siblings, 0 replies; 85+ messages in thread
From: Luis R. Rodriguez @ 2015-07-09  1:40 UTC (permalink / raw)
  To: Toshi Kani
  Cc: Russell King - ARM Linux, Matthew Wilcox, Ross Zwisler,
	Christoph Hellwig, Andy Lutomirski, Benjamin Herrenschmidt,
	Geert Uytterhoeven, Julia Lawall, Dan Williams, Arnd Bergmann,
	Ingo Molnar, Borislav Petkov, H. Peter Anvin, Thomas Gleixner,
	Andrew Morton, Juergen Gross, X86 ML, linux-nvdimm@lists.01.org,
	Konrad Rzeszutek Wilk, linux-kernel, Stefan Bader, Linux MM,
	Ralf Baechle, Henrique de Moraes Holschuh, Michael Ellerman,
	Tejun Heo, Paul Mackerras, mcgrof, linux-arm-kernel

On Tue, Jul 07, 2015 at 05:10:58PM -0600, Toshi Kani wrote:
> On Tue, 2015-07-07 at 18:07 +0200, Luis R. Rodriguez wrote:
> > On Tue, Jul 07, 2015 at 11:13:30AM +0100, Russell King - ARM Linux 
> > wrote:
>   :
> > > On ARM, we (probably) have a lot of cases where ioremap() is used 
> > > multiple
> > > times for the same physical address space, so we shouldn't rule out 
> > > having
> > > multiple mappings of the same type.
> > 
> > Why is that done? Don't worry if you are not sure why but only 
> > speculate of the
> > practice's existence (sloppy drivers or lazy driver developers). FWIW 
> > for x86
> > IIRC I ended up concluding that overlapping ioremap() calls with the 
> > same type
> > would work but not if they differ in type.  Although I haven't 
> > written a
> > grammer rule to hunt down overlapping ioremap() I suspected its use 
> > was likely
> > odd and likely should be reconsidered. Would this be true for ARM too 
> > ? Or are
> > you saying this should be a feature ? I don't expect an answer now 
> > but I'm
> > saying we *should* all together decide on this, and if you're 
> > inclined to
> > believe that this should ideally be avoided I'd like to hear that. If 
> > you feel
> > strongly though this should be a feature I would like to know why.
> 
> There are multiple mapping interfaces, and overlapping can happen among
> them as well.  For instance, remap_pfn_range() (and 
> io_remap_pfn_range(), which is the same as remap_pfn_range() on x86)
> creates a mapping to user space. The same physical ranges may be
> mapped to kernel and user spaces.  /dev/mem is one example that may
> create a user space mapping to a physical address that is already
> mapped with ioremap() by other module.

Thanks for the feedback. The restriction seems to be differing cache types
requirements, other than this, are there any other concerns ? For instance are
we completley happy with aliasing so long as cache types match everywhere?  I'd
expect no architecture would want cache types to differ when aliasing, what
should differ then I think would just be how to verify this and it doesn't seem
we may be doing this for all architectures.

Even for userspace we seem to be covered -- we enable userspace mmap() calls to
get their mapped space with a cache type, on the kernel we'd say use
pgprot_writecombine() on the vma->vm_page_prot prior to the
io_remap_pfn_range() -- that maps to remap_pfn_range() on x86 and as you note
that checks cache type via reserve_memtype() -- but only on x86...

Other than this differing cache type concern are we OK with aliasing in
userspace all the time ?

If we want to restrict aliasing either for the kernel or userspace mapping
we might be able to do it, I just want to know if we want to or not care
at all.

> pmem and DAX also create mappings to the same NVDIMM ranges.  DAX calls
> vm_insert_mixed(), which is particularly a problematic since
> vm_insert_mixed() does not verify aliasing.  ioremap() and remap_pfn_range()
> call reserve_memtype() to verify aliasing on x86.  reserve_memtype() is
> x86-specific and there is no arch-generic wrapper for such check.

As clarified by Matthew Wilcox via commit d92576f1167cacf7844 ("dax: does not
work correctly with virtual aliasing caches") caches are virtually mapped for
some architectures, it seems it should be possible to fix this for DAX somehow
though.

> I think DAX could get a cache type from pmem to keep them in sync, though.

pmem is x86 specific right now, are other folks going to expose something
similar ? Otherwise we seem to only be addressing these deep concerns for
x86 so far.

 Luis

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org.  For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>

^ permalink raw reply	[flat|nested] 85+ messages in thread

* Re: [PATCH v5 2/6] arch: unify ioremap prototypes and macro aliases
@ 2015-07-09  1:40                           ` Luis R. Rodriguez
  0 siblings, 0 replies; 85+ messages in thread
From: Luis R. Rodriguez @ 2015-07-09  1:40 UTC (permalink / raw)
  To: Toshi Kani
  Cc: Russell King - ARM Linux, Matthew Wilcox, Ross Zwisler,
	Christoph Hellwig, Andy Lutomirski, Benjamin Herrenschmidt,
	Geert Uytterhoeven, Julia Lawall, Dan Williams, Arnd Bergmann,
	Ingo Molnar, Borislav Petkov, H. Peter Anvin, Thomas Gleixner,
	Andrew Morton, Juergen Gross, X86 ML, linux-nvdimm@lists.01.org,
	Konrad Rzeszutek Wilk, linux-kernel, Stefan Bader, Linux MM,
	Ralf Baechle, Henrique de Moraes Holschuh, Michael Ellerman,
	Tejun Heo, Paul Mackerras, mcgrof, linux-arm-kernel

On Tue, Jul 07, 2015 at 05:10:58PM -0600, Toshi Kani wrote:
> On Tue, 2015-07-07 at 18:07 +0200, Luis R. Rodriguez wrote:
> > On Tue, Jul 07, 2015 at 11:13:30AM +0100, Russell King - ARM Linux 
> > wrote:
>   :
> > > On ARM, we (probably) have a lot of cases where ioremap() is used 
> > > multiple
> > > times for the same physical address space, so we shouldn't rule out 
> > > having
> > > multiple mappings of the same type.
> > 
> > Why is that done? Don't worry if you are not sure why but only 
> > speculate of the
> > practice's existence (sloppy drivers or lazy driver developers). FWIW 
> > for x86
> > IIRC I ended up concluding that overlapping ioremap() calls with the 
> > same type
> > would work but not if they differ in type.  Although I haven't 
> > written a
> > grammer rule to hunt down overlapping ioremap() I suspected its use 
> > was likely
> > odd and likely should be reconsidered. Would this be true for ARM too 
> > ? Or are
> > you saying this should be a feature ? I don't expect an answer now 
> > but I'm
> > saying we *should* all together decide on this, and if you're 
> > inclined to
> > believe that this should ideally be avoided I'd like to hear that. If 
> > you feel
> > strongly though this should be a feature I would like to know why.
> 
> There are multiple mapping interfaces, and overlapping can happen among
> them as well.  For instance, remap_pfn_range() (and 
> io_remap_pfn_range(), which is the same as remap_pfn_range() on x86)
> creates a mapping to user space. The same physical ranges may be
> mapped to kernel and user spaces.  /dev/mem is one example that may
> create a user space mapping to a physical address that is already
> mapped with ioremap() by other module.

Thanks for the feedback. The restriction seems to be differing cache types
requirements, other than this, are there any other concerns ? For instance are
we completley happy with aliasing so long as cache types match everywhere?  I'd
expect no architecture would want cache types to differ when aliasing, what
should differ then I think would just be how to verify this and it doesn't seem
we may be doing this for all architectures.

Even for userspace we seem to be covered -- we enable userspace mmap() calls to
get their mapped space with a cache type, on the kernel we'd say use
pgprot_writecombine() on the vma->vm_page_prot prior to the
io_remap_pfn_range() -- that maps to remap_pfn_range() on x86 and as you note
that checks cache type via reserve_memtype() -- but only on x86...

Other than this differing cache type concern are we OK with aliasing in
userspace all the time ?

If we want to restrict aliasing either for the kernel or userspace mapping
we might be able to do it, I just want to know if we want to or not care
at all.

> pmem and DAX also create mappings to the same NVDIMM ranges.  DAX calls
> vm_insert_mixed(), which is particularly a problematic since
> vm_insert_mixed() does not verify aliasing.  ioremap() and remap_pfn_range()
> call reserve_memtype() to verify aliasing on x86.  reserve_memtype() is
> x86-specific and there is no arch-generic wrapper for such check.

As clarified by Matthew Wilcox via commit d92576f1167cacf7844 ("dax: does not
work correctly with virtual aliasing caches") caches are virtually mapped for
some architectures, it seems it should be possible to fix this for DAX somehow
though.

> I think DAX could get a cache type from pmem to keep them in sync, though.

pmem is x86 specific right now, are other folks going to expose something
similar ? Otherwise we seem to only be addressing these deep concerns for
x86 so far.

 Luis

^ permalink raw reply	[flat|nested] 85+ messages in thread

* [PATCH v5 2/6] arch: unify ioremap prototypes and macro aliases
@ 2015-07-09  1:40                           ` Luis R. Rodriguez
  0 siblings, 0 replies; 85+ messages in thread
From: Luis R. Rodriguez @ 2015-07-09  1:40 UTC (permalink / raw)
  To: linux-arm-kernel

On Tue, Jul 07, 2015 at 05:10:58PM -0600, Toshi Kani wrote:
> On Tue, 2015-07-07 at 18:07 +0200, Luis R. Rodriguez wrote:
> > On Tue, Jul 07, 2015 at 11:13:30AM +0100, Russell King - ARM Linux 
> > wrote:
>   :
> > > On ARM, we (probably) have a lot of cases where ioremap() is used 
> > > multiple
> > > times for the same physical address space, so we shouldn't rule out 
> > > having
> > > multiple mappings of the same type.
> > 
> > Why is that done? Don't worry if you are not sure why but only 
> > speculate of the
> > practice's existence (sloppy drivers or lazy driver developers). FWIW 
> > for x86
> > IIRC I ended up concluding that overlapping ioremap() calls with the 
> > same type
> > would work but not if they differ in type.  Although I haven't 
> > written a
> > grammer rule to hunt down overlapping ioremap() I suspected its use 
> > was likely
> > odd and likely should be reconsidered. Would this be true for ARM too 
> > ? Or are
> > you saying this should be a feature ? I don't expect an answer now 
> > but I'm
> > saying we *should* all together decide on this, and if you're 
> > inclined to
> > believe that this should ideally be avoided I'd like to hear that. If 
> > you feel
> > strongly though this should be a feature I would like to know why.
> 
> There are multiple mapping interfaces, and overlapping can happen among
> them as well.  For instance, remap_pfn_range() (and 
> io_remap_pfn_range(), which is the same as remap_pfn_range() on x86)
> creates a mapping to user space. The same physical ranges may be
> mapped to kernel and user spaces.  /dev/mem is one example that may
> create a user space mapping to a physical address that is already
> mapped with ioremap() by other module.

Thanks for the feedback. The restriction seems to be differing cache types
requirements, other than this, are there any other concerns ? For instance are
we completley happy with aliasing so long as cache types match everywhere?  I'd
expect no architecture would want cache types to differ when aliasing, what
should differ then I think would just be how to verify this and it doesn't seem
we may be doing this for all architectures.

Even for userspace we seem to be covered -- we enable userspace mmap() calls to
get their mapped space with a cache type, on the kernel we'd say use
pgprot_writecombine() on the vma->vm_page_prot prior to the
io_remap_pfn_range() -- that maps to remap_pfn_range() on x86 and as you note
that checks cache type via reserve_memtype() -- but only on x86...

Other than this differing cache type concern are we OK with aliasing in
userspace all the time ?

If we want to restrict aliasing either for the kernel or userspace mapping
we might be able to do it, I just want to know if we want to or not care
at all.

> pmem and DAX also create mappings to the same NVDIMM ranges.  DAX calls
> vm_insert_mixed(), which is particularly a problematic since
> vm_insert_mixed() does not verify aliasing.  ioremap() and remap_pfn_range()
> call reserve_memtype() to verify aliasing on x86.  reserve_memtype() is
> x86-specific and there is no arch-generic wrapper for such check.

As clarified by Matthew Wilcox via commit d92576f1167cacf7844 ("dax: does not
work correctly with virtual aliasing caches") caches are virtually mapped for
some architectures, it seems it should be possible to fix this for DAX somehow
though.

> I think DAX could get a cache type from pmem to keep them in sync, though.

pmem is x86 specific right now, are other folks going to expose something
similar ? Otherwise we seem to only be addressing these deep concerns for
x86 so far.

 Luis

^ permalink raw reply	[flat|nested] 85+ messages in thread

* Re: [PATCH v5 2/6] arch: unify ioremap prototypes and macro aliases
  2015-06-22  8:24   ` Dan Williams
@ 2015-07-09 18:54     ` Luis R. Rodriguez
  -1 siblings, 0 replies; 85+ messages in thread
From: Luis R. Rodriguez @ 2015-07-09 18:54 UTC (permalink / raw)
  To: Dan Williams
  Cc: arnd, mingo, bp, hpa, tglx, ross.zwisler, akpm, jgross, x86,
	toshi.kani, linux-nvdimm, benh, konrad.wilk, linux-kernel,
	stefan.bader, luto, linux-mm, geert, ralf, hmh, mpe, tj, paulus,
	hch

On Mon, Jun 22, 2015 at 04:24:27AM -0400, Dan Williams wrote:
> diff --git a/include/asm-generic/iomap.h b/include/asm-generic/iomap.h
> index d8f8622fa044..4789b1cec313 100644
> --- a/include/asm-generic/iomap.h
> +++ b/include/asm-generic/iomap.h
> @@ -62,14 +62,6 @@ extern void __iomem *ioport_map(unsigned long port, unsigned int nr);
>  extern void ioport_unmap(void __iomem *);
>  #endif
>  
> -#ifndef ARCH_HAS_IOREMAP_WC
> -#define ioremap_wc ioremap_nocache
> -#endif
> -
> -#ifndef ARCH_HAS_IOREMAP_WT
> -#define ioremap_wt ioremap_nocache
> -#endif
> -
>  #ifdef CONFIG_PCI
>  /* Destroy a virtual mapping cookie for a PCI BAR (memory or IO) */
>  struct pci_dev;

While at it we should also detangle ioremap() variants default implementations
from requiring !CONFIG_MMU, so to be clear, if you have CONFIG_MMU you should
implement ioremap() and iounmap(), then additionally if you have a way to
support an ioremap_*() variant you should do so as well. You can
include asm-generic/iomap.h to help complete ioremap_*() variants you may not
have defined but note below.

***Big fat note**: this however assumes we have a *safe* general ioremap() to
default to for all architectures but for a slew of reasons we cannot have this
today and further discussion is needed to see if it may be possible one day. In
the meantime we must then settle to advocate architecture developers to
provide their own ioremap_*() variant implementations. We can do this two ways:

  1) make new defaults return NULL - to avoid improper behaviour
  2) revisit current default implementations on asm-generic for
     ioremap_*() variants and vet that they are safe for each architecture
     actually using them, if they are safe tuck under each arch its own
     mapping. After all this then convert default to return NULL. This
     will prevent future issues with other architectures.
  3) long term: work towards the lofty objective of defining an architecturally
     sane iorema_*() variant default. This can only be done once all the
     semantics of all the others are well established.

I'll provide a small demo patch with a very specific fix. We can either
address this as separate work prior to your patchset or mesh this work
together.

  Luis

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org.  For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>

^ permalink raw reply	[flat|nested] 85+ messages in thread

* Re: [PATCH v5 2/6] arch: unify ioremap prototypes and macro aliases
@ 2015-07-09 18:54     ` Luis R. Rodriguez
  0 siblings, 0 replies; 85+ messages in thread
From: Luis R. Rodriguez @ 2015-07-09 18:54 UTC (permalink / raw)
  To: Dan Williams
  Cc: arnd, mingo, bp, hpa, tglx, ross.zwisler, akpm, jgross, x86,
	toshi.kani, linux-nvdimm, benh, konrad.wilk, linux-kernel,
	stefan.bader, luto, linux-mm, geert, ralf, hmh, mpe, tj, paulus,
	hch

On Mon, Jun 22, 2015 at 04:24:27AM -0400, Dan Williams wrote:
> diff --git a/include/asm-generic/iomap.h b/include/asm-generic/iomap.h
> index d8f8622fa044..4789b1cec313 100644
> --- a/include/asm-generic/iomap.h
> +++ b/include/asm-generic/iomap.h
> @@ -62,14 +62,6 @@ extern void __iomem *ioport_map(unsigned long port, unsigned int nr);
>  extern void ioport_unmap(void __iomem *);
>  #endif
>  
> -#ifndef ARCH_HAS_IOREMAP_WC
> -#define ioremap_wc ioremap_nocache
> -#endif
> -
> -#ifndef ARCH_HAS_IOREMAP_WT
> -#define ioremap_wt ioremap_nocache
> -#endif
> -
>  #ifdef CONFIG_PCI
>  /* Destroy a virtual mapping cookie for a PCI BAR (memory or IO) */
>  struct pci_dev;

While at it we should also detangle ioremap() variants default implementations
from requiring !CONFIG_MMU, so to be clear, if you have CONFIG_MMU you should
implement ioremap() and iounmap(), then additionally if you have a way to
support an ioremap_*() variant you should do so as well. You can
include asm-generic/iomap.h to help complete ioremap_*() variants you may not
have defined but note below.

***Big fat note**: this however assumes we have a *safe* general ioremap() to
default to for all architectures but for a slew of reasons we cannot have this
today and further discussion is needed to see if it may be possible one day. In
the meantime we must then settle to advocate architecture developers to
provide their own ioremap_*() variant implementations. We can do this two ways:

  1) make new defaults return NULL - to avoid improper behaviour
  2) revisit current default implementations on asm-generic for
     ioremap_*() variants and vet that they are safe for each architecture
     actually using them, if they are safe tuck under each arch its own
     mapping. After all this then convert default to return NULL. This
     will prevent future issues with other architectures.
  3) long term: work towards the lofty objective of defining an architecturally
     sane iorema_*() variant default. This can only be done once all the
     semantics of all the others are well established.

I'll provide a small demo patch with a very specific fix. We can either
address this as separate work prior to your patchset or mesh this work
together.

  Luis

^ permalink raw reply	[flat|nested] 85+ messages in thread

* Re: [PATCH v5 2/6] arch: unify ioremap prototypes and macro aliases
  2015-07-09  1:40                           ` Luis R. Rodriguez
  (?)
@ 2015-07-09 23:43                             ` Toshi Kani
  -1 siblings, 0 replies; 85+ messages in thread
From: Toshi Kani @ 2015-07-09 23:43 UTC (permalink / raw)
  To: Luis R. Rodriguez
  Cc: Russell King - ARM Linux, Matthew Wilcox, Ross Zwisler,
	Christoph Hellwig, Andy Lutomirski, Benjamin Herrenschmidt,
	Geert Uytterhoeven, Julia Lawall, Dan Williams, Arnd Bergmann,
	Ingo Molnar, Borislav Petkov, H. Peter Anvin, Thomas Gleixner,
	Andrew Morton, Juergen Gross, X86 ML, linux-nvdimm@lists.01.org,
	Konrad Rzeszutek Wilk, linux-kernel, Stefan Bader, Linux MM,
	Ralf Baechle, Henrique de Moraes Holschuh, Michael Ellerman,
	Tejun Heo, Paul Mackerras, mcgrof, linux-arm-kernel

On Thu, 2015-07-09 at 03:40 +0200, Luis R. Rodriguez wrote:
> On Tue, Jul 07, 2015 at 05:10:58PM -0600, Toshi Kani wrote:
> > On Tue, 2015-07-07 at 18:07 +0200, Luis R. Rodriguez wrote:
> > > On Tue, Jul 07, 2015 at 11:13:30AM +0100, Russell King - ARM 
> > > Linux 
> > > wrote:
> >   :
> > > > On ARM, we (probably) have a lot of cases where ioremap() is 
> > > > used 
> > > > multiple
> > > > times for the same physical address space, so we shouldn't rule 
> > > > out 
> > > > having
> > > > multiple mappings of the same type.
> > > 
> > > Why is that done? Don't worry if you are not sure why but only 
> > > speculate of the
> > > practice's existence (sloppy drivers or lazy driver developers). 
> > > FWIW 
> > > for x86
> > > IIRC I ended up concluding that overlapping ioremap() calls with 
> > > the 
> > > same type
> > > would work but not if they differ in type.  Although I haven't 
> > > written a
> > > grammer rule to hunt down overlapping ioremap() I suspected its 
> > > use 
> > > was likely
> > > odd and likely should be reconsidered. Would this be true for ARM 
> > > too 
> > > ? Or are
> > > you saying this should be a feature ? I don't expect an answer 
> > > now 
> > > but I'm
> > > saying we *should* all together decide on this, and if you're 
> > > inclined to
> > > believe that this should ideally be avoided I'd like to hear 
> > > that. If 
> > > you feel
> > > strongly though this should be a feature I would like to know 
> > > why.
> > 
> > There are multiple mapping interfaces, and overlapping can happen 
> > among
> > them as well.  For instance, remap_pfn_range() (and 
> > io_remap_pfn_range(), which is the same as remap_pfn_range() on 
> > x86)
> > creates a mapping to user space. The same physical ranges may be
> > mapped to kernel and user spaces.  /dev/mem is one example that may
> > create a user space mapping to a physical address that is already
> > mapped with ioremap() by other module.
> 
> Thanks for the feedback. The restriction seems to be differing cache 
> types
> requirements, other than this, are there any other concerns ? For 
> instance are
> we completley happy with aliasing so long as cache types match 
> everywhere?  I'd
> expect no architecture would want cache types to differ when 
> aliasing, what
> should differ then I think would just be how to verify this and it 
> doesn't seem
> we may be doing this for all architectures.
> 
> Even for userspace we seem to be covered -- we enable userspace 
> mmap() calls to
> get their mapped space with a cache type, on the kernel we'd say use
> pgprot_writecombine() on the vma->vm_page_prot prior to the
> io_remap_pfn_range() -- that maps to remap_pfn_range() on x86 and as 
> you note
> that checks cache type via reserve_memtype() -- but only on x86...
> 
> Other than this differing cache type concern are we OK with aliasing 
> in
> userspace all the time ?
> 
> If we want to restrict aliasing either for the kernel or userspace 
> mapping
> we might be able to do it, I just want to know if we want to or not 
> care
> at all.

Yes, we allow to create multiple mappings to a same physical page as
long as their cache type is the same.  There are multiple use-cases
that depend on this ability.

> > pmem and DAX also create mappings to the same NVDIMM ranges.  DAX 
> > calls
> > vm_insert_mixed(), which is particularly a problematic since
> > vm_insert_mixed() does not verify aliasing.  ioremap() and 
> > remap_pfn_range()
> > call reserve_memtype() to verify aliasing on x86. 
> >  reserve_memtype() is
> > x86-specific and there is no arch-generic wrapper for such check.
> 
> As clarified by Matthew Wilcox via commit d92576f1167cacf7844 ("dax: 
> does not
> work correctly with virtual aliasing caches") caches are virtually 
> mapped for
> some architectures, it seems it should be possible to fix this for 
> DAX somehow
> though.

I simply described this DAX case as an example of how two modules might
request different cache types.  Yes, we should be able to fix this
case.

> > I think DAX could get a cache type from pmem to keep them in sync, 
> > though.
> 
> pmem is x86 specific right now, are other folks going to expose 
> something
> similar ? Otherwise we seem to only be addressing these deep concerns 
> for
> x86 so far.

pmem is a generic driver and is not x86-specific. 

Thanks,
-Toshi

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org.  For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>

^ permalink raw reply	[flat|nested] 85+ messages in thread

* Re: [PATCH v5 2/6] arch: unify ioremap prototypes and macro aliases
@ 2015-07-09 23:43                             ` Toshi Kani
  0 siblings, 0 replies; 85+ messages in thread
From: Toshi Kani @ 2015-07-09 23:43 UTC (permalink / raw)
  To: Luis R. Rodriguez
  Cc: Russell King - ARM Linux, Matthew Wilcox, Ross Zwisler,
	Christoph Hellwig, Andy Lutomirski, Benjamin Herrenschmidt,
	Geert Uytterhoeven, Julia Lawall, Dan Williams, Arnd Bergmann,
	Ingo Molnar, Borislav Petkov, H. Peter Anvin, Thomas Gleixner,
	Andrew Morton, Juergen Gross, X86 ML, linux-nvdimm@lists.01.org,
	Konrad Rzeszutek Wilk, linux-kernel, Stefan Bader, Linux MM,
	Ralf Baechle, Henrique de Moraes Holschuh, Michael Ellerman,
	Tejun Heo, Paul Mackerras, mcgrof, linux-arm-kernel

On Thu, 2015-07-09 at 03:40 +0200, Luis R. Rodriguez wrote:
> On Tue, Jul 07, 2015 at 05:10:58PM -0600, Toshi Kani wrote:
> > On Tue, 2015-07-07 at 18:07 +0200, Luis R. Rodriguez wrote:
> > > On Tue, Jul 07, 2015 at 11:13:30AM +0100, Russell King - ARM 
> > > Linux 
> > > wrote:
> >   :
> > > > On ARM, we (probably) have a lot of cases where ioremap() is 
> > > > used 
> > > > multiple
> > > > times for the same physical address space, so we shouldn't rule 
> > > > out 
> > > > having
> > > > multiple mappings of the same type.
> > > 
> > > Why is that done? Don't worry if you are not sure why but only 
> > > speculate of the
> > > practice's existence (sloppy drivers or lazy driver developers). 
> > > FWIW 
> > > for x86
> > > IIRC I ended up concluding that overlapping ioremap() calls with 
> > > the 
> > > same type
> > > would work but not if they differ in type.  Although I haven't 
> > > written a
> > > grammer rule to hunt down overlapping ioremap() I suspected its 
> > > use 
> > > was likely
> > > odd and likely should be reconsidered. Would this be true for ARM 
> > > too 
> > > ? Or are
> > > you saying this should be a feature ? I don't expect an answer 
> > > now 
> > > but I'm
> > > saying we *should* all together decide on this, and if you're 
> > > inclined to
> > > believe that this should ideally be avoided I'd like to hear 
> > > that. If 
> > > you feel
> > > strongly though this should be a feature I would like to know 
> > > why.
> > 
> > There are multiple mapping interfaces, and overlapping can happen 
> > among
> > them as well.  For instance, remap_pfn_range() (and 
> > io_remap_pfn_range(), which is the same as remap_pfn_range() on 
> > x86)
> > creates a mapping to user space. The same physical ranges may be
> > mapped to kernel and user spaces.  /dev/mem is one example that may
> > create a user space mapping to a physical address that is already
> > mapped with ioremap() by other module.
> 
> Thanks for the feedback. The restriction seems to be differing cache 
> types
> requirements, other than this, are there any other concerns ? For 
> instance are
> we completley happy with aliasing so long as cache types match 
> everywhere?  I'd
> expect no architecture would want cache types to differ when 
> aliasing, what
> should differ then I think would just be how to verify this and it 
> doesn't seem
> we may be doing this for all architectures.
> 
> Even for userspace we seem to be covered -- we enable userspace 
> mmap() calls to
> get their mapped space with a cache type, on the kernel we'd say use
> pgprot_writecombine() on the vma->vm_page_prot prior to the
> io_remap_pfn_range() -- that maps to remap_pfn_range() on x86 and as 
> you note
> that checks cache type via reserve_memtype() -- but only on x86...
> 
> Other than this differing cache type concern are we OK with aliasing 
> in
> userspace all the time ?
> 
> If we want to restrict aliasing either for the kernel or userspace 
> mapping
> we might be able to do it, I just want to know if we want to or not 
> care
> at all.

Yes, we allow to create multiple mappings to a same physical page as
long as their cache type is the same.  There are multiple use-cases
that depend on this ability.

> > pmem and DAX also create mappings to the same NVDIMM ranges.  DAX 
> > calls
> > vm_insert_mixed(), which is particularly a problematic since
> > vm_insert_mixed() does not verify aliasing.  ioremap() and 
> > remap_pfn_range()
> > call reserve_memtype() to verify aliasing on x86. 
> >  reserve_memtype() is
> > x86-specific and there is no arch-generic wrapper for such check.
> 
> As clarified by Matthew Wilcox via commit d92576f1167cacf7844 ("dax: 
> does not
> work correctly with virtual aliasing caches") caches are virtually 
> mapped for
> some architectures, it seems it should be possible to fix this for 
> DAX somehow
> though.

I simply described this DAX case as an example of how two modules might
request different cache types.  Yes, we should be able to fix this
case.

> > I think DAX could get a cache type from pmem to keep them in sync, 
> > though.
> 
> pmem is x86 specific right now, are other folks going to expose 
> something
> similar ? Otherwise we seem to only be addressing these deep concerns 
> for
> x86 so far.

pmem is a generic driver and is not x86-specific. 

Thanks,
-Toshi

^ permalink raw reply	[flat|nested] 85+ messages in thread

* [PATCH v5 2/6] arch: unify ioremap prototypes and macro aliases
@ 2015-07-09 23:43                             ` Toshi Kani
  0 siblings, 0 replies; 85+ messages in thread
From: Toshi Kani @ 2015-07-09 23:43 UTC (permalink / raw)
  To: linux-arm-kernel

On Thu, 2015-07-09 at 03:40 +0200, Luis R. Rodriguez wrote:
> On Tue, Jul 07, 2015 at 05:10:58PM -0600, Toshi Kani wrote:
> > On Tue, 2015-07-07 at 18:07 +0200, Luis R. Rodriguez wrote:
> > > On Tue, Jul 07, 2015 at 11:13:30AM +0100, Russell King - ARM 
> > > Linux 
> > > wrote:
> >   :
> > > > On ARM, we (probably) have a lot of cases where ioremap() is 
> > > > used 
> > > > multiple
> > > > times for the same physical address space, so we shouldn't rule 
> > > > out 
> > > > having
> > > > multiple mappings of the same type.
> > > 
> > > Why is that done? Don't worry if you are not sure why but only 
> > > speculate of the
> > > practice's existence (sloppy drivers or lazy driver developers). 
> > > FWIW 
> > > for x86
> > > IIRC I ended up concluding that overlapping ioremap() calls with 
> > > the 
> > > same type
> > > would work but not if they differ in type.  Although I haven't 
> > > written a
> > > grammer rule to hunt down overlapping ioremap() I suspected its 
> > > use 
> > > was likely
> > > odd and likely should be reconsidered. Would this be true for ARM 
> > > too 
> > > ? Or are
> > > you saying this should be a feature ? I don't expect an answer 
> > > now 
> > > but I'm
> > > saying we *should* all together decide on this, and if you're 
> > > inclined to
> > > believe that this should ideally be avoided I'd like to hear 
> > > that. If 
> > > you feel
> > > strongly though this should be a feature I would like to know 
> > > why.
> > 
> > There are multiple mapping interfaces, and overlapping can happen 
> > among
> > them as well.  For instance, remap_pfn_range() (and 
> > io_remap_pfn_range(), which is the same as remap_pfn_range() on 
> > x86)
> > creates a mapping to user space. The same physical ranges may be
> > mapped to kernel and user spaces.  /dev/mem is one example that may
> > create a user space mapping to a physical address that is already
> > mapped with ioremap() by other module.
> 
> Thanks for the feedback. The restriction seems to be differing cache 
> types
> requirements, other than this, are there any other concerns ? For 
> instance are
> we completley happy with aliasing so long as cache types match 
> everywhere?  I'd
> expect no architecture would want cache types to differ when 
> aliasing, what
> should differ then I think would just be how to verify this and it 
> doesn't seem
> we may be doing this for all architectures.
> 
> Even for userspace we seem to be covered -- we enable userspace 
> mmap() calls to
> get their mapped space with a cache type, on the kernel we'd say use
> pgprot_writecombine() on the vma->vm_page_prot prior to the
> io_remap_pfn_range() -- that maps to remap_pfn_range() on x86 and as 
> you note
> that checks cache type via reserve_memtype() -- but only on x86...
> 
> Other than this differing cache type concern are we OK with aliasing 
> in
> userspace all the time ?
> 
> If we want to restrict aliasing either for the kernel or userspace 
> mapping
> we might be able to do it, I just want to know if we want to or not 
> care
> at all.

Yes, we allow to create multiple mappings to a same physical page as
long as their cache type is the same.  There are multiple use-cases
that depend on this ability.

> > pmem and DAX also create mappings to the same NVDIMM ranges.  DAX 
> > calls
> > vm_insert_mixed(), which is particularly a problematic since
> > vm_insert_mixed() does not verify aliasing.  ioremap() and 
> > remap_pfn_range()
> > call reserve_memtype() to verify aliasing on x86. 
> >  reserve_memtype() is
> > x86-specific and there is no arch-generic wrapper for such check.
> 
> As clarified by Matthew Wilcox via commit d92576f1167cacf7844 ("dax: 
> does not
> work correctly with virtual aliasing caches") caches are virtually 
> mapped for
> some architectures, it seems it should be possible to fix this for 
> DAX somehow
> though.

I simply described this DAX case as an example of how two modules might
request different cache types.  Yes, we should be able to fix this
case.

> > I think DAX could get a cache type from pmem to keep them in sync, 
> > though.
> 
> pmem is x86 specific right now, are other folks going to expose 
> something
> similar ? Otherwise we seem to only be addressing these deep concerns 
> for
> x86 so far.

pmem is a generic driver and is not x86-specific. 

Thanks,
-Toshi

^ permalink raw reply	[flat|nested] 85+ messages in thread

end of thread, other threads:[~2015-07-09 23:44 UTC | newest]

Thread overview: 85+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-06-22  8:24 [PATCH v5 0/6] pmem api, generic ioremap_cache, and memremap Dan Williams
2015-06-22  8:24 ` Dan Williams
2015-06-22  8:24 ` [PATCH v5 1/6] arch, drivers: don't include <asm/io.h> directly, use <linux/io.h> instead Dan Williams
2015-06-22  8:24   ` Dan Williams
2015-06-22 16:01   ` Christoph Hellwig
2015-06-22 16:01     ` Christoph Hellwig
2015-06-22  8:24 ` [PATCH v5 2/6] arch: unify ioremap prototypes and macro aliases Dan Williams
2015-06-22  8:24   ` Dan Williams
2015-06-22 16:10   ` Christoph Hellwig
2015-06-22 16:10     ` Christoph Hellwig
2015-06-22 17:12     ` Dan Williams
2015-06-22 17:12       ` Dan Williams
2015-06-23 10:07       ` Christoph Hellwig
2015-06-23 10:07         ` Christoph Hellwig
2015-06-23 15:04         ` Dan Williams
2015-06-23 15:04           ` Dan Williams
2015-06-24 12:24           ` Christoph Hellwig
2015-06-24 12:24             ` Christoph Hellwig
2015-06-30 22:57     ` Dan Williams
2015-06-30 22:57       ` Dan Williams
2015-06-30 22:57       ` Dan Williams
2015-07-01  6:23       ` Christoph Hellwig
2015-07-01  6:23         ` Christoph Hellwig
2015-07-01  6:23         ` Christoph Hellwig
2015-07-01  6:55         ` Geert Uytterhoeven
2015-07-01  6:55           ` Geert Uytterhoeven
2015-07-01  6:55           ` Geert Uytterhoeven
2015-07-01  6:59           ` Christoph Hellwig
2015-07-01  6:59             ` Christoph Hellwig
2015-07-01  6:59             ` Christoph Hellwig
2015-07-01  7:19             ` Geert Uytterhoeven
2015-07-01  7:19               ` Geert Uytterhoeven
2015-07-01  7:19               ` Geert Uytterhoeven
2015-07-01  7:28               ` Christoph Hellwig
2015-07-01  7:28                 ` Christoph Hellwig
2015-07-01  7:28                 ` Christoph Hellwig
2015-07-07  9:50                 ` Luis R. Rodriguez
2015-07-07  9:50                   ` Luis R. Rodriguez
2015-07-07  9:50                   ` Luis R. Rodriguez
2015-07-07 10:13                   ` Russell King - ARM Linux
2015-07-07 10:13                     ` Russell King - ARM Linux
2015-07-07 10:13                     ` Russell King - ARM Linux
2015-07-07 10:27                     ` Geert Uytterhoeven
2015-07-07 10:27                       ` Geert Uytterhoeven
2015-07-07 10:27                       ` Geert Uytterhoeven
2015-07-07 16:07                     ` Luis R. Rodriguez
2015-07-07 16:07                       ` Luis R. Rodriguez
2015-07-07 16:07                       ` Luis R. Rodriguez
2015-07-07 23:10                       ` Toshi Kani
2015-07-07 23:10                         ` Toshi Kani
2015-07-07 23:10                         ` Toshi Kani
2015-07-09  1:40                         ` Luis R. Rodriguez
2015-07-09  1:40                           ` Luis R. Rodriguez
2015-07-09  1:40                           ` Luis R. Rodriguez
2015-07-09 23:43                           ` Toshi Kani
2015-07-09 23:43                             ` Toshi Kani
2015-07-09 23:43                             ` Toshi Kani
2015-07-01  8:09           ` Russell King - ARM Linux
2015-07-01  8:09             ` Russell King - ARM Linux
2015-07-01  8:09             ` Russell King - ARM Linux
2015-07-01 16:47             ` Dan Williams
2015-07-01 16:47               ` Dan Williams
2015-07-01 16:47               ` Dan Williams
2015-07-09 18:54   ` Luis R. Rodriguez
2015-07-09 18:54     ` Luis R. Rodriguez
2015-06-22  8:24 ` [PATCH v5 3/6] cleanup IORESOURCE_CACHEABLE vs ioremap() Dan Williams
2015-06-22  8:24   ` Dan Williams
2015-06-22  8:24 ` [PATCH v5 4/6] devm: fix ioremap_cache() usage Dan Williams
2015-06-22  8:24   ` Dan Williams
2015-06-22  8:24 ` [PATCH v5 5/6] arch: introduce memremap_cache() and memremap_wt() Dan Williams
2015-06-22  8:24   ` Dan Williams
2015-06-22  8:24 ` [PATCH v5 6/6] arch, x86: pmem api for ensuring durability of persistent memory updates Dan Williams
2015-06-22  8:24   ` Dan Williams
2015-06-22 16:17   ` Christoph Hellwig
2015-06-22 16:17     ` Christoph Hellwig
2015-06-22 17:51     ` Dan Williams
2015-06-22 17:51       ` Dan Williams
2015-06-23 10:09       ` Christoph Hellwig
2015-06-23 10:09         ` Christoph Hellwig
2015-06-23 10:39     ` Richard Weinberger
2015-06-23 10:39       ` Richard Weinberger
2015-06-24 12:08       ` Christoph Hellwig
2015-06-24 12:08         ` Christoph Hellwig
2015-06-24 12:35         ` Richard Weinberger
2015-06-24 12:35           ` Richard Weinberger

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.