Skip to content

Commit

Permalink
Merge tag 'libnvdimm-for-4.3' of git://git.kernel.org/pub/scm/linux/k…
Browse files Browse the repository at this point in the history
…ernel/git/nvdimm/nvdimm

Pull libnvdimm updates from Dan Williams:
 "This update has successfully completed a 0day-kbuild run and has
  appeared in a linux-next release.  The changes outside of the typical
  drivers/nvdimm/ and drivers/acpi/nfit.[ch] paths are related to the
  removal of IORESOURCE_CACHEABLE, the introduction of memremap(), and
  the introduction of ZONE_DEVICE + devm_memremap_pages().

  Summary:

   - Introduce ZONE_DEVICE and devm_memremap_pages() as a generic
     mechanism for adding device-driver-discovered memory regions to the
     kernel's direct map.

     This facility is used by the pmem driver to enable pfn_to_page()
     operations on the page frames returned by DAX ('direct_access' in
     'struct block_device_operations').

     For now, the 'memmap' allocation for these "device" pages comes
     from "System RAM".  Support for allocating the memmap from device
     memory will arrive in a later kernel.

   - Introduce memremap() to replace usages of ioremap_cache() and
     ioremap_wt().  memremap() drops the __iomem annotation for these
     mappings to memory that do not have i/o side effects.  The
     replacement of ioremap_cache() with memremap() is limited to the
     pmem driver to ease merging the api change in v4.3.

     Completion of the conversion is targeted for v4.4.

   - Similar to the usage of memcpy_to_pmem() + wmb_pmem() in the pmem
     driver, update the VFS DAX implementation and PMEM api to provide
     persistence guarantees for kernel operations on a DAX mapping.

   - Convert the ACPI NFIT 'BLK' driver to map the block apertures as
     cacheable to improve performance.

   - Miscellaneous updates and fixes to libnvdimm including support for
     issuing "address range scrub" commands, clarifying the optimal
     'sector size' of pmem devices, a clarification of the usage of the
     ACPI '_STA' (status) property for DIMM devices, and other minor
     fixes"

* tag 'libnvdimm-for-4.3' of git://git.kernel.org/pub/scm/linux/kernel/git/nvdimm/nvdimm: (34 commits)
  libnvdimm, pmem: direct map legacy pmem by default
  libnvdimm, pmem: 'struct page' for pmem
  libnvdimm, pfn: 'struct page' provider infrastructure
  x86, pmem: clarify that ARCH_HAS_PMEM_API implies PMEM mapped WB
  add devm_memremap_pages
  mm: ZONE_DEVICE for "device memory"
  mm: move __phys_to_pfn and __pfn_to_phys to asm/generic/memory_model.h
  dax: drop size parameter to ->direct_access()
  nd_blk: change aperture mapping from WC to WB
  nvdimm: change to use generic kvfree()
  pmem, dax: have direct_access use __pmem annotation
  dax: update I/O path to do proper PMEM flushing
  pmem: add copy_from_iter_pmem() and clear_pmem()
  pmem, x86: clean up conditional pmem includes
  pmem: remove layer when calling arch_has_wmb_pmem()
  pmem, x86: move x86 PMEM API to new pmem.h header
  libnvdimm, e820: make CONFIG_X86_PMEM_LEGACY a tristate option
  pmem: switch to devm_ allocations
  devres: add devm_memremap
  libnvdimm, btt: write and validate parent_uuid
  ...
  • Loading branch information
torvalds committed Sep 8, 2015
2 parents d9241b2 + 004f1af commit 12f03ee
Show file tree
Hide file tree
Showing 92 changed files with 2,142 additions and 745 deletions.
3 changes: 2 additions & 1 deletion Documentation/filesystems/Locking
Original file line number Diff line number Diff line change
Expand Up @@ -397,7 +397,8 @@ prototypes:
int (*release) (struct gendisk *, fmode_t);
int (*ioctl) (struct block_device *, fmode_t, unsigned, unsigned long);
int (*compat_ioctl) (struct block_device *, fmode_t, unsigned, unsigned long);
int (*direct_access) (struct block_device *, sector_t, void **, unsigned long *);
int (*direct_access) (struct block_device *, sector_t, void __pmem **,
unsigned long *);
int (*media_changed) (struct gendisk *);
void (*unlock_native_capacity) (struct gendisk *);
int (*revalidate_disk) (struct gendisk *);
Expand Down
1 change: 1 addition & 0 deletions MAINTAINERS
Original file line number Diff line number Diff line change
Expand Up @@ -6229,6 +6229,7 @@ Q: https://patchwork.kernel.org/project/linux-nvdimm/list/
S: Supported
F: drivers/nvdimm/pmem.c
F: include/linux/pmem.h
F: arch/*/include/asm/pmem.h

LINUX FOR IBM pSERIES (RS/6000)
M: Paul Mackerras <[email protected]>
Expand Down
6 changes: 0 additions & 6 deletions arch/arm/include/asm/memory.h
Original file line number Diff line number Diff line change
Expand Up @@ -118,12 +118,6 @@
#define DTCM_OFFSET UL(0xfffe8000)
#endif

/*
* Convert a physical address to a Page Frame Number and back
*/
#define __phys_to_pfn(paddr) ((unsigned long)((paddr) >> PAGE_SHIFT))
#define __pfn_to_phys(pfn) ((phys_addr_t)(pfn) << PAGE_SHIFT)

