From: Christoph Lameter Add a synthetic benchmark that can be used to measure performance of VM statistics. This is used to analyze any improvements or regressions in functions that are frequently used in hot code paths. The test is run by inserting the module: modprobe test_vmstat The module insertion will always fail so that it is automatically unloaded; the results are in the kernel log. Signed-off-by: Christoph Lameter Signed-off-by: David Rientjes --- lib/Kconfig.debug | 10 +++++ lib/Makefile | 1 + lib/test_vmstat.c | 95 +++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 106 insertions(+) create mode 100644 lib/test_vmstat.c diff --git a/lib/Kconfig.debug b/lib/Kconfig.debug index 1244dcac2294..6d743c8e27fa 100644 --- a/lib/Kconfig.debug +++ b/lib/Kconfig.debug @@ -3427,6 +3427,16 @@ config TEST_KEXEC_HANDOVER If unsure, say N. +config TEST_VMSTAT + tristate "VM Statistics Benchmark" + default n + help + A synthetic benchmark measuring the performance of VM statistics, + useful to analyze any improvements or regressions in functions that + are frequently used in hot code paths. + + If unsure, say N. + config RATELIMIT_KUNIT_TEST tristate "KUnit Test for correctness and stress of ratelimit" if !KUNIT_ALL_TESTS depends on KUNIT diff --git a/lib/Makefile b/lib/Makefile index 7f75cc6edf94..5f3ebabd0224 100644 --- a/lib/Makefile +++ b/lib/Makefile @@ -105,6 +105,7 @@ obj-$(CONFIG_TEST_FREE_PAGES) += test_free_pages.o obj-$(CONFIG_TEST_REF_TRACKER) += test_ref_tracker.o obj-$(CONFIG_TEST_OBJPOOL) += test_objpool.o obj-$(CONFIG_TEST_KEXEC_HANDOVER) += test_kho.o +obj-$(CONFIG_TEST_VMSTAT) += test_vmstat.o obj-$(CONFIG_TEST_FPU) += test_fpu.o test_fpu-y := test_fpu_glue.o test_fpu_impl.o diff --git a/lib/test_vmstat.c b/lib/test_vmstat.c new file mode 100644 index 000000000000..f63f439ab9d2 --- /dev/null +++ b/lib/test_vmstat.c @@ -0,0 +1,95 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * Test module for in-kernel synthetic vm statistics performance. + * + * execute + * + * modprobe test_vmstat + * + * to run this test + * + * (C) 2009 Linux Foundation, Christoph Lameter + */ + +#include +#include +#include +#include +#include +#include + +#define TEST_COUNT 10000 + +static int vmstat_test_init(void) +{ + unsigned int i; + cycles_t time1, time2, time; + int rem; + struct page *page = alloc_page(GFP_KERNEL); + + pr_alert("VMstat testing\n"); + pr_alert("=====================\n"); + pr_alert("1. inc_zone_page_state() then dec_zone_page_state()\n"); + time1 = get_cycles(); + for (i = 0; i < TEST_COUNT; i++) + inc_zone_page_state(page, NR_FREE_CMA_PAGES); + + time2 = get_cycles(); + time = time2 - time1; + + pr_alert("%i times inc_zone_page_state() ", i); + time = div_u64_rem(time, TEST_COUNT, &rem); + pr_cont("-> %llu cycles ", (unsigned long long) time); + + time1 = get_cycles(); + for (i = 0; i < TEST_COUNT; i++) + __dec_zone_page_state(page, NR_FREE_CMA_PAGES); + + time2 = get_cycles(); + time = time2 - time1; + + pr_cont("__dec_z_p_s() "); + time = div_u64_rem(time, TEST_COUNT, &rem); + pr_cont("-> %llu cycles\n", (unsigned long long) time); + + pr_alert("2. inc_zone_page_state()/dec_zone_page_state()\n"); + time1 = get_cycles(); + for (i = 0; i < TEST_COUNT; i++) { + inc_zone_page_state(page, NR_FREE_CMA_PAGES); + dec_zone_page_state(page, NR_FREE_CMA_PAGES); + } + + time2 = get_cycles(); + time = time2 - time1; + + pr_alert("%i times inc/dec ", i); + time = div_u64_rem(time, TEST_COUNT, &rem); + pr_cont("-> %llu cycles\n", (unsigned long long) time); + + pr_alert("3. count_vm_event()\n"); + time1 = get_cycles(); + for (i = 0; i < TEST_COUNT; i++) + count_vm_event(SLABS_SCANNED); + + time2 = get_cycles(); + time = time2 - time1; + + count_vm_events(SLABS_SCANNED, -TEST_COUNT); + pr_alert("%i count_vm_events ", i); + time = div_u64_rem(time, TEST_COUNT, &rem); + pr_cont("-> %llu cycles\n", (unsigned long long) time); + __free_page(page); + return -EAGAIN; /* Fail will directly unload the module */ +} + +static void vmstat_test_exit(void) +{ + pr_alert("test exit\n"); +} + +module_init(vmstat_test_init) +module_exit(vmstat_test_exit) + +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Christoph Lameter"); +MODULE_DESCRIPTION("VM statistics test");