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: 7138970383
("mm, zone_device: Replace {get, put}_zone_device_page()...")
Signed-off-by: Dan Williams <dan.j.williams@intel.com>
This commit is contained in:
parent
5fdf8e5ba5
commit
949b93250a
|
@ -275,8 +275,15 @@ static unsigned long pfn_end(struct dev_pagemap *pgmap)
|
||||||
return (res->start + resource_size(res)) >> PAGE_SHIFT;
|
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) \
|
#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)
|
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;
|
resource_size_t align_start, align_size, align_end;
|
||||||
struct vmem_altmap *altmap = pgmap->altmap_valid ?
|
struct vmem_altmap *altmap = pgmap->altmap_valid ?
|
||||||
&pgmap->altmap : NULL;
|
&pgmap->altmap : NULL;
|
||||||
|
struct resource *res = &pgmap->res;
|
||||||
unsigned long pfn, pgoff, order;
|
unsigned long pfn, pgoff, order;
|
||||||
pgprot_t pgprot = PAGE_KERNEL;
|
pgprot_t pgprot = PAGE_KERNEL;
|
||||||
int error, nid, is_ram, i = 0;
|
int error, nid, is_ram;
|
||||||
struct resource *res = &pgmap->res;
|
|
||||||
|
|
||||||
align_start = res->start & ~(SECTION_SIZE - 1);
|
align_start = res->start & ~(SECTION_SIZE - 1);
|
||||||
align_size = ALIGN(res->start + resource_size(res), SECTION_SIZE)
|
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);
|
list_del(&page->lru);
|
||||||
page->pgmap = pgmap;
|
page->pgmap = pgmap;
|
||||||
percpu_ref_get(pgmap->ref);
|
percpu_ref_get(pgmap->ref);
|
||||||
if (!(++i % 1024))
|
|
||||||
cond_resched();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
devm_add_action(dev, devm_memremap_pages_release, pgmap);
|
devm_add_action(dev, devm_memremap_pages_release, pgmap);
|
||||||
|
|
Loading…
Reference in New Issue