All of lore.kernel.org
 help / color / mirror / Atom feed
From: "Emilio G. Cota" <cota@braap.org>
To: qemu-devel@nongnu.org
Cc: Paolo Bonzini <pbonzini@redhat.com>,
	Peter Crosthwaite <crosthwaite.peter@gmail.com>,
	Richard Henderson <rth@twiddle.net>
Subject: [Qemu-devel] [RFC v3 04/56] cpu: make qemu_work_cond per-cpu
Date: Thu, 18 Oct 2018 21:05:33 -0400	[thread overview]
Message-ID: <20181019010625.25294-5-cota@braap.org> (raw)
In-Reply-To: <20181019010625.25294-1-cota@braap.org>

This eliminates the need to use the BQL to queue CPU work.

While at it, give the per-cpu field a generic name ("cond") since
it will soon be used for more than just queueing CPU work.

Cc: Peter Crosthwaite <crosthwaite.peter@gmail.com>
Cc: Richard Henderson <rth@twiddle.net>
Signed-off-by: Emilio G. Cota <cota@braap.org>
---
 include/qom/cpu.h |  6 +++---
 cpus-common.c     | 48 ++++++++++++++++++++++++++++++++++-------------
 cpus.c            |  2 +-
 qom/cpu.c         |  1 +
 4 files changed, 40 insertions(+), 17 deletions(-)

diff --git a/include/qom/cpu.h b/include/qom/cpu.h
index 1292e7aa33..82937881ef 100644
--- a/include/qom/cpu.h
+++ b/include/qom/cpu.h
@@ -316,6 +316,7 @@ struct qemu_work_item;
  * @mem_io_vaddr: Target virtual address at which the memory was accessed.
  * @kvm_fd: vCPU file descriptor for KVM.
  * @lock: Lock to prevent multiple access to per-CPU fields.
+ * @cond: Condition variable for per-CPU events.
  * @work_list: List of pending asynchronous work.
  * @trace_dstate_delayed: Delayed changes to trace_dstate (includes all changes
  *                        to @trace_dstate).
