Merge remote-tracking branch 'nvdimm/libnvdimm-for-next'
authorStephen Rothwell <sfr@canb.auug.org.au>
Thu, 5 Nov 2015 04:33:45 +0000 (15:33 +1100)
committerStephen Rothwell <sfr@canb.auug.org.au>
Thu, 5 Nov 2015 04:33:45 +0000 (15:33 +1100)
arch/x86/mm/init.c
arch/x86/mm/init_64.c
drivers/base/devres.c
drivers/nvdimm/pmem.c
include/linux/device.h
include/linux/pmem.h
kernel/memremap.c

index 1f37cb2..493f541 100644 (file)
@@ -354,7 +354,7 @@ static int __meminit split_mem_range(struct map_range *mr, int nr_range,
        }
 
        for (i = 0; i < nr_range; i++)
-               printk(KERN_DEBUG " [mem %#010lx-%#010lx] page %s\n",
+               pr_debug(" [mem %#010lx-%#010lx] page %s\n",
                                mr[i].start, mr[i].end - 1,
                                page_size_string(&mr[i]));
 
@@ -401,7 +401,7 @@ unsigned long __init_refok init_memory_mapping(unsigned long start,
        unsigned long ret = 0;
        int nr_range, i;
 
-       pr_info("init_memory_mapping: [mem %#010lx-%#010lx]\n",
+       pr_debug("init_memory_mapping: [mem %#010lx-%#010lx]\n",
               start, end - 1);
 
        memset(mr, 0, sizeof(mr));
index 5ed62ef..ec081fe 100644 (file)
@@ -1270,7 +1270,7 @@ static int __meminit vmemmap_populate_hugepages(unsigned long start,
                                /* check to see if we have contiguous blocks */
                                if (p_end != p || node_start != node) {
                                        if (p_start)
-                                               printk(KERN_DEBUG " [%lx-%lx] PMD -> [%p-%p] on node %d\n",
+                                               pr_debug(" [%lx-%lx] PMD -> [%p-%p] on node %d\n",
                                                       addr_start, addr_end-1, p_start, p_end-1, node_start);
                                        addr_start = addr;
                                        node_start = node;
@@ -1368,7 +1368,7 @@ void register_page_bootmem_memmap(unsigned long section_nr,
 void __meminit vmemmap_populate_print_last(void)
 {
        if (p_start) {
-               printk(KERN_DEBUG " [%lx-%lx] PMD -> [%p-%p] on node %d\n",
+               pr_debug(" [%lx-%lx] PMD -> [%p-%p] on node %d\n",
                        addr_start, addr_end-1, p_start, p_end-1, node_start);
                p_start = NULL;
                p_end = NULL;
index 8754646..8fc654f 100644 (file)
@@ -82,12 +82,12 @@ static struct devres_group * node_to_group(struct devres_node *node)
 }
 
 static __always_inline struct devres * alloc_dr(dr_release_t release,
-                                               size_t size, gfp_t gfp)
+                                               size_t size, gfp_t gfp, int nid)
 {
        size_t tot_size = sizeof(struct devres) + size;
        struct devres *dr;
 
-       dr = kmalloc_track_caller(tot_size, gfp);
+       dr = kmalloc_node_track_caller(tot_size, gfp, nid);
        if (unlikely(!dr))
                return NULL;
 
@@ -106,24 +106,25 @@ static void add_dr(struct device *dev, struct devres_node *node)
 }
 
 #ifdef CONFIG_DEBUG_DEVRES
-void * __devres_alloc(dr_release_t release, size_t size, gfp_t gfp,
+void * __devres_alloc_node(dr_release_t release, size_t size, gfp_t gfp, int nid,
                      const char *name)
 {
        struct devres *dr;
 
-       dr = alloc_dr(release, size, gfp | __GFP_ZERO);
+       dr = alloc_dr(release, size, gfp | __GFP_ZERO, nid);
        if (unlikely(!dr))
                return NULL;
        set_node_dbginfo(&dr->node, name, size);
        return dr->data;
 }
-EXPORT_SYMBOL_GPL(__devres_alloc);
+EXPORT_SYMBOL_GPL(__devres_alloc_node);
 #else
 /**
  * devres_alloc - Allocate device resource data
  * @release: Release function devres will be associated with
  * @size: Allocation size
  * @gfp: Allocation flags
+ * @nid: NUMA node
  *
  * Allocate devres of @size bytes.  The allocated area is zeroed, then
  * associated with @release.  The returned pointer can be passed to
@@ -132,16 +133,16 @@ EXPORT_SYMBOL_GPL(__devres_alloc);
  * RETURNS:
  * Pointer to allocated devres on success, NULL on failure.
  */
-void * devres_alloc(dr_release_t release, size_t size, gfp_t gfp)
+void * devres_alloc_node(dr_release_t release, size_t size, gfp_t gfp, int nid)
 {
        struct devres *dr;
 
-       dr = alloc_dr(release, size, gfp | __GFP_ZERO);
+       dr = alloc_dr(release, size, gfp | __GFP_ZERO, nid);
        if (unlikely(!dr))
                return NULL;
        return dr->data;
 }
-EXPORT_SYMBOL_GPL(devres_alloc);
+EXPORT_SYMBOL_GPL(devres_alloc_node);
 #endif
 
 /**
@@ -776,7 +777,7 @@ void * devm_kmalloc(struct device *dev, size_t size, gfp_t gfp)
        struct devres *dr;
 
        /* use raw alloc_dr for kmalloc caller tracing */
-       dr = alloc_dr(devm_kmalloc_release, size, gfp);
+       dr = alloc_dr(devm_kmalloc_release, size, gfp, dev_to_node(dev));
        if (unlikely(!dr))
                return NULL;
 
index 0ba6a97..349f03e 100644 (file)
@@ -150,18 +150,15 @@ static struct pmem_device *pmem_alloc(struct device *dev,
                return ERR_PTR(-EBUSY);
        }
 
-       if (pmem_should_map_pages(dev)) {
-               void *addr = devm_memremap_pages(dev, res);
+       if (pmem_should_map_pages(dev))
+               pmem->virt_addr = (void __pmem *) devm_memremap_pages(dev, res);
+       else
+               pmem->virt_addr = (void __pmem *) devm_memremap(dev,
+                               pmem->phys_addr, pmem->size,
+                               ARCH_MEMREMAP_PMEM);
 
-               if (IS_ERR(addr))
-                       return addr;
-               pmem->virt_addr = (void __pmem *) addr;
-       } else {
-               pmem->virt_addr = memremap_pmem(dev, pmem->phys_addr,
-                               pmem->size);
-               if (!pmem->virt_addr)
-                       return ERR_PTR(-ENXIO);
-       }
+       if (IS_ERR(pmem->virt_addr))
+               return (void __force *) pmem->virt_addr;
 
        return pmem;
 }
@@ -179,9 +176,10 @@ static void pmem_detach_disk(struct pmem_device *pmem)
 static int pmem_attach_disk(struct device *dev,
                struct nd_namespace_common *ndns, struct pmem_device *pmem)
 {
+       int nid = dev_to_node(dev);
        struct gendisk *disk;
 
-       pmem->pmem_queue = blk_alloc_queue(GFP_KERNEL);
+       pmem->pmem_queue = blk_alloc_queue_node(GFP_KERNEL, nid);
        if (!pmem->pmem_queue)
                return -ENOMEM;
 
@@ -191,7 +189,7 @@ static int pmem_attach_disk(struct device *dev,
        blk_queue_bounce_limit(pmem->pmem_queue, BLK_BOUNCE_ANY);
        queue_flag_set_unlocked(QUEUE_FLAG_NONROT, pmem->pmem_queue);
 
-       disk = alloc_disk(0);
+       disk = alloc_disk_node(0, nid);
        if (!disk) {
                blk_cleanup_queue(pmem->pmem_queue);
                return -ENOMEM;
@@ -363,8 +361,8 @@ static int nvdimm_namespace_attach_pfn(struct nd_namespace_common *ndns)
 
        /* establish pfn range for lookup, and switch to direct map */
        pmem = dev_get_drvdata(dev);
-       memunmap_pmem(dev, pmem->virt_addr);
-       pmem->virt_addr = (void __pmem *)devm_memremap_pages(dev, &nsio->res);
+       devm_memunmap(dev, (void __force *) pmem->virt_addr);
+       pmem->virt_addr = (void __pmem *) devm_memremap_pages(dev, &nsio->res);
        if (IS_ERR(pmem->virt_addr)) {
                rc = PTR_ERR(pmem->virt_addr);
                goto err;
index 5d7bc63..b8f411b 100644 (file)
@@ -604,13 +604,21 @@ typedef void (*dr_release_t)(struct device *dev, void *res);
 typedef int (*dr_match_t)(struct device *dev, void *res, void *match_data);
 
 #ifdef CONFIG_DEBUG_DEVRES
-extern void *__devres_alloc(dr_release_t release, size_t size, gfp_t gfp,
-                            const char *name);
+extern void *__devres_alloc_node(dr_release_t release, size_t size, gfp_t gfp,
+                                int nid, const char *name);
 #define devres_alloc(release, size, gfp) \
-       __devres_alloc(release, size, gfp, #release)
+       __devres_alloc_node(release, size, gfp, NUMA_NO_NODE, #release)
+#define devres_alloc_node(release, size, gfp, nid) \
+       __devres_alloc_node(release, size, gfp, nid, #release)
 #else
-extern void *devres_alloc(dr_release_t release, size_t size, gfp_t gfp);
+extern void *devres_alloc_node(dr_release_t release, size_t size, gfp_t gfp,
+                              int nid);
+static inline void *devres_alloc(dr_release_t release, size_t size, gfp_t gfp)
+{
+       return devres_alloc_node(release, size, gfp, NUMA_NO_NODE);
+}
 #endif
+
 extern void devres_for_each_res(struct device *dev, dr_release_t release,
                                dr_match_t match, void *match_data,
                                void (*fn)(struct device *, void *, void *),
index 85f810b..acfea8c 100644 (file)
@@ -65,11 +65,6 @@ static inline void memcpy_from_pmem(void *dst, void __pmem const *src, size_t si
        memcpy(dst, (void __force const *) src, size);
 }
 
-static inline void memunmap_pmem(struct device *dev, void __pmem *addr)
-{
-       devm_memunmap(dev, (void __force *) addr);
-}
-
 static inline bool arch_has_pmem_api(void)
 {
        return IS_ENABLED(CONFIG_ARCH_HAS_PMEM_API);
@@ -93,7 +88,7 @@ static inline bool arch_has_wmb_pmem(void)
  * 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
+ * ARCH_MEMREMAP_PMEM + default_memcpy_to_pmem is sufficient for
  * making data durable relative to i/o completion.
  */
 static inline void default_memcpy_to_pmem(void __pmem *dst, const void *src,
@@ -117,25 +112,6 @@ static inline void default_clear_pmem(void __pmem *addr, size_t size)
 }
 
 /**
- * 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(struct device *dev,
-               resource_size_t offset, unsigned long size)
-{
-       return (void __pmem *) devm_memremap(dev, offset, size,
-                       ARCH_MEMREMAP_PMEM);
-}
-
-/**
  * memcpy_to_pmem - copy data to persistent memory
  * @dst: destination buffer for the copy
  * @src: source buffer for the copy
index 9d6b555..7658d32 100644 (file)
@@ -124,9 +124,10 @@ void *devm_memremap(struct device *dev, resource_size_t offset,
 {
        void **ptr, *addr;
 
-       ptr = devres_alloc(devm_memremap_release, sizeof(*ptr), GFP_KERNEL);
+       ptr = devres_alloc_node(devm_memremap_release, sizeof(*ptr), GFP_KERNEL,
+                       dev_to_node(dev));
        if (!ptr)
-               return NULL;
+               return ERR_PTR(-ENOMEM);
 
        addr = memremap(offset, size, flags);
        if (addr) {
@@ -141,9 +142,8 @@ EXPORT_SYMBOL(devm_memremap);
 
 void devm_memunmap(struct device *dev, void *addr)
 {
-       WARN_ON(devres_destroy(dev, devm_memremap_release, devm_memremap_match,
-                              addr));
-       memunmap(addr);
+       WARN_ON(devres_release(dev, devm_memremap_release,
+                               devm_memremap_match, addr));
 }
 EXPORT_SYMBOL(devm_memunmap);
 
@@ -176,8 +176,8 @@ void *devm_memremap_pages(struct device *dev, struct resource *res)
        if (is_ram == REGION_INTERSECTS)
                return __va(res->start);
 
-       page_map = devres_alloc(devm_memremap_pages_release,
-                       sizeof(*page_map), GFP_KERNEL);
+       page_map = devres_alloc_node(devm_memremap_pages_release,
+                       sizeof(*page_map), GFP_KERNEL, dev_to_node(dev));
        if (!page_map)
                return ERR_PTR(-ENOMEM);
 
@@ -185,7 +185,7 @@ void *devm_memremap_pages(struct device *dev, struct resource *res)
 
        nid = dev_to_node(dev);
        if (nid < 0)
-               nid = 0;
+               nid = numa_mem_id();
 
        error = arch_add_memory(nid, res->start, resource_size(res), true);
        if (error) {