/*
* Convert a page to/from a physical address
*/
Expand Down
2 changes: 1 addition & 1 deletion arch/arm/mach-clps711x/board-cdb89712.c
Original file line number Diff line number Diff line change
Expand Up @@ -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 = {
Expand Down
2 changes: 1 addition & 1 deletion arch/arm/mach-shmobile/pm-rcar.c
Original file line number Diff line number Diff line change
Expand Up @@ -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 Common */
Expand Down
6 changes: 0 additions & 6 deletions arch/arm64/include/asm/memory.h
Original file line number Diff line number Diff line change
Expand Up @@ -80,12 +80,6 @@
#define __virt_to_phys(x) (((phys_addr_t)(x) - PAGE_OFFSET + PHYS_OFFSET))
#define __phys_to_virt(x) ((unsigned long)((x) - PHYS_OFFSET + PAGE_OFFSET))

/*
* Convert a physical address to a Page Frame Number and back
*/
#define __phys_to_pfn(paddr) ((unsigned long)((paddr) >> PAGE_SHIFT))
#define __pfn_to_phys(pfn) ((phys_addr_t)(pfn) << PAGE_SHIFT)

/*
* Convert a page to/from a physical address
*/
Expand Down
1 change: 1 addition & 0 deletions arch/ia64/include/asm/io.h
Original file line number Diff line number Diff line change
Expand Up @@ -435,6 +435,7 @@ static inline void __iomem * ioremap_cache (unsigned long phys_addr, unsigned lo
{
return ioremap(phys_addr, size);
}
#define ioremap_cache ioremap_cache


/*
Expand Down
2 changes: 1 addition & 1 deletion arch/ia64/kernel/cyclone.c
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
4 changes: 2 additions & 2 deletions arch/ia64/mm/init.c
Original file line number Diff line number Diff line change
Expand Up @@ -645,7 +645,7 @@ mem_init (void)
}

#ifdef CONFIG_MEMORY_HOTPLUG
int arch_add_memory(int nid, u64 start, u64 size)
int arch_add_memory(int nid, u64 start, u64 size, bool for_device)
{
pg_data_t *pgdat;
struct zone *zone;
Expand All @@ -656,7 +656,7 @@ int arch_add_memory(int nid, u64 start, u64 size)
pgdat = NODE_DATA(nid);

zone = pgdat->node_zones +
zone_for_memory(nid, start, size, ZONE_NORMAL);
zone_for_memory(nid, start, size, ZONE_NORMAL, for_device);
ret = __add_pages(nid, zone, start_pfn, nr_pages);

if (ret)
Expand Down
2 changes: 1 addition & 1 deletion arch/powerpc/kernel/pci_of_scan.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
4 changes: 2 additions & 2 deletions arch/powerpc/mm/mem.c
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,7 @@ int memory_add_physaddr_to_nid(u64 start)
}
#endif

int arch_add_memory(int nid, u64 start, u64 size)
int arch_add_memory(int nid, u64 start, u64 size, bool for_device)
{
struct pglist_data *pgdata;
struct zone *zone;
Expand All @@ -128,7 +128,7 @@ int arch_add_memory(int nid, u64 start, u64 size)

/* this should work for most non-highmem platforms */
zone = pgdata->node_zones +
zone_for_memory(nid, start, size, 0);
zone_for_memory(nid, start, size, 0, for_device);

return __add_pages(nid, zone, start_pfn, nr_pages);
}
Expand Down
7 changes: 4 additions & 3 deletions arch/powerpc/sysdev/axonram.c
Original file line number Diff line number Diff line change
Expand Up @@ -141,13 +141,14 @@ axon_ram_make_request(struct request_queue *queue, struct bio *bio)
*/
static long
axon_ram_direct_access(struct block_device *device, sector_t sector,
void **kaddr, unsigned long *pfn, long size)
void __pmem **kaddr, unsigned long *pfn)
{
struct axon_ram_bank *bank = device->bd_disk->private_data;
loff_t offset = (loff_t)sector << AXON_RAM_SECTOR_SHIFT;
void *addr = (void *)(bank->ph_addr + offset);

*kaddr = (void *)(bank->ph_addr + offset);
*pfn = virt_to_phys(*kaddr) >> PAGE_SHIFT;
*kaddr = (void __pmem *)addr;
*pfn = virt_to_phys(addr) >> PAGE_SHIFT;

return bank->size - offset;
}
Expand Down
2 changes: 1 addition & 1 deletion arch/s390/mm/init.c
Original file line number Diff line number Diff line change
Expand Up @@ -169,7 +169,7 @@ void __init free_initrd_mem(unsigned long start, unsigned long end)
#endif

