mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
From: Rik van Riel <riel@surriel.com>
To: Andrew Morton <akpm@linux-foundation.org>
Cc: David Hildenbrand <david@kernel.org>,
	Lorenzo Stoakes <ljs@kernel.org>,
	"Liam R. Howlett" <liam@infradead.org>,
	Vlastimil Babka <vbabka@kernel.org>,
	Mike Rapoport <rppt@kernel.org>,
	Suren Baghdasaryan <surenb@google.com>,
	Michal Hocko <mhocko@suse.com>,
	linux-mm@kvack.org, linux-kernel@vger.kernel.org,
	kernel-team@meta.com
Subject: [RFC PATCH] mm/cma: don't release CMA pages still in use
Date: Sun, 9 Aug 2026 21:06:08 -0400	[thread overview]
Message-ID: <20260809210608.06b5ccb9@fangorn> (raw)

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, ret is incremented, WARN fires, but the code proceeds
to free_contig_frozen_range() putting a live page onto buddy and
clearing the bitmap. Later cma_alloc() hands 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.

Fix by freeing already-frozen pages in contiguous runs via
__cma_release_frozen(), while skipping still-referenced pages.
The CMA address space for pages that are still in use at
cma_release() time gets leaked, but the pages themselves
will get freed once the user drops the last refcount.

This change should be safe because nothing can get reallocated while it
is still in use.

Fixes: 9bda131c6093 ("mm: cma: add cma_alloc_frozen{_compound}()")
Cc: stable@vger.kernel.org
Assisted-by: Hermes:muse-spark-1.2
Reported-by: Chris Mason <clm@meta.com>
Signed-off-by: Rik van Riel <riel@surriel.com>
---
 mm/cma.c | 36 +++++++++++++++++++++++++++++-------
 1 file changed, 29 insertions(+), 7 deletions(-)

diff --git a/mm/cma.c b/mm/cma.c
index a13ce4999b39..66952bb03abb 100644
--- a/mm/cma.c
+++ b/mm/cma.c
@@ -1018,20 +1018,42 @@ bool cma_release(struct cma *cma, const struct page *pages,
 		 unsigned long count)
 {
 	struct cma_memrange *cmr;
-	unsigned long ret = 0;
+	unsigned long skipped = 0;
 	unsigned long i, pfn;
+	unsigned long base_pfn;
+	unsigned long run_start = 0;
+	unsigned long run_len = 0;
 
 	cmr = find_cma_memrange(cma, pages, count);
 	if (!cmr)
 		return false;
 
-	pfn = page_to_pfn(pages);
-	for (i = 0; i < count; i++, pfn++)
-		ret += !put_page_testzero(pfn_to_page(pfn));
-
-	WARN(ret, "%lu pages are still in use!\n", ret);
+	base_pfn = page_to_pfn(pages);
+	pfn = base_pfn;
+	for (i = 0; i < count; i++, pfn++) {
+		if (put_page_testzero(pfn_to_page(pfn))) {
+			/* Add it to the batch. */
+			if (run_len == 0)
+				run_start = pfn;
+			run_len++;
+		} else {
+			/*
+			 * This page is still in use! Free the freeable
+			 * pages encountered so far, but skip this page.
+			 */
+			if (run_len) {
+				__cma_release_frozen(cma, cmr,
+						     pfn_to_page(run_start),
+						     run_len);
+				run_len = 0;
+			}
+			skipped++;
+		}
+	}
+	if (run_len)
+		__cma_release_frozen(cma, cmr, pfn_to_page(run_start), run_len);
 
-	__cma_release_frozen(cma, cmr, pages, count);
+	WARN(skipped, "%lu pages are still in use!\n", skipped);
 
 	return true;
 }
-- 
2.55.0


             reply	other threads:[~2026-08-10  1:09 UTC|newest]

Thread overview: 2+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-08-10  1:06 Rik van Riel [this message]
2026-08-10  3:16 ` Rik van Riel

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20260809210608.06b5ccb9@fangorn \
    --to=riel@surriel.com \
    --cc=akpm@linux-foundation.org \
    --cc=david@kernel.org \
    --cc=kernel-team@meta.com \
    --cc=liam@infradead.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-mm@kvack.org \
    --cc=ljs@kernel.org \
    --cc=mhocko@suse.com \
    --cc=rppt@kernel.org \
    --cc=surenb@google.com \
    --cc=vbabka@kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

all inboxes | Powered by JetHome®