@@ -358,6 +359,7 @@ struct CPUState {
 
     QemuMutex lock;
     /* fields below protected by @lock */
+    QemuCond cond;
     QSIMPLEQ_HEAD(, qemu_work_item) work_list;
 
     CPUAddressSpace *cpu_ases;
@@ -762,12 +764,10 @@ bool cpu_is_stopped(CPUState *cpu);
  * @cpu: The vCPU to run on.
  * @func: The function to be executed.
  * @data: Data to pass to the function.
- * @mutex: Mutex to release while waiting for @func to run.
  *
  * Used internally in the implementation of run_on_cpu.
  */
-void do_run_on_cpu(CPUState *cpu, run_on_cpu_func func, run_on_cpu_data data,
-                   QemuMutex *mutex);
+void do_run_on_cpu(CPUState *cpu, run_on_cpu_func func, run_on_cpu_data data);
 
 /**
  * run_on_cpu:
diff --git a/cpus-common.c b/cpus-common.c
index 2913294cb7..2881707c35 100644
--- a/cpus-common.c
+++ b/cpus-common.c
@@ -26,7 +26,6 @@
 static QemuMutex qemu_cpu_list_lock;
 static QemuCond exclusive_cond;
 static QemuCond exclusive_resume;
-static QemuCond qemu_work_cond;
 
 /* >= 1 if a thread is inside start_exclusive/end_exclusive.  Written
  * under qemu_cpu_list_lock, read with atomic operations.
@@ -42,7 +41,6 @@ void qemu_init_cpu_list(void)
     qemu_mutex_init(&qemu_cpu_list_lock);
     qemu_cond_init(&exclusive_cond);
     qemu_cond_init(&exclusive_resume);
-    qemu_cond_init(&qemu_work_cond);
 }
 
 void cpu_list_lock(void)
@@ -113,39 +111,52 @@ struct qemu_work_item {
     bool free, exclusive, done;
 };
 
-static void queue_work_on_cpu(CPUState *cpu, struct qemu_work_item *wi)
+/* Called with the CPU's lock held */
+static void queue_work_on_cpu_locked(CPUState *cpu, struct qemu_work_item *wi)
 {
-    qemu_mutex_lock(&cpu->lock);
     QSIMPLEQ_INSERT_TAIL(&cpu->work_list, wi, node);
     wi->done = false;
-    qemu_mutex_unlock(&cpu->lock);
 
     qemu_cpu_kick(cpu);
 }
 
-void do_run_on_cpu(CPUState *cpu, run_on_cpu_func func, run_on_cpu_data data,
-                   QemuMutex *mutex)
+static void queue_work_on_cpu(CPUState *cpu, struct qemu_work_item *wi)
+{
+    cpu_mutex_lock(cpu);
+    queue_work_on_cpu_locked(cpu, wi);
+    cpu_mutex_unlock(cpu);
+}
+
+void do_run_on_cpu(CPUState *cpu, run_on_cpu_func func, run_on_cpu_data data)
 {
     struct qemu_work_item wi;
 
+    g_assert(qemu_mutex_iothread_locked());
+
     if (qemu_cpu_is_self(cpu)) {
         func(cpu, data);
         return;
     }
 
+    qemu_mutex_unlock_iothread();
+
     wi.func = func;
     wi.data = data;
     wi.done = false;
     wi.free = false;
     wi.exclusive = false;
 
-    queue_work_on_cpu(cpu, &wi);
+    cpu_mutex_lock(cpu);
+    queue_work_on_cpu_locked(cpu, &wi);
     while (!atomic_mb_read(&wi.done)) {
         CPUState *self_cpu = current_cpu;
 
-        qemu_cond_wait(&qemu_work_cond, mutex);
+        qemu_cond_wait(&cpu->cond, &cpu->lock);
         current_cpu = self_cpu;
     }
+    cpu_mutex_unlock(cpu);
+
+    qemu_mutex_lock_iothread();
 }
 
 void async_run_on_cpu(CPUState *cpu, run_on_cpu_func func, run_on_cpu_data data)
@@ -307,6 +318,7 @@ void async_safe_run_on_cpu(CPUState *cpu, run_on_cpu_func func,
 void process_queued_cpu_work(CPUState *cpu)
 {
     struct qemu_work_item *wi;
+    bool has_bql = qemu_mutex_iothread_locked();
 
     qemu_mutex_lock(&cpu->lock);
     if (QSIMPLEQ_EMPTY(&cpu->work_list)) {
@@ -324,13 +336,23 @@ void process_queued_cpu_work(CPUState *cpu)
              * BQL, so it goes to sleep; start_exclusive() is sleeping too, so
              * neither CPU can proceed.
              */
-            qemu_mutex_unlock_iothread();
+            if (has_bql) {
+                qemu_mutex_unlock_iothread();
+            }
             start_exclusive();
             wi->func(cpu, wi->data);
             end_exclusive();
-            qemu_mutex_lock_iothread();
+            if (has_bql) {
+                qemu_mutex_lock_iothread();
+            }
         } else {
-            wi->func(cpu, wi->data);
+            if (has_bql) {
+                wi->func(cpu, wi->data);
+            } else {
+                qemu_mutex_lock_iothread();
+                wi->func(cpu, wi->data);
+                qemu_mutex_unlock_iothread();
+            }
         }
         qemu_mutex_lock(&cpu->lock);
         if (wi->free) {
@@ -340,5 +362,5 @@ void process_queued_cpu_work(CPUState *cpu)
         }
     }
     qemu_mutex_unlock(&cpu->lock);
-    qemu_cond_broadcast(&qemu_work_cond);
+    qemu_cond_broadcast(&cpu->cond);
 }
diff --git a/cpus.c b/cpus.c
index a190651653..e844335386 100644
--- a/cpus.c
+++ b/cpus.c
@@ -1236,7 +1236,7 @@ void qemu_init_cpu_loop(void)
 
 void run_on_cpu(CPUState *cpu, run_on_cpu_func func, run_on_cpu_data data)
 {
-    do_run_on_cpu(cpu, func, data, &qemu_global_mutex);
+    do_run_on_cpu(cpu, func, data);
 }
 
 static void qemu_kvm_destroy_vcpu(CPUState *cpu)
diff --git a/qom/cpu.c b/qom/cpu.c
index d0758c907d..bb031a3a6a 100644
--- a/qom/cpu.c
+++ b/qom/cpu.c
@@ -373,6 +373,7 @@ static void cpu_common_initfn(Object *obj)
     cpu->nr_threads = 1;
 
     qemu_mutex_init(&cpu->lock);
+    qemu_cond_init(&cpu->cond);
     QSIMPLEQ_INIT(&cpu->work_list);
     QTAILQ_INIT(&cpu->breakpoints);
     QTAILQ_INIT(&cpu->watchpoints);
-- 
2.17.1

  parent reply	other threads:[~2018-10-19  1:06 UTC|newest]

Thread overview: 118+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2018-10-19  1:05 [Qemu-devel] [RFC v3 0/56] per-CPU locks Emilio G. Cota
2018-10-19  1:05 ` [Qemu-devel] [RFC v3 01/56] cpu: convert queued work to a QSIMPLEQ Emilio G. Cota
2018-10-19  6:26   ` Richard Henderson
2018-10-19  1:05 ` [Qemu-devel] [RFC v3 02/56] cpu: rename cpu->work_mutex to cpu->lock Emilio G. Cota
2018-10-19  6:26   ` Richard Henderson
2018-10-19  1:05 ` [Qemu-devel] [RFC v3 03/56] cpu: introduce cpu_mutex_lock/unlock Emilio G. Cota
2018-10-19  1:05 ` Emilio G. Cota [this message]
2018-10-19  1:05 ` [Qemu-devel] [RFC v3 05/56] cpu: move run_on_cpu to cpus-common Emilio G. Cota
2018-10-19  6:39   ` Richard Henderson
2018-10-19  1:05 ` [Qemu-devel] [RFC v3 06/56] cpu: introduce process_queued_cpu_work_locked Emilio G. Cota
2018-10-19  6:41   ` Richard Henderson
2018-10-19  1:05 ` [Qemu-devel] [RFC v3 07/56] target/m68k: rename cpu_halted to cpu_halt Emilio G. Cota
2018-10-21 12:53   ` Richard Henderson
2018-10-21 13:38     ` Richard Henderson
2018-10-22 22:58       ` Emilio G. Cota
2018-10-19  1:05 ` [Qemu-devel] [RFC v3 08/56] cpu: define cpu_halted helpers Emilio G. Cota
2018-10-21 12:54   ` Richard Henderson
2018-10-19  1:05 ` [Qemu-devel] [RFC v3 09/56] arm: convert to cpu_halted Emilio G. Cota
2018-10-21 12:55   ` Richard Henderson
2018-10-19  1:05 ` [Qemu-devel] [RFC v3 10/56] ppc: " Emilio G. Cota
2018-10-21 12:56   ` Richard Henderson
2018-10-22 21:12     ` Emilio G. Cota
2018-10-19  1:05 ` [Qemu-devel] [RFC v3 11/56] sh4: " Emilio G. Cota
2018-10-21 12:57   ` Richard Henderson
2018-10-19  1:05 ` [Qemu-devel] [RFC v3 12/56] i386: " Emilio G. Cota
2018-10-21 12:59   ` Richard Henderson
2018-10-19  1:05 ` [Qemu-devel] [RFC v3 13/56] lm32: " Emilio G. Cota
2018-10-21 13:00   ` Richard Henderson
2018-10-19  1:05 ` [Qemu-devel] [RFC v3 14/56] m68k: " Emilio G. Cota
2018-10-21 13:01   ` Richard Henderson
2018-10-19  1:05 ` [Qemu-devel] [RFC v3 15/56] mips: " Emilio G. Cota
2018-10-21 13:02   ` Richard Henderson
2018-10-19  1:05 ` [Qemu-devel] [RFC v3 16/56] riscv: " Emilio G. Cota
2018-10-19 17:24   ` Palmer Dabbelt
2018-10-19  1:05 ` [Qemu-devel] [RFC v3 17/56] s390x: " Emilio G. Cota
2018-10-21 13:04   ` Richard Henderson
2018-10-19  1:05 ` [Qemu-devel] [RFC v3 18/56] sparc: " Emilio G. Cota
2018-10-21 13:04   ` Richard Henderson
2018-10-19  1:05 ` [Qemu-devel] [RFC v3 19/56] xtensa: " Emilio G. Cota
2018-10-21 13:10   ` Richard Henderson
2018-10-19  1:05 ` [Qemu-devel] [RFC v3 20/56] gdbstub: " Emilio G. Cota
2018-10-21 13:10   ` Richard Henderson
2018-10-19  1:05 ` [Qemu-devel] [RFC v3 21/56] openrisc: " Emilio G. Cota
2018-10-21 13:11   ` Richard Henderson
2018-10-19  1:05 ` [Qemu-devel] [RFC v3 22/56] cpu-exec: " Emilio G. Cota
2018-10-19  1:05 ` [Qemu-devel] [RFC v3 23/56] cpu: define cpu_interrupt_request helpers Emilio G. Cota
2018-10-21 13:15   ` Richard Henderson
2018-10-19  1:05 ` [Qemu-devel] [RFC v3 24/56] ppc: use cpu_reset_interrupt Emilio G. Cota
2018-10-21 13:15   ` Richard Henderson
2018-10-19  1:05 ` [Qemu-devel] [RFC v3 25/56] exec: " Emilio G. Cota
2018-10-21 13:17   ` Richard Henderson
2018-10-22 23:28     ` Emilio G. Cota
2018-10-19  1:05 ` [Qemu-devel] [RFC v3 26/56] i386: " Emilio G. Cota
2018-10-21 13:18   ` Richard Henderson
2018-10-19  1:05 ` [Qemu-devel] [RFC v3 27/56] s390x: " Emilio G. Cota
2018-10-21 13:18   ` Richard Henderson
2018-10-19  1:05 ` [Qemu-devel] [RFC v3 28/56] openrisc: " Emilio G. Cota
2018-10-21 13:18   ` Richard Henderson
2018-10-19  1:05 ` [Qemu-devel] [RFC v3 29/56] arm: convert to cpu_interrupt_request Emilio G. Cota
2018-10-21 13:21   ` Richard Henderson
2018-10-19  1:05 ` [Qemu-devel] [RFC v3 30/56] i386: " Emilio G. Cota
2018-10-21 13:27   ` Richard Henderson
2018-10-23 20:28     ` Emilio G. Cota
2018-10-19  1:06 ` [Qemu-devel] [RFC v3 31/56] ppc: " Emilio G. Cota
2018-10-19  1:06 ` [Qemu-devel] [RFC v3 32/56] sh4: " Emilio G. Cota
2018-10-21 13:28   ` Richard Henderson
2018-10-19  1:06 ` [Qemu-devel] [RFC v3 33/56] cris: " Emilio G. Cota
2018-10-21 13:29   ` Richard Henderson
2018-10-19  1:06 ` [Qemu-devel] [RFC v3 34/56] hppa: " Emilio G. Cota
2018-10-21 13:29   ` Richard Henderson
2018-10-19  1:06 ` [Qemu-devel] [RFC v3 35/56] lm32: " Emilio G. Cota
2018-10-21 13:29   ` Richard Henderson
2018-10-19  1:06 ` [Qemu-devel] [RFC v3 36/56] m68k: " Emilio G. Cota
2018-10-21 13:29   ` Richard Henderson
2018-10-19  1:06 ` [Qemu-devel] [RFC v3 37/56] mips: " Emilio G. Cota
2018-10-21 13:30   ` Richard Henderson
2018-10-22 23:38     ` Emilio G. Cota
2018-10-19  1:06 ` [Qemu-devel] [RFC v3 38/56] nios: " Emilio G. Cota
2018-10-21 13:30   ` Richard Henderson
2018-10-19  1:06 ` [Qemu-devel] [RFC v3 39/56] s390x: " Emilio G. Cota
2018-10-21 13:30   ` Richard Henderson
2018-10-19  1:06 ` [Qemu-devel] [RFC v3 40/56] alpha: " Emilio G. Cota
2018-10-21 13:31   ` Richard Henderson
2018-10-19  1:06 ` [Qemu-devel] [RFC v3 41/56] moxie: " Emilio G. Cota
2018-10-21 13:31   ` Richard Henderson
2018-10-19  1:06 ` [Qemu-devel] [RFC v3 42/56] sparc: " Emilio G. Cota
2018-10-21 13:32   ` Richard Henderson
2018-10-19  1:06 ` [Qemu-devel] [RFC v3 43/56] openrisc: " Emilio G. Cota
2018-10-21 13:32   ` Richard Henderson
2018-10-19  1:06 ` [Qemu-devel] [RFC v3 44/56] unicore32: " Emilio G. Cota
2018-10-21 13:33   ` Richard Henderson
2018-10-19  1:06 ` [Qemu-devel] [RFC v3 45/56] microblaze: " Emilio G. Cota
2018-10-21 13:33   ` Richard Henderson
2018-10-19  1:06 ` [Qemu-devel] [RFC v3 46/56] accel/tcg: " Emilio G. Cota
2018-10-21 13:34   ` Richard Henderson
2018-10-22 23:50     ` Emilio G. Cota
2018-10-23  2:17       ` Richard Henderson
2018-10-23 20:21         ` Emilio G. Cota
2018-10-19  1:06 ` [Qemu-devel] [RFC v3 47/56] cpu: call .cpu_has_work with the CPU lock held Emilio G. Cota
2018-10-19  1:06 ` [Qemu-devel] [RFC v3 48/56] ppc: acquire the BQL in cpu_has_work Emilio G. Cota
2018-10-19  6:58   ` Paolo Bonzini
2018-10-20 16:31     ` Emilio G. Cota
2018-10-21 13:42       ` Richard Henderson
2018-10-19  1:06 ` [Qemu-devel] [RFC v3 49/56] mips: " Emilio G. Cota
2018-10-19  1:06 ` [Qemu-devel] [RFC v3 50/56] s390: " Emilio G. Cota
2018-10-19  1:06 ` [Qemu-devel] [RFC v3 51/56] riscv: " Emilio G. Cota
2018-10-19 17:24   ` Palmer Dabbelt
2018-10-19  1:06 ` [Qemu-devel] [RFC v3 52/56] sparc: " Emilio G. Cota
2018-10-19  1:06 ` [Qemu-devel] [RFC v3 53/56] xtensa: " Emilio G. Cota
2018-10-19  1:06 ` [Qemu-devel] [RFC v3 54/56] cpu: protect most CPU state with cpu->lock Emilio G. Cota
2018-10-19  1:06 ` [Qemu-devel] [RFC v3 55/56] cpu: add async_run_on_cpu_no_bql Emilio G. Cota
2018-10-19  1:06 ` [Qemu-devel] [RFC v3 56/56] cputlb: queue async flush jobs without the BQL Emilio G. Cota
2018-10-19  6:59 ` [Qemu-devel] [RFC v3 0/56] per-CPU locks Paolo Bonzini
2018-10-19 14:50   ` Emilio G. Cota
2018-10-19 16:01     ` Paolo Bonzini
2018-10-19 19:29       ` Emilio G. Cota
2018-10-19 23:46         ` Emilio G. Cota
2018-10-22 15:30           ` Paolo Bonzini

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=20181019010625.25294-5-cota@braap.org \
    --to=cota@braap.org \
    --cc=crosthwaite.peter@gmail.com \
    --cc=pbonzini@redhat.com \
    --cc=qemu-devel@nongnu.org \
    --cc=rth@twiddle.net \
    /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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.