2012-02-05 08:16:09

by Dave Young

[permalink] [raw]
Subject: [PATCH 3/3] move hugepage test examples to tools/testing/selftests/vm

hugepage-mmap.c, hugepage-shm.c and map_hugetlb.c in Documentation/vm are
simple pass/fail tests, It's better to promote them to tools/testing/selftests

Thanks suggestion of Andrew Morton about this. They all need firstly setting up
proper nr_hugepages and hugepage-mmap need to mount hugetlbfs. So I add a shell
script run_test to do such work which will call the three test programs and
check the return value of them.

Changes to original code including below:
a. add run_test script
b. return error when read_bytes mismatch with writed bytes.
c. coding style fixes: do not use assignment in if condition

Signed-off-by: Dave Young <[email protected]>
---
Documentation/vm/Makefile | 8 --
tools/testing/selftests/Makefile | 2 +-
tools/testing/selftests/run_tests | 6 +-
tools/testing/selftests/vm/Makefile | 11 +++
.../testing/selftests}/vm/hugepage-mmap.c | 13 ++--
.../testing/selftests}/vm/hugepage-shm.c | 10 ++-
.../testing/selftests}/vm/map_hugetlb.c | 10 ++-
tools/testing/selftests/vm/run_test | 77 ++++++++++++++++++++
8 files changed, 112 insertions(+), 25 deletions(-)
delete mode 100644 Documentation/vm/Makefile
create mode 100644 tools/testing/selftests/vm/Makefile
rename {Documentation => tools/testing/selftests}/vm/hugepage-mmap.c (93%)
rename {Documentation => tools/testing/selftests}/vm/hugepage-shm.c (94%)
rename {Documentation => tools/testing/selftests}/vm/map_hugetlb.c (94%)
create mode 100755 tools/testing/selftests/vm/run_test

diff --git a/Documentation/vm/Makefile b/Documentation/vm/Makefile
deleted file mode 100644
index e538864..0000000
--- a/Documentation/vm/Makefile
+++ /dev/null
@@ -1,8 +0,0 @@
-# kbuild trick to avoid linker error. Can be omitted if a module is built.
-obj- := dummy.o
-
-# List of programs to build
-hostprogs-y := hugepage-mmap hugepage-shm map_hugetlb
-
-# Tell kbuild to always build the programs
-always := $(hostprogs-y)
diff --git a/tools/testing/selftests/Makefile b/tools/testing/selftests/Makefile
index 4ec8401..9a72fe5 100644
--- a/tools/testing/selftests/Makefile
+++ b/tools/testing/selftests/Makefile
@@ -1,4 +1,4 @@
-TARGETS = breakpoints
+TARGETS = breakpoints vm

all:
for TARGET in $(TARGETS); do \
diff --git a/tools/testing/selftests/run_tests b/tools/testing/selftests/run_tests
index 320718a..1f4a5ef 100644
--- a/tools/testing/selftests/run_tests
+++ b/tools/testing/selftests/run_tests
@@ -1,8 +1,10 @@
#!/bin/bash

-TARGETS=breakpoints
+TARGETS="breakpoints vm"

for TARGET in $TARGETS
do
- $TARGET/run_test
+ cd "$TARGET"
+ ./run_test
+ cd ..
done
diff --git a/tools/testing/selftests/vm/Makefile b/tools/testing/selftests/vm/Makefile
new file mode 100644
index 0000000..537ec38
--- /dev/null
+++ b/tools/testing/selftests/vm/Makefile
@@ -0,0 +1,11 @@
+# Makefile for vm selftests
+
+CC = $(CROSS_COMPILE)gcc
+CFLAGS = -Wall -Wextra
+
+all: hugepage-mmap hugepage-shm map_hugetlb
+%: %.c
+ $(CC) $(CFLAGS) -o $@ $^
+
+clean:
+ $(RM) hugepage-mmap hugepage-shm map_hugetlb
diff --git a/Documentation/vm/hugepage-mmap.c b/tools/testing/selftests/vm/hugepage-mmap.c
similarity index 93%
rename from Documentation/vm/hugepage-mmap.c
rename to tools/testing/selftests/vm/hugepage-mmap.c
index db0dd9a..a10f310 100644
--- a/Documentation/vm/hugepage-mmap.c
+++ b/tools/testing/selftests/vm/hugepage-mmap.c
@@ -22,7 +22,7 @@
#include <sys/mman.h>
#include <fcntl.h>

-#define FILE_NAME "/mnt/hugepagefile"
+#define FILE_NAME "huge/hugepagefile"
#define LENGTH (256UL*1024*1024)
#define PROTECTION (PROT_READ | PROT_WRITE)

@@ -48,7 +48,7 @@ static void write_bytes(char *addr)
*(addr + i) = (char)i;
}

-static void read_bytes(char *addr)
+static int read_bytes(char *addr)
{
unsigned long i;

@@ -56,14 +56,15 @@ static void read_bytes(char *addr)
for (i = 0; i < LENGTH; i++)
if (*(addr + i) != (char)i) {
printf("Mismatch at %lu\n", i);
- break;
+ return 1;
}
+ return 0;
}

