|
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [PATCH v2 3/3] xen/mm: limit non-scrubbed allocations to a specific order
The current logic allows for up to 1G pages to be scrubbed in place, which
can cause the watchdog to trigger in practice. Reduce the limit for
in-place scrubbed allocations to a newly introduced define:
CONFIG_DIRTY_MAX_ORDER. This currently defaults to CONFIG_DOMU_MAX_ORDER
on all architectures. Also introduce a command line option to set the
value.
Fixes: 74d2e11ccfd2 ("mm: Scrub pages in alloc_heap_pages() if needed")
Signed-off-by: Roger Pau Monné <roger.pau@xxxxxxxxxx>
---
Changes since v1:
- Split from previous patch.
- Introduce a command line option to set the limit.
---
docs/misc/xen-command-line.pandoc | 9 +++++++++
xen/common/page_alloc.c | 23 ++++++++++++++++++++++-
2 files changed, 31 insertions(+), 1 deletion(-)
diff --git a/docs/misc/xen-command-line.pandoc
b/docs/misc/xen-command-line.pandoc
index 50d7edb2488e..65b4dfc826b5 100644
--- a/docs/misc/xen-command-line.pandoc
+++ b/docs/misc/xen-command-line.pandoc
@@ -1822,6 +1822,15 @@ Specify the deepest C-state CPUs are permitted to be
placed in, and
optionally the maximum sub C-state to be used used. The latter only applies
to the highest permitted C-state.
+### max-order-dirty
+> `= <integer>`
+
+Specify the maximum allocation order allowed when scrubbing allocated pages
+in-place. The allocation is non-preemptive, and hence the value must be keep
+low enough to avoid hogging the CPU for too long.
+
+Defaults to `CONFIG_DIRTY_MAX_ORDER` or if unset to `CONFIG_DOMU_MAX_ORDER`.
+
### max_gsi_irqs (x86)
> `= <integer>`
diff --git a/xen/common/page_alloc.c b/xen/common/page_alloc.c
index c9e82fd7ab62..728b4d6c9861 100644
--- a/xen/common/page_alloc.c
+++ b/xen/common/page_alloc.c
@@ -267,6 +267,13 @@ static PAGE_LIST_HEAD(page_offlined_list);
/* Broken page list, protected by heap_lock. */
static PAGE_LIST_HEAD(page_broken_list);
+/* Maximum order allowed for allocations with MEMF_no_scrub. */
+#ifndef CONFIG_DIRTY_MAX_ORDER
+# define CONFIG_DIRTY_MAX_ORDER CONFIG_DOMU_MAX_ORDER
+#endif
+static unsigned int __ro_after_init dirty_max_order = CONFIG_DIRTY_MAX_ORDER;
+integer_param("max-order-dirty", dirty_max_order);
+
/*************************
* BOOT-TIME ALLOCATOR
*/
@@ -1008,7 +1015,13 @@ static struct page_info *alloc_heap_pages(
pg = get_free_buddy(zone_lo, zone_hi, order, memflags, d);
/* Try getting a dirty buddy if we couldn't get a clean one. */
- if ( !pg && !(memflags & MEMF_no_scrub) )
+ if ( !pg && !(memflags & MEMF_no_scrub) &&
+ /*
+ * Allow any order unscrubbed allocations during boot time, we
+ * compensate by processing softirqs in the scrubbing loop below once
+ * irqs are enabled.
+ */
+ (order <= dirty_max_order || system_state < SYS_STATE_active) )
pg = get_free_buddy(zone_lo, zone_hi, order,
memflags | MEMF_no_scrub, d);
if ( !pg )
@@ -1117,6 +1130,14 @@ static struct page_info *alloc_heap_pages(
scrub_one_page(&pg[i], cold);
dirty_cnt++;
+
+ /*
+ * Use SYS_STATE_smp_boot explicitly; ahead of that state
+ * interrupts are disabled.
+ */
+ if ( system_state == SYS_STATE_smp_boot &&
+ !(dirty_cnt & 0xff) )
+ process_pending_softirqs();
}
else
check_one_page(&pg[i]);
--
2.51.0
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |