summary refs log tree commit diff stats
path: root/async.c
diff options
context:
space:
mode:
authorPeter Maydell <peter.maydell@linaro.org>2016-10-10 15:19:20 +0100
committerPeter Maydell <peter.maydell@linaro.org>2016-10-10 15:19:20 +0100
commit0f183e679d85fec74fc83f35f973cf8e56d97861 (patch)
tree24ab65457f2b67288502b78e6f179e4ed695171b /async.c
parenta20fd901afdb453b8afc578a7be14703c3a36300 (diff)
parent9c7f3fcae714925153c4c5ada086ca4fcf6bbbd8 (diff)
downloadfocaccia-qemu-0f183e679d85fec74fc83f35f973cf8e56d97861.tar.gz
focaccia-qemu-0f183e679d85fec74fc83f35f973cf8e56d97861.zip
Merge remote-tracking branch 'remotes/kevin/tags/for-upstream' into staging
Block layer patches

# gpg: Signature made Mon 10 Oct 2016 12:33:14 BST
# gpg:                using RSA key 0x7F09B272C88F2FD6
# gpg: Good signature from "Kevin Wolf <kwolf@redhat.com>"
# Primary key fingerprint: DC3D EB15 9A9A F95D 3D74  56FE 7F09 B272 C88F 2FD6

* remotes/kevin/tags/for-upstream:
  dmg: Move libbz2 code to dmg-bz2.so
  module: Don't load the same module if requested multiple times
  scripts: Allow block module to not define BlockDriver
  block: Add qdev ID to DEVICE_TRAY_MOVED
  block-backend: Remember if attached device is non-qdev
  block: Add node name to BLOCK_IO_ERROR event
  block: Add bdrv_runtime_opts to query-command-line-options
  block: use aio_bh_schedule_oneshot
  async: add aio_bh_schedule_oneshot
  block: use bdrv_add_before_write_notifier

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Diffstat (limited to 'async.c')
-rw-r--r--async.c27
1 files changed, 23 insertions, 4 deletions
diff --git a/async.c b/async.c
index 3bca9b0adb..f30d011ebc 100644
--- a/async.c
+++ b/async.c
@@ -44,6 +44,25 @@ struct QEMUBH {
     bool deleted;
 };
 
+void aio_bh_schedule_oneshot(AioContext *ctx, QEMUBHFunc *cb, void *opaque)
+{
+    QEMUBH *bh;
+    bh = g_new(QEMUBH, 1);
+    *bh = (QEMUBH){
+        .ctx = ctx,
+        .cb = cb,
+        .opaque = opaque,
+    };
+    qemu_mutex_lock(&ctx->bh_lock);
+    bh->next = ctx->first_bh;
+    bh->scheduled = 1;
+    bh->deleted = 1;
+    /* Make sure that the members are ready before putting bh into list */
+    smp_wmb();
+    ctx->first_bh = bh;
+    qemu_mutex_unlock(&ctx->bh_lock);
+}
+
 QEMUBH *aio_bh_new(AioContext *ctx, QEMUBHFunc *cb, void *opaque)
 {
     QEMUBH *bh;
@@ -86,7 +105,7 @@ int aio_bh_poll(AioContext *ctx)
          * thread sees the zero before bh->cb has run, and thus will call
          * aio_notify again if necessary.
          */
-        if (!bh->deleted && atomic_xchg(&bh->scheduled, 0)) {
+        if (atomic_xchg(&bh->scheduled, 0)) {
             /* Idle BHs and the notify BH don't count as progress */
             if (!bh->idle && bh != ctx->notify_dummy_bh) {
                 ret = 1;
@@ -104,7 +123,7 @@ int aio_bh_poll(AioContext *ctx)
         bhp = &ctx->first_bh;
         while (*bhp) {
             bh = *bhp;
-            if (bh->deleted) {
+            if (bh->deleted && !bh->scheduled) {
                 *bhp = bh->next;
                 g_free(bh);
             } else {
@@ -168,7 +187,7 @@ aio_compute_timeout(AioContext *ctx)
     QEMUBH *bh;
 
     for (bh = ctx->first_bh; bh; bh = bh->next) {
-        if (!bh->deleted && bh->scheduled) {
+        if (bh->scheduled) {
             if (bh->idle) {
                 /* idle bottom halves will be polled at least
                  * every 10ms */
@@ -216,7 +235,7 @@ aio_ctx_check(GSource *source)
     aio_notify_accept(ctx);
 
     for (bh = ctx->first_bh; bh; bh = bh->next) {
-        if (!bh->deleted && bh->scheduled) {
+        if (bh->scheduled) {
             return true;
         }
     }