lib/bug.c: use common WARN helper
[linux-2.6-block.git] / kernel / memremap.c
index 97b31c774274f5009be2facaf4ffb37928944fb0..584febd13e2e3864a336c66998c69f85480d4211 100644 (file)
@@ -29,10 +29,10 @@ __weak void __iomem *ioremap_cache(resource_size_t offset, unsigned long size)
 
 static void *try_ram_remap(resource_size_t offset, size_t size)
 {
-       struct page *page = pfn_to_page(offset >> PAGE_SHIFT);
+       unsigned long pfn = PHYS_PFN(offset);
 
        /* In the simple case just return the existing linear address */
-       if (!PageHighMem(page))
+       if (pfn_valid(pfn) && !PageHighMem(pfn_to_page(pfn)))
                return __va(offset);
        return NULL; /* fallback to ioremap_cache */
 }
@@ -271,13 +271,17 @@ struct dev_pagemap *find_dev_pagemap(resource_size_t phys)
 void *devm_memremap_pages(struct device *dev, struct resource *res,
                struct percpu_ref *ref, struct vmem_altmap *altmap)
 {
-       int is_ram = region_intersects(res->start, resource_size(res),
-                                      IORESOURCE_SYSTEM_RAM, IORES_DESC_NONE);
        resource_size_t key, align_start, align_size, align_end;
        struct dev_pagemap *pgmap;
        struct page_map *page_map;
+       int error, nid, is_ram;
        unsigned long pfn;
-       int error, nid;
+
+       align_start = res->start & ~(SECTION_SIZE - 1);
+       align_size = ALIGN(res->start + resource_size(res), SECTION_SIZE)
+               - align_start;
+       is_ram = region_intersects(align_start, align_size,
+               IORESOURCE_SYSTEM_RAM, IORES_DESC_NONE);
 
        if (is_ram == REGION_MIXED) {
                WARN_ONCE(1, "%s attempted on mixed region %pr\n",
@@ -315,8 +319,6 @@ void *devm_memremap_pages(struct device *dev, struct resource *res,
 
        mutex_lock(&pgmap_lock);
        error = 0;
-       align_start = res->start & ~(SECTION_SIZE - 1);
-       align_size = ALIGN(resource_size(res), SECTION_SIZE);
        align_end = align_start + align_size - 1;
        for (key = align_start; key <= align_end; key += SECTION_SIZE) {
                struct dev_pagemap *dup;
@@ -352,8 +354,13 @@ void *devm_memremap_pages(struct device *dev, struct resource *res,
        for_each_device_pfn(pfn, page_map) {
                struct page *page = pfn_to_page(pfn);
 
-               /* ZONE_DEVICE pages must never appear on a slab lru */
-               list_force_poison(&page->lru);
+               /*
+                * ZONE_DEVICE pages union ->lru with a ->pgmap back
+                * pointer.  It is a bug if a ZONE_DEVICE page is ever
+                * freed or placed on a driver-private list.  Seed the
+                * storage with LIST_POISON* values.
+                */
+               list_del(&page->lru);
                page->pgmap = pgmap;
        }
        devres_add(dev, page_map);
@@ -384,7 +391,7 @@ struct vmem_altmap *to_vmem_altmap(unsigned long memmap_start)
        /*
         * 'memmap_start' is the virtual address for the first "struct
         * page" in this range of the vmemmap array.  In the case of
-        * CONFIG_SPARSE_VMEMMAP a page_to_pfn conversion is simple
+        * CONFIG_SPARSEMEM_VMEMMAP a page_to_pfn conversion is simple
         * pointer arithmetic, so we can perform this to_vmem_altmap()
         * conversion without concern for the initialization state of
         * the struct page fields.
@@ -393,7 +400,7 @@ struct vmem_altmap *to_vmem_altmap(unsigned long memmap_start)
        struct dev_pagemap *pgmap;
 
        /*
-        * Uncoditionally retrieve a dev_pagemap associated with the
+        * Unconditionally retrieve a dev_pagemap associated with the
         * given physical address, this is only for use in the
         * arch_{add|remove}_memory() for setting up and tearing down
         * the memmap.