int main(void)
{
void *addr;
- int fd;
+ int fd, ret;

fd = open(FILE_NAME, O_CREAT | O_RDWR, 0755);
if (fd < 0) {
@@ -81,11 +82,11 @@ int main(void)
printf("Returned address is %p\n", addr);
check_bytes(addr);
write_bytes(addr);
- read_bytes(addr);
+ ret = read_bytes(addr);

munmap(addr, LENGTH);
close(fd);
unlink(FILE_NAME);

- return 0;
+ return ret;
}
diff --git a/Documentation/vm/hugepage-shm.c b/tools/testing/selftests/vm/hugepage-shm.c
similarity index 94%
rename from Documentation/vm/hugepage-shm.c
rename to tools/testing/selftests/vm/hugepage-shm.c
index 07956d8..0d0ef4f 100644
--- a/Documentation/vm/hugepage-shm.c
+++ b/tools/testing/selftests/vm/hugepage-shm.c
@@ -57,8 +57,8 @@ int main(void)
unsigned long i;
char *shmaddr;

- if ((shmid = shmget(2, LENGTH,
- SHM_HUGETLB | IPC_CREAT | SHM_R | SHM_W)) < 0) {
+ shmid = shmget(2, LENGTH, SHM_HUGETLB | IPC_CREAT | SHM_R | SHM_W);
+ if (shmid < 0) {
perror("shmget");
exit(1);
}
@@ -82,14 +82,16 @@ int main(void)

dprintf("Starting the Check...");
for (i = 0; i < LENGTH; i++)
- if (shmaddr[i] != (char)i)
+ if (shmaddr[i] != (char)i) {
printf("\nIndex %lu mismatched\n", i);
+ exit(3);
+ }
dprintf("Done.\n");

if (shmdt((const void *)shmaddr) != 0) {
perror("Detach failure");
shmctl(shmid, IPC_RMID, NULL);
- exit(3);
+ exit(4);
}

shmctl(shmid, IPC_RMID, NULL);
diff --git a/Documentation/vm/map_hugetlb.c b/tools/testing/selftests/vm/map_hugetlb.c
similarity index 94%
rename from Documentation/vm/map_hugetlb.c
rename to tools/testing/selftests/vm/map_hugetlb.c
index eda1a6d..ac56639 100644
--- a/Documentation/vm/map_hugetlb.c
+++ b/tools/testing/selftests/vm/map_hugetlb.c
@@ -44,7 +44,7 @@ static void write_bytes(char *addr)
*(addr + i) = (char)i;
}

-static void read_bytes(char *addr)
+static int read_bytes(char *addr)
{
unsigned long i;

@@ -52,13 +52,15 @@ static void read_bytes(char *addr)
for (i = 0; i < LENGTH; i++)
if (*(addr + i) != (char)i) {
printf("Mismatch at %lu\n", i);
- break;
+ return 1;
}
+ return 0;
}

int main(void)
{
void *addr;
+ int ret;

addr = mmap(ADDR, LENGTH, PROTECTION, FLAGS, 0, 0);
if (addr == MAP_FAILED) {
@@ -69,9 +71,9 @@ int main(void)
printf("Returned address is %p\n", addr);
check_bytes(addr);
write_bytes(addr);
- read_bytes(addr);
+ ret = read_bytes(addr);

munmap(addr, LENGTH);

- return 0;
+ return ret;
}
diff --git a/tools/testing/selftests/vm/run_test b/tools/testing/selftests/vm/run_test
new file mode 100755
index 0000000..33d355d
--- /dev/null
+++ b/tools/testing/selftests/vm/run_test
@@ -0,0 +1,77 @@
+#!/bin/bash
+#please run as root
+
+#we need 256M, below is the size in kB
+needmem=262144
+mnt=./huge
+
+#get pagesize and freepages from /proc/meminfo
+while read name size unit; do
+ if [ "$name" = "HugePages_Free:" ]; then
+ freepgs=$size
+ fi
+ if [ "$name" = "Hugepagesize:" ]; then
+ pgsize=$size
+ fi
+done < /proc/meminfo
+
+#set proper nr_hugepages
+if [ -n "$freepgs" ] && [ -n "$pgsize" ]; then
+ nr_hugepgs=`cat /proc/sys/vm/nr_hugepages`
+ needpgs=`expr $needmem / $pgsize`
+ if [ $freepgs -lt $needpgs ]; then
+ lackpgs=$(( $needpgs - $freepgs ))
+ echo $(( $lackpgs + $nr_hugepgs )) > /proc/sys/vm/nr_hugepages
+ if [ $? -ne 0 ]; then
+ echo "Please run this test as root"
+ exit 1
+ fi
+ fi
+else
+ echo "no hugetlbfs support in kernel?"
+ exit 1
+fi
+
+mkdir $mnt
+mount -t hugetlbfs none $mnt
+
+echo "--------------------"
+echo "runing hugepage-mmap"
+echo "--------------------"
+./hugepage-mmap
+if [ $? -ne 0 ]; then
+ echo "[FAIL]"
+else
+ echo "[PASS]"
+fi
+
+shmmax=`cat /proc/sys/kernel/shmmax`
+shmall=`cat /proc/sys/kernel/shmall`
+echo 268435456 > /proc/sys/kernel/shmmax
+echo 4194304 > /proc/sys/kernel/shmall
+echo "--------------------"
+echo "runing hugepage-shm"
+echo "--------------------"
+./hugepage-shm
+echo $shmmax > /proc/sys/kernel/shmmax
+echo $shmall > /proc/sys/kernel/shmall
+if [ $? -ne 0 ]; then
+ echo "[FAIL]"
+else
+ echo "[PASS]"
+fi
+
+echo "--------------------"
+echo "runing map_hugetlb"
+echo "--------------------"
+./map_hugetlb
+if [ $? -ne 0 ]; then
+ echo "[FAIL]"
+else
+ echo "[PASS]"
+fi
+
+#cleanup
+umount $mnt
+rm -rf $mnt
+echo $nr_hugepgs > /proc/sys/vm/nr_hugepages
--
1.7.4.4


2012-02-06 23:53:48

by Andrew Morton

[permalink] [raw]
Subject: Re: [PATCH 3/3] move hugepage test examples to tools/testing/selftests/vm

On Sun, 5 Feb 2012 16:15:55 +0800
Dave Young <[email protected]> wrote:

> hugepage-mmap.c, hugepage-shm.c and map_hugetlb.c in Documentation/vm are
> simple pass/fail tests, It's better to promote them to tools/testing/selftests
>
> Thanks suggestion of Andrew Morton about this. They all need firstly setting up
> proper nr_hugepages and hugepage-mmap need to mount hugetlbfs. So I add a shell
> script run_test to do such work which will call the three test programs and
> check the return value of them.
>
> Changes to original code including below:
> a. add run_test script
> b. return error when read_bytes mismatch with writed bytes.
> c. coding style fixes: do not use assignment in if condition
>

I think Frederic is doing away with tools/testing/selftests/run_tests
in favour of a Makefile target? ("make run_tests", for example).

Until we see such a patch we cannot finalise your patch and if I apply
your patch, his patch will need more work. Not that this is rocket
science ;)

>
> ...
>
> --- /dev/null
> +++ b/tools/testing/selftests/vm/run_test

(We now have a "run_tests" and a "run_test". The difference in naming
is irritating)

Your vm/run_test file does quite a lot of work and we couldn't sensibly
move all its functionality into Makefile, I expect.

So I think it's OK to retain a script for this, but I do think that we
should think up a standardized way of invoking it from vm/Makefile, so
the top-level Makefile in tools/testing/selftests can simply do "cd
vm;make run_test", where the run_test target exists in all
subdirectories. The vm/Makefile run_test target can then call out to
the script.

Also, please do not assume that the script has the x bit set. The x
bit easily gets lost on kernel scripts (patch(1) can lose it) so it is
safer to invoke the script via "/bin/sh script-name" or $SHELL or
whatever.

Anyway, we should work with Frederic on sorting out some standard
behavior before we can finalize this work, please.

2012-02-07 01:29:15

by Dave Young

[permalink] [raw]
Subject: Re: [PATCH 3/3] move hugepage test examples to tools/testing/selftests/vm

On 02/07/2012 07:53 AM, Andrew Morton wrote:

> On Sun, 5 Feb 2012 16:15:55 +0800
> Dave Young <[email protected]> wrote:
>
>> hugepage-mmap.c, hugepage-shm.c and map_hugetlb.c in Documentation/vm are
>> simple pass/fail tests, It's better to promote them to tools/testing/selftests
>>
>> Thanks suggestion of Andrew Morton about this. They all need firstly setting up
>> proper nr_hugepages and hugepage-mmap need to mount hugetlbfs. So I add a shell
>> script run_test to do such work which will call the three test programs and
>> check the return value of them.
>>
>> Changes to original code including below:
>> a. add run_test script
>> b. return error when read_bytes mismatch with writed bytes.
>> c. coding style fixes: do not use assignment in if condition
>>
>
> I think Frederic is doing away with tools/testing/selftests/run_tests
> in favour of a Makefile target? ("make run_tests", for example).

>

> Until we see such a patch we cannot finalise your patch and if I apply
> your patch, his patch will need more work. Not that this is rocket
> science ;)


Understand.

>
>>
>> ...
>>
>> --- /dev/null
>> +++ b/tools/testing/selftests/vm/run_test
>
> (We now have a "run_tests" and a "run_test". The difference in naming
> is irritating)


Yes, I'm just refer to the breakpoints/Makefile which will make a target
breakpoints/run_test

>
> Your vm/run_test file does quite a lot of work and we couldn't sensibly
> move all its functionality into Makefile, I expect.
>
> So I think it's OK to retain a script for this, but I do think that we
> should think up a standardized way of invoking it from vm/Makefile, so
> the top-level Makefile in tools/testing/selftests can simply do "cd
> vm;make run_test", where the run_test target exists in all
> subdirectories. The vm/Makefile run_test target can then call out to
> the script.


Frederic, do you have any idea about this?

>
> Also, please do not assume that the script has the x bit set. The x
> bit easily gets lost on kernel scripts (patch(1) can lose it) so it is
> safer to invoke the script via "/bin/sh script-name" or $SHELL or
> whatever.


Agree, and quilt can not keep the x bit as well, I have to use git to
create a executable shell script

>
> Anyway, we should work with Frederic on sorting out some standard
> behavior before we can finalize this work, please.
>


Fine, I can redo this after the standard behavior is out

--
Thanks
Dave

2012-02-07 01:30:24

by Dave Young

[permalink] [raw]
Subject: Re: [PATCH 3/3] move hugepage test examples to tools/testing/selftests/vm

On 02/05/2012 04:15 PM, Dave Young wrote:

