mirror of
https://github.com/xen-project/xen.git
synced 2026-10-28 02:01:24 +01:00
[XEN] Extend dom0_mem syntax to support min/max clamps.
dom0_mem=[min:<min_amt>,][max:<max_amt>,][<amt>]
<min_amt>: The minimum amount of memory which should be allocated for dom0.
<max_amt>: The maximum amount of memory which should be allocated for dom0.
<amt>: The precise amount of memory to allocate for dom0.
Notes:
1. <amt> is clamped from below by <min_amt> and from above by available
memory and <max_amt>
2. <min_amt> is clamped from above by available memory and <max_amt>
3. <min_amt> is ignored if it is greater than <max_amt>
4. If <amt> is not specified, it is calculated as follows:
"All of memory is allocated to domain 0, minus 1/16th which is reserved
for uses such as DMA buffers (the reservation is clamped to 128MB)."
Each value can be specified as positive or negative:
If +ve: The specified amount is an absolute value.
If -ve: The specified amount is subtracted from total available memory.
Signed-off-by: Keir Fraser <keir@xensource.com>
This commit is contained in:
1 parent
aeade7ad12
commit
7ffcc43b02
8 files changed
+92
-48
No files matched your search
+13
-4
@@ -3202,12 +3202,21 @@ editing \path{grub.conf}.
|
||||
ignored. This parameter may be specified with a B, K, M or G suffix,
|
||||
representing bytes, kilobytes, megabytes and gigabytes respectively.
|
||||
The default unit, if no suffix is specified, is kilobytes.
|
||||
\item [ dom0\_mem=xxx ] Set the amount of memory to be allocated to
|
||||
domain0. In Xen 3.x the parameter may be specified with a B, K, M or
|
||||
\item [ dom0\_mem=$<$specifier list$>$ ] Set the amount of memory to
|
||||
be allocated to domain 0. This is a comma-separated list containing
|
||||
the following optional components:
|
||||
\begin{description}
|
||||
\item[ min:$<$min\_amt$>$ ] Minimum amount to allocate to domain 0
|
||||
\item[ max:$<$min\_amt$>$ ] Maximum amount to allocate to domain 0
|
||||
\item[ $<$amt$>$ ] Precise amount to allocate to domain 0
|
||||
\end{description}
|
||||
Each numeric parameter may be specified with a B, K, M or
|
||||
G suffix, representing bytes, kilobytes, megabytes and gigabytes
|
||||
respectively; if no suffix is specified, the parameter defaults to
|
||||
kilobytes. In previous versions of Xen, suffixes were not supported
|
||||
and the value is always interpreted as kilobytes.
|
||||
kilobytes. Negative values are subtracted from total available
|
||||
memory. If $<$amt$>$ is not specified, it defaults to all available
|
||||
memory less a small amount (clamped to 128MB) for uses such as DMA
|
||||
buffers.
|
||||
\item [ dom0\_vcpus\_pin ] Pins domain 0 VCPUs on their respective
|
||||
physical CPUS (default=false).
|
||||
\item [ tbuf\_size=xxx ] Set the size of the per-cpu trace buffers, in
|
||||
|
||||
@@ -1177,6 +1177,6 @@ void sync_vcpu_execstate(struct vcpu *v)
|
||||
|
||||
static void parse_dom0_mem(char *s)
|
||||
{
|
||||
dom0_size = parse_size_and_unit(s);
|
||||
dom0_size = parse_size_and_unit(s, NULL);
|
||||
}
|
||||
custom_param("dom0_mem", parse_dom0_mem);
|
||||
@@ -40,7 +40,7 @@ static void parse_dom0_mem(char *s)
|
||||
{
|
||||
unsigned long long bytes;
|
||||
|
||||
bytes = parse_size_and_unit(s);
|
||||
bytes = parse_size_and_unit(s, NULL);
|
||||
dom0_nrpages = bytes >> PAGE_SHIFT;
|
||||
}
|
||||
custom_param("dom0_mem", parse_dom0_mem);
|
||||
|
||||
+64
-36
@@ -33,28 +33,45 @@
|
||||
extern unsigned long initial_images_nrpages(void);
|
||||
extern void discard_initial_images(void);
|
||||
|
||||
static long dom0_nrpages;
|
||||
static long dom0_nrpages, dom0_min_nrpages, dom0_max_nrpages = LONG_MAX;
|
||||
|
||||
/*
|
||||
* dom0_mem:
|
||||
* If +ve:
|
||||
* * The specified amount of memory is allocated to domain 0.
|
||||
* If -ve:
|
||||
* * All of memory is allocated to domain 0, minus the specified amount.
|
||||
* If not specified:
|
||||
* * All of memory is allocated to domain 0, minus 1/16th which is reserved
|
||||
* for uses such as DMA buffers (the reservation is clamped to 128MB).
|
||||
* dom0_mem=[min:<min_amt>,][max:<max_amt>,][<amt>]
|
||||
*
|
||||
* <min_amt>: The minimum amount of memory which should be allocated for dom0.
|
||||
* <max_amt>: The maximum amount of memory which should be allocated for dom0.
|
||||
* <amt>: The precise amount of memory to allocate for dom0.
|
||||
*
|
||||
* Notes:
|
||||
* 1. <amt> is clamped from below by <min_amt> and from above by available
|
||||
* memory and <max_amt>
|
||||
* 2. <min_amt> is clamped from above by available memory and <max_amt>
|
||||
* 3. <min_amt> is ignored if it is greater than <max_amt>
|
||||
* 4. If <amt> is not specified, it is calculated as follows:
|
||||
* "All of memory is allocated to domain 0, minus 1/16th which is reserved
|
||||
* for uses such as DMA buffers (the reservation is clamped to 128MB)."
|
||||
*
|
||||
* Each value can be specified as positive or negative:
|
||||
* If +ve: The specified amount is an absolute value.
|
||||
* If -ve: The specified amount is subtracted from total available memory.
|
||||
*/
|
||||
static long parse_amt(char *s, char **ps)
|
||||
{
|
||||
long pages = parse_size_and_unit((*s == '-') ? s+1 : s, ps) >> PAGE_SHIFT;
|
||||
return (*s == '-') ? -pages : pages;
|
||||
}
|
||||
static void parse_dom0_mem(char *s)
|
||||
{
|
||||
unsigned long long bytes;
|
||||
char *t = s;
|
||||
if ( *s == '-' )
|
||||
t++;
|
||||
bytes = parse_size_and_unit(t);
|
||||
dom0_nrpages = bytes >> PAGE_SHIFT;
|
||||
if ( *s == '-' )
|
||||
dom0_nrpages = -dom0_nrpages;
|
||||
do {
|
||||
if ( !strncmp(s, "min:", 4) )
|
||||
dom0_min_nrpages = parse_amt(s+4, &s);
|
||||
else if ( !strncmp(s, "max:", 4) )
|
||||
dom0_max_nrpages = parse_amt(s+4, &s);
|
||||
else
|
||||
dom0_nrpages = parse_amt(s, &s);
|
||||
if ( *s != ',' )
|
||||
break;
|
||||
} while ( *s++ == ',' );
|
||||
}
|
||||
custom_param("dom0_mem", parse_dom0_mem);
|
||||
|
||||
@@ -103,6 +120,35 @@ static struct page_info *alloc_chunk(struct domain *d, unsigned long max_pages)
|
||||
return page;
|
||||
}
|
||||
|
||||
static unsigned long compute_dom0_nr_pages(void)
|
||||
{
|
||||
unsigned long avail = avail_domheap_pages() + initial_images_nrpages();
|
||||
|
||||
/*
|
||||
* If domain 0 allocation isn't specified, reserve 1/16th of available
|
||||
* memory for things like DMA buffers. This reservation is clamped to
|
||||
* a maximum of 128MB.
|
||||
*/
|
||||
if ( dom0_nrpages == 0 )
|
||||
{
|
||||
dom0_nrpages = avail;
|
||||
dom0_nrpages = min(dom0_nrpages / 16, 128L << (20 - PAGE_SHIFT));
|
||||
dom0_nrpages = -dom0_nrpages;
|
||||
}
|
||||
|
||||
/* Negative memory specification means "all memory - specified amount". */
|
||||
if ( dom0_nrpages < 0 ) dom0_nrpages += avail;
|
||||
if ( dom0_min_nrpages < 0 ) dom0_min_nrpages += avail;
|
||||
if ( dom0_max_nrpages < 0 ) dom0_max_nrpages += avail;
|
||||
|
||||
/* Clamp dom0 memory according to min/max limits and available memory. */
|
||||
dom0_nrpages = max(dom0_nrpages, dom0_min_nrpages);
|
||||
dom0_nrpages = min(dom0_nrpages, dom0_max_nrpages);
|
||||
dom0_nrpages = min(dom0_nrpages, (long)avail);
|
||||
|
||||
return dom0_nrpages;
|
||||
}
|
||||
|
||||
static void process_dom0_ioports_disable(void)
|
||||
{
|
||||
unsigned long io_from, io_to;
|
||||
@@ -269,25 +315,7 @@ int construct_dom0(struct domain *d,
|
||||
|
||||
d->max_pages = ~0U;
|
||||
|
||||
/*
|
||||
* If domain 0 allocation isn't specified, reserve 1/16th of available
|
||||
* memory for things like DMA buffers. This reservation is clamped to
|
||||
* a maximum of 128MB.
|
||||
*/
|
||||
if ( dom0_nrpages == 0 )
|
||||
{
|
||||
dom0_nrpages = avail_domheap_pages() + initial_images_nrpages();
|
||||
dom0_nrpages = min(dom0_nrpages / 16, 128L << (20 - PAGE_SHIFT));
|
||||
dom0_nrpages = -dom0_nrpages;
|
||||
}
|
||||
|
||||
/* Negative memory specification means "all memory - specified amount". */
|
||||
if ( dom0_nrpages < 0 )
|
||||
nr_pages = avail_domheap_pages() + initial_images_nrpages() +
|
||||
dom0_nrpages;
|
||||
else
|
||||
nr_pages = min(avail_domheap_pages() + initial_images_nrpages(),
|
||||
(unsigned long)dom0_nrpages);
|
||||
nr_pages = compute_dom0_nr_pages();
|
||||
|
||||
if ( (rc = parseelfimage(&dsi)) != 0 )
|
||||
return rc;
|
||||
|
||||
+1
-1
@@ -6,7 +6,7 @@
|
||||
|
||||
/* opt_mem: Limit of physical RAM. Any RAM beyond this point is ignored. */
|
||||
unsigned long long opt_mem;
|
||||
static void parse_mem(char *s) { opt_mem = parse_size_and_unit(s); }
|
||||
static void parse_mem(char *s) { opt_mem = parse_size_and_unit(s, NULL); }
|
||||
custom_param("mem", parse_mem);
|
||||
|
||||
struct e820map e820;
|
||||
|
||||
+10
-3
@@ -439,21 +439,28 @@ s64 __moddi3(s64 a, s64 b)
|
||||
|
||||
#endif /* BITS_PER_LONG == 32 */
|
||||
|
||||
unsigned long long parse_size_and_unit(char *s)
|
||||
unsigned long long parse_size_and_unit(const char *s, char **ps)
|
||||
{
|
||||
unsigned long long ret = simple_strtoull(s, &s, 0);
|
||||
unsigned long long ret = simple_strtoull(s, (char **)&s, 0);
|
||||
|
||||
switch (*s) {
|
||||
case 'G': case 'g':
|
||||
ret <<= 10;
|
||||
case 'M': case 'm':
|
||||
ret <<= 10;
|
||||
case 'K': case 'k': default:
|
||||
case 'K': case 'k':
|
||||
ret <<= 10;
|
||||
case 'B': case 'b':
|
||||
s++;
|
||||
break;
|
||||
default:
|
||||
ret <<= 10; /* default to kB */
|
||||
break;
|
||||
}
|
||||
|
||||
if (ps != NULL)
|
||||
*ps = (char *)s;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
@@ -54,7 +54,7 @@ static unsigned long lowmem_emergency_pool_pages;
|
||||
static void parse_lowmem_emergency_pool(char *s)
|
||||
{
|
||||
unsigned long long bytes;
|
||||
bytes = parse_size_and_unit(s);
|
||||
bytes = parse_size_and_unit(s, NULL);
|
||||
lowmem_emergency_pool_pages = bytes >> PAGE_SHIFT;
|
||||
}
|
||||
custom_param("lowmem_emergency_pool", parse_lowmem_emergency_pool);
|
||||
|
||||
@@ -86,7 +86,7 @@ long long simple_strtoll(
|
||||
unsigned long long simple_strtoull(
|
||||
const char *cp,char **endp, unsigned int base);
|
||||
|
||||
unsigned long long parse_size_and_unit(char *s);
|
||||
unsigned long long parse_size_and_unit(const char *s, char **ps);
|
||||
|
||||
#define TAINT_UNSAFE_SMP (1<<0)
|
||||
#define TAINT_MACHINE_CHECK (1<<1)
|
||||
|
||||