|
@@ -241,13 +241,16 @@ int device_private_entry_fault(struct vm_area_struct *vma,
|
|
|
EXPORT_SYMBOL(device_private_entry_fault);
|
|
|
#endif /* CONFIG_DEVICE_PRIVATE */
|
|
|
|
|
|
-static void pgmap_radix_release(struct resource *res)
|
|
|
+static void pgmap_radix_release(struct resource *res, unsigned long end_pgoff)
|
|
|
{
|
|
|
unsigned long pgoff, order;
|
|
|
|
|
|
mutex_lock(&pgmap_lock);
|
|
|
- foreach_order_pgoff(res, order, pgoff)
|
|
|
+ foreach_order_pgoff(res, order, pgoff) {
|
|
|
+ if (pgoff >= end_pgoff)
|
|
|
+ break;
|
|
|
radix_tree_delete(&pgmap_radix, PHYS_PFN(res->start) + pgoff);
|
|
|
+ }
|
|
|
mutex_unlock(&pgmap_lock);
|
|
|
|
|
|
synchronize_rcu();
|
|
@@ -302,7 +305,7 @@ static void devm_memremap_pages_release(void *data)
|
|
|
mem_hotplug_done();
|
|
|
|
|
|
untrack_pfn(NULL, PHYS_PFN(align_start), align_size);
|
|
|
- pgmap_radix_release(res);
|
|
|
+ pgmap_radix_release(res, -1);
|
|
|
dev_WARN_ONCE(dev, pgmap->altmap.alloc,
|
|
|
"%s: failed to free all reserved pages\n", __func__);
|
|
|
}
|
|
@@ -418,7 +421,7 @@ void *devm_memremap_pages(struct device *dev, struct dev_pagemap *pgmap)
|
|
|
untrack_pfn(NULL, PHYS_PFN(align_start), align_size);
|
|
|
err_pfn_remap:
|
|
|
err_radix:
|
|
|
- pgmap_radix_release(res);
|
|
|
+ pgmap_radix_release(res, pgoff);
|
|
|
devres_free(pgmap);
|
|
|
return ERR_PTR(error);
|
|
|
}
|