From: Sarina Canelake <sarina.canelake@Oracle.Com>
To: xen-devel@lists.xensource.com
Subject: [RFC] new totalmem= boot parameter
Date: Mon, 19 Jul 2010 10:56:52 -0700 (PDT) [thread overview]
Message-ID: <682e4bcf-71e3-4b49-a25b-79404ae470bb@default> (raw)
[-- Attachment #1: Type: text/plain, Size: 1543 bytes --]
We have a need for ensuring the total RAM available to [Xen / the kernel] at boot is X MB because there are situations in which you wish to limit the amount of RAM available to a box. The existing mem= option doesn't work because it limits the maximum physical address, NOT the amount of available RAM. Many, if not all, systems contain a substantial memory hole below 4 Gb, typically a 0.5 or 1 Gb hole from 3-4 Gb. Thus, on a system with 6 Gb of RAM, requesting mem=4096M will yield a box with maximum physical address in the 4 Gb neighborhood but perhaps only 3 or 3.5 actual gigs of RAM available.
So I propose to add a new kernel argument, which I call totalmem, that limits the total amount of memory available, ignoring holes. So requesting totalmem=4096M in the preceding example, the maximum physical address may extend much higher depending on the size of the memory map hole. An example patch is attached; it doesn't apply directly to xen-unstable but should provide an example implementation for discussion; I implemented it to conform to the changes made to the clip_to_limit function in xen-unstable.
Alternately, we could modify mem= to do this; according to documentation, it seems that the behavior of totalmem reflects the designer's goal for mem. However, I would be worried about issues of backwards compatibility, as people may already be exploiting the current functionality of mem= to directly cut off the address space. Comments? (P.S. This is my first post to xen-devel so please be kind :)
Thanks,
Sarina
[-- Attachment #2: xen-add-totalmem-kernel-arg.patch --]
[-- Type: text/x-patch, Size: 3913 bytes --]
Adds a new kernel arg, totalmem=, to specify the amount of physical memory
(whereas the prveious available option had only been mem=, which limits the
address of physical memory)
07/19/2010
patch written by Sarina Canelake (sarina.canelake@oracle.com)
diff -up xen/arch/x86/e820.c.orig xen/arch/x86/e820.c
--- xen/arch/x86/e820.c.orig 2010-07-19 11:50:49.000000000 -0600
+++ xen/arch/x86/e820.c 2010-07-19 11:52:13.000000000 -0600
@@ -10,10 +10,14 @@
#include <asm/mtrr.h>
#include <asm/msr.h>
-/* opt_mem: Limit of physical RAM. Any RAM beyond this point is ignored. */
+/* opt_mem: Limit address of physical RAM. Any RAM beyond this point is ignored. */
static unsigned long long __initdata opt_mem;
size_param("mem", opt_mem);
+/* opt_totalmem: Limit amount of physical RAM; any RAM beyond this point is ignored. */
+static unsigned long long __initdata opt_totalmem;
+size_param("totalmem", opt_totalmem);
+
/* opt_nomtrr_check: Don't clip ram to highest cacheable MTRR. */
static int __initdata e820_mtrr_clip = -1;
boolean_param("e820-mtrr-clip", e820_mtrr_clip);
@@ -416,6 +420,77 @@ static void __init clip_to_limit(uint64_
}
}
+static void __init clip_to_totalmem_limit(uint64_t totalmem_limit, char *warnmsg)
+{
+ int i;
+ char _warnmsg[160];
+ uint64_t old_limit, test_limit, start_addr = 0;
+
+ for ( ; ; )
+ {
+ test_limit = 0; old_limit = 0;
+ /* Find a RAM region needing clipping. */
+ for ( i=0; i < e820.nr_map; i++ )
+ {
+ /* Try adding this region's memory; test if exceeds */
+ test_limit = old_limit + e820.map[i].size;
+ if ( (e820.map[i].type == E820_RAM) &&
+ (test_limit > totalmem_limit) )
+ {
+ /* If exceeds we need to mark this region as unusable. Determine
+ the starting address of where to start the unusable segment. */
+ if ( start_addr == 0 ) {
+ start_addr = e820.map[i].addr + (totalmem_limit - old_limit);
+
+ }
+ else
+ start_addr = e820.map[i].addr;
+
+ break;
+ }
+
+ old_limit = test_limit;
+ }
+
+ /* If none found, we are done. */
+ if ( i == e820.nr_map )
+ break;
+
+ /* We try to convert clipped RAM areas to E820_UNUSABLE
+ (need to give an address to start from marking at unusable)*/
+ if ( e820_change_range_type(&e820, start_addr,
+ e820.map[i].addr + e820.map[i].size,
+ E820_RAM, E820_UNUSABLE) )
+ continue;
+
+ /*
+ * If the type change fails (e.g., not space in table) then we clip or
+ * delete the region as appropriate.
+ */
+ if ( old_limit < totalmem_limit )
+ {
+ e820.map[i].size = totalmem_limit - old_limit;
+ }
+ else
+ {
+ memmove(&e820.map[i], &e820.map[i+1],
+ (e820.nr_map - i - 1) * sizeof(struct e820entry));
+ e820.nr_map--;
+ }
+ }
+
+ if ( old_limit )
+ {
+ if ( warnmsg )
+ {
+ snprintf(_warnmsg, sizeof(_warnmsg), warnmsg, (long)(totalmem_limit>>30));
+ printk("WARNING: %s\n", _warnmsg);
+ }
+ printk("Truncating RAM from %lukB to %lukB\n",
+ (unsigned long)(old_limit >> 10), (unsigned long)(totalmem_limit >> 10));
+ }
+}
+
/* Conservative estimate of top-of-RAM by looking for MTRR WB regions. */
#define MSR_MTRRphysBase(reg) (0x200 + 2 * (reg))
#define MSR_MTRRphysMask(reg) (0x200 + 2 * (reg) + 1)
@@ -513,6 +588,9 @@ static void __init machine_specific_memo
if ( opt_mem )
clip_to_limit(opt_mem, NULL);
+ else if ( opt_totalmem )
+ clip_to_totalmem_limit(opt_totalmem, NULL);
+
#ifdef __i386__
clip_to_limit((1ULL << 30) * MACHPHYS_MBYTES,
"Only the first %lu GB of the physical memory map "
[-- Attachment #3: Type: text/plain, Size: 138 bytes --]
_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xensource.com
http://lists.xensource.com/xen-devel
next reply other threads:[~2010-07-19 17:56 UTC|newest]
Thread overview: 5+ messages / expand[flat|nested] mbox.gz Atom feed top
2010-07-19 17:56 Sarina Canelake [this message]
2010-07-19 18:11 ` [RFC] new totalmem= boot parameter Keir Fraser
2010-07-20 21:26 ` Sarina Canelake
2010-07-20 21:55 ` Konrad Rzeszutek Wilk
2010-07-21 7:46 ` Keir Fraser
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=682e4bcf-71e3-4b49-a25b-79404ae470bb@default \
--to=sarina.canelake@oracle.com \
--cc=xen-devel@lists.xensource.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).