On Wed, Oct 29, 2008 at 04:02:53PM +0000, Andy Whitcroft wrote: > Add support for multiple page sizes to hugectl. Now that the library > supports specification of the backing page size to use for the various > mappings we should expose this functionality in hugectl. This patch > adds an optional size argument to all of the segment mapping options > specifying the backing page size required. These are converted into the > appropriate variables and passed on. For example, the following incantation > requests text be placed in 2MB pages, data in 64KB pages and the heap in > the default size: > > hugectl --text=2M --data=64K --heap ls > > Combinations which are not possible result in warnings as normal. > The sizes are not validated but passed verbatim to the library which will > then validate them.
Ok, I can confirm that on an opteron with 2M and 1G pages, that I can text/data one size and heap another. When running a basic program that just mallocs and goes to sleep, I see 00400000-00600000 r-xp 00000000 00:11 8711 /var/lib/hugetlbfs/mounts/pagesize-2097152/libhugetlbfs.tmp.kCVwTh (deleted) 00800000-00a00000 rw-p 00000000 00:11 8712 /var/lib/hugetlbfs/mounts/pagesize-2097152/libhugetlbfs.tmp.ChUZCu (deleted) 40000000-80000000 rw-p 00000000 00:12 8713 /var/lib/hugetlbfs/mounts/pagesize-1073741824/libhugetlbfs.tmp.a66ImH (deleted) and the pagesize mounts are what you would expect. So, this is functionally correct by the looks of things. > Signed-off-by: Andy Whitcroft <[EMAIL PROTECTED]> > --- > hugectl.c | 108 > ++++++++++++++++++++++++++++++++++++++++--------------------- > 1 files changed, 71 insertions(+), 37 deletions(-) > > diff --git a/hugectl.c b/hugectl.c > index 902085e..a07fcb5 100644 > --- a/hugectl.c > +++ b/hugectl.c > @@ -154,49 +154,73 @@ void verbose_expose(void) > #define LONG_LIBRARY (LONG_BASE | 'l') > > /* > - * Mapping selectors, one bit per remappable/backable area as requested > + * Mapping selectors, one per remappable/backable area as requested > * by the user. These are also used as returns from getopts where they > * are offset from MAP_BASE, which must be removed before they are compared. > */ > -#define MAP_DISABLE 0x0001 > -#define MAP_TEXT 0x0002 > -#define MAP_DATA 0x0004 > -#define MAP_BSS 0x0008 > -#define MAP_HEAP 0x0010 > -#define MAP_SHM 0x0020 > - > -void setup_mappings(int which) > +enum { > + MAP_TEXT, > + MAP_DATA, > + MAP_BSS, > + MAP_HEAP, > + MAP_SHM, > + MAP_DISABLE, > + > + MAP_COUNT, > +}; > +char *map_size[MAP_COUNT]; > + > +char default_size[] = "the default hugepage size"; > +#define DEFAULT_SIZE default_size > + I don't believe you actually use the contents of default_size anywhere and you just use it as a pointer value for the purposes of comparison. It probably could have been NULL or &mapsize too. Not that it matters a whole pile. > +void setup_mappings(int count) > { > - char remap[3] = { 0, 0, 0 }; > - int n = 0; > + char value[20 + 20]; > + char *ptr = value; > What's this 20 + 20 about? I'm guessing it's the maximum sensible string size that can be placed in the environment variable but we never check the bounds of it, nor do we ever check if ptr goes over it. If hugectl was a suid binary like a hugetlbfs user to access a mount or accessible under sudo, this could be an exploit? > /* > * HUGETLB_ELFMAP should be set to either a combination of 'R' and 'W' > * which indicate which segments should be remapped. It may also be > * set to 'no' to prevent remapping. > */ The comment here is now a tad stale. > - if (which & MAP_TEXT) > - remap[n++] = 'R'; > - if (which & (MAP_DATA|MAP_BSS)) { > - if ((which & (MAP_DATA|MAP_BSS)) != (MAP_DATA|MAP_BSS)) > - WARNING("data and bss remapped together\n"); > - remap[n++] = 'W'; > + if (map_size[MAP_TEXT]) { > + *ptr++ = ':'; > + if (map_size[MAP_TEXT] == DEFAULT_SIZE) > + *ptr++ = 'R'; > + else > + ptr += sprintf(ptr, "R=%s", map_size[MAP_TEXT]); heh, took me a few minutes to figure out why the environment variable did not always start with a ':' :) > } > - if (which & MAP_DISABLE) { > - if (which != MAP_DISABLE) > - WARNING("--disable masks requested remap\n"); > - n = 0; > - remap[n++] = 'n'; > - remap[n++] = 'o'; > + if (map_size[MAP_DATA] != 0 || map_size[MAP_BSS] != 0) { Any reason why it's not simply map_size[MAP_DATA] like the MAP_TEXT check above? > + char *size = map_size[MAP_BSS]; > + if (map_size[MAP_DATA]) > + size = map_size[MAP_DATA]; > + if (map_size[MAP_DATA] != map_size[MAP_BSS]) > + WARNING("data and bss remapped together in %s\n", size); ouch, this is a curious one. It's actually pretty bad if the user expects these things to be mapped different. However, our default level is ERROR, not WARNING so this message is not displayed unless there is at least one -v. It's not an error either though hmmm... Not much that can be done about it I guess. > + *ptr++ = ':'; > + if (size == DEFAULT_SIZE) > + *ptr++ = 'W'; > + else > + ptr += sprintf(ptr, "W=%s", size); > } > + *ptr = '\0'; > + if (ptr != value) > + setup_environment("HUGETLB_ELFMAP", &value[1]); > > - if (n) > - setup_environment("HUGETLB_ELFMAP", remap); > + if (map_size[MAP_DISABLE]) { > + if (ptr != value) > + WARNING("--disable masks requested remap\n"); > + setup_environment("HUGETLB_ELFMAP", "no"); > + } > > - if (which & MAP_HEAP) > + if (map_size[MAP_HEAP] == DEFAULT_SIZE) > setup_environment("HUGETLB_MORECORE", "yes"); > + else if (map_size[MAP_HEAP]) > + setup_environment("HUGETLB_MORECORE", map_size[MAP_HEAP]); > > - if (which & MAP_SHM) > + if (map_size[MAP_SHM] && map_size[MAP_SHM] != DEFAULT_SIZE) > + WARNING("shm segments may only be mapped in the " > + "default hugepage size\n"); Similarly there is an important warning that can be omitted without -v. > + if (map_size[MAP_SHM]) > setup_environment("HUGETLB_SHM", "yes"); > } > > @@ -256,9 +280,16 @@ void library_path(char *path) > setup_environment("LD_LIBRARY_PATH", val); > } > > -void ldpreload(int which) > +void ldpreload(int count) > { > - if (which & (MAP_HEAP|MAP_SHM)) { > + int allowed = 0; > + > + if (map_size[MAP_HEAP]) > + allowed++; > + if (map_size[MAP_SHM]) > + allowed++; > + > + if (allowed == count) { > setup_environment("LD_PRELOAD", "libhugetlbfs.so"); > WARNING("LD_PRELOAD in use for lone --heap/--shm\n"); > } else { > @@ -284,12 +315,12 @@ int main(int argc, char** argv) > {"library-use-path", > no_argument, NULL, LONG_NO_LIBRARY}, > > - {"disable", no_argument, NULL, MAP_BASE|MAP_DISABLE}, > - {"text", no_argument, NULL, MAP_BASE|MAP_TEXT}, > - {"data", no_argument, NULL, MAP_BASE|MAP_DATA}, > - {"bss", no_argument, NULL, MAP_BASE|MAP_BSS}, > - {"heap", no_argument, NULL, MAP_BASE|MAP_HEAP}, > - {"shm", no_argument, NULL, MAP_BASE|MAP_SHM}, > + {"disable", optional_argument, NULL, MAP_BASE|MAP_DISABLE}, > + {"text", optional_argument, NULL, MAP_BASE|MAP_TEXT}, > + {"data", optional_argument, NULL, MAP_BASE|MAP_DATA}, > + {"bss", optional_argument, NULL, MAP_BASE|MAP_BSS}, > + {"heap", optional_argument, NULL, MAP_BASE|MAP_HEAP}, > + {"shm", optional_argument, NULL, MAP_BASE|MAP_SHM}, > We update for optinal arguments here, but the help message is not updated, or the man page. > {0}, > }; > @@ -299,7 +330,11 @@ int main(int argc, char** argv) > while (ret != -1) { > ret = getopt_long(argc, argv, opts, long_opts, &index); > if (ret > 0 && (ret & MAP_BASE)) { > - opt_mappings |= ret; > + if (optarg) > + map_size[ret & ~MAP_BASE] = optarg; > + else > + map_size[ret & ~MAP_BASE] = DEFAULT_SIZE; > + opt_mappings++; > continue; > } > switch (ret) { > @@ -343,7 +378,6 @@ int main(int argc, char** argv) > } > } > index = optind; > - opt_mappings &= ~MAP_BASE; > > if (!opt_dry_run && (argc - index) < 1) { > print_usage(); > -- > 1.6.0.2.711.gf1ba4 > -- Mel Gorman Part-time Phd Student Linux Technology Center University of Limerick IBM Dublin Software Lab ------------------------------------------------------------------------- This SF.Net email is sponsored by the Moblin Your Move Developer's challenge Build the coolest Linux based applications with Moblin SDK & win great prizes Grand prize is a trip for two to an Open Source event anywhere in the world http://moblin-contest.org/redirect.php?banner_id=100&url=/ _______________________________________________ Libhugetlbfs-devel mailing list Libhugetlbfs-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/libhugetlbfs-devel