diff options
author | Hui Zhu <teawater@gmail.com> | 2020-03-05 10:36:04 +0800 |
---|---|---|
committer | Fengguang Wu <wufengguang@huawei.com> | 2020-03-05 13:55:23 +0800 |
commit | 0b057c87ae336580df8b80e1ecde829b83ec84b3 (patch) | |
tree | 53fcbac5881cd31dba4e2df98245441008bc21e3 | |
parent | 9b8c7fa79441e8d9708ead507f37964447874880 (diff) | |
download | vm-scalability-0b057c87ae336580df8b80e1ecde829b83ec84b3.tar.gz |
usemem: Add new option --punch-holes for generating fragmented pages
Hi Fengguang,
Thanks for your review. This is the new version that was updated
according to you comments.
This commit adds new option --punch-holes. usemem will free every
other page after allocation. Then it will generate size/2/pagesize
fragmented pages with this option.
Its implementation is to use madvise to release a page every other page.
For example:
usemem --punch-holes -s -1 400m
Ideally, this command will generate 200m fragmented pages in the system.
This command can help test anti-fragmentation function and other features
that are affected by fragmentation issues of the Linux kernel.
Signed-off-by: Hui Zhu <teawaterz@linux.alibaba.com>
Signed-off-by: Fengguang Wu <wufengguang@huawei.com>
-rw-r--r-- | usemem.c | 46 |
1 files changed, 45 insertions, 1 deletions
@@ -95,6 +95,7 @@ int opt_sync_free = 0; int opt_bind_interval = 0; unsigned long opt_delay = 0; int opt_read_again = 0; +int opt_punch_holes = 0; int nr_task; int nr_thread; int nr_cpu; @@ -153,6 +154,7 @@ void usage(int ok) " -O|--anonymous mmap with MAP_ANONYMOUS\n" " -U|--hugetlb allocate hugetlbfs page\n" " -Z|--read-again read memory again after access the memory\n" + " --punch-holes free every other page after allocation\n" " -h|--help show this message\n" , ourname); @@ -191,6 +193,7 @@ static const struct option opts[] = { { "delay" , 1, NULL, 'e' }, { "hugetlb" , 0, NULL, 'U' }, { "read-again" , 0, NULL, 'Z' }, + { "punch-holes", 0, NULL, 0 }, { "help" , 0, NULL, 'h' }, { NULL , 0, NULL, 0 } }; @@ -655,6 +658,21 @@ static void timing_free(void *ptrs[], unsigned int nptr, static void wait_for_sigusr1(int signal) {} +static void do_punch_holes(void *addr, unsigned long len) +{ + unsigned long offset; + + for (offset = 0; offset + 2 * pagesize <= len; offset += 2 * pagesize) { + if (madvise(addr + offset, pagesize, + MADV_DONTNEED) != 0) { + fprintf(stderr, + "madvise failed with error %s\n", + strerror(errno)); + exit(1); + } + } +} + long do_units(void) { struct drand48_data rand_data; @@ -752,6 +770,15 @@ long do_units(void) } } + if (opt_punch_holes) { + if (prealloc) + do_punch_holes(prealloc, opt_bytes); + else { + for (i = 0; i < nptr; i++) + do_punch_holes(ptrs[i], lens[i]); + } + } + while (sleep_secs) sleep_secs = sleep(sleep_secs); @@ -896,6 +923,7 @@ int do_tasks(void) int main(int argc, char *argv[]) { int c; + int opt_index = 0; #ifdef DBG /* print the command line parameters passed on to main */ @@ -910,9 +938,18 @@ int main(int argc, char *argv[]) pagesize = getpagesize(); while ((c = getopt_long(argc, argv, - "aAB:f:FPp:gqowRMm:n:t:b:ds:T:Sr:u:j:e:EHDNLWyxOUZh", opts, NULL)) != -1) + "aAB:f:FPp:gqowRMm:n:t:b:ds:T:Sr:u:j:e:EHDNLWyxOUZh", + opts, &opt_index)) != -1) { switch (c) { + case 0: + if (strcmp(opts[opt_index].name, + "punch-holes") == 0) { + opt_punch_holes = 1; + } else + usage(1); + break; + case 'a': opt_malloc++; break; @@ -1045,6 +1082,13 @@ int main(int argc, char *argv[]) } } + if (opt_punch_holes && opt_malloc) { + fprintf(stderr, + "%s: malloc options ignored for punch-holes\n", + ourname); + opt_malloc = 0; + } + if (opt_malloc) { if (map_populate|map_anonymous|map_hugetlb) fprintf(stderr, |