memremap: fix softlockup reports at teardown
authorDan Williams <dan.j.williams@intel.com>
Wed, 7 Feb 2018 03:34:11 +0000 (19:34 -0800)
committerDan Williams <dan.j.williams@intel.com>
Sat, 3 Mar 2018 03:34:50 +0000 (19:34 -0800)
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>
kernel/memremap.c

index 4849be5f9b3c30120f0f964dfd32f5bbf1546a54..4dd4274cabe252ecaa64e1c9a5a9d4f5478f1e24 100644 (file)
@@ -275,8 +275,15 @@ static unsigned long pfn_end(struct dev_pagemap *pgmap)
        return (res->start + resource_size(res)) >> PAGE_SHIFT;
 }
 
+static unsigned long pfn_next(unsigned long pfn)
+{
+       if (pfn % 1024 == 0)
+               cond_resched();
+       return pfn + 1;
+}
+
 #define for_each_device_pfn(pfn, map) \
-       for (pfn = pfn_first(map); pfn < pfn_end(map); pfn++)
+       for (pfn = pfn_first(map); pfn < pfn_end(map); pfn = pfn_next(pfn))
 
 static void devm_memremap_pages_release(void *data)
 {
@@ -337,10 +344,10 @@ void *devm_memremap_pages(struct device *dev, struct dev_pagemap *pgmap)
        resource_size_t align_start, align_size, align_end;
        struct vmem_altmap *altmap = pgmap->altmap_valid ?
                        &pgmap->altmap : NULL;
+       struct resource *res = &pgmap->res;
        unsigned long pfn, pgoff, order;
        pgprot_t pgprot = PAGE_KERNEL;
-       int error, nid, is_ram, i = 0;
-       struct resource *res = &pgmap->res;
+       int error, nid, is_ram;
 
        align_start = res->start & ~(SECTION_SIZE - 1);
        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)
                list_del(&page->lru);
                page->pgmap = pgmap;
                percpu_ref_get(pgmap->ref);
-               if (!(++i % 1024))
-                       cond_resched();
        }
 
        devm_add_action(dev, devm_memremap_pages_release, pgmap);