]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
alloc_tag: introduce clear_page_tag_ref() helper function
authorSuren Baghdasaryan <surenb@google.com>
Tue, 13 Aug 2024 15:07:56 +0000 (08:07 -0700)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Thu, 29 Aug 2024 15:35:41 +0000 (17:35 +0200)
commit a8fc28dad6d574582cdf2f7e78c73c59c623df30 upstream.

In several cases we are freeing pages which were not allocated using
common page allocators.  For such cases, in order to keep allocation
accounting correct, we should clear the page tag to indicate that the page
being freed is expected to not have a valid allocation tag.  Introduce
clear_page_tag_ref() helper function to be used for this.

Link: https://lkml.kernel.org/r/20240813150758.855881-1-surenb@google.com
Fixes: d224eb0287fb ("codetag: debug: mark codetags for reserved pages as empty")
Signed-off-by: Suren Baghdasaryan <surenb@google.com>
Suggested-by: David Hildenbrand <david@redhat.com>
Acked-by: David Hildenbrand <david@redhat.com>
Reviewed-by: Pasha Tatashin <pasha.tatashin@soleen.com>
Cc: Kees Cook <keescook@chromium.org>
Cc: Kent Overstreet <kent.overstreet@linux.dev>
Cc: Sourav Panda <souravpanda@google.com>
Cc: Vlastimil Babka <vbabka@suse.cz>
Cc: <stable@vger.kernel.org> [6.10]
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
include/linux/pgalloc_tag.h
mm/mm_init.c
mm/page_alloc.c

index 18cd0c0c73d93d9c80ba46b708763dad3c15752e..207f0c83c8e9750ac7050cc488f1618a69c4fd5c 100644 (file)
@@ -43,6 +43,18 @@ static inline void put_page_tag_ref(union codetag_ref *ref)
        page_ext_put(page_ext_from_codetag_ref(ref));
 }
 
+static inline void clear_page_tag_ref(struct page *page)
+{
+       if (mem_alloc_profiling_enabled()) {
+               union codetag_ref *ref = get_page_tag_ref(page);
+
+               if (ref) {
+                       set_codetag_empty(ref);
+                       put_page_tag_ref(ref);
+               }
+       }
+}
+
 static inline void pgalloc_tag_add(struct page *page, struct task_struct *task,
                                   unsigned int nr)
 {
@@ -126,6 +138,7 @@ static inline void pgalloc_tag_sub_pages(struct alloc_tag *tag, unsigned int nr)
 
 static inline union codetag_ref *get_page_tag_ref(struct page *page) { return NULL; }
 static inline void put_page_tag_ref(union codetag_ref *ref) {}
+static inline void clear_page_tag_ref(struct page *page) {}
 static inline void pgalloc_tag_add(struct page *page, struct task_struct *task,
                                   unsigned int nr) {}
 static inline void pgalloc_tag_sub(struct page *page, unsigned int nr) {}
index 13eb7cd58d9e21cee6d3a43d2574fc7b7f1604ad..2addc701790aed8041fd90ddfec0223a591aebd6 100644 (file)
@@ -2507,15 +2507,7 @@ void __init memblock_free_pages(struct page *page, unsigned long pfn,
        }
 
        /* pages were reserved and not allocated */
-       if (mem_alloc_profiling_enabled()) {
-               union codetag_ref *ref = get_page_tag_ref(page);
-
-               if (ref) {
-                       set_codetag_empty(ref);
-                       put_page_tag_ref(ref);
-               }
-       }
-
+       clear_page_tag_ref(page);
        __free_pages_core(page, order);
 }
 
index decbed9eb4721d1b5c3c93d5a4a1e43d4f737a7e..b50060405d947442560707c52ff4c7a92bcf3be6 100644 (file)
@@ -5806,14 +5806,7 @@ unsigned long free_reserved_area(void *start, void *end, int poison, const char
 
 void free_reserved_page(struct page *page)
 {
-       if (mem_alloc_profiling_enabled()) {
-               union codetag_ref *ref = get_page_tag_ref(page);
-
-               if (ref) {
-                       set_codetag_empty(ref);
-                       put_page_tag_ref(ref);
-               }
-       }
+       clear_page_tag_ref(page);
        ClearPageReserved(page);
        init_page_count(page);
        __free_page(page);