On Fri, 2008-10-10 at 16:58 +0100, Andy Whitcroft wrote: > Expose pool allocations for each of the available page sizes via the > --pool-list command. Exposes the miniumum and maximimum values indicating > the dedicated pages and the size of the overcommit for all supported page > sizes. > > Signed-off-by: Andy Whitcroft <[EMAIL PROTECTED]> > Acked-by: Mel Gorman <[EMAIL PROTECTED]> Acked-by: Adam Litke <[EMAIL PROTECTED]>
> --- > hugeadm.c | 35 +++++++++++++++++++ > hugeutils.c | 85 > +++++++++++++++++++++++++++++++++++++++++++++++ > libhugetlbfs_internal.h | 9 +++++ > 3 files changed, 129 insertions(+), 0 deletions(-) > > diff --git a/hugeadm.c b/hugeadm.c > index 78beec7..86dc97b 100644 > --- a/hugeadm.c > +++ b/hugeadm.c > @@ -47,11 +47,40 @@ void print_usage() > fprintf(stderr, "hugectl [options] target\n"); > fprintf(stderr, "options:\n"); > > + OPTION("--pool-list", "List all pools"); > + > OPTION("--help, -h", "Prints this message"); > } > > int opt_dry_run = 0; > > +/* > + * getopts return values for options which are long only. > + */ > +#define LONG_POOL ('p' << 8) > +#define LONG_POOL_LIST (LONG_POOL|'l') > + > +#define MAX_POOLS 32 > +void pool_list(void) > +{ > + struct hpage_pool pools[MAX_POOLS]; > + int pos; > + int cnt; > + > + cnt = __lh_hpool_sizes(pools, MAX_POOLS); > + if (cnt < 0) { > + ERROR("unable to obtain pools list"); > + exit(EXIT_FAILURE); > + } > + > + printf("%10s %8s %8s %8s\n", "Size", "Minimum", "Current", "Maximum"); > + for (pos = 0; cnt--; pos++) { > + printf("%10ld %8ld %8ld %8ld\n", pools[pos].pagesize_kb, > + pools[pos].minimum, pools[pos].size, > + pools[pos].maximum); > + } > +} > + > int main(int argc, char** argv) > { > char opts[] = "+h"; > @@ -59,6 +88,8 @@ int main(int argc, char** argv) > struct option long_opts[] = { > {"help", no_argument, NULL, 'h'}, > > + {"pool-list", no_argument, NULL, LONG_POOL_LIST}, > + > {0}, > }; > > @@ -78,6 +109,10 @@ int main(int argc, char** argv) > print_usage(); > exit(EXIT_SUCCESS); > > + case LONG_POOL_LIST: > + pool_list(); > + break; > + > default: > WARNING("unparsed option %08x\n", ret); > ret = -1; > diff --git a/hugeutils.c b/hugeutils.c > index 7d7f8c3..0d2dba9 100644 > --- a/hugeutils.c > +++ b/hugeutils.c > @@ -43,6 +43,7 @@ > #include <sys/syscall.h> > #include <linux/types.h> > #include <linux/unistd.h> > +#include <dirent.h> > > #include "libhugetlbfs_internal.h" > #include "hugetlbfs.h" > @@ -455,6 +456,90 @@ void __lh_setup_mounts(void) > debug_show_page_sizes(); > } > > +static int get_pool_size(long size, struct hpage_pool *pool) > +{ > + long nr_over = 0; > + long nr_used = 0; > + long nr_surp = 0; > + long nr_resv = 0; > + long nr_static = 0; > + > + long it_used = -1; > + long it_surp = -1; > + long it_resv = -1; > + > + /* > + * Pick up those values which are basically stable with respect to > + * the admin; ie. only changed by them. > + */ > + nr_over = get_huge_page_counter(size, HUGEPAGES_OC); > + > + /* Sample the volatile values until they are stable. */ > + while (nr_used != it_used || nr_surp != it_surp || nr_resv != it_resv) { > + nr_used = it_used; > + nr_surp = it_surp; > + nr_resv = it_resv; > + > + it_used = get_huge_page_counter(size, HUGEPAGES_TOTAL); > + it_surp = get_huge_page_counter(size, HUGEPAGES_SURP); > + it_resv = get_huge_page_counter(size, HUGEPAGES_RSVD); > + } > + > + nr_static = nr_used - nr_surp; > + > + if (nr_static >= 0) { > + DEBUG("size<%ld> min<%ld> max<%ld> " > + "size<%ld>\n", > + size, nr_static, nr_static + nr_over, > + nr_used + nr_resv); > + pool->pagesize_kb = size; > + pool->minimum = nr_static; > + pool->maximum = nr_static + nr_over; > + pool->size = nr_used + nr_resv; > + > + return 1; > + } > + > + return 0; > +} > + > +int __lh_hpool_sizes(struct hpage_pool *pools, int pcnt) > +{ > + long default_size; > + int which = 0; > + DIR *dir; > + struct dirent *entry; > + > + default_size = size_to_smaller_unit(file_read_ulong(MEMINFO, > + "Hugepagesize:")); > + if (default_size >= 0 && which < pcnt) > + if (get_pool_size(default_size, &pools[which])) > + which++; > + > + dir = opendir(SYSFS_HUGEPAGES_DIR); > + if (dir) { > + while ((entry = readdir(dir))) { > + char *name = entry->d_name; > + long size; > + > + DEBUG("parsing<%s>\n", name); > + if (strncmp(name, "hugepages-", 10) != 0) > + continue; > + name += 10; > + > + size = size_to_smaller_unit(atol(name)); > + if (size < 0 || size == default_size) > + continue; > + > + if (get_pool_size(size, &pools[which])) > + which++; > + } > + closedir(dir); > + } > + > + return (which < pcnt) ? which : -1; > +} > + > /********************************************************************/ > /* Library user visible functions */ > /********************************************************************/ > diff --git a/libhugetlbfs_internal.h b/libhugetlbfs_internal.h > index 197fa05..2912c5e 100644 > --- a/libhugetlbfs_internal.h > +++ b/libhugetlbfs_internal.h > @@ -89,6 +89,15 @@ struct hpage_size { > char mount[PATH_MAX+1]; > }; > > +struct hpage_pool { > + unsigned long pagesize_kb; > + unsigned long minimum; > + unsigned long maximum; > + unsigned long size; > +}; > + > +extern int __lh_hpool_sizes(struct hpage_pool *, int); > + > /* Arch-specific callbacks */ > extern int direct_syscall(int sysnum, ...); > extern ElfW(Word) plt_extrasz(ElfW(Dyn) *dyntab); -- Adam Litke - (agl at us.ibm.com) IBM Linux Technology Center ------------------------------------------------------------------------- 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