|
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [xen staging-4.19] Revert "xen/mm: allow deferred scrub of physmap populate allocated pages"
commit 360813e9e829f0b9439ac08a16808341cf74e993
Author: Jan Beulich <jbeulich@xxxxxxxx>
AuthorDate: Thu Mar 26 11:16:35 2026 +0100
Commit: Jan Beulich <jbeulich@xxxxxxxx>
CommitDate: Thu Mar 26 11:16:58 2026 +0100
Revert "xen/mm: allow deferred scrub of physmap populate allocated pages"
This reverts commit 52f3b7c6f89abe1f8fd4fc702f150cf3ec1fe89f and its
prereq 49a4deb467caea989d81f3692ed19a406ef6ee83 ("xen/mm: remove
aliasing of PGC_need_scrub over PGC_allocated"). Further fixes are
needed before this can be considered for backporting.
---
xen/arch/arm/include/asm/mm.h | 10 ++--
xen/arch/ppc/include/asm/mm.h | 10 ++--
xen/arch/x86/include/asm/mm.h | 18 +++++---
xen/common/domain.c | 25 ----------
xen/common/memory.c | 105 +-----------------------------------------
xen/common/page_alloc.c | 6 +--
xen/include/xen/mm.h | 9 ----
xen/include/xen/sched.h | 5 --
8 files changed, 28 insertions(+), 160 deletions(-)
diff --git a/xen/arch/arm/include/asm/mm.h b/xen/arch/arm/include/asm/mm.h
index ed71cf9bca..48538b5337 100644
--- a/xen/arch/arm/include/asm/mm.h
+++ b/xen/arch/arm/include/asm/mm.h
@@ -145,9 +145,6 @@ struct page_info
#else
#define PGC_static 0
#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)
@@ -167,6 +164,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
+
#ifdef CONFIG_ARM_32
#define is_xen_heap_page(page) is_xen_heap_mfn(page_to_mfn(page))
#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 9b654945de..a433936076 100644
--- a/xen/arch/ppc/include/asm/mm.h
+++ b/xen/arch/ppc/include/asm/mm.h
@@ -58,9 +58,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)
@@ -79,6 +76,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/x86/include/asm/mm.h b/xen/arch/x86/include/asm/mm.h
index 52d2d5ff60..98b66edaca 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 77dacffd22..00c59a9baa 100644
--- a/xen/common/domain.c
+++ b/xen/common/domain.c
@@ -392,18 +392,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.
@@ -463,9 +451,6 @@ static int domain_teardown(struct domain *d)
case PROG_none:
BUILD_BUG_ON(PROG_none != 0);
- /* Trivial teardown, not long-running enough to need a preemption
check. */
- domain_pending_scrub_free(d);
-
PROGRESS(gnttab_mappings):
rc = gnttab_release_mappings(d);
if ( rc )
@@ -508,7 +493,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);
@@ -1436,15 +1420,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 09bb1198bb..9b23cd0bdb 100644
--- a/xen/common/memory.c
+++ b/xen/common/memory.c
@@ -155,73 +155,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;
@@ -338,19 +271,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) )
{
@@ -361,30 +282,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]);
-
- 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 4304c3dbd4..bbb8578459 100644
--- a/xen/common/page_alloc.c
+++ b/xen/common/page_alloc.c
@@ -2364,8 +2364,7 @@ int assign_pages(
for ( i = 0; i < nr; i++ )
{
- ASSERT(!(pg[i].count_info &
- ~(PGC_extra | PGC_static | PGC_need_scrub)));
+ ASSERT(!(pg[i].count_info & ~(PGC_extra | PGC_static)));
if ( pg[i].count_info & PGC_extra )
extra_pages++;
}
@@ -2425,8 +2424,7 @@ int assign_pages(
page_set_owner(&pg[i], d);
smp_wmb(); /* Domain pointer must be visible before updating refcnt. */
pg[i].count_info =
- (pg[i].count_info & (PGC_extra | PGC_static | PGC_need_scrub)) |
- PGC_allocated | 1;
+ (pg[i].count_info & (PGC_extra | PGC_static)) | PGC_allocated | 1;
page_list_add_tail(&pg[i], page_to_list(d, &pg[i]));
}
diff --git a/xen/include/xen/mm.h b/xen/include/xen/mm.h
index fe32ef81cb..7561297a75 100644
--- a/xen/include/xen/mm.h
+++ b/xen/include/xen/mm.h
@@ -142,15 +142,6 @@ unsigned long avail_domheap_pages(void);
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)
-
unsigned 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 ff831c7254..2a83b9dacf 100644
--- a/xen/include/xen/sched.h
+++ b/xen/include/xen/sched.h
@@ -636,11 +636,6 @@ struct domain
} ioreq_server;
#endif
- /* Pointer to allocated domheap page that possibly needs scrubbing. */
- struct page_info *pending_scrub;
- unsigned int pending_scrub_order;
- unsigned int pending_scrub_index;
-
/* Holding CDF_* constant. Internal flags for domain creation. */
unsigned int cdf;
};
--
generated by git-patchbot for /home/xen/git/xen.git#staging-4.19
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |