summaryrefslogtreecommitdiff
path: root/lib/alloc_tag.c
diff options
context:
space:
mode:
authorPeter Zijlstra <peterz@infradead.org>2024-12-20 15:31:19 +0100
committerPeter Zijlstra <peterz@infradead.org>2024-12-20 15:31:19 +0100
commitc2db11a750fb626d0d04f2dc76e548a1f07617df (patch)
tree01c899b2a06855633ae991f2064242f976987809 /lib/alloc_tag.c
parent63a48181fbcddefe5fb4c6618938bb64c543945b (diff)
parent4a077914578183ec397ad09f7156a357e00e5d72 (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.c36
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)