2021-03-30 08:12:38

by Yanan Wang

[permalink] [raw]
Subject: [PATCH v6 00/10] KVM: selftests: some improvement and a new test for kvm page table

Hi,
This v6 series can mainly include two parts.
Rebased on kvm queue branch: https://git.kernel.org/pub/scm/virt/kvm/kvm.git/log/?h=queue

In the first part, all the known hugetlb backing src types specified
with different hugepage sizes are listed, so that we can specify use
of hugetlb source of the exact granularity that we want, instead of
the system default ones. And as all the known hugetlb page sizes are
listed, it's appropriate for all architectures. Besides, a helper that
can get granularity of different backing src types(anonumous/thp/hugetlb)
is added, so that we can use the accurate backing src granularity for
kinds of alignment or guest memory accessing of vcpus.

In the second part, a new test is added:
This test is added to serve as a performance tester and a bug reproducer
for kvm page table code (GPA->HPA mappings), it gives guidance for the
people trying to make some improvement for kvm. And the following explains
what we can exactly do through this test.

The function guest_code() can cover the conditions where a single vcpu or
multiple vcpus access guest pages within the same memory region, in three
VM stages(before dirty logging, during dirty logging, after dirty logging).
Besides, the backing src memory type(ANONYMOUS/THP/HUGETLB) of the tested
memory region can be specified by users, which means normal page mappings
or block mappings can be chosen by users to be created in the test.

If ANONYMOUS memory is specified, kvm will create normal page mappings
for the tested memory region before dirty logging, and update attributes
of the page mappings from RO to RW during dirty logging. If THP/HUGETLB
memory is specified, kvm will create block mappings for the tested memory
region before dirty logging, and split the blcok mappings into normal page
mappings during dirty logging, and coalesce the page mappings back into
block mappings after dirty logging is stopped.

So in summary, as a performance tester, this test can present the
performance of kvm creating/updating normal page mappings, or the
performance of kvm creating/splitting/recovering block mappings,
through execution time.

When we need to coalesce the page mappings back to block mappings after
dirty logging is stopped, we have to firstly invalidate *all* the TLB
entries for the page mappings right before installation of the block entry,
because a TLB conflict abort error could occur if we can't invalidate the
TLB entries fully. We have hit this TLB conflict twice on aarch64 software
implementation and fixed it. As this test can imulate process from dirty
logging enabled to dirty logging stopped of a VM with block mappings,
so it can also reproduce this TLB conflict abort due to inadequate TLB
invalidation when coalescing tables.

Links about the TLB conflict abort:
https://lore.kernel.org/lkml/[email protected]/

---

Change logs:

v5->v6:
- Address Andrew Jones's comments for v5 series
- Add Andrew Jones's R-b tags in some patches
- Rebased on newest kvm/queue tree
- v5: https://lore.kernel.org/lkml/[email protected]/

v4->v5:
- Use synchronization(sem_wait) for time measurement
- Add a new patch about TEST_ASSERT(patch 4)
- Address Andrew Jones's comments for v4 series
- Add Andrew Jones's R-b tags in some patches
- v4: https://lore.kernel.org/lkml/[email protected]/

v3->v4:
- Add a helper to get system default hugetlb page size
- Add tags of Reviewed-by of Ben in the patches
- v3: https://lore.kernel.org/lkml/[email protected]/

v2->v3:
- Add tags of Suggested-by, Reviewed-by in the patches
- Add a generic micro to get hugetlb page sizes
- Some changes for suggestions about v2 series
- v2: https://lore.kernel.org/lkml/[email protected]/

v1->v2:
- Add a patch to sync header files
- Add helpers to get granularity of different backing src types
- Some changes for suggestions about v1 series
- v1: https://lore.kernel.org/lkml/[email protected]/

---

Yanan Wang (10):
tools headers: sync headers of asm-generic/hugetlb_encode.h
mm/hugetlb: Add a macro to get HUGETLB page sizes for mmap
KVM: selftests: Use flag CLOCK_MONOTONIC_RAW for timing
KVM: selftests: Print the errno besides error-string in TEST_ASSERT
KVM: selftests: Make a generic helper to get vm guest mode strings
KVM: selftests: Add a helper to get system configured THP page size
KVM: selftests: Add a helper to get system default hugetlb page size
KVM: selftests: List all hugetlb src types specified with page sizes
KVM: selftests: Adapt vm_userspace_mem_region_add to new helpers
KVM: selftests: Add a test for kvm page table code