#ifdef CONFIG_MEMORY_HOTPLUG
int arch_add_memory(int nid, u64 start, u64 size)
int arch_add_memory(int nid, u64 start, u64 size, bool for_device)
{
unsigned long normal_end_pfn = PFN_DOWN(memblock_end_of_DRAM());
unsigned long dma_end_pfn = PFN_DOWN(MAX_DMA_ADDRESS);
Expand Down
1 change: 1 addition & 0 deletions arch/sh/include/asm/io.h
Original file line number Diff line number Diff line change
Expand Up @@ -342,6 +342,7 @@ 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 *
Expand Down
5 changes: 3 additions & 2 deletions arch/sh/mm/init.c
Original file line number Diff line number Diff line change
Expand Up @@ -485,7 +485,7 @@ void free_initrd_mem(unsigned long start, unsigned long end)
#endif

#ifdef CONFIG_MEMORY_HOTPLUG
int arch_add_memory(int nid, u64 start, u64 size)
int arch_add_memory(int nid, u64 start, u64 size, bool for_device)
{
pg_data_t *pgdat;
unsigned long start_pfn = PFN_DOWN(start);
Expand All @@ -496,7 +496,8 @@ int arch_add_memory(int nid, u64 start, u64 size)

/* We only have ZONE_NORMAL, so this is easy.. */
ret = __add_pages(nid, pgdat->node_zones +
zone_for_memory(nid, start, size, ZONE_NORMAL),
zone_for_memory(nid, start, size, ZONE_NORMAL,
for_device),
start_pfn, nr_pages);
if (unlikely(ret))
printk("%s: Failed, __add_pages() == %d\n", __func__, ret);
Expand Down
3 changes: 1 addition & 2 deletions arch/sparc/kernel/pci.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
2 changes: 1 addition & 1 deletion arch/tile/mm/init.c
Original file line number Diff line number Diff line change
Expand Up @@ -863,7 +863,7 @@ void __init mem_init(void)
* memory to the highmem for now.
*/
#ifndef CONFIG_NEED_MULTIPLE_NODES
int arch_add_memory(u64 start, u64 size)
int arch_add_memory(u64 start, u64 size, bool for_device)
{
struct pglist_data *pgdata = &contig_page_data;
struct zone *zone = pgdata->node_zones + MAX_NR_ZONES-1;
Expand Down
6 changes: 0 additions & 6 deletions arch/unicore32/include/asm/memory.h
Original file line number Diff line number Diff line change
Expand Up @@ -60,12 +60,6 @@
#define __phys_to_virt(x) ((x) - PHYS_OFFSET + PAGE_OFFSET)
#endif

/*
* Convert a physical address to a Page Frame Number and back
*/
#define __phys_to_pfn(paddr) ((paddr) >> PAGE_SHIFT)
#define __pfn_to_phys(pfn) ((pfn) << PAGE_SHIFT)

/*
* Convert a page to/from a physical address
*/
Expand Down
9 changes: 7 additions & 2 deletions arch/x86/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,8 @@ config X86
select ARCH_HAS_ELF_RANDOMIZE
select ARCH_HAS_FAST_MULTIPLIER
select ARCH_HAS_GCOV_PROFILE_ALL
select ARCH_HAS_PMEM_API
select ARCH_HAS_PMEM_API if X86_64
select ARCH_HAS_MMIO_FLUSH
select ARCH_HAS_SG_CHAIN
select ARCH_HAVE_NMI_SAFE_CMPXCHG
select ARCH_MIGHT_HAVE_ACPI_PDC if ACPI
Expand Down Expand Up @@ -1450,10 +1451,14 @@ config ILLEGAL_POINTER_VALUE

source "mm/Kconfig"

config X86_PMEM_LEGACY_DEVICE
bool

config X86_PMEM_LEGACY
bool "Support non-standard NVDIMMs and ADR protected memory"
tristate "Support non-standard NVDIMMs and ADR protected memory"
depends on PHYS_ADDR_T_64BIT
depends on BLK_DEV
select X86_PMEM_LEGACY_DEVICE
select LIBNVDIMM
help
Treat memory marked using the non-standard e820 type of 12 as used
Expand Down
73 changes: 2 additions & 71 deletions arch/x86/include/asm/cacheflush.h
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,8 @@ int set_pages_rw(struct page *page, int numpages);

void clflush_cache_range(void *addr, unsigned int size);

#define mmio_flush_range(addr, size) clflush_cache_range(addr, size)

#ifdef CONFIG_DEBUG_RODATA
void mark_rodata_ro(void);
extern const int rodata_test_data;
Expand All @@ -109,75 +111,4 @@ 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 */
6 changes: 0 additions & 6 deletions arch/x86/include/asm/io.h
Original file line number Diff line number Diff line change
Expand Up @@ -250,12 +250,6 @@ 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);
Expand Down
Loading

0 comments on commit 12f03ee

Please sign in to comment.