> hugepage-mmap.c, hugepage-shm.c and map_hugetlb.c in Documentation/vm are
> simple pass/fail tests, It's better to promote them to tools/testing/selftests
>
> Thanks suggestion of Andrew Morton about this. They all need firstly setting up
> proper nr_hugepages and hugepage-mmap need to mount hugetlbfs. So I add a shell
> script run_test to do such work which will call the three test programs and
> check the return value of them.
>
> Changes to original code including below:
> a. add run_test script
> b. return error when read_bytes mismatch with writed bytes.
> c. coding style fixes: do not use assignment in if condition
>
> Signed-off-by: Dave Young <[email protected]>
> ---
> Documentation/vm/Makefile | 8 --
> tools/testing/selftests/Makefile | 2 +-
> tools/testing/selftests/run_tests | 6 +-
> tools/testing/selftests/vm/Makefile | 11 +++
> .../testing/selftests}/vm/hugepage-mmap.c | 13 ++--
> .../testing/selftests}/vm/hugepage-shm.c | 10 ++-
> .../testing/selftests}/vm/map_hugetlb.c | 10 ++-
> tools/testing/selftests/vm/run_test | 77 ++++++++++++++++++++
> 8 files changed, 112 insertions(+), 25 deletions(-)
> delete mode 100644 Documentation/vm/Makefile
> create mode 100644 tools/testing/selftests/vm/Makefile
> rename {Documentation => tools/testing/selftests}/vm/hugepage-mmap.c (93%)
> rename {Documentation => tools/testing/selftests}/vm/hugepage-shm.c (94%)
> rename {Documentation => tools/testing/selftests}/vm/map_hugetlb.c (94%)
> create mode 100755 tools/testing/selftests/vm/run_test
>
> diff --git a/Documentation/vm/Makefile b/Documentation/vm/Makefile
> deleted file mode 100644
> index e538864..0000000
> --- a/Documentation/vm/Makefile
> +++ /dev/null
> @@ -1,8 +0,0 @@
> -# kbuild trick to avoid linker error. Can be omitted if a module is built.
> -obj- := dummy.o
> -
> -# List of programs to build
> -hostprogs-y := hugepage-mmap hugepage-shm map_hugetlb
> -
> -# Tell kbuild to always build the programs
> -always := $(hostprogs-y)
> diff --git a/tools/testing/selftests/Makefile b/tools/testing/selftests/Makefile
> index 4ec8401..9a72fe5 100644
> --- a/tools/testing/selftests/Makefile
> +++ b/tools/testing/selftests/Makefile
> @@ -1,4 +1,4 @@
> -TARGETS = breakpoints
> +TARGETS = breakpoints vm
>
> all:
> for TARGET in $(TARGETS); do \
> diff --git a/tools/testing/selftests/run_tests b/tools/testing/selftests/run_tests
> index 320718a..1f4a5ef 100644
> --- a/tools/testing/selftests/run_tests
> +++ b/tools/testing/selftests/run_tests
> @@ -1,8 +1,10 @@
> #!/bin/bash
>
> -TARGETS=breakpoints
> +TARGETS="breakpoints vm"
>
> for TARGET in $TARGETS
> do
> - $TARGET/run_test
> + cd "$TARGET"
> + ./run_test
> + cd ..
> done
> diff --git a/tools/testing/selftests/vm/Makefile b/tools/testing/selftests/vm/Makefile
> new file mode 100644
> index 0000000..537ec38
> --- /dev/null
> +++ b/tools/testing/selftests/vm/Makefile
> @@ -0,0 +1,11 @@
> +# Makefile for vm selftests
> +
> +CC = $(CROSS_COMPILE)gcc
> +CFLAGS = -Wall -Wextra
> +
> +all: hugepage-mmap hugepage-shm map_hugetlb
> +%: %.c
> + $(CC) $(CFLAGS) -o $@ $^
> +
> +clean:
> + $(RM) hugepage-mmap hugepage-shm map_hugetlb
> diff --git a/Documentation/vm/hugepage-mmap.c b/tools/testing/selftests/vm/hugepage-mmap.c
> similarity index 93%
> rename from Documentation/vm/hugepage-mmap.c
> rename to tools/testing/selftests/vm/hugepage-mmap.c
> index db0dd9a..a10f310 100644
> --- a/Documentation/vm/hugepage-mmap.c
> +++ b/tools/testing/selftests/vm/hugepage-mmap.c
> @@ -22,7 +22,7 @@
> #include <sys/mman.h>
> #include <fcntl.h>
>
> -#define FILE_NAME "/mnt/hugepagefile"
> +#define FILE_NAME "huge/hugepagefile"
> #define LENGTH (256UL*1024*1024)
> #define PROTECTION (PROT_READ | PROT_WRITE)
>
> @@ -48,7 +48,7 @@ static void write_bytes(char *addr)
> *(addr + i) = (char)i;
> }
>
> -static void read_bytes(char *addr)
> +static int read_bytes(char *addr)
> {
> unsigned long i;
>
> @@ -56,14 +56,15 @@ static void read_bytes(char *addr)
> for (i = 0; i < LENGTH; i++)
> if (*(addr + i) != (char)i) {
> printf("Mismatch at %lu\n", i);
> - break;
> + return 1;
> }
> + return 0;
> }
>
> int main(void)
> {
> void *addr;
> - int fd;
> + int fd, ret;
>
> fd = open(FILE_NAME, O_CREAT | O_RDWR, 0755);
> if (fd < 0) {
> @@ -81,11 +82,11 @@ int main(void)
> printf("Returned address is %p\n", addr);
> check_bytes(addr);
> write_bytes(addr);
> - read_bytes(addr);
> + ret = read_bytes(addr);
>
> munmap(addr, LENGTH);
> close(fd);
> unlink(FILE_NAME);
>
> - return 0;
> + return ret;
> }
> diff --git a/Documentation/vm/hugepage-shm.c b/tools/testing/selftests/vm/hugepage-shm.c
> similarity index 94%
> rename from Documentation/vm/hugepage-shm.c
> rename to tools/testing/selftests/vm/hugepage-shm.c
> index 07956d8..0d0ef4f 100644
> --- a/Documentation/vm/hugepage-shm.c
> +++ b/tools/testing/selftests/vm/hugepage-shm.c
> @@ -57,8 +57,8 @@ int main(void)
> unsigned long i;
> char *shmaddr;
>
> - if ((shmid = shmget(2, LENGTH,
> - SHM_HUGETLB | IPC_CREAT | SHM_R | SHM_W)) < 0) {
> + shmid = shmget(2, LENGTH, SHM_HUGETLB | IPC_CREAT | SHM_R | SHM_W);
> + if (shmid < 0) {
> perror("shmget");
> exit(1);
> }
> @@ -82,14 +82,16 @@ int main(void)
>
> dprintf("Starting the Check...");
> for (i = 0; i < LENGTH; i++)
> - if (shmaddr[i] != (char)i)
> + if (shmaddr[i] != (char)i) {
> printf("\nIndex %lu mismatched\n", i);
> + exit(3);
> + }
> dprintf("Done.\n");
>
> if (shmdt((const void *)shmaddr) != 0) {
> perror("Detach failure");
> shmctl(shmid, IPC_RMID, NULL);
> - exit(3);
> + exit(4);
> }
>
> shmctl(shmid, IPC_RMID, NULL);
> diff --git a/Documentation/vm/map_hugetlb.c b/tools/testing/selftests/vm/map_hugetlb.c
> similarity index 94%
> rename from Documentation/vm/map_hugetlb.c
> rename to tools/testing/selftests/vm/map_hugetlb.c
> index eda1a6d..ac56639 100644
> --- a/Documentation/vm/map_hugetlb.c
> +++ b/tools/testing/selftests/vm/map_hugetlb.c
> @@ -44,7 +44,7 @@ static void write_bytes(char *addr)
> *(addr + i) = (char)i;
> }
>
> -static void read_bytes(char *addr)
> +static int read_bytes(char *addr)
> {
> unsigned long i;
>
> @@ -52,13 +52,15 @@ static void read_bytes(char *addr)
> for (i = 0; i < LENGTH; i++)
> if (*(addr + i) != (char)i) {
> printf("Mismatch at %lu\n", i);
> - break;
> + return 1;
> }
> + return 0;
> }
>
> int main(void)
> {
> void *addr;
> + int ret;
>
> addr = mmap(ADDR, LENGTH, PROTECTION, FLAGS, 0, 0);
> if (addr == MAP_FAILED) {
> @@ -69,9 +71,9 @@ int main(void)
> printf("Returned address is %p\n", addr);
> check_bytes(addr);
> write_bytes(addr);
> - read_bytes(addr);
> + ret = read_bytes(addr);
>
> munmap(addr, LENGTH);
>
> - return 0;
> + return ret;
> }
> diff --git a/tools/testing/selftests/vm/run_test b/tools/testing/selftests/vm/run_test
> new file mode 100755
> index 0000000..33d355d
> --- /dev/null
> +++ b/tools/testing/selftests/vm/run_test
> @@ -0,0 +1,77 @@
> +#!/bin/bash
> +#please run as root
> +
> +#we need 256M, below is the size in kB
> +needmem=262144
> +mnt=./huge
> +
> +#get pagesize and freepages from /proc/meminfo
> +while read name size unit; do
> + if [ "$name" = "HugePages_Free:" ]; then
> + freepgs=$size
> + fi
> + if [ "$name" = "Hugepagesize:" ]; then
> + pgsize=$size
> + fi
> +done < /proc/meminfo
> +
> +#set proper nr_hugepages
> +if [ -n "$freepgs" ] && [ -n "$pgsize" ]; then
> + nr_hugepgs=`cat /proc/sys/vm/nr_hugepages`
> + needpgs=`expr $needmem / $pgsize`
> + if [ $freepgs -lt $needpgs ]; then
> + lackpgs=$(( $needpgs - $freepgs ))
> + echo $(( $lackpgs + $nr_hugepgs )) > /proc/sys/vm/nr_hugepages
> + if [ $? -ne 0 ]; then
> + echo "Please run this test as root"
> + exit 1
> + fi
> + fi
> +else
> + echo "no hugetlbfs support in kernel?"
> + exit 1
> +fi
> +
> +mkdir $mnt
> +mount -t hugetlbfs none $mnt
> +
> +echo "--------------------"
> +echo "runing hugepage-mmap"
> +echo "--------------------"
> +./hugepage-mmap
> +if [ $? -ne 0 ]; then
> + echo "[FAIL]"
> +else
> + echo "[PASS]"
> +fi
> +
> +shmmax=`cat /proc/sys/kernel/shmmax`
> +shmall=`cat /proc/sys/kernel/shmall`
> +echo 268435456 > /proc/sys/kernel/shmmax
> +echo 4194304 > /proc/sys/kernel/shmall
> +echo "--------------------"
> +echo "runing hugepage-shm"
> +echo "--------------------"
> +./hugepage-shm
> +echo $shmmax > /proc/sys/kernel/shmmax
> +echo $shmall > /proc/sys/kernel/shmall
> +if [ $? -ne 0 ]; then


Oops, $? check place is wrong, will fix in v2

> + echo "[FAIL]"
> +else
> + echo "[PASS]"
> +fi
> +
> +echo "--------------------"
> +echo "runing map_hugetlb"
> +echo "--------------------"
> +./map_hugetlb
> +if [ $? -ne 0 ]; then
> + echo "[FAIL]"
> +else
> + echo "[PASS]"
> +fi
> +
> +#cleanup
> +umount $mnt
> +rm -rf $mnt
> +echo $nr_hugepgs > /proc/sys/vm/nr_hugepages



--
Thanks
Dave

2012-02-08 03:41:06

by Frederic Weisbecker

[permalink] [raw]
Subject: [PATCH] selftests: Launch individual selftests from the main Makefile

On Mon, Feb 06, 2012 at 03:53:40PM -0800, Andrew Morton wrote:
> On Sun, 5 Feb 2012 16:15:55 +0800
> Dave Young <[email protected]> wrote:
>
> > hugepage-mmap.c, hugepage-shm.c and map_hugetlb.c in Documentation/vm are
> > simple pass/fail tests, It's better to promote them to tools/testing/selftests
> >
> > Thanks suggestion of Andrew Morton about this. They all need firstly setting up
> > proper nr_hugepages and hugepage-mmap need to mount hugetlbfs. So I add a shell
> > script run_test to do such work which will call the three test programs and
> > check the return value of them.
> >
> > Changes to original code including below:
> > a. add run_test script
> > b. return error when read_bytes mismatch with writed bytes.
> > c. coding style fixes: do not use assignment in if condition
> >
>
> I think Frederic is doing away with tools/testing/selftests/run_tests
> in favour of a Makefile target? ("make run_tests", for example).
>
> Until we see such a patch we cannot finalise your patch and if I apply
> your patch, his patch will need more work. Not that this is rocket
> science ;)
>
> >
> > ...
> >
> > --- /dev/null
> > +++ b/tools/testing/selftests/vm/run_test
>
> (We now have a "run_tests" and a "run_test". The difference in naming
> is irritating)
>
> Your vm/run_test file does quite a lot of work and we couldn't sensibly
> move all its functionality into Makefile, I expect.
>
> So I think it's OK to retain a script for this, but I do think that we
> should think up a standardized way of invoking it from vm/Makefile, so
> the top-level Makefile in tools/testing/selftests can simply do "cd
> vm;make run_test", where the run_test target exists in all
> subdirectories. The vm/Makefile run_test target can then call out to
> the script.
>
> Also, please do not assume that the script has the x bit set. The x
> bit easily gets lost on kernel scripts (patch(1) can lose it) so it is
> safer to invoke the script via "/bin/sh script-name" or $SHELL or
> whatever.
>
> Anyway, we should work with Frederic on sorting out some standard
> behavior before we can finalize this work, please.
>

Ok. Would the following patch work?

---
From: Frederic Weisbecker <[email protected]>
Date: Wed, 8 Feb 2012 04:21:46 +0100
Subject: [PATCH] selftests: Launch individual selftests from the main
Makefile

Drop the run_tests script and launch the selftests by calling
"make run_tests" from the selftests top directory instead. This
delegates to the Makefile on each selftest directory where it
is decided how to launch the local test.

This drops the need to add each selftest directory on the
now removed "run_tests" top script.

Signed-off-by: Frederic Weisbecker <[email protected]>
---
tools/testing/selftests/Makefile | 5 +++++
tools/testing/selftests/breakpoints/Makefile | 7 +++++--
tools/testing/selftests/run_tests | 8 --------
3 files changed, 10 insertions(+), 10 deletions(-)
delete mode 100644 tools/testing/selftests/run_tests

diff --git a/tools/testing/selftests/Makefile b/tools/testing/selftests/Makefile
index 4ec8401..b1119f0 100644
--- a/tools/testing/selftests/Makefile
+++ b/tools/testing/selftests/Makefile
@@ -5,6 +5,11 @@ all:
make -C $$TARGET; \
done;

+run_tests:
+ for TARGET in $(TARGETS); do \
+ make -C $$TARGET run_tests; \
+ done;
+
clean:
for TARGET in $(TARGETS); do \
make -C $$TARGET clean; \
diff --git a/tools/testing/selftests/breakpoints/Makefile b/tools/testing/selftests/breakpoints/Makefile
index f362722..9312780 100644
--- a/tools/testing/selftests/breakpoints/Makefile
+++ b/tools/testing/selftests/breakpoints/Makefile
@@ -11,10 +11,13 @@ endif

all:
ifeq ($(ARCH),x86)
- gcc breakpoint_test.c -o run_test
+ gcc breakpoint_test.c -o breakpoint_test
else
echo "Not an x86 target, can't build breakpoints selftests"
endif

+run_tests:
+ ./breakpoint_test
+
clean:
- rm -fr run_test
+ rm -fr breakpoint_test
diff --git a/tools/testing/selftests/run_tests b/tools/testing/selftests/run_tests
deleted file mode 100644
index 320718a..0000000
--- a/tools/testing/selftests/run_tests
+++ /dev/null
@@ -1,8 +0,0 @@
-#!/bin/bash
-
-TARGETS=breakpoints
-
-for TARGET in $TARGETS
-do
- $TARGET/run_test
-done
--
1.7.5.4

Subject: Re: [PATCH] selftests: Launch individual selftests from the main Makefile

Note that slub also has an embedded selftest (see function
resiliency_test). That code could be separated out and put with the
selftests that you are creating now.

I also have a series of in kernel benchmarks for the page allocation, vm
statistics and slab allocators that could be useful to included somewhere.

All this code runs in the kernel context.

For the in kernel benchmarks I am creating modules that fail to load but
first run the tests.

2012-02-08 15:38:09

by Frederic Weisbecker

[permalink] [raw]
Subject: Re: [PATCH] selftests: Launch individual selftests from the main Makefile

On Wed, Feb 08, 2012 at 08:45:35AM -0600, Christoph Lameter wrote:
> Note that slub also has an embedded selftest (see function
> resiliency_test). That code could be separated out and put with the
> selftests that you are creating now.

That would be nice. As long as it's in userspace and it runs validation
tests, it's pretty welcome.

It's deemed to test expected behaviour with deterministic tests. stress tests
probably don't fit well there although it should be no problem if they are short.


> I also have a series of in kernel benchmarks for the page allocation, vm
> statistics and slab allocators that could be useful to included somewhere.
>
> All this code runs in the kernel context.
>
> For the in kernel benchmarks I am creating modules that fail to load but
> first run the tests.

Hmm, benchmarks tend to require some user analysis, I'm not sure if a batch of
validation tests is the right place for them. But loading modules is probably
not a problem.

2012-02-08 23:20:25

by Andrew Morton

[permalink] [raw]
Subject: Re: [PATCH] selftests: Launch individual selftests from the main Makefile

On Wed, 8 Feb 2012 04:40:59 +0100
Frederic Weisbecker <[email protected]> wrote:

> Drop the run_tests script and launch the selftests by calling
> "make run_tests" from the selftests top directory instead. This
> delegates to the Makefile on each selftest directory where it
> is decided how to launch the local test.
>
> This drops the need to add each selftest directory on the
> now removed "run_tests" top script.

Looks good.

I did

cd tools/testing/selftests
make run_tests

and it didn't work. This?



From: Andrew Morton <[email protected]>
Subject: selftests/Makefile: make `run_tests' depend on `all'

So a "make run_tests" will build the tests before trying to run them.

Cc: Frederic Weisbecker <[email protected]>
Signed-off-by: Andrew Morton <[email protected]>
---

tools/testing/selftests/Makefile | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)

