FAILED: patch "[PATCH] mm: Fix devm_memremap_pages() collision handling" failed to apply to 4.14-stable tree
[email protected]
maintainerThe patch below does not apply to the 4.14-stable tree.
If someone wants it applied there, or to any other stable or longterm tree, then please email the backport, including the original git commit id to <[email protected]>.
thanks,
greg k-h
------------------ original commit in Linus's tree ------------------
Quoted 1 line
From
77dd66a3c67c93ab401ccc15efff25578be281fdMon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jan=20H=2E=20Sch=C3=B6nherr?= <[email protected]>
Date: Fri, 19 Jan 2018 16:26:33 -0800
Subject: [PATCH] mm: Fix devm_memremap_pages() collision handling
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
If devm_memremap_pages() detects a collision while adding entries to the radix-tree, we call pgmap_radix_release(). Unfortunately, the function removes *all* entries for the range -- including the entries that caused the collision in the first place.
Modify pgmap_radix_release() to take an additional argument to indicate where to stop, so that only newly added entries are removed from the tree.
kernel/memremap.c +7 -4
@@ -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); }