linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Raghavendra Rao Ananta <rananta@google.com>
To: Andrew Jones <drjones@redhat.com>
Cc: Paolo Bonzini <pbonzini@redhat.com>,
	Marc Zyngier <maz@kernel.org>, James Morse <james.morse@arm.com>,
	Alexandru Elisei <alexandru.elisei@arm.com>,
	Suzuki K Poulose <suzuki.poulose@arm.com>,
	Catalin Marinas <catalin.marinas@arm.com>,
	Will Deacon <will@kernel.org>, Peter Shier <pshier@google.com>,
	Ricardo Koller <ricarkol@google.com>,
	Oliver Upton <oupton@google.com>,
	Reiji Watanabe <reijiw@google.com>,
	Jing Zhang <jingzhangos@google.com>,
	linux-arm-kernel@lists.infradead.org,
	kvmarm@lists.cs.columbia.edu, linux-kernel@vger.kernel.org,
	kvm@vger.kernel.org
Subject: Re: [PATCH v4 16/18] KVM: arm64: selftests: arch_timer: Support vCPU migration
Date: Thu, 9 Sep 2021 10:33:47 -0700	[thread overview]
Message-ID: <CAJHc60yth9RpUf5MQLZxJHWsdqM_Jo611ReyJJ0HRdM1q7K6AQ@mail.gmail.com> (raw)
In-Reply-To: <20210909134520.yxrjestdwsishce2@gator>