diff -puN tools/testing/selftests/Makefile~a tools/testing/selftests/Makefile
--- a/tools/testing/selftests/Makefile~a
+++ a/tools/testing/selftests/Makefile
@@ -5,7 +5,7 @@ all:
make -C $$TARGET; \
done;

-run_tests:
+run_tests: all
for TARGET in $(TARGETS); do \
make -C $$TARGET run_tests; \
done;
_

2012-02-08 23:58:03

by Frederic Weisbecker

[permalink] [raw]
Subject: Re: [PATCH] selftests: Launch individual selftests from the main Makefile

On Wed, Feb 08, 2012 at 03:20:22PM -0800, Andrew Morton wrote:
> On Wed, 8 Feb 2012 04:40:59 +0100
> Frederic Weisbecker <[email protected]> wrote:
>
> > Drop the run_tests script and launch the selftests by calling
> > "make run_tests" from the selftests top directory instead. This
> > delegates to the Makefile on each selftest directory where it
> > is decided how to launch the local test.
> >
> > This drops the need to add each selftest directory on the
> > now removed "run_tests" top script.
>
> Looks good.
>
> I did
>
> cd tools/testing/selftests
> make run_tests
>
> and it didn't work. This?
>
>
>
> From: Andrew Morton <[email protected]>
> Subject: selftests/Makefile: make `run_tests' depend on `all'
>
> So a "make run_tests" will build the tests before trying to run them.
>
> Cc: Frederic Weisbecker <[email protected]>
> Signed-off-by: Andrew Morton <[email protected]>
> ---
>
> tools/testing/selftests/Makefile | 2 +-
> 1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff -puN tools/testing/selftests/Makefile~a tools/testing/selftests/Makefile
> --- a/tools/testing/selftests/Makefile~a
> +++ a/tools/testing/selftests/Makefile
> @@ -5,7 +5,7 @@ all:
> make -C $$TARGET; \
> done;
>
> -run_tests:
> +run_tests: all
> for TARGET in $(TARGETS); do \
> make -C $$TARGET run_tests; \
> done;

Yeah that's good. Thanks!

2012-02-09 01:46:50

by Dave Young

[permalink] [raw]
Subject: Re: [PATCH 3/3 v2] move hugepage test examples to tools/testing/selftests/vm

