Messages in this thread Patch in this message | | | From | Pasha Tatashin <> | Subject | [PATCH v2 2/9] mm: Avoid using set_page_count() in set_page_recounted() | Date | Tue, 21 Dec 2021 15:01:33 +0000 |
| |
set_page_refcounted() converts a non-refcounted page that has (page->_refcount == 0) into a refcounted page by setting _refcount to 1.
The current apporach uses the following logic:
VM_BUG_ON_PAGE(page_ref_count(page), page); set_page_count(page, 1);
However, if _refcount changes from 0 to 1 between the VM_BUG_ON_PAGE() and set_page_count() we can break _refcount, which can cause other problems such as memory corruptions.
Instead, use a safer method: increment _refcount first and verify that at increment time it was indeed 1.
refcnt = page_ref_inc_return(page); VM_BUG_ON_PAGE(refcnt != 1, page);
Use page_ref_inc_return() to avoid unconditionally overwriting the _refcount value with set_page_count(), and check the return value.
Signed-off-by: Pasha Tatashin <pasha.tatashin@soleen.com> --- mm/internal.h | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/mm/internal.h b/mm/internal.h index deb9bda18e59..4d45ef2ffea6 100644 --- a/mm/internal.h +++ b/mm/internal.h @@ -162,9 +162,11 @@ static inline bool page_evictable(struct page *page) */ static inline void set_page_refcounted(struct page *page) { + int refcnt; + VM_BUG_ON_PAGE(PageTail(page), page); - VM_BUG_ON_PAGE(page_ref_count(page), page); - set_page_count(page, 1); + refcnt = page_ref_inc_return(page); + VM_BUG_ON_PAGE(refcnt != 1, page); } extern unsigned long highest_memmap_pfn; -- 2.34.1.307.g9b7440fafd-goog
| |