* [RFC PATCH v3] mm/cma: don't release CMA pages still in use
@ 2026-08-11 17:20 Rik van Riel
0 siblings, 0 replies; only message in thread
From: Rik van Riel @ 2026-08-11 17:20 UTC (permalink / raw)
To: David Hildenbrand
Cc: Andrew Morton, Lorenzo Stoakes, Liam R. Howlett, Vlastimil Babka,
Mike Rapoport, Suren Baghdasaryan, Michal Hocko, linux-mm,
linux-kernel
When a driver calls dma_free_contiguous() before quiescing DMA, the
page still has a reference from the device. put_page_testzero() there
returns false, WARN fires, but the code proceeds to
free_contig_frozen_range() putting a live page onto buddy and clearing
the bitmap. A subsequent allocation can hand the same PFN to a new
owner while the original holder still references it.
A concurrent put_page() that drops the last reference between the
testzero loop and free_contig_frozen_range() can double-queue the page
via page->lru, corrupting buddy lists.
Avoid the corruption by not freeing a CMA region if any of the
pages inside are still in use.
Make it explicit in the warning that the driver allowed a leak.
Fixes: 9bda131c6093 ("mm: cma: add cma_alloc_frozen{_compound}()")
Link: https://lore.kernel.org/linux-mm/20260809210608.06b5ccb9@fangorn/ [v1]
Link: https://lore.kernel.org/linux-mm/20260810122737.030f8452@fangorn/ [v2]
Cc: stable@vger.kernel.org
Signed-off-by: Rik van Riel <riel@surriel.com>
---
v3:
- simplify things by simply leaking the CMA range, drivers should not
call cma_release() while the space is still in use (David Hildenbrand)
mm/cma.c | 9 ++++++---
1 file changed, 6 insertions(+), 3 deletions(-)
diff --git a/mm/cma.c b/mm/cma.c
index a13ce4999b39..c1425f25c39b 100644
--- a/mm/cma.c
+++ b/mm/cma.c
@@ -1018,7 +1018,7 @@ bool cma_release(struct cma *cma, const struct page *pages,
unsigned long count)
{
struct cma_memrange *cmr;
- unsigned long ret = 0;
+ unsigned long leaked = 0;
unsigned long i, pfn;
cmr = find_cma_memrange(cma, pages, count);
@@ -1027,9 +1027,12 @@ bool cma_release(struct cma *cma, const struct page *pages,
pfn = page_to_pfn(pages);
for (i = 0; i < count; i++, pfn++)
- ret += !put_page_testzero(pfn_to_page(pfn));
+ leaked += !put_page_testzero(pfn_to_page(pfn));
- WARN(ret, "%lu pages are still in use!\n", ret);
+ if (leaked) {
+ WARN(1, "%lu pages are still in use, not freeing CMA region!\n", leaked);
+ return true;
+ }
__cma_release_frozen(cma, cmr, pages, count);
--
2.55.0
^ permalink raw reply related [flat|nested] only message in thread
only message in thread, other threads:[~2026-08-11 17:21 UTC | newest]
Thread overview: (only message) (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-08-11 17:20 [RFC PATCH v3] mm/cma: don't release CMA pages still in use Rik van Riel
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.