[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-Id: <20211208203544.2297121-10-pasha.tatashin@soleen.com>
Date: Wed, 8 Dec 2021 20:35:43 +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
Subject: [PATCH 09/10] 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 8c76bf3bf7e1..26676d3bcd58 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.34.1.400.ga245620fadb-goog
Powered by blists - more mailing lists