On Mon, Feb 06, 2012 at 03:53:40PM -0800, Andrew Morton wrote:
> On Sun, 5 Feb 2012 16:15:55 +0800
> Dave Young <[email protected]> wrote:
>
> > hugepage-mmap.c, hugepage-shm.c and map_hugetlb.c in Documentation/vm are
> > simple pass/fail tests, It's better to promote them to tools/testing/selftests
> >
> > Thanks suggestion of Andrew Morton about this. They all need firstly setting up
> > proper nr_hugepages and hugepage-mmap need to mount hugetlbfs. So I add a shell
> > script run_test to do such work which will call the three test programs and
> > check the return value of them.
> >
> > Changes to original code including below:
> > a. add run_test script
> > b. return error when read_bytes mismatch with writed bytes.
> > c. coding style fixes: do not use assignment in if condition
> >
>
> I think Frederic is doing away with tools/testing/selftests/run_tests
> in favour of a Makefile target? ("make run_tests", for example).
>
> Until we see such a patch we cannot finalise your patch and if I apply
> your patch, his patch will need more work. Not that this is rocket
> science ;)
>
> >
> > ...
> >
> > --- /dev/null
> > +++ b/tools/testing/selftests/vm/run_test
>
> (We now have a "run_tests" and a "run_test". The difference in naming
> is irritating)
>
> Your vm/run_test file does quite a lot of work and we couldn't sensibly
> move all its functionality into Makefile, I expect.
>
> So I think it's OK to retain a script for this, but I do think that we
> should think up a standardized way of invoking it from vm/Makefile, so
> the top-level Makefile in tools/testing/selftests can simply do "cd
> vm;make run_test", where the run_test target exists in all
> subdirectories. The vm/Makefile run_test target can then call out to
> the script.
>
> Also, please do not assume that the script has the x bit set. The x
> bit easily gets lost on kernel scripts (patch(1) can lose it) so it is
> safer to invoke the script via "/bin/sh script-name" or $SHELL or
> whatever.
>
> Anyway, we should work with Frederic on sorting out some standard
> behavior before we can finalize this work, please.
>

Andrew, updated the patch as below, is it ok to you?
---

hugepage-mmap.c, hugepage-shm.c and map_hugetlb.c in Documentation/vm are
simple pass/fail tests, It's better to promote them to tools/testing/selftests

Thanks suggestion of Andrew Morton about this. They all need firstly setting up
proper nr_hugepages and hugepage-mmap need to mount hugetlbfs. So I add a shell
script run_vmtests to do such work which will call the three test programs and
check the return value of them.

Changes to original code including below:
a. add run_vmtests script
b. return error when read_bytes mismatch with writed bytes.
c. coding style fixes: do not use assignment in if condition

[v1 -> v2]:
1. [akpm:] rebased on runing make run_tests from Makefile
2. [akpm:] rename test script from run_test ro run_vmtests
2. fix a bug about shell exit code checking

Signed-off-by: Dave Young <[email protected]>
---
Documentation/vm/Makefile | 8 --
Documentation/vm/hugepage-mmap.c | 91 --------------------------
Documentation/vm/hugepage-shm.c | 98 ----------------------------
Documentation/vm/map_hugetlb.c | 77 ----------------------
tools/testing/selftests/Makefile | 2
tools/testing/selftests/vm/Makefile | 14 ++++
tools/testing/selftests/vm/hugepage-mmap.c | 92 ++++++++++++++++++++++++++
tools/testing/selftests/vm/hugepage-shm.c | 100 +++++++++++++++++++++++++++++
tools/testing/selftests/vm/map_hugetlb.c | 79 ++++++++++++++++++++++
tools/testing/selftests/vm/run_vmtests | 77 ++++++++++++++++++++++
10 files changed, 363 insertions(+), 275 deletions(-)

--- linux-2.6.orig/Documentation/vm/Makefile 2012-02-09 09:25:05.053163733 +0800
+++ /dev/null 1970-01-01 00:00:00.000000000 +0000
@@ -1,8 +0,0 @@
-# kbuild trick to avoid linker error. Can be omitted if a module is built.
-obj- := dummy.o
-
-# List of programs to build
-hostprogs-y := hugepage-mmap hugepage-shm map_hugetlb
-
-# Tell kbuild to always build the programs
-always := $(hostprogs-y)
--- linux-2.6.orig/Documentation/vm/hugepage-mmap.c 2012-02-09 09:25:05.053163733 +0800
+++ /dev/null 1970-01-01 00:00:00.000000000 +0000
@@ -1,91 +0,0 @@
-/*
- * hugepage-mmap:
- *
- * Example of using huge page memory in a user application using the mmap
- * system call. Before running this application, make sure that the
- * administrator has mounted the hugetlbfs filesystem (on some directory
- * like /mnt) using the command mount -t hugetlbfs nodev /mnt. In this
- * example, the app is requesting memory of size 256MB that is backed by
- * huge pages.
- *
- * For the ia64 architecture, the Linux kernel reserves Region number 4 for
- * huge pages. That means that if one requires a fixed address, a huge page
- * aligned address starting with 0x800000... will be required. If a fixed
- * address is not required, the kernel will select an address in the proper
- * range.
- * Other architectures, such as ppc64, i386 or x86_64 are not so constrained.
- */
-
-#include <stdlib.h>
-#include <stdio.h>
-#include <unistd.h>
-#include <sys/mman.h>
-#include <fcntl.h>
-
-#define FILE_NAME "/mnt/hugepagefile"
-#define LENGTH (256UL*1024*1024)
-#define PROTECTION (PROT_READ | PROT_WRITE)
-
-/* Only ia64 requires this */
-#ifdef __ia64__
-#define ADDR (void *)(0x8000000000000000UL)
-#define FLAGS (MAP_SHARED | MAP_FIXED)
-#else
-#define ADDR (void *)(0x0UL)
-#define FLAGS (MAP_SHARED)
-#endif
-
-static void check_bytes(char *addr)
-{
- printf("First hex is %x\n", *((unsigned int *)addr));
-}
-
-static void write_bytes(char *addr)
-{
- unsigned long i;
-
- for (i = 0; i < LENGTH; i++)
- *(addr + i) = (char)i;
-}
-
-static void read_bytes(char *addr)
-{
- unsigned long i;
-
- check_bytes(addr);
- for (i = 0; i < LENGTH; i++)
- if (*(addr + i) != (char)i) {
- printf("Mismatch at %lu\n", i);
- break;
- }
-}
-
-int main(void)
-{
- void *addr;
- int fd;
-
- fd = open(FILE_NAME, O_CREAT | O_RDWR, 0755);
- if (fd < 0) {
- perror("Open failed");
- exit(1);
- }
-
- addr = mmap(ADDR, LENGTH, PROTECTION, FLAGS, fd, 0);
- if (addr == MAP_FAILED) {
- perror("mmap");
- unlink(FILE_NAME);
- exit(1);
- }
-
- printf("Returned address is %p\n", addr);
- check_bytes(addr);
- write_bytes(addr);
- read_bytes(addr);
-
- munmap(addr, LENGTH);
- close(fd);
- unlink(FILE_NAME);
-
- return 0;
-}
--- linux-2.6.orig/Documentation/vm/hugepage-shm.c 2012-02-09 09:25:05.053163733 +0800
+++ /dev/null 1970-01-01 00:00:00.000000000 +0000
@@ -1,98 +0,0 @@
-/*
- * hugepage-shm:
- *
- * Example of using huge page memory in a user application using Sys V shared
- * memory system calls. In this example the app is requesting 256MB of
- * memory that is backed by huge pages. The application uses the flag
- * SHM_HUGETLB in the shmget system call to inform the kernel that it is
- * requesting huge pages.
- *
- * For the ia64 architecture, the Linux kernel reserves Region number 4 for
- * huge pages. That means that if one requires a fixed address, a huge page
- * aligned address starting with 0x800000... will be required. If a fixed
- * address is not required, the kernel will select an address in the proper
- * range.
- * Other architectures, such as ppc64, i386 or x86_64 are not so constrained.
- *
- * Note: The default shared memory limit is quite low on many kernels,
- * you may need to increase it via:
- *
- * echo 268435456 > /proc/sys/kernel/shmmax
- *
- * This will increase the maximum size per shared memory segment to 256MB.
- * The other limit that you will hit eventually is shmall which is the
- * total amount of shared memory in pages. To set it to 16GB on a system
- * with a 4kB pagesize do:
- *
- * echo 4194304 > /proc/sys/kernel/shmall
- */
-
-#include <stdlib.h>
-#include <stdio.h>
-#include <sys/types.h>
-#include <sys/ipc.h>
-#include <sys/shm.h>
-#include <sys/mman.h>
-
-#ifndef SHM_HUGETLB
-#define SHM_HUGETLB 04000
-#endif
-
-#define LENGTH (256UL*1024*1024)
-
-#define dprintf(x) printf(x)
-
-/* Only ia64 requires this */
-#ifdef __ia64__
-#define ADDR (void *)(0x8000000000000000UL)
-#define SHMAT_FLAGS (SHM_RND)
-#else
-#define ADDR (void *)(0x0UL)
-#define SHMAT_FLAGS (0)
-#endif
-
-int main(void)
-{
- int shmid;
- unsigned long i;
- char *shmaddr;
-
- if ((shmid = shmget(2, LENGTH,
- SHM_HUGETLB | IPC_CREAT | SHM_R | SHM_W)) < 0) {
- perror("shmget");
- exit(1);
- }
- printf("shmid: 0x%x\n", shmid);
-
- shmaddr = shmat(shmid, ADDR, SHMAT_FLAGS);
- if (shmaddr == (char *)-1) {
- perror("Shared memory attach failure");
- shmctl(shmid, IPC_RMID, NULL);
- exit(2);
- }
- printf("shmaddr: %p\n", shmaddr);
-
- dprintf("Starting the writes:\n");
- for (i = 0; i < LENGTH; i++) {
- shmaddr[i] = (char)(i);
- if (!(i % (1024 * 1024)))
- dprintf(".");
- }
- dprintf("\n");
-
- dprintf("Starting the Check...");
- for (i = 0; i < LENGTH; i++)
- if (shmaddr[i] != (char)i)
- printf("\nIndex %lu mismatched\n", i);
- dprintf("Done.\n");
-
- if (shmdt((const void *)shmaddr) != 0) {
- perror("Detach failure");
- shmctl(shmid, IPC_RMID, NULL);
- exit(3);
- }
-
- shmctl(shmid, IPC_RMID, NULL);
-
- return 0;
-}
--- linux-2.6.orig/Documentation/vm/map_hugetlb.c 2012-02-09 09:25:05.053163733 +0800
+++ /dev/null 1970-01-01 00:00:00.000000000 +0000
@@ -1,77 +0,0 @@
-/*
- * Example of using hugepage memory in a user application using the mmap
- * system call with MAP_HUGETLB flag. Before running this program make
- * sure the administrator has allocated enough default sized huge pages
- * to cover the 256 MB allocation.
- *
- * For ia64 architecture, Linux kernel reserves Region number 4 for hugepages.
- * That means the addresses starting with 0x800000... will need to be
- * specified. Specifying a fixed address is not required on ppc64, i386
- * or x86_64.
- */
-#include <stdlib.h>
-#include <stdio.h>
-#include <unistd.h>
-#include <sys/mman.h>
-#include <fcntl.h>
-
-#define LENGTH (256UL*1024*1024)
-#define PROTECTION (PROT_READ | PROT_WRITE)
-
-#ifndef MAP_HUGETLB
-#define MAP_HUGETLB 0x40000 /* arch specific */
-#endif
-
-/* Only ia64 requires this */
-#ifdef __ia64__
-#define ADDR (void *)(0x8000000000000000UL)
-#define FLAGS (MAP_PRIVATE | MAP_ANONYMOUS | MAP_HUGETLB | MAP_FIXED)
-#else
-#define ADDR (void *)(0x0UL)
-#define FLAGS (MAP_PRIVATE | MAP_ANONYMOUS | MAP_HUGETLB)
-#endif
-
-static void check_bytes(char *addr)
-{
- printf("First hex is %x\n", *((unsigned int *)addr));
-}
-
-static void write_bytes(char *addr)
-{
- unsigned long i;
-
- for (i = 0; i < LENGTH; i++)
- *(addr + i) = (char)i;
-}
-
-static void read_bytes(char *addr)
-{
- unsigned long i;
-
- check_bytes(addr);
- for (i = 0; i < LENGTH; i++)
- if (*(addr + i) != (char)i) {
- printf("Mismatch at %lu\n", i);
- break;
- }
-}
-
-int main(void)
-{
- void *addr;
-
- addr = mmap(ADDR, LENGTH, PROTECTION, FLAGS, 0, 0);
- if (addr == MAP_FAILED) {
- perror("mmap");
- exit(1);
- }
-
- printf("Returned address is %p\n", addr);
- check_bytes(addr);
- write_bytes(addr);
- read_bytes(addr);
-
- munmap(addr, LENGTH);
-
- return 0;
-}
--- linux-2.6.orig/tools/testing/selftests/Makefile 2012-02-09 09:25:05.056497066 +0800
+++ linux-2.6/tools/testing/selftests/Makefile 2012-02-09 09:25:45.963161759 +0800
@@ -1,4 +1,4 @@
-TARGETS = breakpoints
+TARGETS = breakpoints vm

