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..cff5cb8 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,
+                       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..973934b 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 = 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..308aed8 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;
+       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

Reply via email to