include/uapi/linux/mman.h | 2 +
tools/include/asm-generic/hugetlb_encode.h | 3 +
tools/include/uapi/linux/mman.h | 2 +
tools/testing/selftests/kvm/.gitignore | 1 +
tools/testing/selftests/kvm/Makefile | 3 +
.../selftests/kvm/demand_paging_test.c | 8 +-
.../selftests/kvm/dirty_log_perf_test.c | 14 +-
.../testing/selftests/kvm/include/kvm_util.h | 4 +-
.../testing/selftests/kvm/include/test_util.h | 21 +-
.../selftests/kvm/kvm_page_table_test.c | 506 ++++++++++++++++++
tools/testing/selftests/kvm/lib/assert.c | 4 +-
tools/testing/selftests/kvm/lib/kvm_util.c | 59 +-
tools/testing/selftests/kvm/lib/test_util.c | 163 +++++-
tools/testing/selftests/kvm/steal_time.c | 4 +-
14 files changed, 733 insertions(+), 61 deletions(-)
create mode 100644 tools/testing/selftests/kvm/kvm_page_table_test.c

--
2.23.0


2021-03-30 08:12:42

by Yanan Wang

[permalink] [raw]
Subject: [PATCH v6 03/10] KVM: selftests: Use flag CLOCK_MONOTONIC_RAW for timing

In addition to function of CLOCK_MONOTONIC, flag CLOCK_MONOTONIC_RAW can
also shield possiable impact of NTP, which can provide more robustness.

Suggested-by: Vitaly Kuznetsov <[email protected]>
Signed-off-by: Yanan Wang <[email protected]>
Reviewed-by: Ben Gardon <[email protected]>
Reviewed-by: Andrew Jones <[email protected]>
---
tools/testing/selftests/kvm/demand_paging_test.c | 8 ++++----
tools/testing/selftests/kvm/dirty_log_perf_test.c | 14 +++++++-------
tools/testing/selftests/kvm/lib/test_util.c | 2 +-
tools/testing/selftests/kvm/steal_time.c | 4 ++--
4 files changed, 14 insertions(+), 14 deletions(-)

diff --git a/tools/testing/selftests/kvm/demand_paging_test.c b/tools/testing/selftests/kvm/demand_paging_test.c
index 5f7a229c3af1..efbf0c1e9130 100644
--- a/tools/testing/selftests/kvm/demand_paging_test.c
+++ b/tools/testing/selftests/kvm/demand_paging_test.c
@@ -53,7 +53,7 @@ static void *vcpu_worker(void *data)
vcpu_args_set(vm, vcpu_id, 1, vcpu_id);
run = vcpu_state(vm, vcpu_id);

- clock_gettime(CLOCK_MONOTONIC, &start);
+ clock_gettime(CLOCK_MONOTONIC_RAW, &start);

/* Let the guest access its memory */
ret = _vcpu_run(vm, vcpu_id);
@@ -86,7 +86,7 @@ static int handle_uffd_page_request(int uffd, uint64_t addr)
copy.len = perf_test_args.host_page_size;
copy.mode = 0;

- clock_gettime(CLOCK_MONOTONIC, &start);
+ clock_gettime(CLOCK_MONOTONIC_RAW, &start);

