[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-Id: <20220126183429.1840447-9-pasha.tatashin@soleen.com>
Date:   Wed, 26 Jan 2022 18:34:28 +0000
From:   Pasha Tatashin <pasha.tatashin@...een.com>
To:     pasha.tatashin@...een.com, linux-kernel@...r.kernel.org,
        linux-mm@...ck.org, linux-m68k@...ts.linux-m68k.org,
        anshuman.khandual@....com, willy@...radead.org,
        akpm@...ux-foundation.org, william.kucharski@...cle.com,
        mike.kravetz@...cle.com, vbabka@...e.cz, geert@...ux-m68k.org,
        schmitzmic@...il.com, rostedt@...dmis.org, mingo@...hat.com,
        hannes@...xchg.org, guro@...com, songmuchun@...edance.com,
        weixugc@...gle.com, gthelen@...gle.com, rientjes@...gle.com,
        pjt@...gle.com, hughd@...gle.com
Subject: [PATCH v3 8/9] mm: do not use atomic_set_release in page_ref_unfreeze()
In we set the old _refcount value after verifying that the old value was
indeed 0.
VM_BUG_ON_PAGE(page_count(page) != 0, page);
< the _refcount may change here>
atomic_set_release(&page->_refcount, count);
To avoid the smal gap where _refcount may change lets verify the time
of the _refcount at the time of the set operation.
Use atomic_xchg_release() and at the set time verify that the value
was 0.
Signed-off-by: Pasha Tatashin <pasha.tatashin@...een.com>
---
 include/linux/page_ref.h | 5 ++---
 1 file changed, 2 insertions(+), 3 deletions(-)
diff --git a/include/linux/page_ref.h b/include/linux/page_ref.h
index 243fc60ae6c8..9efabeff4e06 100644
--- a/include/linux/page_ref.h
+++ b/include/linux/page_ref.h
@@ -322,10 +322,9 @@ static inline int folio_ref_freeze(struct folio *folio, int count)
 
 static inline void page_ref_unfreeze(struct page *page, int count)
 {
-	VM_BUG_ON_PAGE(page_count(page) != 0, page);
-	VM_BUG_ON(count == 0);
+	int old_val = atomic_xchg_release(&page->_refcount, count);
 
-	atomic_set_release(&page->_refcount, count);
+	VM_BUG_ON_PAGE(count == 0 || old_val != 0, page);
 	if (page_ref_tracepoint_active(page_ref_unfreeze))
 		__page_ref_unfreeze(page, count);
 }
-- 
2.35.0.rc0.227.g00780c9af4-goog
Powered by blists - more mailing lists