all:
for TARGET in $(TARGETS); do \
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ linux-2.6/tools/testing/selftests/vm/Makefile 2012-02-09 09:26:16.843160268 +0800
@@ -0,0 +1,14 @@
+# Makefile for vm selftests
+
+CC = $(CROSS_COMPILE)gcc
+CFLAGS = -Wall -Wextra
+
+all: hugepage-mmap hugepage-shm map_hugetlb
+%: %.c
+ $(CC) $(CFLAGS) -o $@ $^
+
+run_tests:
+ /bin/sh ./run_vmtests
+
+clean:
+ $(RM) hugepage-mmap hugepage-shm map_hugetlb
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ linux-2.6/tools/testing/selftests/vm/hugepage-mmap.c 2012-02-09 09:25:45.966495092 +0800
@@ -0,0 +1,92 @@
+/*
+ * hugepage-mmap:
+ *
+ * Example of using huge page memory in a user application using the mmap
+ * system call. Before running this application, make sure that the
+ * administrator has mounted the hugetlbfs filesystem (on some directory
+ * like /mnt) using the command mount -t hugetlbfs nodev /mnt. In this
+ * example, the app is requesting memory of size 256MB that is backed by
+ * huge pages.
+ *
+ * For the ia64 architecture, the Linux kernel reserves Region number 4 for
+ * huge pages. That means that if one requires a fixed address, a huge page
+ * aligned address starting with 0x800000... will be required. If a fixed
+ * address is not required, the kernel will select an address in the proper
+ * range.
+ * Other architectures, such as ppc64, i386 or x86_64 are not so constrained.
+ */
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <sys/mman.h>
+#include <fcntl.h>
+
+#define FILE_NAME "huge/hugepagefile"
+#define LENGTH (256UL*1024*1024)
+#define PROTECTION (PROT_READ | PROT_WRITE)
+
+/* Only ia64 requires this */
+#ifdef __ia64__
+#define ADDR (void *)(0x8000000000000000UL)
+#define FLAGS (MAP_SHARED | MAP_FIXED)
+#else
+#define ADDR (void *)(0x0UL)
+#define FLAGS (MAP_SHARED)
+#endif
+
+static void check_bytes(char *addr)
+{
+ printf("First hex is %x\n", *((unsigned int *)addr));
+}
+
+static void write_bytes(char *addr)
+{
+ unsigned long i;
+
+ for (i = 0; i < LENGTH; i++)
+ *(addr + i) = (char)i;
+}
+
+static int read_bytes(char *addr)
+{
+ unsigned long i;
+
+ check_bytes(addr);
+ for (i = 0; i < LENGTH; i++)
+ if (*(addr + i) != (char)i) {
+ printf("Mismatch at %lu\n", i);
+ return 1;
+ }
+ return 0;
+}
+
+int main(void)
+{
+ void *addr;
+ int fd, ret;
+
+ fd = open(FILE_NAME, O_CREAT | O_RDWR, 0755);
+ if (fd < 0) {
+ perror("Open failed");
+ exit(1);
+ }
+
+ addr = mmap(ADDR, LENGTH, PROTECTION, FLAGS, fd, 0);
+ if (addr == MAP_FAILED) {
+ perror("mmap");
+ unlink(FILE_NAME);
+ exit(1);
+ }
+
+ printf("Returned address is %p\n", addr);
+ check_bytes(addr);
+ write_bytes(addr);
+ ret = read_bytes(addr);
+
+ munmap(addr, LENGTH);
+ close(fd);
+ unlink(FILE_NAME);
+
+ return ret;
+}
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ linux-2.6/tools/testing/selftests/vm/hugepage-shm.c 2012-02-09 09:25:45.966495092 +0800
@@ -0,0 +1,100 @@
+/*
+ * hugepage-shm:
+ *
+ * Example of using huge page memory in a user application using Sys V shared
+ * memory system calls. In this example the app is requesting 256MB of
+ * memory that is backed by huge pages. The application uses the flag
+ * SHM_HUGETLB in the shmget system call to inform the kernel that it is
+ * requesting huge pages.
+ *
+ * For the ia64 architecture, the Linux kernel reserves Region number 4 for
+ * huge pages. That means that if one requires a fixed address, a huge page
+ * aligned address starting with 0x800000... will be required. If a fixed
+ * address is not required, the kernel will select an address in the proper
+ * range.
+ * Other architectures, such as ppc64, i386 or x86_64 are not so constrained.
+ *
+ * Note: The default shared memory limit is quite low on many kernels,
+ * you may need to increase it via:
+ *
+ * echo 268435456 > /proc/sys/kernel/shmmax
+ *
+ * This will increase the maximum size per shared memory segment to 256MB.
+ * The other limit that you will hit eventually is shmall which is the
+ * total amount of shared memory in pages. To set it to 16GB on a system
+ * with a 4kB pagesize do:
+ *
+ * echo 4194304 > /proc/sys/kernel/shmall
+ */
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/ipc.h>
+#include <sys/shm.h>
+#include <sys/mman.h>
+
+#ifndef SHM_HUGETLB
+#define SHM_HUGETLB 04000
+#endif
+
+#define LENGTH (256UL*1024*1024)
+
+#define dprintf(x) printf(x)
+
+/* Only ia64 requires this */
+#ifdef __ia64__
+#define ADDR (void *)(0x8000000000000000UL)
+#define SHMAT_FLAGS (SHM_RND)
+#else
+#define ADDR (void *)(0x0UL)
+#define SHMAT_FLAGS (0)
+#endif
+
+int main(void)
+{
+ int shmid;
+ unsigned long i;
+ char *shmaddr;
+
+ shmid = shmget(2, LENGTH, SHM_HUGETLB | IPC_CREAT | SHM_R | SHM_W);
+ if (shmid < 0) {
+ perror("shmget");
+ exit(1);
+ }
+ printf("shmid: 0x%x\n", shmid);
+
+ shmaddr = shmat(shmid, ADDR, SHMAT_FLAGS);
+ if (shmaddr == (char *)-1) {
+ perror("Shared memory attach failure");
+ shmctl(shmid, IPC_RMID, NULL);
+ exit(2);
+ }
+ printf("shmaddr: %p\n", shmaddr);
+
+ dprintf("Starting the writes:\n");
+ for (i = 0; i < LENGTH; i++) {
+ shmaddr[i] = (char)(i);
+ if (!(i % (1024 * 1024)))
+ dprintf(".");
+ }
+ dprintf("\n");
+
+ dprintf("Starting the Check...");
+ for (i = 0; i < LENGTH; i++)
+ if (shmaddr[i] != (char)i) {
+ printf("\nIndex %lu mismatched\n", i);
+ exit(3);
+ }
+ dprintf("Done.\n");
+
+ if (shmdt((const void *)shmaddr) != 0) {
+ perror("Detach failure");
+ shmctl(shmid, IPC_RMID, NULL);
+ exit(4);
+ }
+
+ shmctl(shmid, IPC_RMID, NULL);
+
+ return 0;
+}
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ linux-2.6/tools/testing/selftests/vm/map_hugetlb.c 2012-02-09 09:25:45.966495092 +0800
@@ -0,0 +1,79 @@
+/*
+ * Example of using hugepage memory in a user application using the mmap
+ * system call with MAP_HUGETLB flag. Before running this program make
+ * sure the administrator has allocated enough default sized huge pages
+ * to cover the 256 MB allocation.
+ *
+ * For ia64 architecture, Linux kernel reserves Region number 4 for hugepages.
+ * That means the addresses starting with 0x800000... will need to be
+ * specified. Specifying a fixed address is not required on ppc64, i386
+ * or x86_64.
+ */
+#include <stdlib.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <sys/mman.h>
+#include <fcntl.h>
+
+#define LENGTH (256UL*1024*1024)
+#define PROTECTION (PROT_READ | PROT_WRITE)
+
+#ifndef MAP_HUGETLB
+#define MAP_HUGETLB 0x40000 /* arch specific */
+#endif
+
+/* Only ia64 requires this */
+#ifdef __ia64__
+#define ADDR (void *)(0x8000000000000000UL)
+#define FLAGS (MAP_PRIVATE | MAP_ANONYMOUS | MAP_HUGETLB | MAP_FIXED)
+#else
+#define ADDR (void *)(0x0UL)
+#define FLAGS (MAP_PRIVATE | MAP_ANONYMOUS | MAP_HUGETLB)
+#endif
+
+static void check_bytes(char *addr)
+{
+ printf("First hex is %x\n", *((unsigned int *)addr));
+}
+
+static void write_bytes(char *addr)
+{
+ unsigned long i;
+
+ for (i = 0; i < LENGTH; i++)
+ *(addr + i) = (char)i;
+}
+
+static int read_bytes(char *addr)
+{
+ unsigned long i;
+
+ check_bytes(addr);
+ for (i = 0; i < LENGTH; i++)
+ if (*(addr + i) != (char)i) {
+ printf("Mismatch at %lu\n", i);
+ return 1;
+ }
+ return 0;
+}
+
+int main(void)
+{
+ void *addr;
+ int ret;
+
+ addr = mmap(ADDR, LENGTH, PROTECTION, FLAGS, 0, 0);
+ if (addr == MAP_FAILED) {
+ perror("mmap");
+ exit(1);
+ }
+
+ printf("Returned address is %p\n", addr);
+ check_bytes(addr);
+ write_bytes(addr);
+ ret = read_bytes(addr);
+
+ munmap(addr, LENGTH);
+
+ return ret;
+}
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ linux-2.6/tools/testing/selftests/vm/run_vmtests 2012-02-09 09:27:12.163157528 +0800
@@ -0,0 +1,77 @@
+#!/bin/bash
+#please run as root
+
+#we need 256M, below is the size in kB
+needmem=262144
+mnt=./huge
+
+#get pagesize and freepages from /proc/meminfo
+while read name size unit; do
+ if [ "$name" = "HugePages_Free:" ]; then
+ freepgs=$size
+ fi
+ if [ "$name" = "Hugepagesize:" ]; then
+ pgsize=$size
+ fi
+done < /proc/meminfo
+
+#set proper nr_hugepages
+if [ -n "$freepgs" ] && [ -n "$pgsize" ]; then
+ nr_hugepgs=`cat /proc/sys/vm/nr_hugepages`
+ needpgs=`expr $needmem / $pgsize`
+ if [ $freepgs -lt $needpgs ]; then
+ lackpgs=$(( $needpgs - $freepgs ))
+ echo $(( $lackpgs + $nr_hugepgs )) > /proc/sys/vm/nr_hugepages
+ if [ $? -ne 0 ]; then
+ echo "Please run this test as root"
+ exit 1
+ fi
+ fi
+else
+ echo "no hugetlbfs support in kernel?"
+ exit 1
+fi
+
+mkdir $mnt
+mount -t hugetlbfs none $mnt
+
+echo "--------------------"
+echo "runing hugepage-mmap"
+echo "--------------------"
+./hugepage-mmap
+if [ $? -ne 0 ]; then
+ echo "[FAIL]"
+else
+ echo "[PASS]"
+fi
+
+shmmax=`cat /proc/sys/kernel/shmmax`
+shmall=`cat /proc/sys/kernel/shmall`
+echo 268435456 > /proc/sys/kernel/shmmax
+echo 4194304 > /proc/sys/kernel/shmall
+echo "--------------------"
+echo "runing hugepage-shm"
+echo "--------------------"
+./hugepage-shm
+if [ $? -ne 0 ]; then
+ echo "[FAIL]"
+else
+ echo "[PASS]"
+fi
+echo $shmmax > /proc/sys/kernel/shmmax
+echo $shmall > /proc/sys/kernel/shmall
+
+echo "--------------------"
+echo "runing map_hugetlb"
+echo "--------------------"
+./map_hugetlb
+if [ $? -ne 0 ]; then
+ echo "[FAIL]"
+else
+ echo "[PASS]"
+fi
+
+#cleanup
+umount $mnt
+rm -rf $mnt
+echo $nr_hugepgs > /proc/sys/vm/nr_hugepages

