On (09/10/08 20:20), Andy Whitcroft didst pronounce:
> From: Adam Litke <[EMAIL PROTECTED]>
> 
> This patch fixes two intertwined issues:
> 
> When the SHM_HUGETLB flag is passed to shmget(), the system default huge page
> size is used to back the shared memory segment.  Unlike with mmap() there is
> not yet a way to use an alternate huge page size for shared memory segments.
> This exception must be taken into account by the shmget override function -- 
> it
> cannot call gethugepagesize() but must discover the effective huge page size 
> by
> direct examination of /proc/meminfo.  Make the shmoverride test case discover
> the huge page size in the same manner.
> 
> The shmoverride_* test case does not always link against libhugetlbfs.
> Therefore, it cannot use the new mechanism for manipulating pool counters.
> Unfortunately, this means that the logic to read /proc/meminfo must be
> duplicated in order for shmoverride_unlinked to build as a NOLIB test.
> 
> [EMAIL PROTECTED]: consolidate makefile updates in one place]
> Signed-off-by: Adam Litke <[EMAIL PROTECTED]>
> ---
>  shm.c                        |    7 +++-
>  tests/shmoverride_unlinked.c |   74 
> ++++++++++++++++++++++++++++++++++++++----
>  2 files changed, 73 insertions(+), 8 deletions(-)
> 
> diff --git a/shm.c b/shm.c
> index cc9995d..8a56725 100644
> --- a/shm.c
> +++ b/shm.c
> @@ -56,7 +56,12 @@ int shmget(key_t key, size_t size, int shmflg)
>  
>       /* Align the size and set SHM_HUGETLB on request */
>       if (hugetlbshm_enabled) {
> -             aligned_size = ALIGN(size, gethugepagesize());
> +             /*
> +              * Use /proc/meminfo because shm always uses the system
> +              * default huge page size.
> +              */
> +             long hpage_size = read_meminfo("Hugepagesize:") * 1024;
> +             aligned_size = ALIGN(size, hpage_size);
>               if (size != aligned_size) {
>                       DEBUG("hugetlb_shmem: size growth align %zd -> %zd\n",
>                               size, aligned_size);

Ok.

> diff --git a/tests/shmoverride_unlinked.c b/tests/shmoverride_unlinked.c
> index a8af228..5813cb7 100644
> --- a/tests/shmoverride_unlinked.c
> +++ b/tests/shmoverride_unlinked.c
> @@ -26,6 +26,7 @@
>  #include <unistd.h>
>  #include <sys/stat.h>
>  #include <fcntl.h>
> +#include <ctype.h>
>  #include <hugetlbfs.h>
>  #include "hugetests.h"
>  
> @@ -94,11 +95,55 @@ void _shmunmap(int s, int line)
>  }
>  #define shmunmap(s) _shmunmap(s, __LINE__)
>  
> +/*
> + * This test wants to manipulate the hugetlb pool without necessarily linking
> + * to libhugetlbfs so the helpers for doing this may not be available -- 
> hence
> + * the duplicated versions below.
> + *
> + * NOTE: We use /proc/sys/vm/nr_hugepages and /proc/meminfo for writing and
> + * reading pool counters because shared memory will always use the system
> + * default huge page size regardless of any libhugetlbfs settings.
> + */
> +#define MEMINFO_SIZE 2048
> +long local_read_meminfo(const char *tag)
> +{
> +     int fd;
> +     char buf[MEMINFO_SIZE];
> +     int len, readerr;
> +     char *p, *q;
> +     long val;
> +
> +     fd = open("/proc/meminfo", O_RDONLY);
> +     if (fd < 0)
> +             FAIL("Couldn't open /proc/meminfo: %s\n", strerror(errno));
> +
> +     len = read(fd, buf, sizeof(buf));
> +     readerr = errno;
> +     close(fd);
> +     if (len < 0)
> +             FAIL("Error reading /proc/meminfo: %s\n", strerror(errno));
> +
> +     if (len == sizeof(buf))
> +             FAIL("/proc/meminfo is too large\n");
> +     buf[len] = '\0';
> +
> +     p = strstr(buf, tag);
> +     if (!p)
> +             FAIL("Tag %s not found in /proc/meminfo\n", tag);
> +     p += strlen(tag);
> +
> +     val = strtol(p, &q, 0);
> +     if (!isspace(*q))
> +             FAIL("Couldn't parse /proc/meminfo\n");
> +
> +     return val;
> +}
> +
>  void setup_hugetlb_pool(unsigned long count)
>  {
>       FILE *fd;
>       unsigned long poolsize;
> -     count += read_meminfo("HugePages_Rsvd:");
> +     count += local_read_meminfo("HugePages_Rsvd:");
>       fd = fopen("/proc/sys/vm/nr_hugepages", "w");
>       if (!fd)
>               CONFIG("Cannot open nr_hugepages for writing\n");
> @@ -106,12 +151,19 @@ void setup_hugetlb_pool(unsigned long count)
>       fclose(fd);
>  
>       /* Confirm the resize worked */
> -     poolsize = read_meminfo("HugePages_Total:");
> +     poolsize = local_read_meminfo("HugePages_Total:");
>       if (poolsize != count)
>               FAIL("Failed to resize pool to %lu pages. Got %lu instead\n",
>                       count, poolsize);
>  }
>  
> +void local_check_free_huge_pages(int needed_pages)
> +{
> +     int free = local_read_meminfo("HugePages_Free:");
> +     if (free < needed_pages)
> +             CONFIG("Must have at least %i free hugepages", needed_pages);
> +}
> +
>  void run_test(char *desc, int hpages, int bpages, int pool_nr, int 
> expect_diff)
>  {
>       long resv_before, resv_after;
> @@ -119,9 +171,9 @@ void run_test(char *desc, int hpages, int bpages, int 
> pool_nr, int expect_diff)
>       setup_hugetlb_pool(pool_nr);
>  
>       /* untouched, shared mmap */
> -     resv_before = read_meminfo("HugePages_Rsvd:");
> +     resv_before = local_read_meminfo("HugePages_Rsvd:");
>       shmmap(SL_TEST, hpages, bpages);
> -     resv_after = read_meminfo("HugePages_Rsvd:");
> +     resv_after = local_read_meminfo("HugePages_Rsvd:");
>       memset(map_addr[SL_TEST], 0, map_size[SL_TEST]);
>       shmunmap(SL_TEST);
>  
> @@ -134,6 +186,14 @@ void run_test(char *desc, int hpages, int bpages, int 
> pool_nr, int expect_diff)
>  
>  void cleanup(void)
>  {
> +     int i;
> +
> +     /* Clean up any allocated shmids */
> +     for (i = 0; i < NR_SLOTS; i++)
> +             if (map_id[i] > 0)
> +                     shmctl(map_id[i], IPC_RMID, NULL);
> +
> +     /* Restore the pool size. */
>       if (saved_nr_hugepages >= 0)
>               setup_hugetlb_pool(saved_nr_hugepages);
>  }
> @@ -142,15 +202,15 @@ int main(int argc, char **argv)
>  {
>       test_init(argc, argv);
>       check_must_be_root();
> -     check_free_huge_pages(POOL_SIZE);
> -     saved_nr_hugepages = read_meminfo("HugePages_Total:");
> +     local_check_free_huge_pages(POOL_SIZE);
> +     saved_nr_hugepages = local_read_meminfo("HugePages_Total:");
>  
>       /*
>        * We cannot call check_hugepagesize because we are not linked to
>        * libhugetlbfs. This is a bit hacky but we are depending on earlier
>        * tests failing to catch when this wouldn't work
>        */
> -     hpage_size = read_meminfo("Hugepagesize:") * 1024;
> +     hpage_size = local_read_meminfo("Hugepagesize:") * 1024;
>       bpage_size = getpagesize();
>  
>       /* Run the test with small pages */

Acked-by; Mel Gorman <[EMAIL PROTECTED]>

-- 
Mel Gorman
Part-time Phd Student                          Linux Technology Center
University of Limerick                         IBM Dublin Software Lab

-------------------------------------------------------------------------
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