Re: [PATCH v8 11/11] KVM: selftests: Add multi-gen LRU aging to access_tracking_perf_test

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Tue, Nov 5, 2024 at 10:49 AM James Houghton <jthoughton@xxxxxxxxxx> wrote:
>
> This test now has two modes of operation:
> 1. (default) To check how much vCPU performance was affected by access
>              tracking (previously existed, now supports MGLRU aging).
> 2. (-p) To also benchmark how fast MGLRU can do aging while vCPUs are
>         faulting in memory.
>
> Mode (1) also serves as a way to verify that aging is working properly
> for pages only accessed by KVM.  It will fail if one does not have the
> 0x8 lru_gen feature bit.
>
> To support MGLRU, the test creates a memory cgroup, moves itself into
> it, then uses the lru_gen debugfs output to track memory in that cgroup.
> The logic to parse the lru_gen debugfs output has been put into
> selftests/kvm/lib/lru_gen_util.c.
>
> Co-developed-by: Axel Rasmussen <axelrasmussen@xxxxxxxxxx>
> Signed-off-by: Axel Rasmussen <axelrasmussen@xxxxxxxxxx>
> Signed-off-by: James Houghton <jthoughton@xxxxxxxxxx>
> ---
>  tools/testing/selftests/kvm/Makefile          |   1 +
>  .../selftests/kvm/access_tracking_perf_test.c | 366 ++++++++++++++--
>  .../selftests/kvm/include/lru_gen_util.h      |  55 +++
>  .../testing/selftests/kvm/lib/lru_gen_util.c  | 391 ++++++++++++++++++
>  4 files changed, 783 insertions(+), 30 deletions(-)
>  create mode 100644 tools/testing/selftests/kvm/include/lru_gen_util.h
>  create mode 100644 tools/testing/selftests/kvm/lib/lru_gen_util.c
>
> diff --git a/tools/testing/selftests/kvm/Makefile b/tools/testing/selftests/kvm/Makefile
> index f186888f0e00..542548e6e8ba 100644
> --- a/tools/testing/selftests/kvm/Makefile
> +++ b/tools/testing/selftests/kvm/Makefile
> @@ -22,6 +22,7 @@ LIBKVM += lib/elf.c
>  LIBKVM += lib/guest_modes.c
>  LIBKVM += lib/io.c
>  LIBKVM += lib/kvm_util.c
> +LIBKVM += lib/lru_gen_util.c
>  LIBKVM += lib/memstress.c
>  LIBKVM += lib/guest_sprintf.c
>  LIBKVM += lib/rbtree.c
> diff --git a/tools/testing/selftests/kvm/access_tracking_perf_test.c b/tools/testing/selftests/kvm/access_tracking_perf_test.c
> index 3c7defd34f56..8d6c2ce4b98a 100644
> --- a/tools/testing/selftests/kvm/access_tracking_perf_test.c
> +++ b/tools/testing/selftests/kvm/access_tracking_perf_test.c
> @@ -38,6 +38,7 @@
>  #include <inttypes.h>
>  #include <limits.h>
>  #include <pthread.h>
> +#include <stdio.h>
>  #include <sys/mman.h>
>  #include <sys/types.h>
>  #include <sys/stat.h>
> @@ -47,6 +48,19 @@
>  #include "memstress.h"
>  #include "guest_modes.h"
>  #include "processor.h"
> +#include "lru_gen_util.h"
> +
> +static const char *TEST_MEMCG_NAME = "access_tracking_perf_test";
> +static const int LRU_GEN_ENABLED = 0x1;
> +static const int LRU_GEN_MM_WALK = 0x2;
> +static const char *CGROUP_PROCS = "cgroup.procs";
> +/*
> + * If using MGLRU, this test assumes a cgroup v2 or cgroup v1 memory hierarchy
> + * is mounted at cgroup_root.
> + *
> + * Can be changed with -r.
> + */
> +static const char *cgroup_root = "/sys/fs/cgroup";
>
>  /* Global variable used to synchronize all of the vCPU threads. */
>  static int iteration;
> @@ -62,6 +76,9 @@ static enum {
>  /* The iteration that was last completed by each vCPU. */
>  static int vcpu_last_completed_iteration[KVM_MAX_VCPUS];
>
> +/* The time at which the last iteration was completed */
> +static struct timespec vcpu_last_completed_time[KVM_MAX_VCPUS];
> +
>  /* Whether to overlap the regions of memory vCPUs access. */
>  static bool overlap_memory_access;
>
> @@ -74,6 +91,12 @@ struct test_params {
>
>         /* The number of vCPUs to create in the VM. */
>         int nr_vcpus;
> +
> +       /* Whether to use lru_gen aging instead of idle page tracking. */
> +       bool lru_gen;
> +
> +       /* Whether to test the performance of aging itself. */
> +       bool benchmark_lru_gen;
>  };
>
>  static uint64_t pread_uint64(int fd, const char *filename, uint64_t index)
> @@ -89,6 +112,50 @@ static uint64_t pread_uint64(int fd, const char *filename, uint64_t index)
>
>  }
>
> +static void write_file_long(const char *path, long v)
> +{
> +       FILE *f;
> +
> +       f = fopen(path, "w");
> +       TEST_ASSERT(f, "fopen(%s) failed", path);
> +       TEST_ASSERT(fprintf(f, "%ld\n", v) > 0,
> +                   "fprintf to %s failed", path);
> +       TEST_ASSERT(!fclose(f), "fclose(%s) failed", path);
> +}
> +
> +static char *path_join(const char *parent, const char *child)
> +{
> +       char *out = NULL;
> +
> +       return asprintf(&out, "%s/%s", parent, child) >= 0 ? out : NULL;
> +}
> +
> +static char *memcg_path(const char *memcg)
> +{
> +       return path_join(cgroup_root, memcg);
> +}
> +
> +static char *memcg_file_path(const char *memcg, const char *file)
> +{
> +       char *mp = memcg_path(memcg);
> +       char *fp;
> +
> +       if (!mp)
> +               return NULL;
> +       fp = path_join(mp, file);
> +       free(mp);
> +       return fp;
> +}
> +
> +static void move_to_memcg(const char *memcg, pid_t pid)
> +{
> +       char *procs = memcg_file_path(memcg, CGROUP_PROCS);
> +
> +       TEST_ASSERT(procs, "Failed to construct cgroup.procs path");
> +       write_file_long(procs, pid);
> +       free(procs);
> +}
> +


[Index of Archives]     [KVM ARM]     [KVM ia64]     [KVM ppc]     [Virtualization Tools]     [Spice Development]     [Libvirt]     [Libvirt Users]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite Questions]     [Linux Kernel]     [Linux SCSI]     [XFree86]

  Powered by Linux