diff options
author | Peter Zijlstra <peterz@infradead.org> | 2024-12-20 15:31:19 +0100 |
---|---|---|
committer | Peter Zijlstra <peterz@infradead.org> | 2024-12-20 15:31:19 +0100 |
commit | c2db11a750fb626d0d04f2dc76e548a1f07617df (patch) | |
tree | 01c899b2a06855633ae991f2064242f976987809 /lib/alloc_tag.c | |
parent | 63a48181fbcddefe5fb4c6618938bb64c543945b (diff) | |
parent | 4a077914578183ec397ad09f7156a357e00e5d72 (diff) |
Merge branch 'locking/urgent'
Sync with urgent -- avoid conflicts.
Signed-off-by: Peter Zijlstra <peterz@infradead.org>
Diffstat (limited to 'lib/alloc_tag.c')
-rw-r--r-- | lib/alloc_tag.c | 36 |
1 files changed, 22 insertions, 14 deletions
diff --git a/lib/alloc_tag.c b/lib/alloc_tag.c index 2414a7ee7ec77..35f7560a309a4 100644 --- a/lib/alloc_tag.c +++ b/lib/alloc_tag.c @@ -189,26 +189,34 @@ void pgalloc_tag_split(struct folio *folio, int old_order, int new_order) } } -void pgalloc_tag_copy(struct folio *new, struct folio *old) +void pgalloc_tag_swap(struct folio *new, struct folio *old) { - union pgtag_ref_handle handle; - union codetag_ref ref; - struct alloc_tag *tag; + union pgtag_ref_handle handle_old, handle_new; + union codetag_ref ref_old, ref_new; + struct alloc_tag *tag_old, *tag_new; - tag = pgalloc_tag_get(&old->page); - if (!tag) + tag_old = pgalloc_tag_get(&old->page); + if (!tag_old) + return; + tag_new = pgalloc_tag_get(&new->page); + if (!tag_new) return; - if (!get_page_tag_ref(&new->page, &ref, &handle)) + if (!get_page_tag_ref(&old->page, &ref_old, &handle_old)) return; + if (!get_page_tag_ref(&new->page, &ref_new, &handle_new)) { + put_page_tag_ref(handle_old); + return; + } + + /* swap tags */ + __alloc_tag_ref_set(&ref_old, tag_new); + update_page_tag_ref(handle_old, &ref_old); + __alloc_tag_ref_set(&ref_new, tag_old); + update_page_tag_ref(handle_new, &ref_new); - /* Clear the old ref to the original allocation tag. */ - clear_page_tag_ref(&old->page); - /* Decrement the counters of the tag on get_new_folio. */ - alloc_tag_sub(&ref, folio_size(new)); - __alloc_tag_ref_set(&ref, tag); - update_page_tag_ref(handle, &ref); - put_page_tag_ref(handle); + put_page_tag_ref(handle_old); + put_page_tag_ref(handle_new); } static void shutdown_mem_profiling(bool remove_file) |