From patchwork Tue Sep 11 07:51:49 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: pingfan liu X-Patchwork-Id: 183043 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (Client did not present a certificate) by ozlabs.org (Postfix) with ESMTPS id B3C672C0089 for ; Tue, 11 Sep 2012 17:59:17 +1000 (EST) Received: from localhost ([::1]:60084 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1TBLNK-0001JR-Vo for incoming@patchwork.ozlabs.org; Tue, 11 Sep 2012 03:59:14 -0400 Received: from eggs.gnu.org ([208.118.235.92]:40642) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1TBLHN-0008AC-FL for qemu-devel@nongnu.org; Tue, 11 Sep 2012 03:53:11 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1TBLHH-0007QB-GR for qemu-devel@nongnu.org; Tue, 11 Sep 2012 03:53:05 -0400 Received: from mail-pz0-f45.google.com ([209.85.210.45]:43411) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1TBLHH-0007Py-7c for qemu-devel@nongnu.org; Tue, 11 Sep 2012 03:52:59 -0400 Received: by dadn15 with SMTP id n15so163126dad.4 for ; Tue, 11 Sep 2012 00:52:58 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=from:to:cc:subject:date:message-id:x-mailer:in-reply-to:references; bh=NqkBCgeIlQP9hXByEdLrrb4qbJCZJmAm6NhDq4aThOE=; b=XXJspGAvKpwBnQVndTC1NfyHpDNqOUUbiTV6S6YcPZbXLaA+Esp/OIOCrN4PeWX96R Y3Ia/v5JYeqVTtMgIpi16FvLClG199wIhG2JPwiKzdCQeYvtCdMFBs8W+z9YV36Who72 e7etKwSs/uo8hxnQMl8ZBkMBoce3gX1a1NSm2TsDNJsFPiB85hGlYALRxcFw2HEjUCCk GBrT1IgO36sz1rsSC+Rl+6rFG8l1lEszGmvhS9oHqHdeHhEbGgAlmyCQX2xkg8Kq/Q71 oQY/gHUO46M/6H4wf+ZNNOKhjNm7OmjPfFNCNACsXXT1P4AtQn+BvUtpw8drNpBjuZLY /hjA== Received: by 10.68.226.167 with SMTP id rt7mr10144154pbc.146.1347349978370; Tue, 11 Sep 2012 00:52:58 -0700 (PDT) Received: from localhost ([202.108.130.138]) by mx.google.com with ESMTPS id ho7sm9382854pbc.3.2012.09.11.00.52.56 (version=TLSv1/SSLv3 cipher=OTHER); Tue, 11 Sep 2012 00:52:57 -0700 (PDT) From: Liu Ping Fan To: qemu-devel@nongnu.org Date: Tue, 11 Sep 2012 15:51:49 +0800 Message-Id: <1347349912-15611-9-git-send-email-qemulist@gmail.com> X-Mailer: git-send-email 1.7.4.4 In-Reply-To: <1347349912-15611-1-git-send-email-qemulist@gmail.com> References: <1347349912-15611-1-git-send-email-qemulist@gmail.com> X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 209.85.210.45 Cc: Jan Kiszka , Marcelo Tosatti , Avi Kivity , Anthony Liguori , Paolo Bonzini Subject: [Qemu-devel] [PATCH V3 08/11] qom: introduce reclaimer to release obj in async X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org From: Liu Ping Fan DeviceState will be protected by refcnt from disappearing during dispatching. But when refcnt comes down to zero, DeviceState may be still in use by iohandler, timer etc in main loop, we just delay its free untill no reader. This patch aim to build this delay reclaimer. Signed-off-by: Liu Ping Fan --- include/qemu/reclaimer.h | 30 +++++++++++++++++++++++++ main-loop.c | 5 ++++ qemu-tool.c | 5 ++++ qom/Makefile.objs | 2 +- qom/reclaimer.c | 54 ++++++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 95 insertions(+), 1 deletions(-) create mode 100644 include/qemu/reclaimer.h create mode 100644 qom/reclaimer.c diff --git a/include/qemu/reclaimer.h b/include/qemu/reclaimer.h new file mode 100644 index 0000000..5143c4f --- /dev/null +++ b/include/qemu/reclaimer.h @@ -0,0 +1,30 @@ +/* + * QEMU reclaimer + * + * Copyright IBM, Corp. 2012 + * + * This work is licensed under the terms of the GNU GPL, version 2 or later. + * See the COPYING file in the top-level directory. + */ +#ifndef QEMU_RECLAIMER +#define QEMU_RECLAIMER + +#include "qemu-thread.h" + +typedef void ReleaseHandler(void *opaque); +typedef struct Chunk { + QLIST_ENTRY(Chunk) list; + void *opaque; + ReleaseHandler *release; +} Chunk; + +typedef struct ChunkHead { + struct QemuMutex lock; + QLIST_HEAD(, Chunk) reclaim_list; +} ChunkHead; + +extern ChunkHead qdev_reclaimer; +void reclaimer_enqueue(ChunkHead *head, void *opaque, ReleaseHandler *release); +void reclaimer_worker(ChunkHead *head); +void qemu_reclaimer(void); +#endif diff --git a/main-loop.c b/main-loop.c index eb3b6e6..be9d095 100644 --- a/main-loop.c +++ b/main-loop.c @@ -26,6 +26,7 @@ #include "qemu-timer.h" #include "slirp/slirp.h" #include "main-loop.h" +#include "qemu/reclaimer.h" #ifndef _WIN32 @@ -505,5 +506,9 @@ int main_loop_wait(int nonblocking) them. */ qemu_bh_poll(); + /* ref to device from iohandler/bh/timer do not obey the rules, so delay + * reclaiming until now. + */ + qemu_reclaimer(); return ret; } diff --git a/qemu-tool.c b/qemu-tool.c index 18205ba..f250c87 100644 --- a/qemu-tool.c +++ b/qemu-tool.c @@ -21,6 +21,7 @@ #include "main-loop.h" #include "qemu_socket.h" #include "slirp/libslirp.h" +#include "qemu/reclaimer.h" #include @@ -100,6 +101,10 @@ void qemu_mutex_unlock_iothread(void) { } +void qemu_reclaimer(void) +{ +} + int use_icount; void qemu_clock_warp(QEMUClock *clock) diff --git a/qom/Makefile.objs b/qom/Makefile.objs index 5ef060a..a579261 100644 --- a/qom/Makefile.objs +++ b/qom/Makefile.objs @@ -1,4 +1,4 @@ -qom-obj-y = object.o container.o qom-qobject.o +qom-obj-y = object.o container.o qom-qobject.o reclaimer.o qom-obj-twice-y = cpu.o common-obj-y = $(qom-obj-twice-y) user-obj-y = $(qom-obj-twice-y) diff --git a/qom/reclaimer.c b/qom/reclaimer.c new file mode 100644 index 0000000..b098ad7 --- /dev/null +++ b/qom/reclaimer.c @@ -0,0 +1,54 @@ +/* + * QEMU reclaimer + * + * Copyright IBM, Corp. 2012 + * + * This work is licensed under the terms of the GNU GPL, version 2 or later. + * See the COPYING file in the top-level directory. + */ +#include "qemu-common.h" +#include "qemu-thread.h" +#include "main-loop.h" +#include "qemu-queue.h" +#include "qemu/reclaimer.h" + +ChunkHead qdev_reclaimer; + +static void reclaimer_init(ChunkHead *head) +{ + qemu_mutex_init(&head->lock); +} + +void reclaimer_enqueue(ChunkHead *head, void *opaque, ReleaseHandler *release) +{ + Chunk *r = g_malloc0(sizeof(Chunk)); + r->opaque = opaque; + r->release = release; + qemu_mutex_lock(&head->lock); + QLIST_INSERT_HEAD(&head->reclaim_list, r, list); + qemu_mutex_unlock(&head->lock); +} + +void reclaimer_worker(ChunkHead *head) +{ + Chunk *cur, *next; + + qemu_mutex_lock(&head->lock); + QLIST_FOREACH_SAFE(cur, &head->reclaim_list, list, next) { + QLIST_REMOVE(cur, list); + cur->release(cur->opaque); + g_free(cur); + } + qemu_mutex_unlock(&head->lock); +} + +void qemu_reclaimer(void) +{ + static int init; + + if (init == 0) { + init = 1; + reclaimer_init(&qdev_reclaimer); + } + reclaimer_worker(&qdev_reclaimer); +}