linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Pavel Tatashin <pasha.tatashin@soleen.com>
To: Zhansaya Bagdauletkyzy <zhansayabagdaulet@gmail.com>
Cc: Andrew Morton <akpm@linux-foundation.org>,
	shuah@kernel.org, linux-mm <linux-mm@kvack.org>,
	linux-kselftest@vger.kernel.org,
	LKML <linux-kernel@vger.kernel.org>,
	Tyler Hicks <tyhicks@linux.microsoft.com>
Subject: Re: [PATCH 2/2] selftests: vm: add COW time test for KSM pages
Date: Tue, 3 Aug 2021 23:41:07 -0400	[thread overview]
Message-ID: <CA+CK2bDYZBBaU3pC369o01tCgydaJ6y91GZ0_MWONMMCajZOUw@mail.gmail.com> (raw)
In-Reply-To: <26a3cc3d02dc4fa65cc9b135be76e7d795c44877.1627828548.git.zhansayabagdaulet@gmail.com>

On Sun, Aug 1, 2021 at 11:43 AM Zhansaya Bagdauletkyzy
<zhansayabagdaulet@gmail.com> wrote:
>
> 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.

Hi Zhansaya,

This test would make more sense if we also had a baseline on how long
it takes to modify unmerged pages. This way it would show the true
cost of having a write on a previously merged page vs. if it was never
merged.

Also, instead of having all pages merged together, I'd rather see a
collection of merged pairs of pages, which are decoupled as one of the
pages gets modified: i.e.
Page1 - Page2: merged
Page3 - Page4: merged
...

then, go through pages: Page2, Page4, ... and modify the first byte in
each of them and measure the time it takes. Do the same when these
pages are not merged, and print both numbers so the cost of KSM and
COW can be calculated.

Thanks,
Pasha

>
> 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 <zhansayabagdaulet@gmail.com>
> ---
>  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"
>                "     <prot> 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)) {
> --
> 2.25.1
>

      reply	other threads:[~2021-08-04  3:42 UTC|newest]

Thread overview: 5+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-08-01 15:43 [PATCH 0/2] add KSM performance tests Zhansaya Bagdauletkyzy
2021-08-01 15:43 ` [PATCH 1/2] selftests: vm: add KSM merging time test Zhansaya Bagdauletkyzy
2021-08-04  3:33   ` Pavel Tatashin
2021-08-01 15:43 ` [PATCH 2/2] selftests: vm: add COW time test for KSM pages Zhansaya Bagdauletkyzy
2021-08-04  3:41   ` Pavel Tatashin [this message]

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=CA+CK2bDYZBBaU3pC369o01tCgydaJ6y91GZ0_MWONMMCajZOUw@mail.gmail.com \
    --to=pasha.tatashin@soleen.com \
    --cc=akpm@linux-foundation.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-kselftest@vger.kernel.org \
    --cc=linux-mm@kvack.org \
    --cc=shuah@kernel.org \
    --cc=tyhicks@linux.microsoft.com \
    --cc=zhansayabagdaulet@gmail.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).