diff options
author | Dan Williams <dan.j.williams@intel.com> | 2016-03-09 17:08:13 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2016-03-09 18:43:42 -0500 |
commit | 5f29a77cd95771edebbf41e5800fdd557c69302a (patch) | |
tree | 9358ffafdb0863e77d19166ca09b78cb76803287 /kernel/memremap.c | |
parent | d77a117e6871ff78a06def46583d23752593de60 (diff) |
mm: fix mixed zone detection in devm_memremap_pages
The check for whether we overlap "System RAM" needs to be done at
section granularity. For example a system with the following mapping:
100000000-37bffffff : System RAM
37c000000-837ffffff : Persistent Memory
...is unable to use devm_memremap_pages() as it would result in two
zones colliding within a given section.
Signed-off-by: Dan Williams <dan.j.williams@intel.com>
Cc: Ross Zwisler <ross.zwisler@linux.intel.com>
Reviewed-by: Toshi Kani <toshi.kani@hpe.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'kernel/memremap.c')
-rw-r--r-- | kernel/memremap.c | 11 |
1 files changed, 6 insertions, 5 deletions
diff --git a/kernel/memremap.c b/kernel/memremap.c index 778191e3e887..60baf4d3401e 100644 --- a/kernel/memremap.c +++ b/kernel/memremap.c | |||
@@ -270,13 +270,16 @@ struct dev_pagemap *find_dev_pagemap(resource_size_t phys) | |||
270 | void *devm_memremap_pages(struct device *dev, struct resource *res, | 270 | void *devm_memremap_pages(struct device *dev, struct resource *res, |
271 | struct percpu_ref *ref, struct vmem_altmap *altmap) | 271 | struct percpu_ref *ref, struct vmem_altmap *altmap) |
272 | { | 272 | { |
273 | int is_ram = region_intersects(res->start, resource_size(res), | ||
274 | "System RAM"); | ||
275 | resource_size_t key, align_start, align_size, align_end; | 273 | resource_size_t key, align_start, align_size, align_end; |
276 | struct dev_pagemap *pgmap; | 274 | struct dev_pagemap *pgmap; |
277 | struct page_map *page_map; | 275 | struct page_map *page_map; |
276 | int error, nid, is_ram; | ||
278 | unsigned long pfn; | 277 | unsigned long pfn; |
279 | int error, nid; | 278 | |
279 | align_start = res->start & ~(SECTION_SIZE - 1); | ||
280 | align_size = ALIGN(res->start + resource_size(res), SECTION_SIZE) | ||
281 | - align_start; | ||
282 | is_ram = region_intersects(align_start, align_size, "System RAM"); | ||
280 | 283 | ||
281 | if (is_ram == REGION_MIXED) { | 284 | if (is_ram == REGION_MIXED) { |
282 | WARN_ONCE(1, "%s attempted on mixed region %pr\n", | 285 | WARN_ONCE(1, "%s attempted on mixed region %pr\n", |
@@ -314,8 +317,6 @@ void *devm_memremap_pages(struct device *dev, struct resource *res, | |||
314 | 317 | ||
315 | mutex_lock(&pgmap_lock); | 318 | mutex_lock(&pgmap_lock); |
316 | error = 0; | 319 | error = 0; |
317 | align_start = res->start & ~(SECTION_SIZE - 1); | ||
318 | align_size = ALIGN(resource_size(res), SECTION_SIZE); | ||
319 | align_end = align_start + align_size - 1; | 320 | align_end = align_start + align_size - 1; |
320 | for (key = align_start; key <= align_end; key += SECTION_SIZE) { | 321 | for (key = align_start; key <= align_end; key += SECTION_SIZE) { |
321 | struct dev_pagemap *dup; | 322 | struct dev_pagemap *dup; |