r = ioctl(uffd, UFFDIO_COPY, &copy);
if (r == -1) {
@@ -123,7 +123,7 @@ static void *uffd_handler_thread_fn(void *arg)
struct timespec start;
struct timespec ts_diff;

- clock_gettime(CLOCK_MONOTONIC, &start);
+ clock_gettime(CLOCK_MONOTONIC_RAW, &start);
while (!quit_uffd_thread) {
struct uffd_msg msg;
struct pollfd pollfd[2];
@@ -336,7 +336,7 @@ static void run_test(enum vm_guest_mode mode, void *arg)

pr_info("Finished creating vCPUs and starting uffd threads\n");

- clock_gettime(CLOCK_MONOTONIC, &start);
+ clock_gettime(CLOCK_MONOTONIC_RAW, &start);

for (vcpu_id = 0; vcpu_id < nr_vcpus; vcpu_id++) {
pthread_create(&vcpu_threads[vcpu_id], NULL, vcpu_worker,
diff --git a/tools/testing/selftests/kvm/dirty_log_perf_test.c b/tools/testing/selftests/kvm/dirty_log_perf_test.c
index 04a2641261be..6cff4ccf9525 100644
--- a/tools/testing/selftests/kvm/dirty_log_perf_test.c
+++ b/tools/testing/selftests/kvm/dirty_log_perf_test.c
@@ -50,7 +50,7 @@ static void *vcpu_worker(void *data)
while (!READ_ONCE(host_quit)) {
int current_iteration = READ_ONCE(iteration);

- clock_gettime(CLOCK_MONOTONIC, &start);
+ clock_gettime(CLOCK_MONOTONIC_RAW, &start);
ret = _vcpu_run(vm, vcpu_id);
ts_diff = timespec_elapsed(start);

@@ -141,7 +141,7 @@ static void run_test(enum vm_guest_mode mode, void *arg)
iteration = 0;
host_quit = false;

- clock_gettime(CLOCK_MONOTONIC, &start);
+ clock_gettime(CLOCK_MONOTONIC_RAW, &start);
for (vcpu_id = 0; vcpu_id < nr_vcpus; vcpu_id++) {
vcpu_last_completed_iteration[vcpu_id] = -1;

@@ -162,7 +162,7 @@ static void run_test(enum vm_guest_mode mode, void *arg)
ts_diff.tv_sec, ts_diff.tv_nsec);

/* Enable dirty logging */
- clock_gettime(CLOCK_MONOTONIC, &start);
+ clock_gettime(CLOCK_MONOTONIC_RAW, &start);
vm_mem_region_set_flags(vm, PERF_TEST_MEM_SLOT_INDEX,
KVM_MEM_LOG_DIRTY_PAGES);
ts_diff = timespec_elapsed(start);
@@ -174,7 +174,7 @@ static void run_test(enum vm_guest_mode mode, void *arg)
* Incrementing the iteration number will start the vCPUs
* dirtying memory again.
*/
- clock_gettime(CLOCK_MONOTONIC, &start);
+ clock_gettime(CLOCK_MONOTONIC_RAW, &start);
iteration++;

pr_debug("Starting iteration %d\n", iteration);
@@ -189,7 +189,7 @@ static void run_test(enum vm_guest_mode mode, void *arg)
pr_info("Iteration %d dirty memory time: %ld.%.9lds\n",
iteration, ts_diff.tv_sec, ts_diff.tv_nsec);

- clock_gettime(CLOCK_MONOTONIC, &start);
+ clock_gettime(CLOCK_MONOTONIC_RAW, &start);
kvm_vm_get_dirty_log(vm, PERF_TEST_MEM_SLOT_INDEX, bmap);

ts_diff = timespec_elapsed(start);
@@ -199,7 +199,7 @@ static void run_test(enum vm_guest_mode mode, void *arg)
iteration, ts_diff.tv_sec, ts_diff.tv_nsec);

if (dirty_log_manual_caps) {
- clock_gettime(CLOCK_MONOTONIC, &start);
+ clock_gettime(CLOCK_MONOTONIC_RAW, &start);
kvm_vm_clear_dirty_log(vm, PERF_TEST_MEM_SLOT_INDEX, bmap, 0,
host_num_pages);

@@ -212,7 +212,7 @@ static void run_test(enum vm_guest_mode mode, void *arg)
}

/* Disable dirty logging */
- clock_gettime(CLOCK_MONOTONIC, &start);
+ clock_gettime(CLOCK_MONOTONIC_RAW, &start);
vm_mem_region_set_flags(vm, PERF_TEST_MEM_SLOT_INDEX, 0);
ts_diff = timespec_elapsed(start);
pr_info("Disabling dirty logging time: %ld.%.9lds\n",
diff --git a/tools/testing/selftests/kvm/lib/test_util.c b/tools/testing/selftests/kvm/lib/test_util.c
index 906c955384e2..c7c0627c6842 100644
--- a/tools/testing/selftests/kvm/lib/test_util.c
+++ b/tools/testing/selftests/kvm/lib/test_util.c
@@ -89,7 +89,7 @@ struct timespec timespec_elapsed(struct timespec start)
{
struct timespec end;

- clock_gettime(CLOCK_MONOTONIC, &end);
+ clock_gettime(CLOCK_MONOTONIC_RAW, &end);
return timespec_sub(end, start);
}

diff --git a/tools/testing/selftests/kvm/steal_time.c b/tools/testing/selftests/kvm/steal_time.c
index fcc840088c91..5bc582d3f2a2 100644
--- a/tools/testing/selftests/kvm/steal_time.c
+++ b/tools/testing/selftests/kvm/steal_time.c
@@ -237,11 +237,11 @@ static void *do_steal_time(void *arg)
{
struct timespec ts, stop;

- clock_gettime(CLOCK_MONOTONIC, &ts);
+ clock_gettime(CLOCK_MONOTONIC_RAW, &ts);
stop = timespec_add_ns(ts, MIN_RUN_DELAY_NS);

while (1) {
- clock_gettime(CLOCK_MONOTONIC, &ts);
+ clock_gettime(CLOCK_MONOTONIC_RAW, &ts);
if (timespec_to_ns(timespec_sub(ts, stop)) >= 0)
break;
}
--
2.19.1

2021-03-30 08:13:13

by Yanan Wang

[permalink] [raw]
Subject: [PATCH v6 09/10] KVM: selftests: Adapt vm_userspace_mem_region_add to new helpers

With VM_MEM_SRC_ANONYMOUS_THP specified in vm_userspace_mem_region_add(),
we have to get the transparent hugepage size for HVA alignment. With the
new helpers, we can use get_backing_src_pagesz() to check whether THP is
configured and then get the exact configured hugepage size.

As different architectures may have different THP page sizes configured,
this can get the accurate THP page sizes on any platform.

Signed-off-by: Yanan Wang <[email protected]>
Reviewed-by: Ben Gardon <[email protected]>
Reviewed-by: Andrew Jones <[email protected]>
---
tools/testing/selftests/kvm/lib/kvm_util.c | 28 +++++++---------------
1 file changed, 9 insertions(+), 19 deletions(-)

diff --git a/tools/testing/selftests/kvm/lib/kvm_util.c b/tools/testing/selftests/kvm/lib/kvm_util.c
index 3506174c2053..c7a2228deaf3 100644
--- a/tools/testing/selftests/kvm/lib/kvm_util.c
+++ b/tools/testing/selftests/kvm/lib/kvm_util.c
@@ -18,7 +18,6 @@
#include <unistd.h>
#include <linux/kernel.h>

-#define KVM_UTIL_PGS_PER_HUGEPG 512
#define KVM_UTIL_MIN_PFN 2

static int vcpu_mmap_sz(void);
@@ -688,7 +687,7 @@ void vm_userspace_mem_region_add(struct kvm_vm *vm,
{
int ret;
struct userspace_mem_region *region;
- size_t huge_page_size = KVM_UTIL_PGS_PER_HUGEPG * vm->page_size;
+ size_t backing_src_pagesz = get_backing_src_pagesz(src_type);
size_t alignment;

TEST_ASSERT(vm_adjust_num_guest_pages(vm->mode, npages) == npages,
@@ -750,7 +749,7 @@ void vm_userspace_mem_region_add(struct kvm_vm *vm,
#endif

if (src_type == VM_MEM_SRC_ANONYMOUS_THP)
- alignment = max(huge_page_size, alignment);
+ alignment = max(backing_src_pagesz, alignment);

/* Add enough memory to align up if necessary */
if (alignment > 1)
@@ -769,22 +768,13 @@ void vm_userspace_mem_region_add(struct kvm_vm *vm,
region->host_mem = align(region->mmap_start, alignment);

/* As needed perform madvise */
- if (src_type == VM_MEM_SRC_ANONYMOUS || src_type == VM_MEM_SRC_ANONYMOUS_THP) {
- struct stat statbuf;
-
- ret = stat("/sys/kernel/mm/transparent_hugepage", &statbuf);
- TEST_ASSERT(ret == 0 || (ret == -1 && errno == ENOENT),
- "stat /sys/kernel/mm/transparent_hugepage");
-
- TEST_ASSERT(ret == 0 || src_type != VM_MEM_SRC_ANONYMOUS_THP,
- "VM_MEM_SRC_ANONYMOUS_THP requires THP to be configured in the host kernel");
-
- if (ret == 0) {
- ret = madvise(region->host_mem, npages * vm->page_size,
- src_type == VM_MEM_SRC_ANONYMOUS ? MADV_NOHUGEPAGE : MADV_HUGEPAGE);
- TEST_ASSERT(ret == 0, "madvise failed, addr: %p length: 0x%lx src_type: %x",
- region->host_mem, npages * vm->page_size, src_type);
- }
+ if ((src_type == VM_MEM_SRC_ANONYMOUS ||
+ src_type == VM_MEM_SRC_ANONYMOUS_THP) && thp_configured()) {
+ ret = madvise(region->host_mem, npages * vm->page_size,
+ src_type == VM_MEM_SRC_ANONYMOUS ? MADV_NOHUGEPAGE : MADV_HUGEPAGE);
+ TEST_ASSERT(ret == 0, "madvise failed, addr: %p length: 0x%lx src_type: %s",
+ region->host_mem, npages * vm->page_size,
+ vm_mem_backing_src_alias(src_type)->name);
}

region->unused_phy_pages = sparsebit_alloc();
--
2.19.1

2021-04-06 13:02:05

by Yanan Wang

[permalink] [raw]
Subject: Re: [PATCH v6 00/10] KVM: selftests: some improvement and a new test for kvm page table

Kindly ping...

Hi Paolo,
Will this series be picked up soon, or is there any other work for me to do?

Regards,
Yanan


On 2021/3/30 16:08, Yanan Wang wrote:
> Hi,
> This v6 series can mainly include two parts.
> Rebased on kvm queue branch: https://git.kernel.org/pub/scm/virt/kvm/kvm.git/log/?h=queue
>
> In the first part, all the known hugetlb backing src types specified
> with different hugepage sizes are listed, so that we can specify use
> of hugetlb source of the exact granularity that we want, instead of
> the system default ones. And as all the known hugetlb page sizes are
> listed, it's appropriate for all architectures. Besides, a helper that
> can get granularity of different backing src types(anonumous/thp/hugetlb)
> is added, so that we can use the accurate backing src granularity for
> kinds of alignment or guest memory accessing of vcpus.
>
> In the second part, a new test is added:
> This test is added to serve as a performance tester and a bug reproducer
> for kvm page table code (GPA->HPA mappings), it gives guidance for the
> people trying to make some improvement for kvm. And the following explains
> what we can exactly do through this test.
>
> The function guest_code() can cover the conditions where a single vcpu or
> multiple vcpus access guest pages within the same memory region, in three
> VM stages(before dirty logging, during dirty logging, after dirty logging).
> Besides, the backing src memory type(ANONYMOUS/THP/HUGETLB) of the tested
> memory region can be specified by users, which means normal page mappings
> or block mappings can be chosen by users to be created in the test.
>
> If ANONYMOUS memory is specified, kvm will create normal page mappings
> for the tested memory region before dirty logging, and update attributes
> of the page mappings from RO to RW during dirty logging. If THP/HUGETLB
> memory is specified, kvm will create block mappings for the tested memory
> region before dirty logging, and split the blcok mappings into normal page
> mappings during dirty logging, and coalesce the page mappings back into
> block mappings after dirty logging is stopped.
>
> So in summary, as a performance tester, this test can present the
> performance of kvm creating/updating normal page mappings, or the
> performance of kvm creating/splitting/recovering block mappings,
> through execution time.
>
> When we need to coalesce the page mappings back to block mappings after
> dirty logging is stopped, we have to firstly invalidate *all* the TLB
> entries for the page mappings right before installation of the block entry,
> because a TLB conflict abort error could occur if we can't invalidate the
> TLB entries fully. We have hit this TLB conflict twice on aarch64 software
> implementation and fixed it. As this test can imulate process from dirty
> logging enabled to dirty logging stopped of a VM with block mappings,
> so it can also reproduce this TLB conflict abort due to inadequate TLB
> invalidation when coalescing tables.
>
> Links about the TLB conflict abort:
> https://lore.kernel.org/lkml/[email protected]/
>
> ---
>
> Change logs:
>
> v5->v6:
> - Address Andrew Jones's comments for v5 series
> - Add Andrew Jones's R-b tags in some patches
> - Rebased on newest kvm/queue tree
> - v5: https://lore.kernel.org/lkml/[email protected]/
>
> v4->v5:
> - Use synchronization(sem_wait) for time measurement
> - Add a new patch about TEST_ASSERT(patch 4)
> - Address Andrew Jones's comments for v4 series
> - Add Andrew Jones's R-b tags in some patches
> - v4: https://lore.kernel.org/lkml/[email protected]/
>
> v3->v4:
> - Add a helper to get system default hugetlb page size
> - Add tags of Reviewed-by of Ben in the patches
> - v3: https://lore.kernel.org/lkml/[email protected]/
>
> v2->v3:
> - Add tags of Suggested-by, Reviewed-by in the patches
> - Add a generic micro to get hugetlb page sizes
> - Some changes for suggestions about v2 series
> - v2: https://lore.kernel.org/lkml/[email protected]/
>
> v1->v2:
> - Add a patch to sync header files
> - Add helpers to get granularity of different backing src types
> - Some changes for suggestions about v1 series
> - v1: https://lore.kernel.org/lkml/[email protected]/
>
> ---
>
> Yanan Wang (10):
> tools headers: sync headers of asm-generic/hugetlb_encode.h
> mm/hugetlb: Add a macro to get HUGETLB page sizes for mmap
> KVM: selftests: Use flag CLOCK_MONOTONIC_RAW for timing
> KVM: selftests: Print the errno besides error-string in TEST_ASSERT
> KVM: selftests: Make a generic helper to get vm guest mode strings
> KVM: selftests: Add a helper to get system configured THP page size
> KVM: selftests: Add a helper to get system default hugetlb page size
> KVM: selftests: List all hugetlb src types specified with page sizes
> KVM: selftests: Adapt vm_userspace_mem_region_add to new helpers
> KVM: selftests: Add a test for kvm page table code
>
> include/uapi/linux/mman.h | 2 +
> tools/include/asm-generic/hugetlb_encode.h | 3 +
> tools/include/uapi/linux/mman.h | 2 +
> tools/testing/selftests/kvm/.gitignore | 1 +
> tools/testing/selftests/kvm/Makefile | 3 +
> .../selftests/kvm/demand_paging_test.c | 8 +-
> .../selftests/kvm/dirty_log_perf_test.c | 14 +-
> .../testing/selftests/kvm/include/kvm_util.h | 4 +-
> .../testing/selftests/kvm/include/test_util.h | 21 +-
> .../selftests/kvm/kvm_page_table_test.c | 506 ++++++++++++++++++
> tools/testing/selftests/kvm/lib/assert.c | 4 +-
> tools/testing/selftests/kvm/lib/kvm_util.c | 59 +-
> tools/testing/selftests/kvm/lib/test_util.c | 163 +++++-
> tools/testing/selftests/kvm/steal_time.c | 4 +-
> 14 files changed, 733 insertions(+), 61 deletions(-)
> create mode 100644 tools/testing/selftests/kvm/kvm_page_table_test.c
>

2021-04-17 13:24:12

by Paolo Bonzini

[permalink] [raw]
Subject: Re: [PATCH v6 00/10] KVM: selftests: some improvement and a new test for kvm page table

On 06/04/21 05:05, wangyanan (Y) wrote:
> Kindly ping...
>
> Hi Paolo,
> Will this series be picked up soon, or is there any other work for me to
> do?
>
> Regards,
> Yanan
>
>
> On 2021/3/30 16:08, Yanan Wang wrote:
>> Hi,
>> This v6 series can mainly include two parts.
>> Rebased on kvm queue branch:
>> https://git.kernel.org/pub/scm/virt/kvm/kvm.git/log/?h=queue
>>
>> In the first part, all the known hugetlb backing src types specified
>> with different hugepage sizes are listed, so that we can specify use
>> of hugetlb source of the exact granularity that we want, instead of
>> the system default ones. And as all the known hugetlb page sizes are
>> listed, it's appropriate for all architectures. Besides, a helper that
>> can get granularity of different backing src types(anonumous/thp/hugetlb)
>> is added, so that we can use the accurate backing src granularity for
>> kinds of alignment or guest memory accessing of vcpus.
>>
>> In the second part, a new test is added:
>> This test is added to serve as a performance tester and a bug reproducer
>> for kvm page table code (GPA->HPA mappings), it gives guidance for the
>> people trying to make some improvement for kvm. And the following
>> explains
>> what we can exactly do through this test.
>>
>> The function guest_code() can cover the conditions where a single vcpu or
>> multiple vcpus access guest pages within the same memory region, in three
>> VM stages(before dirty logging, during dirty logging, after dirty
>> logging).
>> Besides, the backing src memory type(ANONYMOUS/THP/HUGETLB) of the tested
>> memory region can be specified by users, which means normal page mappings
>> or block mappings can be chosen by users to be created in the test.
>>
>> If ANONYMOUS memory is specified, kvm will create normal page mappings
>> for the tested memory region before dirty logging, and update attributes
>> of the page mappings from RO to RW during dirty logging. If THP/HUGETLB
>> memory is specified, kvm will create block mappings for the tested memory
>> region before dirty logging, and split the blcok mappings into normal
>> page
>> mappings during dirty logging, and coalesce the page mappings back into
>> block mappings after dirty logging is stopped.
>>
>> So in summary, as a performance tester, this test can present the
>> performance of kvm creating/updating normal page mappings, or the
>> performance of kvm creating/splitting/recovering block mappings,
>> through execution time.
>>
>> When we need to coalesce the page mappings back to block mappings after
>> dirty logging is stopped, we have to firstly invalidate *all* the TLB
>> entries for the page mappings right before installation of the block
>> entry,
>> because a TLB conflict abort error could occur if we can't invalidate the
>> TLB entries fully. We have hit this TLB conflict twice on aarch64
>> software
>> implementation and fixed it. As this test can imulate process from dirty
>> logging enabled to dirty logging stopped of a VM with block mappings,
>> so it can also reproduce this TLB conflict abort due to inadequate TLB
>> invalidation when coalescing tables.
>>
>> Links about the TLB conflict abort:
>> https://lore.kernel.org/lkml/[email protected]/
>>
>>
>> ---
>>
>> Change logs:
>>
>> v5->v6:
>> - Address Andrew Jones's comments for v5 series
>> - Add Andrew Jones's R-b tags in some patches
>> - Rebased on newest kvm/queue tree
>> - v5:
>> https://lore.kernel.org/lkml/[email protected]/
>>
>>
>> v4->v5:
>> - Use synchronization(sem_wait) for time measurement
>> - Add a new patch about TEST_ASSERT(patch 4)
>> - Address Andrew Jones's comments for v4 series
>> - Add Andrew Jones's R-b tags in some patches
>> - v4:
>> https://lore.kernel.org/lkml/[email protected]/
>>
>>
>> v3->v4:
>> - Add a helper to get system default hugetlb page size
>> - Add tags of Reviewed-by of Ben in the patches
>> - v3:
>> https://lore.kernel.org/lkml/[email protected]/
>>
>>
>> v2->v3:
>> - Add tags of Suggested-by, Reviewed-by in the patches
>> - Add a generic micro to get hugetlb page sizes
>> - Some changes for suggestions about v2 series
>> - v2:
>> https://lore.kernel.org/lkml/[email protected]/
>>
>>
>> v1->v2:
>> - Add a patch to sync header files
>> - Add helpers to get granularity of different backing src types
>> - Some changes for suggestions about v1 series
>> - v1:
>> https://lore.kernel.org/lkml/[email protected]/
>>
>>
>> ---
>>
>> Yanan Wang (10):
>>    tools headers: sync headers of asm-generic/hugetlb_encode.h
>>    mm/hugetlb: Add a macro to get HUGETLB page sizes for mmap
>>    KVM: selftests: Use flag CLOCK_MONOTONIC_RAW for timing
>>    KVM: selftests: Print the errno besides error-string in TEST_ASSERT
>>    KVM: selftests: Make a generic helper to get vm guest mode strings
>>    KVM: selftests: Add a helper to get system configured THP page size
>>    KVM: selftests: Add a helper to get system default hugetlb page size
>>    KVM: selftests: List all hugetlb src types specified with page sizes
>>    KVM: selftests: Adapt vm_userspace_mem_region_add to new helpers
>>    KVM: selftests: Add a test for kvm page table code
>>
>>   include/uapi/linux/mman.h                     |   2 +
>>   tools/include/asm-generic/hugetlb_encode.h    |   3 +
>>   tools/include/uapi/linux/mman.h               |   2 +
>>   tools/testing/selftests/kvm/.gitignore        |   1 +
>>   tools/testing/selftests/kvm/Makefile          |   3 +
>>   .../selftests/kvm/demand_paging_test.c        |   8 +-
>>   .../selftests/kvm/dirty_log_perf_test.c       |  14 +-
>>   .../testing/selftests/kvm/include/kvm_util.h  |   4 +-
>>   .../testing/selftests/kvm/include/test_util.h |  21 +-
>>   .../selftests/kvm/kvm_page_table_test.c       | 506 ++++++++++++++++++
>>   tools/testing/selftests/kvm/lib/assert.c      |   4 +-
>>   tools/testing/selftests/kvm/lib/kvm_util.c    |  59 +-
>>   tools/testing/selftests/kvm/lib/test_util.c   | 163 +++++-
>>   tools/testing/selftests/kvm/steal_time.c      |   4 +-
>>   14 files changed, 733 insertions(+), 61 deletions(-)
>>   create mode 100644 tools/testing/selftests/kvm/kvm_page_table_test.c
>>
>

Queued, thanks.

I moved MAP_HUGE_PAGE_SIZE from the uapi header to test_util.c, because
I'm not confident in adding a new userspace API without an ack.

Paolo

2021-04-17 13:24:38

by Paolo Bonzini

[permalink] [raw]
Subject: Re: [PATCH v6 03/10] KVM: selftests: Use flag CLOCK_MONOTONIC_RAW for timing

On 30/03/21 10:08, Yanan Wang wrote:
> In addition to function of CLOCK_MONOTONIC, flag CLOCK_MONOTONIC_RAW can
> also shield possiable impact of NTP, which can provide more robustness.
>
> Suggested-by: Vitaly Kuznetsov<[email protected]>
> Signed-off-by: Yanan Wang<[email protected]>
> Reviewed-by: Ben Gardon<[email protected]>
> Reviewed-by: Andrew Jones<[email protected]>

I'm not sure about this one, is the effect visible?

Paolo

2021-04-19 06:47:18

by Yanan Wang

[permalink] [raw]
Subject: Re: [PATCH v6 03/10] KVM: selftests: Use flag CLOCK_MONOTONIC_RAW for timing

Hi Paolo,

On 2021/4/17 21:23, Paolo Bonzini wrote:
> On 30/03/21 10:08, Yanan Wang wrote:
>> In addition to function of CLOCK_MONOTONIC, flag CLOCK_MONOTONIC_RAW can
>> also shield possiable impact of NTP, which can provide more robustness.
>>
>> Suggested-by: Vitaly Kuznetsov<[email protected]>
>> Signed-off-by: Yanan Wang<[email protected]>
>> Reviewed-by: Ben Gardon<[email protected]>
>> Reviewed-by: Andrew Jones<[email protected]>
>
> I'm not sure about this one, is the effect visible?
>
In practice, difference between results got with CLOCK_MONOTONIC and
CLOCK_MONOTONIC_RAW
actually is too little to be visible. But if just in theory,
CLOCK_MONOTONIC_RAW can ensure time results
of the compared tests are based on the same local oscillator frequency,
which is not subject to possible
NTP frequency adjustment. Change in this patch seems like a bit of
optimization.

But either of these two flags is good to me. If this patch is not
convincing enough to be accepted, I will
post a patch later in fix use of CLOCK_MONOTONIC_RAW in
kvm_page_table_test.c just to be consistent
with other kvm tests, please queue. :)

Thanks,
Yanan


2021-04-19 09:30:42

by David Laight

[permalink] [raw]
Subject: RE: [PATCH v6 03/10] KVM: selftests: Use flag CLOCK_MONOTONIC_RAW for timing

From: wangyanan (Y)
> Sent: 19 April 2021 07:40
>
> Hi Paolo,
>
> On 2021/4/17 21:23, Paolo Bonzini wrote:
> > On 30/03/21 10:08, Yanan Wang wrote:
> >> In addition to function of CLOCK_MONOTONIC, flag CLOCK_MONOTONIC_RAW can
> >> also shield possiable impact of NTP, which can provide more robustness.
> >>
> >> Suggested-by: Vitaly Kuznetsov<[email protected]>
> >> Signed-off-by: Yanan Wang<[email protected]>
> >> Reviewed-by: Ben Gardon<[email protected]>
> >> Reviewed-by: Andrew Jones<[email protected]>
> >
> > I'm not sure about this one, is the effect visible?
> >
> In practice, difference between results got with CLOCK_MONOTONIC and
> CLOCK_MONOTONIC_RAW
> actually is too little to be visible. But if just in theory,
> CLOCK_MONOTONIC_RAW can ensure time results
> of the compared tests are based on the same local oscillator frequency,
> which is not subject to possible
> NTP frequency adjustment. Change in this patch seems like a bit of
> optimization.

The real annoyance is when NTP is realigning the local clock.
This typically happens after boot - but can take quite a few
minutes (don't think it can quite get to an hour).
(I think something similar is caused by leap seconds.)

During this period CLOCK_MONOTONIC can run at a significantly
different rate from 'real time'.
This may not matter for timing self tests, but is significant
for RTP audio.

The problem there is that you want the NTP corrected time
during 'normal running' because the small correction (for
crystal error) is useful.

But the kernel HR timers are only defined for CLOCK_MONOTONIC
and the userspace requests for CLOCK_MONOTONIC_RAW are likely
to be real system calls.

What you really want is a clock whose frequency is adjusted
by NTP but doesn't have the NTP offset adjuctments.
In reality this ought to be CLOCK_MONOTONIC.

David

-
Registered Address Lakeside, Bramley Road, Mount Farm, Milton Keynes, MK1 1PT, UK
Registration No: 1397386 (Wales)

2021-04-19 09:41:32

by Yanan Wang

[permalink] [raw]
Subject: Re: [PATCH v6 03/10] KVM: selftests: Use flag CLOCK_MONOTONIC_RAW for timing


On 2021/4/19 16:22, David Laight wrote:
> From: wangyanan (Y)
>> Sent: 19 April 2021 07:40
>>
>> Hi Paolo,
>>
>> On 2021/4/17 21:23, Paolo Bonzini wrote:
>>> On 30/03/21 10:08, Yanan Wang wrote:
>>>> In addition to function of CLOCK_MONOTONIC, flag CLOCK_MONOTONIC_RAW can
>>>> also shield possiable impact of NTP, which can provide more robustness.
>>>>
>>>> Suggested-by: Vitaly Kuznetsov<[email protected]>
>>>> Signed-off-by: Yanan Wang<[email protected]>
>>>> Reviewed-by: Ben Gardon<[email protected]>
>>>> Reviewed-by: Andrew Jones<[email protected]>
>>> I'm not sure about this one, is the effect visible?
>>>
>> In practice, difference between results got with CLOCK_MONOTONIC and
>> CLOCK_MONOTONIC_RAW
>> actually is too little to be visible. But if just in theory,
>> CLOCK_MONOTONIC_RAW can ensure time results
>> of the compared tests are based on the same local oscillator frequency,
>> which is not subject to possible
>> NTP frequency adjustment. Change in this patch seems like a bit of
>> optimization.
> The real annoyance is when NTP is realigning the local clock.
> This typically happens after boot - but can take quite a few
> minutes (don't think it can quite get to an hour).
> (I think something similar is caused by leap seconds.)
>
> During this period CLOCK_MONOTONIC can run at a significantly
> different rate from 'real time'.
> This may not matter for timing self tests, but is significant
> for RTP audio.
>
> The problem there is that you want the NTP corrected time
> during 'normal running' because the small correction (for
> crystal error) is useful.
>
> But the kernel HR timers are only defined for CLOCK_MONOTONIC
> and the userspace requests for CLOCK_MONOTONIC_RAW are likely
> to be real system calls.
>
> What you really want is a clock whose frequency is adjusted
> by NTP but doesn't have the NTP offset adjuctments.
> In reality this ought to be CLOCK_MONOTONIC.
Hi David,

I see now, much thanks for the above explanation. :)
Still have a lot to learn about this part.

Thanks,
Yanan
>
> David
>
> -
> Registered Address Lakeside, Bramley Road, Mount Farm, Milton Keynes, MK1 1PT, UK
> Registration No: 1397386 (Wales)