aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDan Williams <dan.j.williams@intel.com>2018-02-06 22:34:11 -0500
committerDan Williams <dan.j.williams@intel.com>2018-03-02 22:34:50 -0500
commit949b93250a566cc7a578b4f829cf76b70d19a62c (patch)
tree4c0dafd885b4d37cc1edd6cd295986746391e624
parent5fdf8e5ba5666fe153bd61f851a40078a6347822 (diff)
memremap: fix softlockup reports at teardown
The cond_resched() currently in the setup path needs to be duplicated in the teardown path. Rather than require each instance of for_each_device_pfn() to open code the same sequence, embed it in the helper. Link: https://github.com/intel/ixpdimm_sw/issues/11 Cc: "Jérôme Glisse" <jglisse@redhat.com> Cc: Michal Hocko <mhocko@suse.com> Cc: Christoph Hellwig <hch@lst.de> Cc: <stable@vger.kernel.org> Fixes: 71389703839e ("mm, zone_device: Replace {get, put}_zone_device_page()...") Signed-off-by: Dan Williams <dan.j.williams@intel.com>
-rw-r--r--kernel/memremap.c15
1 files changed, 10 insertions, 5 deletions
diff --git a/kernel/memremap.c b/kernel/memremap.c
index 4849be5f9b3c..4dd4274cabe2 100644
--- a/kernel/memremap.c
+++ b/kernel/memremap.c
@@ -275,8 +275,15 @@ static unsigned long pfn_end(struct dev_pagemap *pgmap)
275 return (res->start + resource_size(res)) >> PAGE_SHIFT; 275 return (res->start + resource_size(res)) >> PAGE_SHIFT;
276} 276}
277 277
278static unsigned long pfn_next(unsigned long pfn)
279{
280 if (pfn % 1024 == 0)
281 cond_resched();
282 return pfn + 1;
283}
284
278#define for_each_device_pfn(pfn, map) \ 285#define for_each_device_pfn(pfn, map) \
279 for (pfn = pfn_first(map); pfn < pfn_end(map); pfn++) 286 for (pfn = pfn_first(map); pfn < pfn_end(map); pfn = pfn_next(pfn))
280 287
281static void devm_memremap_pages_release(void *data) 288static void devm_memremap_pages_release(void *data)
282{ 289{
@@ -337,10 +344,10 @@ void *devm_memremap_pages(struct device *dev, struct dev_pagemap *pgmap)
337 resource_size_t align_start, align_size, align_end; 344 resource_size_t align_start, align_size, align_end;
338 struct vmem_altmap *altmap = pgmap->altmap_valid ? 345 struct vmem_altmap *altmap = pgmap->altmap_valid ?
339 &pgmap->altmap : NULL; 346 &pgmap->altmap : NULL;
347 struct resource *res = &pgmap->res;
340 unsigned long pfn, pgoff, order; 348 unsigned long pfn, pgoff, order;
341 pgprot_t pgprot = PAGE_KERNEL; 349 pgprot_t pgprot = PAGE_KERNEL;
342 int error, nid, is_ram, i = 0; 350 int error, nid, is_ram;
343 struct resource *res = &pgmap->res;
344 351
345 align_start = res->start & ~(SECTION_SIZE - 1); 352 align_start = res->start & ~(SECTION_SIZE - 1);
346 align_size = ALIGN(res->start + resource_size(res), SECTION_SIZE) 353 align_size = ALIGN(res->start + resource_size(res), SECTION_SIZE)
@@ -409,8 +416,6 @@ void *devm_memremap_pages(struct device *dev, struct dev_pagemap *pgmap)
409 list_del(&page->lru); 416 list_del(&page->lru);
410 page->pgmap = pgmap; 417 page->pgmap = pgmap;
411 percpu_ref_get(pgmap->ref); 418 percpu_ref_get(pgmap->ref);
412 if (!(++i % 1024))
413 cond_resched();
414 } 419 }
415 420
416 devm_add_action(dev, devm_memremap_pages_release, pgmap); 421 devm_add_action(dev, devm_memremap_pages_release, pgmap);