Commit a8fc28da authored by Suren Baghdasaryan's avatar Suren Baghdasaryan Committed by Andrew Morton
Browse files

alloc_tag: introduce clear_page_tag_ref() helper function

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: d224eb02 ("codetag: debug: mark codetags for reserved pages as empty")
Signed-off-by: default avatarSuren Baghdasaryan <surenb@google.com>
Suggested-by: default avatarDavid Hildenbrand <david@redhat.com>
Acked-by: default avatarDavid Hildenbrand <david@redhat.com>
Reviewed-by: default avatarPasha 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: default avatarAndrew Morton <akpm@linux-foundation.org>
parent edb907a6
Loading
Loading
Loading
Loading
+13 −0
Original line number Diff line number Diff line
@@ -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) {}
+1 −9
Original line number Diff line number Diff line
@@ -2459,15 +2459,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, MEMINIT_EARLY);
}

+1 −8
Original line number Diff line number Diff line
@@ -5815,14 +5815,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);