mirror of
https://github.com/xen-project/xen.git
synced 2026-10-28 02:01:24 +01:00
mm/page_alloc: make bootscrub happen in idle-loop
Scrubbing RAM during boot may take a long time on machines with lots of RAM. Add 'idle' option to bootscrub which marks all pages dirty initially so they will eventually be scrubbed in idle-loop on every online CPU. It's guaranteed that the allocator will return scrubbed pages by doing eager scrubbing during allocation (unless MEMF_no_scrub was provided). Use the new 'idle' option as the default one. Signed-off-by: Sergey Dyasli <sergey.dyasli@citrix.com> Reviewed-by: Jan Beulich <jbeulich@suse.com>
This commit is contained in:
1 parent
cc76410d20
commit
0b24ef7853
2 files changed
+64
-6
No files matched your search
@@ -227,14 +227,19 @@ that byte `0x12345678` is bad, you would place `badpage=0x12345` on
|
||||
Xen's command line.
|
||||
|
||||
### bootscrub
|
||||
> `= <boolean>`
|
||||
> `= idle | <boolean>`
|
||||
|
||||
> Default: `true`
|
||||
> Default: `idle`
|
||||
|
||||
Scrub free RAM during boot. This is a safety feature to prevent
|
||||
accidentally leaking sensitive VM data into other VMs if Xen crashes
|
||||
and reboots.
|
||||
|
||||
In `idle` mode, RAM is scrubbed in background on all CPUs during idle-loop
|
||||
with a guarantee that memory allocations always provide scrubbed pages.
|
||||
This option reduces boot time on machines with a large amount of RAM while
|
||||
still providing security benefits.
|
||||
|
||||
### bootscrub\_chunk
|
||||
> `= <size>`
|
||||
|
||||
|
||||
+57
-4
@@ -161,8 +161,42 @@ string_param("badpage", opt_badpage);
|
||||
/*
|
||||
* no-bootscrub -> Free pages are not zeroed during boot.
|
||||
*/
|
||||
static bool_t opt_bootscrub __initdata = 1;
|
||||
boolean_param("bootscrub", opt_bootscrub);
|
||||
enum bootscrub_mode {
|
||||
BOOTSCRUB_OFF,
|
||||
BOOTSCRUB_ON,
|
||||
BOOTSCRUB_IDLE,
|
||||
};
|
||||
static enum bootscrub_mode __initdata opt_bootscrub = BOOTSCRUB_IDLE;
|
||||
static int __init parse_bootscrub_param(const char *s)
|
||||
{
|
||||
/* Interpret 'bootscrub' alone in its positive boolean form */
|
||||
if ( *s == '\0' )
|
||||
{
|
||||
opt_bootscrub = BOOTSCRUB_ON;
|
||||
return 0;
|
||||
}
|
||||
|
||||
switch ( parse_bool(s, NULL) )
|
||||
{
|
||||
case 0:
|
||||
opt_bootscrub = BOOTSCRUB_OFF;
|
||||
break;
|
||||
|
||||
case 1:
|
||||
opt_bootscrub = BOOTSCRUB_ON;
|
||||
break;
|
||||
|
||||
default:
|
||||
if ( !strcmp(s, "idle") )
|
||||
opt_bootscrub = BOOTSCRUB_IDLE;
|
||||
else
|
||||
return -EINVAL;
|
||||
break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
custom_param("bootscrub", parse_bootscrub_param);
|
||||
|
||||
/*
|
||||
* bootscrub_chunk -> Amount of bytes to scrub lockstep on non-SMT CPUs
|
||||
@@ -1726,6 +1760,7 @@ static void init_heap_pages(
|
||||
struct page_info *pg, unsigned long nr_pages)
|
||||
{
|
||||
unsigned long i;
|
||||
bool idle_scrub = false;
|
||||
|
||||
/*
|
||||
* Some pages may not go through the boot allocator (e.g reserved
|
||||
@@ -1737,6 +1772,9 @@ static void init_heap_pages(
|
||||
first_valid_mfn = mfn_min(page_to_mfn(pg), first_valid_mfn);
|
||||
spin_unlock(&heap_lock);
|
||||
|
||||
if ( system_state < SYS_STATE_active && opt_bootscrub == BOOTSCRUB_IDLE )
|
||||
idle_scrub = true;
|
||||
|
||||
for ( i = 0; i < nr_pages; i++ )
|
||||
{
|
||||
unsigned int nid = phys_to_nid(page_to_maddr(pg+i));
|
||||
@@ -1763,7 +1801,7 @@ static void init_heap_pages(
|
||||
nr_pages -= n;
|
||||
}
|
||||
|
||||
free_heap_pages(pg + i, 0, scrub_debug);
|
||||
free_heap_pages(pg + i, 0, scrub_debug || idle_scrub);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2039,8 +2077,23 @@ void __init heap_init_late(void)
|
||||
*/
|
||||
setup_low_mem_virq();
|
||||
|
||||
if ( opt_bootscrub )
|
||||
switch ( opt_bootscrub )
|
||||
{
|
||||
default:
|
||||
ASSERT_UNREACHABLE();
|
||||
/* Fall through */
|
||||
|
||||
case BOOTSCRUB_IDLE:
|
||||
printk("Scrubbing free RAM on in background\n");
|
||||
break;
|
||||
|
||||
case BOOTSCRUB_ON:
|
||||
scrub_heap_pages();
|
||||
break;
|
||||
|
||||
case BOOTSCRUB_OFF:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||