On Thu, Sep 9, 2021 at 6:45 AM Andrew Jones <drjones@redhat.com> wrote:
>
> On Thu, Sep 09, 2021 at 01:38:16AM +0000, Raghavendra Rao Ananta wrote:
> > Since the timer stack (hardware and KVM) is per-CPU, there
> > are potential chances for races to occur when the scheduler
> > decides to migrate a vCPU thread to a different physical CPU.
> > Hence, include an option to stress-test this part as well by
> > forcing the vCPUs to migrate across physical CPUs in the
> > system at a particular rate.
> >
> > Originally, the bug for the fix with commit 3134cc8beb69d0d
> > ("KVM: arm64: vgic: Resample HW pending state on deactivation")
> > was discovered using arch_timer test with vCPU migrations and
> > can be easily reproduced.
> >
> > Signed-off-by: Raghavendra Rao Ananta <rananta@google.com>
> > ---
> >  .../selftests/kvm/aarch64/arch_timer.c        | 113 +++++++++++++++++-
> >  1 file changed, 112 insertions(+), 1 deletion(-)
> >
> > diff --git a/tools/testing/selftests/kvm/aarch64/arch_timer.c b/tools/testing/selftests/kvm/aarch64/arch_timer.c
> > index 6141c387e6dc..aac7bcea4352 100644
> > --- a/tools/testing/selftests/kvm/aarch64/arch_timer.c
> > +++ b/tools/testing/selftests/kvm/aarch64/arch_timer.c
> > @@ -14,6 +14,8 @@
> >   *
> >   * The test provides command-line options to configure the timer's
> >   * period (-p), number of vCPUs (-n), and iterations per stage (-i).
> > + * To stress-test the timer stack even more, an option to migrate the
> > + * vCPUs across pCPUs (-m), at a particular rate, is also provided.
> >   *
> >   * Copyright (c) 2021, Google LLC.
> >   */
> > @@ -24,6 +26,8 @@
> >  #include <pthread.h>
> >  #include <linux/kvm.h>
> >  #include <linux/sizes.h>
> > +#include <linux/bitmap.h>
> > +#include <sys/sysinfo.h>
> >
> >  #include "kvm_util.h"
> >  #include "processor.h"
> > @@ -36,17 +40,20 @@
> >  #define NR_TEST_ITERS_DEF            5
> >  #define TIMER_TEST_PERIOD_MS_DEF     10
> >  #define TIMER_TEST_ERR_MARGIN_US     100
> > +#define TIMER_TEST_MIGRATION_FREQ_MS 2
> >
> >  struct test_args {
> >       int nr_vcpus;
> >       int nr_iter;
> >       int timer_period_ms;
> > +     int migration_freq_ms;
> >  };
> >
> >  static struct test_args test_args = {
> >       .nr_vcpus = NR_VCPUS_DEF,
> >       .nr_iter = NR_TEST_ITERS_DEF,
> >       .timer_period_ms = TIMER_TEST_PERIOD_MS_DEF,
> > +     .migration_freq_ms = TIMER_TEST_MIGRATION_FREQ_MS,
> >  };
> >
> >  #define msecs_to_usecs(msec)         ((msec) * 1000LL)
> > @@ -81,6 +88,9 @@ struct test_vcpu {
> >  static struct test_vcpu test_vcpu[KVM_MAX_VCPUS];
> >  static struct test_vcpu_shared_data vcpu_shared_data[KVM_MAX_VCPUS];
> >
> > +static unsigned long *vcpu_done_map;
> > +static pthread_mutex_t vcpu_done_map_lock;
> > +
> >  static void
> >  guest_configure_timer_action(struct test_vcpu_shared_data *shared_data)
> >  {
> > @@ -216,6 +226,11 @@ static void *test_vcpu_run(void *arg)
> >
> >       vcpu_run(vm, vcpuid);
> >
> > +     /* Currently, any exit from guest is an indication of completion */
> > +     pthread_mutex_lock(&vcpu_done_map_lock);
> > +     set_bit(vcpuid, vcpu_done_map);
> > +     pthread_mutex_unlock(&vcpu_done_map_lock);
> > +
> >       switch (get_ucall(vm, vcpuid, &uc)) {
> >       case UCALL_SYNC:
> >       case UCALL_DONE:
> > @@ -234,9 +249,76 @@ static void *test_vcpu_run(void *arg)
> >       return NULL;
> >  }
> >
> > +static uint32_t test_get_pcpu(void)
> > +{
> > +     uint32_t pcpu;
> > +     unsigned int nproc_conf;
> > +     cpu_set_t online_cpuset;
> > +
> > +     nproc_conf = get_nprocs_conf();
> > +     sched_getaffinity(0, sizeof(cpu_set_t), &online_cpuset);
> > +
> > +     /* Randomly find an available pCPU to place a vCPU on */
> > +     do {
> > +             pcpu = rand() % nproc_conf;
> > +     } while (!CPU_ISSET(pcpu, &online_cpuset));
> > +
> > +     return pcpu;
> > +}
>
> Missing blank line here.
>
> > +static int test_migrate_vcpu(struct test_vcpu *vcpu)
> > +{
> > +     int ret;
> > +     cpu_set_t cpuset;
> > +     uint32_t new_pcpu = test_get_pcpu();
> > +
> > +     CPU_ZERO(&cpuset);
> > +     CPU_SET(new_pcpu, &cpuset);
> > +
> > +     pr_debug("Migrating vCPU: %u to pCPU: %u\n", vcpu->vcpuid, new_pcpu);
> > +
> > +     ret = pthread_setaffinity_np(vcpu->pt_vcpu_run,
> > +                                     sizeof(cpuset), &cpuset);
> > +
> > +     /* Allow the error where the vCPU thread is already finished */
> > +     TEST_ASSERT(ret == 0 || ret == ESRCH,
> > +                     "Failed to migrate the vCPU:%u to pCPU: %u; ret: %d\n",
> > +                     vcpu->vcpuid, new_pcpu, ret);
> > +
> > +     return ret;
> > +}
>
> Missing blank line here.
>
> > +static void *test_vcpu_migration(void *arg)
> > +{
> > +     unsigned int i, n_done;
> > +     bool vcpu_done;
> > +
> > +     do {
> > +             usleep(msecs_to_usecs(test_args.migration_freq_ms));
> > +
> > +             for (n_done = 0, i = 0; i < test_args.nr_vcpus; i++) {
> > +                     pthread_mutex_lock(&vcpu_done_map_lock);
> > +                     vcpu_done = test_bit(i, vcpu_done_map);
> > +                     pthread_mutex_unlock(&vcpu_done_map_lock);
> > +
> > +                     if (vcpu_done) {
> > +                             n_done++;
> > +                             continue;
> > +                     }
> > +
> > +                     test_migrate_vcpu(&test_vcpu[i]);
> > +             }
> > +     } while (test_args.nr_vcpus != n_done);
> > +
> > +     return NULL;
> > +}
> > +
> >  static void test_run(struct kvm_vm *vm)
> >  {
> >       int i, ret;
> > +     pthread_t pt_vcpu_migration;
> > +
> > +     pthread_mutex_init(&vcpu_done_map_lock, NULL);
> > +     vcpu_done_map = bitmap_alloc(test_args.nr_vcpus);
> > +     TEST_ASSERT(vcpu_done_map, "Failed to allocate vcpu done bitmap\n");
> >
> >       for (i = 0; i < test_args.nr_vcpus; i++) {
> >               ret = pthread_create(&test_vcpu[i].pt_vcpu_run, NULL,
> > @@ -244,8 +326,23 @@ static void test_run(struct kvm_vm *vm)
> >               TEST_ASSERT(!ret, "Failed to create vCPU-%d pthread\n", i);
> >       }
> >
> > +     /* Spawn a thread to control the vCPU migrations */
> > +     if (test_args.migration_freq_ms) {
> > +             srand(time(NULL));
> > +
> > +             ret = pthread_create(&pt_vcpu_migration, NULL,
> > +                                     test_vcpu_migration, NULL);
> > +             TEST_ASSERT(!ret, "Failed to create the migration pthread\n");
> > +     }
> > +
> > +
> >       for (i = 0; i < test_args.nr_vcpus; i++)
> >               pthread_join(test_vcpu[i].pt_vcpu_run, NULL);
> > +
> > +     if (test_args.migration_freq_ms)
> > +             pthread_join(pt_vcpu_migration, NULL);
> > +
> > +     bitmap_free(vcpu_done_map);
> >  }
> >
> >  static struct kvm_vm *test_vm_create(void)
> > @@ -286,6 +383,8 @@ static void test_print_help(char *name)
> >               NR_TEST_ITERS_DEF);
> >       pr_info("\t-p: Periodicity (in ms) of the guest timer (default: %u)\n",
> >               TIMER_TEST_PERIOD_MS_DEF);
> > +     pr_info("\t-m: Frequency (in ms) of vCPUs to migrate to different pCPU. 0 to turn off (default: %u)\n",
> > +             TIMER_TEST_MIGRATION_FREQ_MS);
> >       pr_info("\t-h: print this help screen\n");
> >  }
> >
> > @@ -293,7 +392,7 @@ static bool parse_args(int argc, char *argv[])
> >  {
> >       int opt;
> >
> > -     while ((opt = getopt(argc, argv, "hn:i:p:")) != -1) {
> > +     while ((opt = getopt(argc, argv, "hn:i:p:m:")) != -1) {
> >               switch (opt) {
> >               case 'n':
> >                       test_args.nr_vcpus = atoi(optarg);
> > @@ -320,6 +419,13 @@ static bool parse_args(int argc, char *argv[])
> >                               goto err;
> >                       }
> >                       break;
> > +             case 'm':
> > +                     test_args.migration_freq_ms = atoi(optarg);
> > +                     if (test_args.migration_freq_ms < 0) {
> > +                             pr_info("0 or positive value needed for -m\n");
> > +                             goto err;
> > +                     }
> > +                     break;
> >               case 'h':
> >               default:
> >                       goto err;
> > @@ -343,6 +449,11 @@ int main(int argc, char *argv[])
> >       if (!parse_args(argc, argv))
> >               exit(KSFT_SKIP);
> >
> > +     if (get_nprocs() < 2) {
>
> Even though the chance of being on a uniprocessor is low and the migration
> test is now on by default, we could still do
>
>  if (test_args.migration_freq_ms && get_nprocs() < 2)
>
huh, I had the check earlier; must have dropped it somewhere. Will
place it back.
And I'll fix all the blank line comments.

Regards,
Raghavendra

> since that's why the skip message says it needs two cpus.
>
> > +             print_skip("At least two physical CPUs needed for vCPU migration");
> > +             exit(KSFT_SKIP);
> > +     }
> > +
> >       vm = test_vm_create();
> >       test_run(vm);
> >       kvm_vm_free(vm);
> > --
> > 2.33.0.153.gba50c8fa24-goog
> >
>
> Reviewed-by: Andrew Jones <drjones@redhat.com>
>
> Thanks,
> drew
>

  reply	other threads:[~2021-09-09 17:34 UTC|newest]

Thread overview: 63+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-09-09  1:38 [PATCH v4 00/18] KVM: arm64: selftests: Introduce arch_timer selftest Raghavendra Rao Ananta
2021-09-09  1:38 ` [PATCH v4 01/18] KVM: arm64: selftests: Add MMIO readl/writel support Raghavendra Rao Ananta
2021-09-09  1:38 ` [PATCH v4 02/18] KVM: arm64: selftests: Add sysreg.h Raghavendra Rao Ananta
2021-09-09  2:47   ` Oliver Upton
2021-09-09  6:53     ` Andrew Jones
2021-09-09 16:42       ` Raghavendra Rao Ananta
2021-09-09 17:17   ` Mark Brown
2021-09-09 20:06     ` Raghavendra Rao Ananta
2021-09-10  8:30       ` Mark Brown
2021-09-13 23:38         ` Raghavendra Rao Ananta
2021-09-14 10:39           ` Mark Brown
2021-09-09  1:38 ` [PATCH v4 03/18] KVM: arm64: selftests: Use read/write definitions from sysreg.h Raghavendra Rao Ananta
2021-09-09  2:55   ` Oliver Upton
2021-09-09  6:56   ` Andrew Jones
2021-09-09 16:43     ` Raghavendra Rao Ananta
2021-09-09  1:38 ` [PATCH v4 04/18] KVM: arm64: selftests: Introduce ARM64_SYS_KVM_REG Raghavendra Rao Ananta
2021-09-09  3:02   ` Oliver Upton
2021-09-09 16:48     ` Raghavendra Rao Ananta
2021-09-09  7:04   ` Andrew Jones
2021-09-09 16:49     ` Raghavendra Rao Ananta
2021-09-09  1:38 ` [PATCH v4 05/18] KVM: arm64: selftests: Add support for cpu_relax Raghavendra Rao Ananta
2021-09-09  1:38 ` [PATCH v4 06/18] KVM: arm64: selftests: Add basic support for arch_timers Raghavendra Rao Ananta
2021-09-09  7:07   ` Andrew Jones
2021-09-09  1:38 ` [PATCH v4 07/18] KVM: arm64: selftests: Add basic support to generate delays Raghavendra Rao Ananta
2021-09-09  1:38 ` [PATCH v4 08/18] KVM: arm64: selftests: Add support to disable and enable local IRQs Raghavendra Rao Ananta
2021-09-09  1:38 ` [PATCH v4 09/18] KVM: arm64: selftests: Add guest support to get the vcpuid Raghavendra Rao Ananta
2021-09-09  5:09   ` Oliver Upton
2021-09-09 16:59     ` Raghavendra Rao Ananta
2021-09-09 17:04       ` Oliver Upton
2021-09-09  7:56   ` Andrew Jones
2021-09-09 17:10     ` Raghavendra Rao Ananta
2021-09-10  8:10       ` Andrew Jones
2021-09-10 18:03         ` Raghavendra Rao Ananta
2021-09-13  7:25           ` Andrew Jones
2021-09-12  7:05   ` Reiji Watanabe
2021-09-13  7:35     ` Andrew Jones
2021-09-13 16:51       ` Raghavendra Rao Ananta
2021-09-09  1:38 ` [PATCH v4 10/18] KVM: arm64: selftests: Add light-weight spinlock support Raghavendra Rao Ananta
2021-09-09  1:38 ` [PATCH v4 11/18] KVM: arm64: selftests: Add basic GICv3 support Raghavendra Rao Ananta
2021-09-09  5:18   ` Oliver Upton
2021-09-09 16:38     ` Raghavendra Rao Ananta
2021-09-09  1:38 ` [PATCH v4 12/18] KVM: selftests: Keep track of the number of vCPUs for a VM Raghavendra Rao Ananta
2021-09-09  5:22   ` Oliver Upton
2021-09-09 13:20   ` Andrew Jones
2021-09-09  1:38 ` [PATCH v4 13/18] KVM: selftests: Add support to get the VM's mode Raghavendra Rao Ananta
2021-09-09  1:38 ` [PATCH v4 14/18] KVM: arm64: selftests: Add host support for vGIC Raghavendra Rao Ananta
2021-09-09  5:32   ` Oliver Upton
2021-09-09 13:34     ` Andrew Jones
2021-09-09 17:25       ` Raghavendra Rao Ananta
2021-09-09 17:20     ` Raghavendra Rao Ananta
2021-09-09  1:38 ` [PATCH v4 15/18] KVM: arm64: selftests: Add arch_timer test Raghavendra Rao Ananta
2021-09-09  5:51   ` Oliver Upton
2021-09-09 18:03     ` Raghavendra Rao Ananta
2021-09-09  1:38 ` [PATCH v4 16/18] KVM: arm64: selftests: arch_timer: Support vCPU migration Raghavendra Rao Ananta
2021-09-09 13:45   ` Andrew Jones
2021-09-09 17:33     ` Raghavendra Rao Ananta [this message]
2021-09-09  1:38 ` [PATCH v4 17/18] KVM: arm64: selftests: Replace ARM64_SYS_REG with ARM64_SYS_KVM_REG Raghavendra Rao Ananta
2021-09-09  5:34   ` Oliver Upton
2021-09-09 13:38   ` Andrew Jones
2021-09-09 17:29     ` Raghavendra Rao Ananta
2021-09-09  1:38 ` [PATCH v4 18/18] KVM: selftests: vgic_init: Pull REDIST_REGION_ATTR_ADDR from vgic.h Raghavendra Rao Ananta
2021-09-09  5:36   ` Oliver Upton
2021-09-09 16:41     ` Raghavendra Rao Ananta

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=CAJHc60yth9RpUf5MQLZxJHWsdqM_Jo611ReyJJ0HRdM1q7K6AQ@mail.gmail.com \
    --to=rananta@google.com \
    --cc=alexandru.elisei@arm.com \
    --cc=catalin.marinas@arm.com \
    --cc=drjones@redhat.com \
    --cc=james.morse@arm.com \
    --cc=jingzhangos@google.com \
    --cc=kvm@vger.kernel.org \
    --cc=kvmarm@lists.cs.columbia.edu \
    --cc=linux-arm-kernel@lists.infradead.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=maz@kernel.org \
    --cc=oupton@google.com \
    --cc=pbonzini@redhat.com \
    --cc=pshier@google.com \
    --cc=reijiw@google.com \
    --cc=ricarkol@google.com \
    --cc=suzuki.poulose@arm.com \
    --cc=will@kernel.org \
    /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).