Commit ebac1202 authored by Paolo Bonzini's avatar Paolo Bonzini Committed by Greg Kurz
Browse files

virtio-9p: use QEMU thread pool



The QEMU thread pool already has a mechanism to invoke callbacks in the main
thread.  It does not need an EventNotifier and it is more efficient too.
Use it instead of GAsyncQueue + GThreadPool + glue.

As a side effect, it silences Coverity's complaint about an unchecked
return value for event_notifier_init.

Signed-off-by: default avatarPaolo Bonzini <pbonzini@redhat.com>
Reviewed-by: default avatarGreg Kurz <gkurz@linux.vnet.ibm.com>
(removed no more needed #include <glib.h> from virtio-9p-coth.h)
Signed-off-by: default avatarGreg Kurz <gkurz@linux.vnet.ibm.com>
parent 49f817ca
Loading
Loading
Loading
Loading
+14 −55
Original line number Diff line number Diff line
@@ -12,71 +12,30 @@
 *
 */

#include "fsdev/qemu-fsdev.h"
#include "qemu/thread.h"
#include "qemu/event_notifier.h"
#include "qemu-common.h"
#include "block/thread-pool.h"
#include "qemu/coroutine.h"
#include "qemu/main-loop.h"
#include "virtio-9p-coth.h"

/* v9fs glib thread pool */
static V9fsThPool v9fs_pool;

void co_run_in_worker_bh(void *opaque)
/* Called from QEMU I/O thread.  */
static void coroutine_enter_cb(void *opaque, int ret)
{
    Coroutine *co = opaque;
    g_thread_pool_push(v9fs_pool.pool, co, NULL);
}

static void v9fs_qemu_process_req_done(EventNotifier *e)
{
    Coroutine *co;

    event_notifier_test_and_clear(e);

    while ((co = g_async_queue_try_pop(v9fs_pool.completed)) != NULL) {
    qemu_coroutine_enter(co, NULL);
}
}

static void v9fs_thread_routine(gpointer data, gpointer user_data)
/* Called from worker thread.  */
static int coroutine_enter_func(void *arg)
{
    Coroutine *co = data;

    Coroutine *co = arg;
    qemu_coroutine_enter(co, NULL);

    g_async_queue_push(v9fs_pool.completed, co);

    event_notifier_set(&v9fs_pool.e);
    return 0;
}

int v9fs_init_worker_threads(void)
void co_run_in_worker_bh(void *opaque)
{
    int ret = 0;
    V9fsThPool *p = &v9fs_pool;
    sigset_t set, oldset;

    sigfillset(&set);
    /* Leave signal handling to the iothread.  */
    pthread_sigmask(SIG_SETMASK, &set, &oldset);

    p->pool = g_thread_pool_new(v9fs_thread_routine, p, -1, FALSE, NULL);
    if (!p->pool) {
        ret = -1;
        goto err_out;
    }
    p->completed = g_async_queue_new();
    if (!p->completed) {
        /*
         * We are going to terminate.
         * So don't worry about cleanup
         */
        ret = -1;
        goto err_out;
    }
    event_notifier_init(&p->e, 0);

    event_notifier_set_handler(&p->e, v9fs_qemu_process_req_done);
err_out:
    pthread_sigmask(SIG_SETMASK, &oldset, NULL);
    return ret;
    Coroutine *co = opaque;
    thread_pool_submit_aio(qemu_get_aio_context()->thread_pool,
                           coroutine_enter_func, co, coroutine_enter_cb, co);
}
+1 −9
Original line number Diff line number Diff line
@@ -18,14 +18,6 @@
#include "qemu/thread.h"
#include "qemu/coroutine.h"
#include "virtio-9p.h"
#include <glib.h>

typedef struct V9fsThPool {
    EventNotifier e;

    GThreadPool *pool;
    GAsyncQueue *completed;
} V9fsThPool;

/*
 * we want to use bottom half because we want to make sure the below
@@ -45,7 +37,7 @@ typedef struct V9fsThPool {
        qemu_bh_schedule(co_bh);                                        \
        /*                                                              \
         * yield in qemu thread and re-enter back                       \
         * in glib worker thread                                        \
         * in worker thread                                             \
         */                                                             \
        qemu_coroutine_yield();                                         \
        qemu_bh_delete(co_bh);                                          \
+0 −4
Original line number Diff line number Diff line
@@ -116,10 +116,6 @@ static void virtio_9p_device_realize(DeviceState *dev, Error **errp)
                   " and export path:%s", s->fsconf.fsdev_id, s->ctx.fs_root);
        goto out;
    }
    if (v9fs_init_worker_threads() < 0) {
        error_setg(errp, "worker thread initialization failed");
        goto out;
    }

    /*
     * Check details of export path, We need to use fs driver