|
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [xen staging-4.21] Revert "xen/mm: allow deferred scrub of physmap populate allocated pages"
commit 73f4c7aab763cd1cfbcd778ad309fe2c2991cb43
Author: Jan Beulich <jbeulich@xxxxxxxx>
AuthorDate: Thu Mar 26 11:03:11 2026 +0100
Commit: Jan Beulich <jbeulich@xxxxxxxx>
CommitDate: Thu Mar 26 11:04:14 2026 +0100
Revert "xen/mm: allow deferred scrub of physmap populate allocated pages"
This reverts commit 6228ea8acddadbd815f958fb1a867f54c01ddf78 and its
prereq 15cd2b8f1bac5f4adf0f8303ae79298a612b53e1 ("xen/mm: remove
aliasing of PGC_need_scrub over PGC_allocated"). Further fixes are
needed before these can be considered for backporting.
---
xen/arch/arm/include/asm/mm.h | 10 ++--
xen/arch/ppc/include/asm/mm.h | 10 ++--
xen/arch/riscv/include/asm/mm.h | 10 ++--
xen/arch/x86/include/asm/mm.h | 18 ++++---
xen/common/domain.c | 23 ---------
xen/common/memory.c | 105 +---------------------------------------
xen/common/page_alloc.c | 4 +-
xen/include/xen/mm.h | 10 ----
xen/include/xen/sched.h | 5 --
9 files changed, 35 insertions(+), 160 deletions(-)
diff --git a/xen/arch/arm/include/asm/mm.h b/xen/arch/arm/include/asm/mm.h
index ee1f60c59e..7a93dad2ed 100644
--- a/xen/arch/arm/include/asm/mm.h
+++ b/xen/arch/arm/include/asm/mm.h
@@ -144,9 +144,6 @@ struct page_info
#define _PGC_colored PG_shift(4)
#define PGC_colored PG_mask(1, 4)
#endif
-/* Page needs to be scrubbed. */
-#define _PGC_need_scrub PG_shift(5)
-#define PGC_need_scrub PG_mask(1, 5)
/* ... */
/* Page is broken? */
#define _PGC_broken PG_shift(7)
@@ -166,6 +163,13 @@ struct page_info
#define PGC_count_width PG_shift(10)
#define PGC_count_mask ((1UL<<PGC_count_width)-1)
+/*
+ * Page needs to be scrubbed. Since this bit can only be set on a page that is
+ * free (i.e. in PGC_state_free) we can reuse PGC_allocated bit.
+ */
+#define _PGC_need_scrub _PGC_allocated
+#define PGC_need_scrub PGC_allocated
+
#if defined(CONFIG_ARM_64) || defined(CONFIG_MPU)
#define is_xen_heap_page(page) ((page)->count_info & PGC_xen_heap)
#define is_xen_heap_mfn(mfn) \
diff --git a/xen/arch/ppc/include/asm/mm.h b/xen/arch/ppc/include/asm/mm.h
index 82a9551082..a33eeec43b 100644
--- a/xen/arch/ppc/include/asm/mm.h
+++ b/xen/arch/ppc/include/asm/mm.h
@@ -57,9 +57,6 @@ static inline struct page_info *virt_to_page(const void *v)
/* Page is Xen heap? */
#define _PGC_xen_heap PG_shift(2)
#define PGC_xen_heap PG_mask(1, 2)
-/* Page needs to be scrubbed. */
-#define _PGC_need_scrub PG_shift(3)
-#define PGC_need_scrub PG_mask(1, 3)
/* Page is broken? */
#define _PGC_broken PG_shift(7)
#define PGC_broken PG_mask(1, 7)
@@ -78,6 +75,13 @@ static inline struct page_info *virt_to_page(const void *v)
#define PGC_count_width PG_shift(10)
#define PGC_count_mask ((1UL<<PGC_count_width)-1)
+/*
+ * Page needs to be scrubbed. Since this bit can only be set on a page that is
+ * free (i.e. in PGC_state_free) we can reuse PGC_allocated bit.
+ */
+#define _PGC_need_scrub _PGC_allocated
+#define PGC_need_scrub PGC_allocated
+
#define is_xen_heap_page(page) ((page)->count_info & PGC_xen_heap)
#define is_xen_heap_mfn(mfn) \
(mfn_valid(mfn) && is_xen_heap_page(mfn_to_page(mfn)))
diff --git a/xen/arch/riscv/include/asm/mm.h b/xen/arch/riscv/include/asm/mm.h
index 4c37d87508..9283616c02 100644
--- a/xen/arch/riscv/include/asm/mm.h
+++ b/xen/arch/riscv/include/asm/mm.h
@@ -247,15 +247,19 @@ static inline bool arch_mfns_in_directmap(unsigned long
mfn, unsigned long nr)
#define PGT_count_width PG_shift(2)
#define PGT_count_mask ((1UL << PGT_count_width) - 1)
+/*
+ * Page needs to be scrubbed. Since this bit can only be set on a page that is
+ * free (i.e. in PGC_state_free) we can reuse PGC_allocated bit.
+ */
+#define _PGC_need_scrub _PGC_allocated
+#define PGC_need_scrub PGC_allocated
+
/* Cleared when the owning guest 'frees' this page. */
#define _PGC_allocated PG_shift(1)
#define PGC_allocated PG_mask(1, 1)
/* Page is Xen heap? */
#define _PGC_xen_heap PG_shift(2)
#define PGC_xen_heap PG_mask(1, 2)
-/* Page needs to be scrubbed. */
-#define _PGC_need_scrub PG_shift(4)
-#define PGC_need_scrub PG_mask(1, 4)
/* Page is broken? */
#define _PGC_broken PG_shift(7)
#define PGC_broken PG_mask(1, 7)
diff --git a/xen/arch/x86/include/asm/mm.h b/xen/arch/x86/include/asm/mm.h
index d35086e31e..08153e6d6f 100644
--- a/xen/arch/x86/include/asm/mm.h
+++ b/xen/arch/x86/include/asm/mm.h
@@ -83,25 +83,29 @@
#define PGC_state_offlined PG_mask(2, 6)
#define PGC_state_free PG_mask(3, 6)
#define page_state_is(pg, st) (((pg)->count_info&PGC_state) == PGC_state_##st)
-/* Page needs to be scrubbed. */
-#define _PGC_need_scrub PG_shift(7)
-#define PGC_need_scrub PG_mask(1, 7)
#ifdef CONFIG_SHADOW_PAGING
/* Set when a page table page has been shadowed. */
-#define _PGC_shadowed_pt PG_shift(8)
-#define PGC_shadowed_pt PG_mask(1, 8)
+#define _PGC_shadowed_pt PG_shift(7)
+#define PGC_shadowed_pt PG_mask(1, 7)
#else
#define PGC_shadowed_pt 0
#endif
/* Count of references to this frame. */
#if PGC_shadowed_pt
-#define PGC_count_width PG_shift(8)
-#else
#define PGC_count_width PG_shift(7)
+#else
+#define PGC_count_width PG_shift(6)
#endif
#define PGC_count_mask ((1UL<<PGC_count_width)-1)
+/*
+ * Page needs to be scrubbed. Since this bit can only be set on a page that is
+ * free (i.e. in PGC_state_free) we can reuse PGC_allocated bit.
+ */
+#define _PGC_need_scrub _PGC_allocated
+#define PGC_need_scrub PGC_allocated
+
#ifndef CONFIG_BIGMEM
/*
* This definition is solely for the use in struct page_info (and
diff --git a/xen/common/domain.c b/xen/common/domain.c
index 75c7da16e2..88db82d187 100644
--- a/xen/common/domain.c
+++ b/xen/common/domain.c
@@ -582,18 +582,6 @@ static int __init cf_check parse_dom0_param(const char *s)
}
custom_param("dom0", parse_dom0_param);
-static void domain_pending_scrub_free(struct domain *d)
-{
- rspin_lock(&d->page_alloc_lock);
- if ( d->pending_scrub )
- {
- FREE_DOMHEAP_PAGES(d->pending_scrub, d->pending_scrub_order);
- d->pending_scrub_order = 0;
- d->pending_scrub_index = 0;
- }
- rspin_unlock(&d->page_alloc_lock);
-}
-
/*
* Release resources held by a domain. There may or may not be live
* references to the domain, and it may or may not be fully constructed.
@@ -655,7 +643,6 @@ static int domain_teardown(struct domain *d)
/* Trivial teardown, not long-running enough to need a preemption
check. */
domain_llc_coloring_free(d);
- domain_pending_scrub_free(d);
PROGRESS(gnttab_mappings):
rc = gnttab_release_mappings(d);
@@ -699,7 +686,6 @@ static void _domain_destroy(struct domain *d)
{
BUG_ON(!d->is_dying);
BUG_ON(atomic_read(&d->refcnt) != DOMAIN_DESTROYED);
- ASSERT(!d->pending_scrub);
xfree(d->pbuf);
@@ -1665,15 +1651,6 @@ int domain_unpause_by_systemcontroller(struct domain *d)
*/
if ( new == 0 && !d->creation_finished )
{
- if ( d->pending_scrub )
- {
- printk(XENLOG_ERR
- "%pd: cannot be started with pending unscrubbed pages,
destroying\n",
- d);
- domain_crash(d);
- domain_pending_scrub_free(d);
- return -EBUSY;
- }
d->creation_finished = true;
arch_domain_creation_finished(d);
}
diff --git a/xen/common/memory.c b/xen/common/memory.c
index 9240a6005e..10becf7c1f 100644
--- a/xen/common/memory.c
+++ b/xen/common/memory.c
@@ -159,73 +159,6 @@ static void increase_reservation(struct memop_args *a)
a->nr_done = i;
}
-/*
- * Temporary storage for a domain assigned page that's not been fully scrubbed.
- * Stored pages must be domheap ones.
- *
- * The stashed page can be freed at any time by Xen, the caller must pass the
- * order and NUMA node requirement to the fetch function to ensure the
- * currently stashed page matches it's requirements.
- */
-static void stash_allocation(struct domain *d, struct page_info *page,
- unsigned int order, unsigned int scrub_index)
-{
- rspin_lock(&d->page_alloc_lock);
-
- /*
- * Drop the passed page in preference for the already stashed one. This
- * interface is designed to be used for single-threaded domain creation.
- */
- if ( d->pending_scrub || d->is_dying )
- free_domheap_pages(page, order);
- else
- {
- d->pending_scrub_index = scrub_index;
- d->pending_scrub_order = order;
- d->pending_scrub = page;
- }
-
- rspin_unlock(&d->page_alloc_lock);
-}
-
-static struct page_info *get_stashed_allocation(struct domain *d,
- unsigned int order,
- nodeid_t node,
- unsigned int *scrub_index)
-{
- struct page_info *page = NULL;
-
- rspin_lock(&d->page_alloc_lock);
-
- /*
- * If there's a pending page to scrub check if it satisfies the current
- * request. If it doesn't free it and return NULL.
- */
- if ( d->pending_scrub )
- {
- if ( d->pending_scrub_order == order &&
- (node == NUMA_NO_NODE || node == page_to_nid(d->pending_scrub)) )
- {
- page = d->pending_scrub;
- *scrub_index = d->pending_scrub_index;
- }
- else
- free_domheap_pages(d->pending_scrub, d->pending_scrub_order);
-
- /*
- * The caller now owns the page or it has been freed, clear stashed
- * information. Prevent concurrent usages of get_stashed_allocation()
- * from returning the same page to different contexts.
- */
- d->pending_scrub_index = 0;
- d->pending_scrub_order = 0;
- d->pending_scrub = NULL;
- }
-
- rspin_unlock(&d->page_alloc_lock);
- return page;
-}
-
static void populate_physmap(struct memop_args *a)
{
struct page_info *page;
@@ -342,19 +275,7 @@ static void populate_physmap(struct memop_args *a)
}
else
{
- unsigned int scrub_start = 0;
- unsigned int memflags =
- a->memflags | (d->creation_finished ? 0
- : MEMF_no_scrub);
- nodeid_t node =
- (a->memflags & MEMF_exact_node) ?
MEMF_get_node(a->memflags)
- : NUMA_NO_NODE;
-
- page = get_stashed_allocation(d, a->extent_order, node,
- &scrub_start);
-
- if ( !page )
- page = alloc_domheap_pages(d, a->extent_order, memflags);
+ page = alloc_domheap_pages(d, a->extent_order, a->memflags);
if ( unlikely(!page) )
{
@@ -365,30 +286,6 @@ static void populate_physmap(struct memop_args *a)
goto out;
}
- if ( memflags & MEMF_no_scrub )
- {
- unsigned int dirty_cnt = 0;
-
- /* Check if there's anything to scrub. */
- for ( j = scrub_start; j < (1U << a->extent_order); j++ )
- {
- if ( !test_and_clear_bit(_PGC_need_scrub,
- &page[j].count_info) )
- continue;
-
- scrub_one_page(&page[j], true);
-
- if ( (j + 1) != (1U << a->extent_order) &&
- !(++dirty_cnt & 0xff) &&
- hypercall_preempt_check() )
- {
- a->preempted = 1;
- stash_allocation(d, page, a->extent_order, j + 1);
- goto out;
- }
- }
- }
-
if ( unlikely(a->memflags & MEMF_no_tlbflush) )
{
for ( j = 0; j < (1U << a->extent_order); j++ )
diff --git a/xen/common/page_alloc.c b/xen/common/page_alloc.c
index 588b5b99cb..2efc11ce09 100644
--- a/xen/common/page_alloc.c
+++ b/xen/common/page_alloc.c
@@ -170,7 +170,7 @@
/*
* Flags that are preserved in assign_pages() (and only there)
*/
-#define PGC_preserved (PGC_extra | PGC_static | PGC_colored | PGC_need_scrub)
+#define PGC_preserved (PGC_extra | PGC_static | PGC_colored)
#ifndef PGT_TYPE_INFO_INITIALIZER
#define PGT_TYPE_INFO_INITIALIZER 0
@@ -792,7 +792,7 @@ static void page_list_add_scrub(struct page_info *pg,
unsigned int node,
# define scrub_page_cold clear_page_cold
#endif
-void scrub_one_page(const struct page_info *pg, bool cold)
+static void scrub_one_page(const struct page_info *pg, bool cold)
{
void *ptr;
diff --git a/xen/include/xen/mm.h b/xen/include/xen/mm.h
index 49c34248f9..b968f47b87 100644
--- a/xen/include/xen/mm.h
+++ b/xen/include/xen/mm.h
@@ -145,16 +145,6 @@ unsigned long avail_node_heap_pages(unsigned int nodeid);
#define alloc_domheap_page(d,f) (alloc_domheap_pages(d,0,f))
#define free_domheap_page(p) (free_domheap_pages(p,0))
-/* Free an allocation, and zero the pointer to it. */
-#define FREE_DOMHEAP_PAGES(p, o) do { \
- void *_ptr_ = (p); \
- (p) = NULL; \
- free_domheap_pages(_ptr_, o); \
-} while ( false )
-#define FREE_DOMHEAP_PAGE(p) FREE_DOMHEAP_PAGES(p, 0)
-
-void scrub_one_page(const struct page_info *pg, bool cold);
-
int online_page(mfn_t mfn, uint32_t *status);
int offline_page(mfn_t mfn, int broken, uint32_t *status);
int query_page_offline(mfn_t mfn, uint32_t *status);
diff --git a/xen/include/xen/sched.h b/xen/include/xen/sched.h
index c89b930cbd..610f3d4c0d 100644
--- a/xen/include/xen/sched.h
+++ b/xen/include/xen/sched.h
@@ -662,11 +662,6 @@ struct domain
/* Permission to take ownership of the physical console input. */
bool input_allowed;
} console;
-
- /* Pointer to allocated domheap page that possibly needs scrubbing. */
- struct page_info *pending_scrub;
- unsigned int pending_scrub_order;
- unsigned int pending_scrub_index;
} __aligned(PAGE_SIZE);
static inline struct page_list_head *page_to_list(
--
generated by git-patchbot for /home/xen/git/xen.git#staging-4.21
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |