From b0568542cd902dfdf77bb9c6a3f90914a47fa937 Mon Sep 17 00:00:00 2001 From: Dmitry Antipov Date: Mon, 21 Jan 2013 16:29:15 +0400 Subject: Enforce the kernel to run cache shrinker via /proc/sys/vm/drop_caches. Delete sample input file and add two simple test cases for purge status. --- ashmemtest-expanded/ashmemtest-expanded.l | 65 +++++++++++++------------------ ashmemtest-expanded/example.txt | 22 ----------- ashmemtest-expanded/test0.txt | 12 ++++++ ashmemtest-expanded/test1.txt | 13 +++++++ 4 files changed, 52 insertions(+), 60 deletions(-) delete mode 100644 ashmemtest-expanded/example.txt create mode 100644 ashmemtest-expanded/test0.txt create mode 100644 ashmemtest-expanded/test1.txt diff --git a/ashmemtest-expanded/ashmemtest-expanded.l b/ashmemtest-expanded/ashmemtest-expanded.l index 074a948..f13c7a5 100644 --- a/ashmemtest-expanded/ashmemtest-expanded.l +++ b/ashmemtest-expanded/ashmemtest-expanded.l @@ -42,7 +42,7 @@ range_t * parse_range (char *); void getpages (int); void pinpages (range_t *); void unpinpages (range_t *); -void pressure (int); +void shrink (void); void purgepages (void); void fatal (int, const char *, ...); @@ -56,13 +56,13 @@ pin[ \t]+[0-9]+[ \t]+[0-9]+ { pinpages (parse_range (yytext + 3)); } unpin[ \t]+[0-9]+[ \t]+[0-9]+ { unpinpages (parse_range (yytext + 5)); } -alloc[ \t]+[0-9]+ { pressure (parse_number (yytext + 5)); } +shrink { shrink (); } purge { purgepages (); } [ \t\n]+ /* spaces */ -[ \t]*#.+ /* comment starts from '#' */ +[ \t]*#.* /* comment starts from '#' */ . { fprintf (stderr, "Unrecognized input '%s' at line %d\n", yytext, yylineno); @@ -145,6 +145,7 @@ void pinpages (range_t *range) { struct ashmem_pin pin; + int ret; if (ashmemfd == -1) fatal (0, "pages not allocated (use getpages X first)"); @@ -154,9 +155,10 @@ pinpages (range_t *range) /* Normal order, pin all at once. */ pin.offset = range->beg * pagesize; pin.len = (range->end - range->beg) * pagesize; - if (ioctl (ashmemfd, ASHMEM_PIN, &pin) < 0) + ret = ioctl (ashmemfd, ASHMEM_PIN, &pin); + if (ret < 0) fatal (errno, "can't pin %d..%d", range->beg, range->end); - printf ("-> pin %d..%d OK\n", range->beg, range->end); + printf ("-> pin %d..%d OK ret %d\n", range->beg, range->end, ret); } else { @@ -167,7 +169,8 @@ pinpages (range_t *range) { pin.offset = pgno * pagesize; pin.len = pagesize; - if (ioctl (ashmemfd, ASHMEM_PIN, &pin) < 0) + ret = ioctl (ashmemfd, ASHMEM_PIN, &pin); + if (ret < 0) fatal (errno, "can't pin page %d", pgno); } printf ("-> pin backward %d..%d OK\n", range->beg, range->end); @@ -178,6 +181,7 @@ void unpinpages (range_t *range) { struct ashmem_pin pin; + int ret; if (ashmemfd == -1) fatal (0, "pages not allocated (use getpages X first)"); @@ -187,9 +191,10 @@ unpinpages (range_t *range) /* Normal order, unpin all at once. */ pin.offset = range->beg * pagesize; pin.len = (range->end - range->beg) * pagesize; - if (ioctl (ashmemfd, ASHMEM_UNPIN, &pin) < 0) + ret = ioctl (ashmemfd, ASHMEM_UNPIN, &pin); + if (ret < 0) fatal (errno, "can't unpin %d..%d", range->beg, range->end); - printf ("-> unpin %d..%d OK\n", range->beg, range->end); + printf ("-> unpin %d..%d OK ret %d\n", range->beg, range->end, ret); } else { @@ -200,45 +205,29 @@ unpinpages (range_t *range) { pin.offset = pgno * pagesize; pin.len = pagesize; - if (ioctl (ashmemfd, ASHMEM_UNPIN, &pin) < 0) + ret = ioctl (ashmemfd, ASHMEM_UNPIN, &pin); + if (ret < 0) fatal (errno, "can't unpin page %d", pgno); } printf ("-> unpin backward %d..%d OK\n", range->beg, range->end); } } -/* Percentage is of physical RAM */ +/* Enforce the kernel to run cache shrinker */ void -pressure (int percentage) +shrink (void) { - struct sysinfo si; - int mbytes; - char *mem; - - if (sysinfo (&si) < 0) - fatal (0, "can't obtain system information"); - mbytes = (si.totalram >> 20) * percentage / 100; - switch (fork ()) - { - case 0: /* child */ - mem = (char *) malloc (mbytes << 20); - if (!mem) - fatal (0, "can't allocate %d MBytes", mbytes); - else - { - printf ("-> child allocates %d MBytes\n", mbytes); - memset (mem, 0, mbytes << 20); - /* let's wait for OOM killer */ - pause (); - } - /* NOTREACHED */ - break; - case -1: /* error */ - fatal (errno, "can't fork"); - default: /* parent */ - break; - } + int fd; + char cmd[2]; + + fd = open ("/proc/sys/vm/drop_caches", O_WRONLY); + if (fd < 0) + fatal (errno, "can't open /proc/sys/vm/drop_caches (is /proc mounted?)"); + cmd[0] = '3'; + cmd[1] = '\n'; + if (write (fd, cmd, sizeof cmd) != sizeof cmd) + fatal (errno, "can't write to /proc/sys/vm/drop_caches"); } void diff --git a/ashmemtest-expanded/example.txt b/ashmemtest-expanded/example.txt deleted file mode 100644 index 73ae92c..0000000 --- a/ashmemtest-expanded/example.txt +++ /dev/null @@ -1,22 +0,0 @@ -# Example input for ashmemtest-expanded test program. - -# Get 1000 pages -getpages 1000 - -# Unpin pages 100..200 -unpin 100 200 - -# Unpin pages 400..300 (in that order, e.g. backward) -unpin 400 300 - -# Allocate huge chunk (90% of physical RAM) -alloc 90 - -# Pin 100..200 back -pin 100 200 - -# Pin 300..400 back (in normal order) -pin 300 400 - -# Purge all -purge diff --git a/ashmemtest-expanded/test0.txt b/ashmemtest-expanded/test0.txt new file mode 100644 index 0000000..83c39a9 --- /dev/null +++ b/ashmemtest-expanded/test0.txt @@ -0,0 +1,12 @@ +# Simple test to make sure that the pages aren't purged initially. +# Expected output is: +# +# -> got 1000 pages +# -> unpin 0..500 OK ret 0 +# -> pin 0..500 OK ret 0 +# +# Here the last pin operation should return 0 (e.g. ASHMEM_NOT_PURGED). + +getpages 1000 +unpin 0 500 +pin 0 500 diff --git a/ashmemtest-expanded/test1.txt b/ashmemtest-expanded/test1.txt new file mode 100644 index 0000000..6ecd6df --- /dev/null +++ b/ashmemtest-expanded/test1.txt @@ -0,0 +1,13 @@ +# Simple test to call cache shrinker. Expected output is: +# +# -> got 1000 pages +# -> unpin 0..500 OK ret 0 +# -> pin 0..500 OK ret 1 +# +# Here the call to kernel cache shrinker should give 1 +# (e.g. ASHMEM_WAS_PURGED) for the last pin operation. + +getpages 1000 +unpin 0 500 +shrink +pin 0 500 -- cgit v1.2.3