From patchwork Sun Aug 1 15:43:52 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Zhansaya Bagdauletkyzy X-Patchwork-Id: 12413037 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-12.8 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,FREEMAIL_FORGED_FROMDOMAIN,FREEMAIL_FROM, HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS autolearn=unavailable autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id D85F3C43214 for ; Sun, 1 Aug 2021 15:44:01 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id B7634610CC for ; Sun, 1 Aug 2021 15:44:01 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S232134AbhHAPoI (ORCPT ); Sun, 1 Aug 2021 11:44:08 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:60234 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S232084AbhHAPoI (ORCPT ); Sun, 1 Aug 2021 11:44:08 -0400 Received: from mail-lj1-x229.google.com (mail-lj1-x229.google.com [IPv6:2a00:1450:4864:20::229]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 97732C0613D3; Sun, 1 Aug 2021 08:43:58 -0700 (PDT) Received: by mail-lj1-x229.google.com with SMTP id h11so20555402ljo.12; Sun, 01 Aug 2021 08:43:58 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=date:from:to:cc:subject:message-id:references:mime-version :content-disposition:in-reply-to; bh=JuOyqtRZoM4TE5Y8hFpkb7Y2rcrXHqYKLju1M9KuoRg=; b=eqLeD+MJ7dj/PLhdr3KNx8OplVKL0duHWMcWQSs/Bi2K5Qk+xTNUVatCUxe3QCnj4s KNwiAwBM/grfI5+O8rZ+ZWrX7/HfKyC9qfIMVTko1fBCuOD2jBn05AMuziwIHc4Rzn7n bh/DvhLDmwmKd6Di25HckbP4wcMpt5aI5BqeGIDRo4+dVI+HUXlHHx2euk19c8xgkyHo gCBZmzsbQDM2urpk9UiKFkGicCEIOMQUT3ooh8fQUOJ5a9rVMC0lMxJBNSO1jWO6lzWa g/GmJj3YrY/aZgDX2yrXvCpN0pZg2SUyXgQEqGfz2xYKZLDaPIYuOXXTBcwjEeHsm6kp TUkA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:date:from:to:cc:subject:message-id:references :mime-version:content-disposition:in-reply-to; bh=JuOyqtRZoM4TE5Y8hFpkb7Y2rcrXHqYKLju1M9KuoRg=; b=koG16XAd6x8eZSsNpNk3JRuyUqpM1Xeuy+n/vhbz9UsfyIs0+OBQBXF27N8TDu2Df9 2buFZNebN6A/qT0eqfDXL3w7N+FOSddPfEOfmcEUI576rFgp7s+ZQT/STiIazmy8R1en E+u7J+DbBY8ic0Ybo1h3sTmNV0UacYmLstiVUKzjt4WFA/YAYVA4ziCFGCnZaDOvp88O jb9buEBFK7xWmtGzc9Hgd70JZJWLK0AkMj8kzO7rH4o/UhEk86xb0N8xnsEXqp3NkYMc KuzM/AoSIfQE8b7e0aR3fDFmkAIVoSgidygNAf2mubYo+FmzoFjBA4Eky9Mxykkzolnn GvBA== X-Gm-Message-State: AOAM533Fz4PsO7CinjrcWWdPCWpVcL1D9BnBzvOcMW+I0eC/1JpUYUdp 2WwdecfiAfaRJraOItZ3H/o= X-Google-Smtp-Source: ABdhPJzMF92HX8j6hQ+wIiv6WNx2sUyE7bw4eVLlHRFdJjRsg0VT3Ja6gxKMTnBxqJGvMoXNyOQy2A== X-Received: by 2002:a2e:3c0d:: with SMTP id j13mr8524246lja.414.1627832637026; Sun, 01 Aug 2021 08:43:57 -0700 (PDT) Received: from asus ([147.30.82.254]) by smtp.gmail.com with ESMTPSA id bn41sm632023ljb.6.2021.08.01.08.43.55 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 01 Aug 2021 08:43:56 -0700 (PDT) Date: Sun, 1 Aug 2021 21:43:52 +0600 From: Zhansaya Bagdauletkyzy To: akpm@linux-foundation.org, shuah@kernel.org Cc: linux-mm@kvack.org, linux-kselftest@vger.kernel.org, linux-kernel@vger.kernel.org, tyhicks@linux.microsoft.com, pasha.tatashin@soleen.com Subject: [PATCH 1/2] selftests: vm: add KSM merging time test Message-ID: <5de9beffc409b660229695e0ad921825903156d6.1627828548.git.zhansayabagdaulet@gmail.com> References: MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: Precedence: bulk List-ID: X-Mailing-List: linux-kselftest@vger.kernel.org Add ksm_merge_time() function to determine speed and time needed for merging. The total spent time is shown in seconds while speed is in MB/s. User must specify the size of duplicated memory area (in MB) before running the test. The test is run as follows: ./ksm_tests -P -s 100 The output: Total size: 100 MB Total time: 0.309561 s Average speed: 323 MB/s Signed-off-by: Zhansaya Bagdauletkyzy --- tools/testing/selftests/vm/ksm_tests.c | 76 ++++++++++++++++++++++++-- 1 file changed, 72 insertions(+), 4 deletions(-) diff --git a/tools/testing/selftests/vm/ksm_tests.c b/tools/testing/selftests/vm/ksm_tests.c index cdeb4a028538..91c6ff496655 100644 --- a/tools/testing/selftests/vm/ksm_tests.c +++ b/tools/testing/selftests/vm/ksm_tests.c @@ -7,6 +7,7 @@ #include #include "../kselftest.h" +#include "../../../../include/vdso/time64.h" #define KSM_SYSFS_PATH "/sys/kernel/mm/ksm/" #define KSM_FP(s) (KSM_SYSFS_PATH s) @@ -15,6 +16,7 @@ #define KSM_PROT_STR_DEFAULT "rw" #define KSM_USE_ZERO_PAGES_DEFAULT false #define KSM_MERGE_ACROSS_NODES_DEFAULT true +#define MB_TO_B 1000000ul struct ksm_sysfs { unsigned long max_page_sharing; @@ -30,7 +32,8 @@ enum ksm_test_name { CHECK_KSM_MERGE, CHECK_KSM_UNMERGE, CHECK_KSM_ZERO_PAGE_MERGE, - CHECK_KSM_NUMA_MERGE + CHECK_KSM_NUMA_MERGE, + KSM_MERGE_TIME }; static int ksm_write_sysfs(const char *file_path, unsigned long val) @@ -86,13 +89,16 @@ static int str_to_prot(char *prot_str) static void print_help(void) { printf("usage: ksm_tests [-h] [-a prot] [-p page_count] [-l timeout]\n" - "[-z use_zero_pages] [-m merge_across_nodes]\n"); + "[-z use_zero_pages] [-m merge_across_nodes] [-s size]\n"); printf("Supported :\n" " -M (page merging)\n" " -Z (zero pages merging)\n" " -N (merging of pages in different NUMA nodes)\n" - " -U (page unmerging)\n\n"); + " -U (page unmerging)\n" + " -P evaluate merging time and speed.\n" + " For this test, the size of duplicated memory area (in MB)\n" + " must be provided using -s option\n\n"); printf(" -a: specify the access protections of pages.\n" " must be of the form [rwx].\n" @@ -105,6 +111,7 @@ static void print_help(void) " Default: %d\n", KSM_USE_ZERO_PAGES_DEFAULT); printf(" -m: change merge_across_nodes tunable\n" " Default: %d\n", KSM_MERGE_ACROSS_NODES_DEFAULT); + printf(" -s: the size of duplicated memory area (in MB)\n"); exit(0); } @@ -407,6 +414,49 @@ static int check_ksm_numa_merge(int mapping, int prot, int timeout, bool merge_a return KSFT_FAIL; } +static int ksm_merge_time(int mapping, int prot, int timeout, size_t map_size) +{ + void *map_ptr; + struct timespec start_time, end_time; + long scan_time_s, scan_time_ns; + int avg_speed; + + map_size *= MB_TO_B; + + map_ptr = allocate_memory(NULL, prot, mapping, '*', map_size); + if (!map_ptr) + return KSFT_FAIL; + + if (clock_gettime(CLOCK_MONOTONIC_RAW, &start_time)) { + perror("clock_gettime"); + goto err_out; + } + if (ksm_merge_pages(map_ptr, map_size, start_time, timeout)) + goto err_out; + if (clock_gettime(CLOCK_MONOTONIC_RAW, &end_time)) { + perror("clock_gettime"); + goto err_out; + } + + scan_time_ns = (end_time.tv_sec - start_time.tv_sec) * NSEC_PER_SEC + + (end_time.tv_nsec - start_time.tv_nsec); + scan_time_s = scan_time_ns / NSEC_PER_SEC; + scan_time_ns %= NSEC_PER_SEC; + avg_speed = map_size / (scan_time_s * USEC_PER_SEC + scan_time_ns / NSEC_PER_USEC); + + printf("Total size: %lu MB\n", map_size / MB_TO_B); + printf("Total time: %ld.%06ld s\n", scan_time_s, scan_time_ns / NSEC_PER_USEC); + printf("Average speed: %d MB/s\n", avg_speed); + + munmap(map_ptr, map_size); + return KSFT_PASS; + +err_out: + printf("Not OK\n"); + munmap(map_ptr, map_size); + return KSFT_FAIL; +} + int main(int argc, char *argv[]) { int ret, opt; @@ -418,8 +468,9 @@ int main(int argc, char *argv[]) int test_name = CHECK_KSM_MERGE; bool use_zero_pages = KSM_USE_ZERO_PAGES_DEFAULT; bool merge_across_nodes = KSM_MERGE_ACROSS_NODES_DEFAULT; + long size_MB = 0; - while ((opt = getopt(argc, argv, "ha:p:l:z:m:MUZN")) != -1) { + while ((opt = getopt(argc, argv, "ha:p:l:z:m:s:MUZNP")) != -1) { switch (opt) { case 'a': prot = str_to_prot(optarg); @@ -453,6 +504,12 @@ int main(int argc, char *argv[]) else merge_across_nodes = 1; break; + case 's': + size_MB = atoi(optarg); + if (size_MB <= 0) { + printf("Size must be greater than 0\n"); + return KSFT_FAIL; + } case 'M': break; case 'U': @@ -464,6 +521,9 @@ int main(int argc, char *argv[]) case 'N': test_name = CHECK_KSM_NUMA_MERGE; break; + case 'P': + test_name = KSM_MERGE_TIME; + break; default: return KSFT_FAIL; } @@ -505,6 +565,14 @@ int main(int argc, char *argv[]) ret = check_ksm_numa_merge(MAP_PRIVATE | MAP_ANONYMOUS, prot, ksm_scan_limit_sec, merge_across_nodes, page_size); break; + case KSM_MERGE_TIME: + if (size_MB == 0) { + printf("Option '-s' is required.\n"); + return KSFT_FAIL; + } + ret = ksm_merge_time(MAP_PRIVATE | MAP_ANONYMOUS, prot, ksm_scan_limit_sec, + size_MB); + break; } if (ksm_restore(&ksm_sysfs_old)) { From patchwork Sun Aug 1 15:43:54 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Zhansaya Bagdauletkyzy X-Patchwork-Id: 12413039 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-12.8 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,FREEMAIL_FORGED_FROMDOMAIN,FREEMAIL_FROM, HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 48BB0C4338F for ; Sun, 1 Aug 2021 15:44:02 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 2F565610D1 for ; Sun, 1 Aug 2021 15:44:02 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S232152AbhHAPoJ (ORCPT ); Sun, 1 Aug 2021 11:44:09 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:60242 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S232095AbhHAPoI (ORCPT ); Sun, 1 Aug 2021 11:44:08 -0400 Received: from mail-lj1-x232.google.com (mail-lj1-x232.google.com [IPv6:2a00:1450:4864:20::232]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id A247DC06175F; Sun, 1 Aug 2021 08:43:59 -0700 (PDT) Received: by mail-lj1-x232.google.com with SMTP id q2so20642244ljq.5; Sun, 01 Aug 2021 08:43:59 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=date:from:to:cc:subject:message-id:references:mime-version :content-disposition:in-reply-to; bh=YEjBF3EFihUm9hC1OBOnczDySCO1R9ENPttMMc1lNxs=; b=d/JciGk5DyQlK9x7u8W7Nnmqf1iHCu3fmhSnKn2EbmYiCzJ3T0c/snLSIjaPqvCkfd NXHKpRZHA7qSPEZfUT/eFfKMhDWEP+/9lhpIRecfS7mPO5Qm4KM8qDVnMRVMrUNBV6oA nluqUkJGRhK+7tV9a0jC8euWvj9bpiQk5Kq0zsoRBTyJ56R2xjJXzCsOSGwZIQ38oCZP E+7j92p1b6DXI9Z9PgBGsrZcgwDJPsWl+XCURS535utV/QtThMlG8nZw3mED3BtrTSaI g0itDQpu0IGBrwOMzTEjy80JjHhG2EWJsLCvZfxWFexhBrYyjTGxeEisjvyrVFqB4bb3 eKTA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:date:from:to:cc:subject:message-id:references :mime-version:content-disposition:in-reply-to; bh=YEjBF3EFihUm9hC1OBOnczDySCO1R9ENPttMMc1lNxs=; b=SAjhBx29Wc7vMmZiRj6H7ketD/CWEvJYrSw+0SNoqBRVMa4PDpsszk+iOIBOolavhO etUEQn0EBpYpkxfdZfqhqaABOjNdCTET6SgDqLUJe9jf9Qos1F2W7pu71t0bv0UJ/JGC g7E9RE0ixAVIifltxGwFt5aCvceP7LRvxrTMSsxutPbPsFvN4qfK4dziHBhXikMSaRsr /vm9Od6NPm9YBHkmmp7LBy2x1BrUgBL9TTf7HcGQt0qlzUnR8pS65vOvK4N4RNIuot5o UYuSM/6JHJRYqStrmxRwJ5eraHrobkXuTGLSTv6qAI2HbQoHC0YFfq0zIKEBL7foJvhl xjew== X-Gm-Message-State: AOAM5320QqwnLlG7+vvkqapKXkQ4uCIo+9t3d5q9QmpddWTcFvMlclXq qtXGmIVnpdUMXuQbBSL1PbM= X-Google-Smtp-Source: ABdhPJzFc8TqZENCJ7iHVLn/n13u6Yi3JCp+TDaDFBzQ/pTUU0qJmGuNbRXx8tIJ8TrP7L3TNbr0/g== X-Received: by 2002:a2e:a591:: with SMTP id m17mr8581400ljp.237.1627832638076; Sun, 01 Aug 2021 08:43:58 -0700 (PDT) Received: from asus ([147.30.82.254]) by smtp.gmail.com with ESMTPSA id a10sm702601lfb.93.2021.08.01.08.43.56 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 01 Aug 2021 08:43:57 -0700 (PDT) Date: Sun, 1 Aug 2021 21:43:54 +0600 From: Zhansaya Bagdauletkyzy To: akpm@linux-foundation.org, shuah@kernel.org Cc: linux-mm@kvack.org, linux-kselftest@vger.kernel.org, linux-kernel@vger.kernel.org, tyhicks@linux.microsoft.com, pasha.tatashin@soleen.com Subject: [PATCH 2/2] selftests: vm: add COW time test for KSM pages Message-ID: <26a3cc3d02dc4fa65cc9b135be76e7d795c44877.1627828548.git.zhansayabagdaulet@gmail.com> References: MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: Precedence: bulk List-ID: X-Mailing-List: linux-kselftest@vger.kernel.org Since merged pages are copied every time they need to be modified, the write access time is different between shared and non-shared pages. Add ksm_cow_time() function which evaluates latency of these COW breaks. First, duplicated pages are merged and then the time required to write to each of the pages is detected. The test is run as follows: ./ksm_tests -C -p 5000 The output: Total COW time: 0.012612 s The number of pages: 5000 Average speed: 1623 MB/s Signed-off-by: Zhansaya Bagdauletkyzy --- tools/testing/selftests/vm/ksm_tests.c | 66 ++++++++++++++++++++++++-- 1 file changed, 63 insertions(+), 3 deletions(-) diff --git a/tools/testing/selftests/vm/ksm_tests.c b/tools/testing/selftests/vm/ksm_tests.c index 91c6ff496655..3ffd899b2bd9 100644 --- a/tools/testing/selftests/vm/ksm_tests.c +++ b/tools/testing/selftests/vm/ksm_tests.c @@ -33,7 +33,8 @@ enum ksm_test_name { CHECK_KSM_UNMERGE, CHECK_KSM_ZERO_PAGE_MERGE, CHECK_KSM_NUMA_MERGE, - KSM_MERGE_TIME + KSM_MERGE_TIME, + KSM_COW_TIME }; static int ksm_write_sysfs(const char *file_path, unsigned long val) @@ -98,7 +99,9 @@ static void print_help(void) " -U (page unmerging)\n" " -P evaluate merging time and speed.\n" " For this test, the size of duplicated memory area (in MB)\n" - " must be provided using -s option\n\n"); + " must be provided using -s option\n" + " -C evaluate the time required to break COW of merged pages.\n" + " The number of pages can be defined using -p option.\n\n"); printf(" -a: specify the access protections of pages.\n" " must be of the form [rwx].\n" @@ -457,6 +460,56 @@ static int ksm_merge_time(int mapping, int prot, int timeout, size_t map_size) return KSFT_FAIL; } +static int ksm_cow_time(int mapping, int prot, int timeout, size_t page_size, long page_count) +{ + void *map_ptr; + struct timespec start_time, end_time; + long cow_time_s, cow_time_ns; + int avg_speed; + + if (clock_gettime(CLOCK_MONOTONIC_RAW, &start_time)) { + perror("clock_gettime"); + return KSFT_FAIL; + } + + map_ptr = allocate_memory(NULL, prot, mapping, '*', page_size * page_count); + if (!map_ptr) + return KSFT_FAIL; + + if (ksm_merge_pages(map_ptr, page_size * page_count, start_time, timeout)) + goto err_out; + + if (clock_gettime(CLOCK_MONOTONIC_RAW, &start_time)) { + perror("clock_gettime"); + goto err_out; + } + for (size_t i = 0; i < page_count; i++) + memset(map_ptr + page_size * i, '-', 1); + if (clock_gettime(CLOCK_MONOTONIC_RAW, &end_time)) { + perror("clock_gettime"); + goto err_out; + } + + cow_time_ns = (end_time.tv_sec - start_time.tv_sec) * NSEC_PER_SEC + + (end_time.tv_nsec - start_time.tv_nsec); + cow_time_s = cow_time_ns / NSEC_PER_SEC; + cow_time_ns %= NSEC_PER_SEC; + avg_speed = (page_size * page_count) / (cow_time_s * USEC_PER_SEC + + cow_time_ns / NSEC_PER_USEC); + + printf("Total COW time: %ld.%06ld s\n", cow_time_s, cow_time_ns / NSEC_PER_USEC); + printf("The number of pages: %ld\n", page_count); + printf("Average speed: %d MB/s\n", avg_speed); + + munmap(map_ptr, page_size * page_count); + return KSFT_PASS; + +err_out: + printf("Not OK\n"); + munmap(map_ptr, page_size * page_count); + return KSFT_FAIL; +} + int main(int argc, char *argv[]) { int ret, opt; @@ -470,7 +523,7 @@ int main(int argc, char *argv[]) bool merge_across_nodes = KSM_MERGE_ACROSS_NODES_DEFAULT; long size_MB = 0; - while ((opt = getopt(argc, argv, "ha:p:l:z:m:s:MUZNP")) != -1) { + while ((opt = getopt(argc, argv, "ha:p:l:z:m:s:MUZNPC")) != -1) { switch (opt) { case 'a': prot = str_to_prot(optarg); @@ -524,6 +577,9 @@ int main(int argc, char *argv[]) case 'P': test_name = KSM_MERGE_TIME; break; + case 'C': + test_name = KSM_COW_TIME; + break; default: return KSFT_FAIL; } @@ -573,6 +629,10 @@ int main(int argc, char *argv[]) ret = ksm_merge_time(MAP_PRIVATE | MAP_ANONYMOUS, prot, ksm_scan_limit_sec, size_MB); break; + case KSM_COW_TIME: + ret = ksm_cow_time(MAP_PRIVATE | MAP_ANONYMOUS, prot, ksm_scan_limit_sec, + page_size, page_count); + break; } if (ksm_restore(&ksm_sysfs_old)) {