NEEDS_COMPACTING,
        PAGE_STALE,
        PAGE_CLAIMED, /* by either reclaim or free */
+       PAGE_MIGRATED, /* page is migrated and soon to be released */
 };
 
 /*
                        zhdr = (struct z3fold_header *)(addr & PAGE_MASK);
                        locked = z3fold_page_trylock(zhdr);
                        read_unlock(&slots->lock);
-                       if (locked)
-                               break;
+                       if (locked) {
+                               struct page *page = virt_to_page(zhdr);
+
+                               if (!test_bit(PAGE_MIGRATED, &page->private))
+                                       break;
+                               z3fold_page_unlock(zhdr);
+                       }
                        cpu_relax();
                } while (true);
        } else {
        clear_bit(NEEDS_COMPACTING, &page->private);
        clear_bit(PAGE_STALE, &page->private);
        clear_bit(PAGE_CLAIMED, &page->private);
+       clear_bit(PAGE_MIGRATED, &page->private);
        if (headless)
                return zhdr;
 
        new_zhdr = page_address(newpage);
        memcpy(new_zhdr, zhdr, PAGE_SIZE);
        newpage->private = page->private;
-       page->private = 0;
+       set_bit(PAGE_MIGRATED, &page->private);
        z3fold_page_unlock(zhdr);
        spin_lock_init(&new_zhdr->page_lock);
        INIT_WORK(&new_zhdr->work, compact_page_work);
 
        queue_work_on(new_zhdr->cpu, pool->compact_wq, &new_zhdr->work);
 
-       clear_bit(PAGE_CLAIMED, &page->private);
+       /* PAGE_CLAIMED and PAGE_MIGRATED are cleared now. */
+       page->private = 0;
        put_page(page);
        return 0;
 }