Utilise the new gethugepagesizes call to implement getpagesizes() call returning all page sizes on the system, both base page sizes and all hugepage sizes.
Signed-off-by: Andy Whitcroft <[EMAIL PROTECTED]> --- hugetlbfs.h | 1 + hugeutils.c | 27 +++++++++++++++ tests/gethugepagesizes.c | 84 +++++++++++++++++++++++++++++++++++++--------- 3 files changed, 96 insertions(+), 16 deletions(-) diff --git a/hugetlbfs.h b/hugetlbfs.h index 985e138..3f2eb30 100644 --- a/hugetlbfs.h +++ b/hugetlbfs.h @@ -23,6 +23,7 @@ long gethugepagesize(void); int gethugepagesizes(long pagesizes[], int n_elem); +int getpagesizes(long pagesizes[], int n_elem); int hugetlbfs_test_path(const char *mount); long hugetlbfs_test_pagesize(const char *mount); const char *hugetlbfs_find_path(void); diff --git a/hugeutils.c b/hugeutils.c index 03d059e..afd6933 100644 --- a/hugeutils.c +++ b/hugeutils.c @@ -626,6 +626,33 @@ int gethugepagesizes(long pagesizes[], int n_elem) return nr_sizes; } +int getpagesizes(long pagesizes[], int n_elem) +{ + int ret; + + if (n_elem < 0 || (n_elem > 0 && pagesizes == NULL)) { + errno = EINVAL; + return -1; + } + + /* Requests for sizing, we need one more slot than gethugepagesizes. */ + if (pagesizes == NULL && n_elem == 0) { + ret = gethugepagesizes(pagesizes, n_elem); + + } else { + /* Install the base page size. */ + if (n_elem && pagesizes) + pagesizes[0] = sysconf(_SC_PAGESIZE); + if (n_elem == 1) + return 1; + + ret = gethugepagesizes(pagesizes + 1, n_elem - 1); + } + if (ret < 0) + return ret; + return ret + 1; +} + int hugetlbfs_test_path(const char *mount) { struct statfs64 sb; diff --git a/tests/gethugepagesizes.c b/tests/gethugepagesizes.c index 44aff68..0cd97ed 100644 --- a/tests/gethugepagesizes.c +++ b/tests/gethugepagesizes.c @@ -72,6 +72,8 @@ DIR *opendir(const char *name) } } +#define HPAGE_SIZE (16 * 1024) + /* * Override read_meminfo to simulate various conditions */ @@ -86,7 +88,7 @@ long read_meminfo(const char *tag) switch (meminfo_state) { case OVERRIDE_OFF: return real_read_meminfo(tag); - case OVERRIDE_ON: return 16 * 1024; + case OVERRIDE_ON: return HPAGE_SIZE; default: return -1; } } @@ -141,10 +143,8 @@ void cleanup(void) cleanup_fake_sysfs(); } -#define INIT_SIZES(a, v1, v2, v3) {a[0] = v1; a[1] = v2; a[2] = v3; a[3] = -1;} - -void expect_sizes(int line, int expected, int actual, - long expected_sizes[], long actual_sizes[]) +void validate_sizes(int line, long actual_sizes[], int actual, int max_actual, + long expected_sizes[], int expected) { int i, j; if (expected != actual) @@ -159,12 +159,37 @@ void expect_sizes(int line, int expected, int actual, FAIL("Line %i: Expected size %li not found in actual " "results", line, expected_sizes[i]); } + + for (i = expected; i < max_actual; i++) + if (actual_sizes[i] != 42) + FAIL("Line %i: Wrote past official limit at %i", + line, i); } +#define MAX 16 +#define EXPECT_SIZES(func, max, count, expected) \ +({ \ + long __a[MAX] = { [0 ... MAX-1] = 42 }; \ + int __na; \ + int __l = (count < max) ? count : max; \ + \ + __na = func(__a, max); \ + \ + validate_sizes(__LINE__, __a, __na, MAX, expected, __l); \ + \ + __na; \ +}) + +#define INIT_LIST(a, values...) \ +({ \ + long __e[] = { values }; \ + memcpy(a, __e, sizeof(__e)); \ +}) + int main(int argc, char *argv[]) { - long expected_sizes[4], actual_sizes[4], meminfo_size; - int nr_sizes; + long expected_sizes[MAX], actual_sizes[MAX], meminfo_size; + long base_size = sysconf(_SC_PAGESIZE); test_init(argc, argv); @@ -175,11 +200,17 @@ int main(int argc, char *argv[]) */ meminfo_state = OVERRIDE_OFF; sysfs_state = OVERRIDE_OFF; + if (gethugepagesizes(actual_sizes, -1) != -1 || errno != EINVAL) FAIL("Mishandled params (n_elem < 0)"); if (gethugepagesizes(NULL, 1) != -1 || errno != EINVAL) FAIL("Mishandled params (pagesizes == NULL, n_elem > 0)"); + if (getpagesizes(actual_sizes, -1) != -1 || errno != EINVAL) + FAIL("Mishandled params (n_elem < 0)"); + if (getpagesizes(NULL, 1) != -1 || errno != EINVAL) + FAIL("Mishandled params (pagesizes == NULL, n_elem > 0)"); + /* * === * Test some corner cases using a fake system configuration @@ -190,8 +221,11 @@ int main(int argc, char *argv[]) * Check handling when /proc/meminfo indicates no huge page support */ meminfo_state = OVERRIDE_MISSING; - if (gethugepagesizes(actual_sizes, 1) != 0 || errno != 0) - FAIL("Incorrect handling when huge page support is missing"); + + EXPECT_SIZES(gethugepagesizes, MAX, 0, expected_sizes); + + INIT_LIST(expected_sizes, base_size); + EXPECT_SIZES(getpagesizes, MAX, 1, expected_sizes); /* * When the sysfs heirarchy is not present ... @@ -201,26 +235,44 @@ int main(int argc, char *argv[]) /* ... only the meminfo size is returned. */ meminfo_state = OVERRIDE_ON; meminfo_size = read_meminfo("Hugepagesize:") * 1024; - INIT_SIZES(expected_sizes, meminfo_size, -1, -1); - /* Use 2 to give the function the chance to return too many sizes */ - nr_sizes = gethugepagesizes(actual_sizes, 2); - expect_sizes(__LINE__, 1, nr_sizes, expected_sizes, actual_sizes); + INIT_LIST(expected_sizes, meminfo_size); + EXPECT_SIZES(gethugepagesizes, MAX, 1, expected_sizes); + + INIT_LIST(expected_sizes, base_size, meminfo_size); + EXPECT_SIZES(getpagesizes, MAX, 2, expected_sizes); /* * When sysfs defines additional sizes ... */ - INIT_SIZES(expected_sizes, meminfo_size, 1024, 2048); + INIT_LIST(expected_sizes, meminfo_size, 1024 * 1024, 2048 * 1024); + setup_fake_sysfs(expected_sizes, 3); sysfs_state = OVERRIDE_ON; /* ... make sure all sizes are returned without duplicates */ - nr_sizes = gethugepagesizes(actual_sizes, 4); - expect_sizes(__LINE__, 3, nr_sizes, expected_sizes, actual_sizes); + /* ... while making sure we do not overstep our limit */ + EXPECT_SIZES(gethugepagesizes, MAX, 3, expected_sizes); + EXPECT_SIZES(gethugepagesizes, 1, 3, expected_sizes); + EXPECT_SIZES(gethugepagesizes, 2, 3, expected_sizes); + EXPECT_SIZES(gethugepagesizes, 3, 3, expected_sizes); + EXPECT_SIZES(gethugepagesizes, 4, 3, expected_sizes); + + INIT_LIST(expected_sizes, + base_size, meminfo_size, 1024 * 1024, 2048 * 1024); + EXPECT_SIZES(getpagesizes, MAX, 4, expected_sizes); + EXPECT_SIZES(getpagesizes, 1, 4, expected_sizes); + EXPECT_SIZES(getpagesizes, 2, 4, expected_sizes); + EXPECT_SIZES(getpagesizes, 3, 4, expected_sizes); + EXPECT_SIZES(getpagesizes, 4, 4, expected_sizes); + EXPECT_SIZES(getpagesizes, 5, 4, expected_sizes); /* ... we can check how many sizes are supported. */ if (gethugepagesizes(NULL, 0) != 3) FAIL("Unable to check the number of supported sizes"); + if (getpagesizes(NULL, 0) != 4) + FAIL("Unable to check the number of supported sizes"); + PASS(); } -- 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