It has been asserted that the name get_huge_pages() implies the API is a close-to-kernel interface for allocating hugepages and nothing else. In 2.1-preX, this definition does not fit as it allows fallback to base pages for example. This patch enforces the meaning implied by the function name by removing the ability of the function to fallback to base pages and redefines GHP_DEFAULT to mean "Use the default hugepage size to back the region".
Signed-off-by: Mel Gorman <[EMAIL PROTECTED]> --- alloc.c | 22 +++++++------------ hugetlbfs.h | 10 ++------ man/get_huge_pages.3 | 20 ++++++++++-------- tests/get_huge_pages.c | 53 ------------------------------------------------ 4 files changed, 22 insertions(+), 83 deletions(-) diff --git a/alloc.c b/alloc.c index c118f18..6e026c5 100644 --- a/alloc.c +++ b/alloc.c @@ -65,15 +65,13 @@ static void *fallback_base_pages(size_t len, ghp_t flags) /** * get_huge_pages - Allocate an amount of memory backed by huge pages - * len: Size of the region to allocate + * len: Size of the region to allocate, must be hugepage-aligned * flags: Flags specifying the behaviour of the function * - * This function allocates a region of memory backed by huge pages and - * at least hugepage-aligned. This is not a suitable drop-in for malloc() - * and is only suitable in the event the length is expected to be - * hugepage-aligned. However, a malloc-like library could use this function - * to create additional heap similar in principal to what morecore does for - * glibc malloc. + * This function allocates a region of memory that is backed by huge pages + * and hugepage-aligned. This is not a suitable drop-in for malloc() but a + * a malloc library could use this function to create a new fixed-size heap + * similar in principal to what morecore does for glibc malloc. */ void *get_huge_pages(size_t len, ghp_t flags) { @@ -93,10 +91,6 @@ void *get_huge_pages(size_t len, ghp_t flags) if (buf == MAP_FAILED) { close(heap_fd); - /* Try falling back to base pages if allowed */ - if (flags & GHP_FALLBACK) - return fallback_base_pages(len, flags); - WARNING("get_huge_pages: New region mapping failed (flags: 0x%lX): %s\n", flags, strerror(errno)); return NULL; @@ -107,9 +101,9 @@ void *get_huge_pages(size_t len, ghp_t flags) munmap(buf, len); close(heap_fd); - /* Try falling back to base pages if allowed */ - if (flags & GHP_FALLBACK) - return fallback_base_pages(len, flags); + WARNING("get_huge_pages: Prefaulting failed (flags: 0x%lX): %s\n", + flags, strerror(errno)); + return NULL; } /* Close the file so we do not have to track the descriptor */ diff --git a/hugetlbfs.h b/hugetlbfs.h index 0694a0b..0efa02c 100644 --- a/hugetlbfs.h +++ b/hugetlbfs.h @@ -40,16 +40,12 @@ int hugetlbfs_unlinked_fd_for_size(long page_size); #define PF_LINUX_HUGETLB 0x100000 /* - * Direct alloc flags and types + * Direct hugepage allocation flags and types * - * GHP_DEFAULT - Use a combination of flags deemed to be a sensible default - * by the current implementation of the library - * GHP_FALLBACK - Use the default hugepage size if possible but fallback to - * smaller pages if necessary + * GHP_DEFAULT - Use the default hugepage size to back the region */ typedef unsigned long ghp_t; -#define GHP_FALLBACK (0x01UL) -#define GHP_DEFAULT (0) +#define GHP_DEFAULT ((ghp_t)0x01UL) /* Direct alloc functions */ void *get_huge_pages(size_t len, ghp_t flags); diff --git a/man/get_huge_pages.3 b/man/get_huge_pages.3 index a2173f8..f2a33a4 100644 --- a/man/get_huge_pages.3 +++ b/man/get_huge_pages.3 @@ -16,7 +16,7 @@ .\" .sp <n> insert n+1 empty lines .\" for manpage-specific macros, see man(7) .SH NAME -get_huge_pages, free_huge_pages \- Allocate and free memory regions backed by hugepages +get_huge_pages, free_huge_pages \- Allocate and free hugepages .SH SYNOPSIS .B #include <hugetlbfs.h> .br @@ -33,19 +33,19 @@ large amounts of address space and suffer a performance hit due to TLB misses. Wall-clock time or oprofile can be used to determine if there is a performance benefit from using hugepages or not. +The \fBlen\fP parameter must be hugepage-aligned. In the current +implementation, only the default hugepage size may be allocated via this +function. Use \fBgethugepagesize\fP to discover what the alignment should +be. + The \fBflags\fP argument changes the behaviour of the function. Flags may be or'd together. .TP .B GHP_DEFAULT -Allocate a region of memory of the requested length backed by -hugepages. Return NULL if sufficient pages are not available -.TP -.B GHP_FALLBACK -Allocate a region of memory backed by hugepages. If sufficient hugepages -are not available, return an MAP_ANONYMOUS region of memory backed by base -page-sized pages instead. +Allocate a region of memory of the requested length backed by hugepages of +the default hugepage size. Return NULL if sufficient pages are not available .PP @@ -55,13 +55,15 @@ is used, valid or otherwise, is undefined. .SH RETURN VALUE -For \fBget_huge_pages()\fP, return a pointer to the allocated memory. On +On success, a pointer is returned for to the allocated memory. On error, NULL is returned. errno will be set based on what the failure of mmap() was due to. .SH SEE ALSO .I oprofile(1) , +.I gethugepagesize(3) +, .I libhugetlbfs(7) .SH AUTHORS libhugetlbfs was written by various people on the libhugetlbfs-devel diff --git a/tests/get_huge_pages.c b/tests/get_huge_pages.c index 62b27ea..5687699 100644 --- a/tests/get_huge_pages.c +++ b/tests/get_huge_pages.c @@ -62,58 +62,6 @@ void test_get_huge_pages(int num_hugepages) FAIL("hugepage was not correctly freed"); } -void test_GHP_FALLBACK(void) -{ - int err; - long rsvd_hugepages = get_huge_page_counter(hpage_size, HUGEPAGES_RSVD); - long num_hugepages = get_huge_page_counter(hpage_size, HUGEPAGES_TOTAL) - - rsvd_hugepages; - - /* We must disable overcommitted huge pages to test this */ - oc_hugepages = get_huge_page_counter(hpage_size, HUGEPAGES_OC); - set_nr_overcommit_hugepages(hpage_size, 0); - - /* We should be able to allocate the whole pool */ - void *p = get_huge_pages(num_hugepages * hpage_size, GHP_DEFAULT); - if (p == NULL) - FAIL("test_GHP_FALLBACK(GHP_DEFAULT) failed for %ld hugepages", - num_hugepages); - memset(p, 1, hpage_size); - err = test_addr_huge(p + (num_hugepages - 1) * hpage_size); - if (err != 1) - FAIL("Returned page is not hugepage"); - free_and_confirm_region_free(p, __LINE__); - - /* We should fail allocating too much */ - num_hugepages++; - p = get_huge_pages(num_hugepages * hpage_size, GHP_DEFAULT); - if (p != NULL) - FAIL("test_GHP_FALLBACK() for %ld expected fail, got success", num_hugepages); - - /* GHP_FALLBACK should succeed by allocating base pages */ - p = get_huge_pages(num_hugepages * hpage_size, GHP_FALLBACK); - if (p == NULL) - FAIL("test_GHP_FALLBACK(GHP_FALLBACK) failed for %ld hugepages", - num_hugepages); - memset(p, 1, hpage_size); - err = test_addr_huge(p + (num_hugepages - 1) * hpage_size); - if (err == 1) - FAIL("Returned page is not a base page"); - - /* - * We allocate a second fallback region to see can they be told apart - * on free. Merging VMAs would cause problems - */ - void *pb = get_huge_pages(num_hugepages * hpage_size, GHP_FALLBACK); - if (pb == NULL) - FAIL("test_GHP_FALLBACK(GHP_FALLBACK) x2 failed for %ld hugepages", - num_hugepages); - memset(pb, 1, hpage_size); - - free_and_confirm_region_free(pb, __LINE__); - free_and_confirm_region_free(p, __LINE__); -} - int main(int argc, char *argv[]) { test_init(argc, argv); @@ -121,7 +69,6 @@ int main(int argc, char *argv[]) check_free_huge_pages(4); test_get_huge_pages(1); test_get_huge_pages(4); - test_GHP_FALLBACK(); PASS(); } -- 1.5.6.5 ------------------------------------------------------------------------- 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