From mboxrd@z Thu Jan 1 00:00:00 1970 From: Cyril Hrubis Date: Tue, 18 Feb 2020 17:27:39 +0100 Subject: [LTP] [PATCH v4 1/2] lib: add .request_hugepages to reserve hugepage In-Reply-To: <20200208092014.24824-1-liwang@redhat.com> References: <20200208092014.24824-1-liwang@redhat.com> Message-ID: <20200218162739.GA9985@rei.lan> List-Id: MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit To: ltp@lists.linux.it Hi! > Many of the ltp tests need to use hugepage in their testing, this allows > the test can reserve hpages from system only via .request_hugepages = xx. > > If set non-zero number of request_hugepages, test will try to reserve the > expected number of hugepage for testing in setup phase. If system does not > have enough hpage for using, it will try the best to reserve 80% available > number of hpages. For a system without hugetlb supporting, variable > 'tst_hugepage' will be set to 0. > > Signed-off-by: Li Wang > --- > > Notes: > v3 --> v4 > * add doc to check the hpage number in setup() > * remove the TCONF print if hugepage is not supported > * check here that max_hpages * 0.8 > 1 > > doc/test-writing-guidelines.txt | 58 ++++++++++++++++++++++++++++++++ > include/tst_hugepage.h | 29 ++++++++++++++++ > include/tst_test.h | 13 ++++++++ > lib/newlib_tests/.gitignore | 1 + > lib/newlib_tests/test20.c | 45 +++++++++++++++++++++++++ > lib/tst_hugepage.c | 59 +++++++++++++++++++++++++++++++++ > lib/tst_test.c | 6 ++-- > 7 files changed, 209 insertions(+), 2 deletions(-) > create mode 100644 include/tst_hugepage.h > create mode 100644 lib/newlib_tests/test20.c > create mode 100644 lib/tst_hugepage.c > > diff --git a/doc/test-writing-guidelines.txt b/doc/test-writing-guidelines.txt > index 546bb7a49..fa7cb89c1 100644 > --- a/doc/test-writing-guidelines.txt > +++ b/doc/test-writing-guidelines.txt > @@ -1933,6 +1933,64 @@ specified by the user plus some other heuristics. > > For full documentation see the comments in 'include/tst_fuzzy_sync.h'. > > +2.2.34 Reserving hugepages > +^^^^^^^^^^^^^^^^^^^^^^^^^^ > + > +Many of the ltp tests need to use hugepage in their testing, this allows the > +test can reserve hugepages from system only via .request_hugepages = xx. > + > +If set non-zero number of request_hugepages, test will try to reserve the > +expected number of hugepage for testing in setup phase. If system does not > +have enough hpage for using, it will try the best to reserve 80% available > +number of hpages. With success test stores the reserved hugepage number in > +'tst_hugepages. For the system without hugetlb supporting, variable > +'tst_hugepages' will be set to 0. > + > +Also, we do cleanup and restore work for the hpages resetting automatically. > + > +[source,c] > +------------------------------------------------------------------------------- > +#include "tst_test.h" > + > +static void run(void) > +{ > + ... > + > + if (tst_hugepages == test.request_hugepages) > + TEST(do_hpage_test); > + else > + ... > + ... > +} > + > +struct tst_test test = { > + .test_all = run, > + .request_hugepages = 2, > + ... > +}; > + > +or, > + > +#include "tst_test.h" > + > +static void run(void) > +{ > + ... > +} > + > +static void setup(void) > +{ > +?? ?? ?? ?? if (tst_hugepages != test.requested_hugepages) > +?? ?? ?? ?? ?? ?? ?? ?? tst_brk(TCONF, "..."); > +} > + > +struct tst_test test = { > + .test_all = run, > + .request_hugepages = 2, > + ... > +}; > +------------------------------------------------------------------------------- > + > 2.3 Writing a testcase in shell > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > > diff --git a/include/tst_hugepage.h b/include/tst_hugepage.h > new file mode 100644 > index 000000000..10e0eaf47 > --- /dev/null > +++ b/include/tst_hugepage.h > @@ -0,0 +1,29 @@ > +// SPDX-License-Identifier: GPL-2.0-or-later > +/* > + * Copyright (c) 2019 Red Hat, Inc. > + */ > + > +#ifndef TST_HUGEPAGE__ > +#define TST_HUGEPAGE__ > + > +#define PATH_HUGEPAGES "/sys/kernel/mm/hugepages/" > +#define PATH_NR_HPAGES "/proc/sys/vm/nr_hugepages" > + > +/* > + * Try the best to request a specified number of huge pages from system, > + * it will store the reserved hpage number in tst_hugepages. > + * > + * Note: this depend on the status of system memory fragmentation. > + */ > +int tst_request_hugepages(int hpages); > + > +/* > + * This variable is used for recording the number of hugepages which system can > + * provides. It will be equal to 'hpages' if tst_request_hugepages on success, > + * otherwise set it to a number of hugepages that we were able to reserve. > + * > + * If system does not support hugetlb, then it will be set to 0. > + */ > +extern unsigned int tst_hugepages; > + > +#endif /* TST_HUGEPAGE_H */ > diff --git a/include/tst_test.h b/include/tst_test.h > index 21c7dfbdb..1026a422a 100644 > --- a/include/tst_test.h > +++ b/include/tst_test.h > @@ -37,6 +37,7 @@ > #include "tst_coredump.h" > #include "tst_buffers.h" > #include "tst_capability.h" > +#include "tst_hugepage.h" > > /* > * Reports testcase result. > @@ -148,6 +149,18 @@ struct tst_test { > */ > int all_filesystems:1; > > + /* > + * If set non-zero number of request_hugepages, test will try to reserve the > + * expected number of hugepage for testing in setup phase. If system does not > + * have enough hpage for using, it will try the best to reserve 80% available > + * number of hpages. With success test stores the reserved hugepage number in > + * 'tst_hugepages. For the system without hugetlb supporting, variable > + * 'tst_hugepages' will be set to 0. > + * > + * Also, we do cleanup and restore work for the hpages resetting automatically. > + */ > + unsigned int request_hugepages; > + > /* > * If set non-zero denotes number of test variant, the test is executed > * variants times each time with tst_variant set to different number. > diff --git a/lib/newlib_tests/.gitignore b/lib/newlib_tests/.gitignore > index d4aa4935f..ab3a92c4c 100644 > --- a/lib/newlib_tests/.gitignore > +++ b/lib/newlib_tests/.gitignore > @@ -23,6 +23,7 @@ tst_strstatus > test17 > test18 > test19 > +test20 > tst_expiration_timer > test_exec > test_exec_child > diff --git a/lib/newlib_tests/test20.c b/lib/newlib_tests/test20.c > new file mode 100644 > index 000000000..92e230976 > --- /dev/null > +++ b/lib/newlib_tests/test20.c > @@ -0,0 +1,45 @@ > +// SPDX-License-Identifier: GPL-2.0-or-later > +/* > + * Copyright (c) 2019 Li Wang > + */ > + > +/* > + * Tests .request_hugepages + .save_restore > + */ > + > +#include "tst_test.h" > +#include "tst_hugepage.h" > +#include "tst_sys_conf.h" > + > +static const char * const save_restore[] = { > + "!/proc/sys/kernel/numa_balancing", > + NULL, > +}; > + > +static void do_test(void) { > + > + int val, hpages; > + > + tst_res(TINFO, "tst_hugepages = %u", tst_hugepages); > + SAFE_FILE_PRINTF("/proc/sys/kernel/numa_balancing", "1"); > + > + hpages = test.request_hugepages; > + SAFE_FILE_SCANF(PATH_NR_HPAGES, "%d", &val); > + if (val != hpages) > + tst_brk(TBROK, "nr_hugepages = %d, but expect %d", val, hpages); > + else > + tst_res(TPASS, "test .needs_hugepges"); > + > + hpages = tst_request_hugepages(3); > + SAFE_FILE_SCANF(PATH_NR_HPAGES, "%d", &val); > + if (val != hpages) > + tst_brk(TBROK, "nr_hugepages = %d, but expect %d", val, hpages); > + else > + tst_res(TPASS, "tst_request_hugepages"); > +} > + > +static struct tst_test test = { > + .test_all = do_test, > + .request_hugepages = 2, > + .save_restore = save_restore, > +}; > diff --git a/lib/tst_hugepage.c b/lib/tst_hugepage.c > new file mode 100644 > index 000000000..d37b45e3a > --- /dev/null > +++ b/lib/tst_hugepage.c > @@ -0,0 +1,59 @@ > +// SPDX-License-Identifier: GPL-2.0-or-later > +/* > + * Copyright (c) 2019 Red Hat, Inc. > + */ > + > +#define TST_NO_DEFAULT_MAIN > + > +#include "tst_test.h" > +#include "tst_hugepage.h" > + > +unsigned int tst_hugepages; > + > +int tst_request_hugepages(int hpages) > +{ > + int val; > + long mem_avail, max_hpages; > + > + if (access(PATH_HUGEPAGES, F_OK)) { > + tst_hugepages = 0; > + goto out; > + } > + > + tst_hugepages = hpages; > + > + SAFE_FILE_PRINTF("/proc/sys/vm/drop_caches", "3"); > + > + if (FILE_LINES_SCANF("/proc/meminfo", > + "MemAvailable: %ld", &mem_avail)) { > + /* > + * Using "MemFree:" on kernel that doesn't have > + * "MemAvailable:" in Meminfo > + */ > + tst_res(TINFO, "MemAvailable: not found in /proc/meminfo"); > + > + mem_avail = SAFE_READ_MEMINFO("MemFree:"); > + } I guess that we don't have to bother with MemAvailable here, since we do drop the system caches the MemFree should be equal to MemAvailable. So I would be for reading just MemFree unconditionally here. If you agree with this change I can change it before applying. > + max_hpages = mem_avail / SAFE_READ_MEMINFO("Hugepagesize:"); > + > + if (hpages > max_hpages) { > + tst_res(TINFO, "Requested number(%d) of hugepages is too large, " > + "limiting to 80%% of the max hugepage count %ld", > + hpages, max_hpages); > + tst_hugepages = max_hpages * 0.8; > + > + if (tst_hugepages < 1) > + goto out; > + } > + > + tst_sys_conf_save("?/proc/sys/vm/nr_hugepages"); > + SAFE_FILE_PRINTF(PATH_NR_HPAGES, "%d", tst_hugepages); > + SAFE_FILE_SCANF(PATH_NR_HPAGES, "%d", &val); > + if (val != tst_hugepages) > + tst_brk(TBROK, "nr_hugepages = %d, but expect %d", val, tst_hugepages); > + > + tst_res(TINFO, "%d hugepage(s) reserved", tst_hugepages); > +out: > + return tst_hugepages; > +} > diff --git a/lib/tst_test.c b/lib/tst_test.c > index 8d7dee2cc..9a24cffc5 100644 > --- a/lib/tst_test.c > +++ b/lib/tst_test.c > @@ -890,6 +890,9 @@ static void do_setup(int argc, char *argv[]) > if (tst_test->all_filesystems) > tst_test->needs_device = 1; > > + if (tst_test->request_hugepages) > + tst_request_hugepages(tst_test->request_hugepages); > + > setup_ipc(); > > if (tst_test->bufs) > @@ -1006,8 +1009,7 @@ static void do_cleanup(void) > tst_rmdir(); > } > > - if (tst_test->save_restore) > - tst_sys_conf_restore(0); > + tst_sys_conf_restore(0); > > if (tst_test->restore_wallclock) > tst_wallclock_restore(); > -- > 2.20.1 > > > -- > Mailing list info: https://lists.linux.it/listinfo/ltp -- Cyril Hrubis chrubis@suse.cz