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]> --- hpoolcfg.c | 35 +++++++++++++++++++ hugeutils.c | 86 +++++++++++++++++++++++++++++++++++++++++++++++ libhugetlbfs_internal.h | 9 +++++ 3 files changed, 130 insertions(+), 0 deletions(-) diff --git a/hpoolcfg.c b/hpoolcfg.c index 887b8ed..46e8de4 100644 --- a/hpoolcfg.c +++ b/hpoolcfg.c @@ -48,11 +48,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("%10ldkB %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"; @@ -60,6 +89,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}, }; @@ -79,6 +110,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 1ce6494..3eb9af6 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" @@ -446,6 +447,91 @@ void __lh_setup_mounts(void) debug_show_page_sizes(); } +#define MAX_POOLS 32 +int __lh_hpool_sizes(struct hpage_pool *pools, int pcnt) +{ + long default_size; + int which = 0; + DIR *dir; + struct dirent *entry; + + long nr_static; + long nr_over; + long nr_used; + long nr_resv; + long nr_surp; + + default_size = size_to_smaller_unit(file_read_ulong(MEMINFO, + "Hugepagesize:")); + if (default_size >= 0) { + nr_used = get_huge_page_counter(default_size, HUGEPAGES_TOTAL); + nr_surp = get_huge_page_counter(default_size, HUGEPAGES_SURP); + nr_over = get_huge_page_counter(default_size, HUGEPAGES_OC); + nr_resv = get_huge_page_counter(default_size, HUGEPAGES_RSVD); + + /* + * XXX: this is racy with respect to ongoing + * allocations. We need to a nr_static_hugepages. + */ + nr_static = nr_used - nr_surp; + + if (which < pcnt && nr_static >= 0) { + DEBUG("default_size<%ld> min<%ld> max<%ld> " + "size<%ld>\n", + default_size, nr_static, nr_static + nr_over, + nr_used + nr_resv); + pools[which].pagesize_kb = default_size; + pools[which].minimum = nr_static; + pools[which].maximum = nr_static + nr_over; + pools[which].size = nr_used + nr_resv; + 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; + + nr_used = get_huge_page_counter(size, HUGEPAGES_TOTAL); + nr_surp = get_huge_page_counter(size, HUGEPAGES_SURP); + nr_over = get_huge_page_counter(size, HUGEPAGES_OC); + nr_resv = get_huge_page_counter(size, HUGEPAGES_RSVD); + + /* + * XXX: this is racy with respect to ongoing + * allocations. We need to a nr_static_hugepages. + */ + nr_static = nr_used - nr_surp; + + if (which < pcnt && nr_used >= 0) { + DEBUG("size<%ld> min<%ld> max<%ld> " + "size<%ld>\n", + size, nr_static, nr_static + nr_over, + nr_used + nr_resv); + pools[which].pagesize_kb = size; + pools[which].minimum = nr_static; + pools[which].maximum = nr_static + nr_over; + pools[which].size = nr_used + nr_resv; + 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); -- 1.6.0.1.451.gc8d31 ------------------------------------------------------------------------- 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