2012-02-09 23:03:32

by Andrew Morton

[permalink] [raw]
Subject: Re: [PATCH 3/3 v2] move hugepage test examples to tools/testing/selftests/vm

On Thu, 9 Feb 2012 09:46:22 +0800
Dave Young <[email protected]> wrote:

> Andrew, updated the patch as below, is it ok to you?
> ---
>
> hugepage-mmap.c, hugepage-shm.c and map_hugetlb.c in Documentation/vm are
> simple pass/fail tests, It's better to promote them to tools/testing/selftests
>
> Thanks suggestion of Andrew Morton about this. They all need firstly setting up
> proper nr_hugepages and hugepage-mmap need to mount hugetlbfs. So I add a shell
> script run_vmtests to do such work which will call the three test programs and
> check the return value of them.
>
> Changes to original code including below:
> a. add run_vmtests script
> b. return error when read_bytes mismatch with writed bytes.
> c. coding style fixes: do not use assignment in if condition
>
> [v1 -> v2]:
> 1. [akpm:] rebased on runing make run_tests from Makefile
> 2. [akpm:] rename test script from run_test ro run_vmtests
> 2. fix a bug about shell exit code checking
>

So I tried to run this, from tools/testing/selftests.

a) The testing failed because ./vm's run_test target requires root.

We need to make a policy decision here. Do we require that
selftests run as root? If not then the root-requiring selftests
should warn and bail out without declaring a failure, so that those
tests which can be run without root permissions can be successfully
used.

b) When I ran the vm test, my machine went paralytically comatose
for half a minute. That's a bit rude - if all the selftests do this
then the selftests become kinda useless.

c) I can run "make run_tests" in the top-lvel directory and all is
well: the tools in ./vm get compiled first. But when I do "make
clean ; cd vm ; make run-tests" it fails, because vm/Makefile
doesn't build the targets before trying to run them.

This can be fixed with

--- a/tools/testing/selftests/vm/Makefile~a
+++ a/tools/testing/selftests/vm/Makefile
@@ -7,7 +7,7 @@ all: hugepage-mmap hugepage-shm map_hug
%: %.c
$(CC) $(CFLAGS) -o $@ $^

