[RFC PATCH v1 15/17] accel/kvm: pin the vCPU threads of a CoVE guest

Baolong Duan <[email protected]>
Newsgroups gmane.comp.emulators.qemu
Message-ID <[email protected]>
The TSM binds a TVM vCPU to the hart it first runs on, so the thread
running it has to stay on that host CPU.  With every host CPU running a
pinned vCPU thread the host is then starved, which shows up as RCU
stalls, hence the short sleep after each KVM_RUN.

Both are workarounds that do not belong in target independent code:
thread placement is normally left to the user or to the management layer,
and the sleep papers over a host scheduling problem.  Guidance on how to
express the TSM requirement properly would be appreciated.

Signed-off-by: Baolong Duan <[email protected]>
---
 accel/kvm/kvm-accel-ops.c | 16 ++++++++++++++++
 accel/kvm/kvm-all.c       |  9 +++++++++
 2 files changed, 25 insertions(+)

diff --git a/accel/kvm/kvm-accel-ops.c b/accel/kvm/kvm-accel-ops.c
index c8e7aa3870..30e1cb181c 100644
--- a/accel/kvm/kvm-accel-ops.c
+++ b/accel/kvm/kvm-accel-ops.c
@@ -24,6 +24,7 @@
 #include "system/cpus.h"
 #include "qemu/guest-random.h"
 #include "qapi/error.h"
+#include "hw/riscv/cove.h"
 
 #include <linux/kvm.h>
 #include "kvm-cpus.h"
@@ -43,6 +44,21 @@ static void *kvm_vcpu_thread_fn(void *arg)
     r = kvm_init_vcpu(cpu, &error_fatal);
     kvm_init_cpu_signals(cpu);
 
+    /*
+     * The TSM binds a TVM vCPU to the hart it first runs on, so pin vCPU N
+     * to host CPU N before the first KVM_RUN.
+     */
+    if (riscv_cove_vm_active()) {
+        cpu_set_t cpuset;
+
+        CPU_ZERO(&cpuset);
+        CPU_SET(cpu->cpu_index, &cpuset);
+        if (sched_setaffinity(0, sizeof(cpuset), &cpuset) < 0) {
+            error_report("Unable to pin vCPU %d: %s", cpu->cpu_index,
+                         strerror(errno));
+        }
+    }
+
     /* signal CPU creation */
     cpu_thread_signal_created(cpu);
     qemu_guest_random_seed_thread_part2(cpu->random_seed);
diff --git a/accel/kvm/kvm-all.c b/accel/kvm/kvm-all.c
index aaaa88bd2b..7b33a9aa3a 100644
--- a/accel/kvm/kvm-all.c
+++ b/accel/kvm/kvm-all.c
@@ -3510,6 +3510,15 @@ int kvm_cpu_exec(CPUState *cpu)
          * as true, cpu->exit_request will always read as true.
          */
 
+        /*
+         * Yield briefly after each KVM_RUN of a CoVE guest: with one pinned
+         * vCPU thread per host CPU the host is otherwise starved and reports
+         * RCU stalls.
+         */
+        if (riscv_cove_vm_active()) {
+            usleep(100);
+        }
+
         attrs = kvm_arch_post_run(cpu, run);
 
 #ifdef KVM_HAVE_MCE_INJECTION
-- 
2.34.1
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.