Thread (12 messages) 12 messages, 5 authors, 2022-01-12

Re: [PATCH v2] mm: fix race between MADV_FREE reclaim and blkdev direct IO read

From: Yu Zhao <hidden>
Date: 2022-01-11 06:48:21
Also in: linux-mm

On Wed, Jan 05, 2022 at 08:34:40PM -0300, Mauricio Faria de Oliveira wrote:
quoted hunk ↗ jump to hunk
diff --git a/mm/rmap.c b/mm/rmap.c
index 163ac4e6bcee..8671de473c25 100644
--- a/mm/rmap.c
+++ b/mm/rmap.c
@@ -1570,7 +1570,20 @@ static bool try_to_unmap_one(struct page *page, struct vm_area_struct *vma,
 
 			/* MADV_FREE page check */
 			if (!PageSwapBacked(page)) {
-				if (!PageDirty(page)) {
+				int ref_count = page_ref_count(page);
+				int map_count = page_mapcount(page);
+
+				/*
+				 * The only page refs must be from the isolation
+				 * (checked by the caller shrink_page_list() too)
+				 * and one or more rmap's (dropped by discard:).
+				 *
+				 * Check the reference count before dirty flag
+				 * with memory barrier; see __remove_mapping().
+				 */
+				smp_rmb();
+				if ((ref_count - 1 == map_count) &&
+				    !PageDirty(page)) {
 					/* Invalidate as we cleared the pte */
 					mmu_notifier_invalidate_range(mm,
 						address, address + PAGE_SIZE);
Out of curiosity, how does it work with COW in terms of reordering?
Specifically, it seems to me get_page() and page_dup_rmap() in
copy_present_pte() can happen in any order, and if page_dup_rmap()
is seen first, and direct io is holding a refcnt, this check can still
pass?
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help