mm,page_owner: fix accounting of pages when migrating
[sfrench/cifs-2.6.git] / mm / page_owner.c
index 5df0d6892bdce616aa94fde8b8e46e48a7c04c26..b4476f45b376e177bdb401f23a4ba97deaa51eb5 100644 (file)
@@ -366,9 +366,12 @@ void __split_page_owner(struct page *page, int old_order, int new_order)
 
 void __folio_copy_owner(struct folio *newfolio, struct folio *old)
 {
+       int i;
        struct page_ext *old_ext;
        struct page_ext *new_ext;
        struct page_owner *old_page_owner;
+       struct page_owner *new_page_owner;
+       depot_stack_handle_t migrate_handle;
 
        old_ext = page_ext_get(&old->page);
        if (unlikely(!old_ext))
@@ -381,6 +384,8 @@ void __folio_copy_owner(struct folio *newfolio, struct folio *old)
        }
 
        old_page_owner = get_page_owner(old_ext);
+       new_page_owner = get_page_owner(new_ext);
+       migrate_handle = new_page_owner->handle;
        __update_page_owner_handle(new_ext, old_page_owner->handle,
                                   old_page_owner->order, old_page_owner->gfp_mask,
                                   old_page_owner->last_migrate_reason,
@@ -395,6 +400,16 @@ void __folio_copy_owner(struct folio *newfolio, struct folio *old)
                                        old_page_owner->free_pid,
                                        old_page_owner->free_tgid,
                                        old_page_owner->free_ts_nsec);
+       /*
+        * We linked the original stack to the new folio, we need to do the same
+        * for the new one and the old folio otherwise there will be an imbalance
+        * when subtracting those pages from the stack.
+        */
+       for (i = 0; i < (1 << new_page_owner->order); i++) {
+               old_page_owner->handle = migrate_handle;
+               old_ext = page_ext_next(old_ext);
+               old_page_owner = get_page_owner(old_ext);
+       }
 
        page_ext_put(new_ext);
        page_ext_put(old_ext);