-run_tests:
+run_tests: all
/bin/sh ./run_vmtests

clean:

But this is unpleasing: a top-level "make run_tests" will end up
trying to compile the targets twice.

We could change the top-level Makefile to a single-pass thing
which just descends into the subdirectories and runs "make
run_tests". But that gives us no way of compiling everything
without also running everything. That's a huge PITA if running
everything sends your machine comatose for half a minute!

So I think I'll go with the above patch.

2012-02-10 02:59:07

by Dave Young

[permalink] [raw]
Subject: Re: [PATCH 3/3 v2] move hugepage test examples to tools/testing/selftests/vm

On Thu, Feb 09, 2012 at 03:03:16PM -0800, Andrew Morton wrote:
> On Thu, 9 Feb 2012 09:46:22 +0800
> Dave Young <[email protected]> wrote:
>
> > Andrew, updated the patch as below, is it ok to you?
> > ---
> >
> > hugepage-mmap.c, hugepage-shm.c and map_hugetlb.c in Documentation/vm are
> > simple pass/fail tests, It's better to promote them to tools/testing/selftests
> >
> > Thanks suggestion of Andrew Morton about this. They all need firstly setting up
> > proper nr_hugepages and hugepage-mmap need to mount hugetlbfs. So I add a shell
> > script run_vmtests to do such work which will call the three test programs and
> > check the return value of them.
> >
> > Changes to original code including below:
> > a. add run_vmtests script
> > b. return error when read_bytes mismatch with writed bytes.
> > c. coding style fixes: do not use assignment in if condition
> >
> > [v1 -> v2]:
> > 1. [akpm:] rebased on runing make run_tests from Makefile
> > 2. [akpm:] rename test script from run_test ro run_vmtests
> > 2. fix a bug about shell exit code checking
> >
>
> So I tried to run this, from tools/testing/selftests.
>
> a) The testing failed because ./vm's run_test target requires root.
>
> We need to make a policy decision here. Do we require that
> selftests run as root? If not then the root-requiring selftests
> should warn and bail out without declaring a failure, so that those
> tests which can be run without root permissions can be successfully
> used.

I agree with bailing out with warning for root-requiring selftests.

>
> b) When I ran the vm test, my machine went paralytically comatose
> for half a minute. That's a bit rude - if all the selftests do this
> then the selftests become kinda useless.

Maybe 256M testing is too much, how about lower it to 64M hugepage test?

>
> c) I can run "make run_tests" in the top-lvel directory and all is
> well: the tools in ./vm get compiled first. But when I do "make
> clean ; cd vm ; make run-tests" it fails, because vm/Makefile
> doesn't build the targets before trying to run them.
>
> This can be fixed with
>
> --- a/tools/testing/selftests/vm/Makefile~a
> +++ a/tools/testing/selftests/vm/Makefile
> @@ -7,7 +7,7 @@ all: hugepage-mmap hugepage-shm map_hug
> %: %.c
> $(CC) $(CFLAGS) -o $@ $^
>
> -run_tests:
> +run_tests: all
> /bin/sh ./run_vmtests
>
> clean:
>
> But this is unpleasing: a top-level "make run_tests" will end up
> trying to compile the targets twice.
>
> We could change the top-level Makefile to a single-pass thing
> which just descends into the subdirectories and runs "make
> run_tests". But that gives us no way of compiling everything
> without also running everything. That's a huge PITA if running
> everything sends your machine comatose for half a minute!
>
> So I think I'll go with the above patch.
>

Thanks for the fix. For your comment a) and b), how about below fix?
If it's ok, then do you need I resend it with a refreshed whole patch?

---

Run make run_tests will fail without root previledge for vm selftests.
Change to Just bail out with a warning. At the same time lower the test
memory to 64M to avoid comatose machine.

Signed-off-by: Dave Young <[email protected]>
---
tools/testing/selftests/vm/hugepage-mmap.c | 4 ++--
tools/testing/selftests/vm/hugepage-shm.c | 8 ++++----
tools/testing/selftests/vm/map_hugetlb.c | 4 ++--
tools/testing/selftests/vm/run_vmtests | 14 +++++++-------
4 files changed, 15 insertions(+), 15 deletions(-)

--- linux-2.6.orig/tools/testing/selftests/vm/run_vmtests 2012-02-10 10:33:38.623148609 +0800
+++ linux-2.6/tools/testing/selftests/vm/run_vmtests 2012-02-10 10:40:24.229796996 +0800
@@ -1,8 +1,8 @@
#!/bin/bash
#please run as root

-#we need 256M, below is the size in kB
-needmem=262144
+#we need 64M, below is the size in kB
+needmem=65536
mnt=./huge

#get pagesize and freepages from /proc/meminfo
@@ -23,13 +23,13 @@ if [ -n "$freepgs" ] && [ -n "$pgsize" ]
lackpgs=$(( $needpgs - $freepgs ))
echo $(( $lackpgs + $nr_hugepgs )) > /proc/sys/vm/nr_hugepages
if [ $? -ne 0 ]; then
- echo "Please run this test as root"
- exit 1
+ echo "WARN: Bail out! Please run vm tests as root."
+ exit 0
fi
fi
else
- echo "no hugetlbfs support in kernel?"
- exit 1
+ echo "WARN: Bail out! no hugetlbfs support in kernel?"
+ exit 0
fi

mkdir $mnt
@@ -47,7 +47,7 @@ fi

shmmax=`cat /proc/sys/kernel/shmmax`
shmall=`cat /proc/sys/kernel/shmall`
-echo 268435456 > /proc/sys/kernel/shmmax
+echo 67108864 > /proc/sys/kernel/shmmax
echo 4194304 > /proc/sys/kernel/shmall
echo "--------------------"
echo "runing hugepage-shm"
--- linux-2.6.orig/tools/testing/selftests/vm/hugepage-mmap.c 2012-02-10 10:39:50.619798511 +0800
+++ linux-2.6/tools/testing/selftests/vm/hugepage-mmap.c 2012-02-10 10:40:07.656464407 +0800
@@ -5,7 +5,7 @@
* system call. Before running this application, make sure that the
* administrator has mounted the hugetlbfs filesystem (on some directory
* like /mnt) using the command mount -t hugetlbfs nodev /mnt. In this
- * example, the app is requesting memory of size 256MB that is backed by
+ * example, the app is requesting memory of size 64MB that is backed by
* huge pages.
*
* For the ia64 architecture, the Linux kernel reserves Region number 4 for
@@ -23,7 +23,7 @@
#include <fcntl.h>

#define FILE_NAME "huge/hugepagefile"
-#define LENGTH (256UL*1024*1024)
+#define LENGTH (64UL*1024*1024)
#define PROTECTION (PROT_READ | PROT_WRITE)

/* Only ia64 requires this */
--- linux-2.6.orig/tools/testing/selftests/vm/hugepage-shm.c 2012-02-10 10:39:47.966465296 +0800
+++ linux-2.6/tools/testing/selftests/vm/hugepage-shm.c 2012-02-10 10:40:24.229796996 +0800
@@ -2,7 +2,7 @@
* hugepage-shm:
*
* Example of using huge page memory in a user application using Sys V shared
- * memory system calls. In this example the app is requesting 256MB of
+ * memory system calls. In this example the app is requesting 64MB of
* memory that is backed by huge pages. The application uses the flag
* SHM_HUGETLB in the shmget system call to inform the kernel that it is
* requesting huge pages.
@@ -17,9 +17,9 @@
* Note: The default shared memory limit is quite low on many kernels,
* you may need to increase it via:
*
- * echo 268435456 > /proc/sys/kernel/shmmax
+ * echo 67108864 > /proc/sys/kernel/shmmax
*
- * This will increase the maximum size per shared memory segment to 256MB.
+ * This will increase the maximum size per shared memory segment to 64MB.
* The other limit that you will hit eventually is shmall which is the
* total amount of shared memory in pages. To set it to 16GB on a system
* with a 4kB pagesize do:
@@ -38,7 +38,7 @@
#define SHM_HUGETLB 04000
#endif

-#define LENGTH (256UL*1024*1024)
+#define LENGTH (64UL*1024*1024)

#define dprintf(x) printf(x)

--- linux-2.6.orig/tools/testing/selftests/vm/map_hugetlb.c 2012-02-10 10:39:50.623131844 +0800
+++ linux-2.6/tools/testing/selftests/vm/map_hugetlb.c 2012-02-10 10:40:07.659797740 +0800
@@ -2,7 +2,7 @@
* Example of using hugepage memory in a user application using the mmap
* system call with MAP_HUGETLB flag. Before running this program make
* sure the administrator has allocated enough default sized huge pages
- * to cover the 256 MB allocation.
+ * to cover the 64 MB allocation.
*
* For ia64 architecture, Linux kernel reserves Region number 4 for hugepages.
* That means the addresses starting with 0x800000... will need to be
@@ -15,7 +15,7 @@
#include <sys/mman.h>
#include <fcntl.h>

-#define LENGTH (256UL*1024*1024)
+#define LENGTH (64UL*1024*1024)
#define PROTECTION (PROT_READ | PROT_WRITE)

#ifndef MAP_HUGETLB