From mboxrd@z Thu Jan 1 00:00:00 1970 From: Liu Ping Fan Subject: [PATCH 06/15] memory: use refcnt to manage MemoryRegion Date: Wed, 8 Aug 2012 14:25:47 +0800 Message-ID: <1344407156-25562-7-git-send-email-qemulist@gmail.com> References: <1344407156-25562-1-git-send-email-qemulist@gmail.com> Cc: kvm@vger.kernel.org, Anthony Liguori , Avi Kivity , Jan Kiszka , Marcelo Tosatti , Stefan Hajnoczi , Paolo Bonzini , Blue Swirl , =?UTF-8?q?Andreas=20F=C3=A4rber?= , qemulist@gmail.com To: qemu-devel@nongnu.org Return-path: Received: from mail-pb0-f46.google.com ([209.85.160.46]:61001 "EHLO mail-pb0-f46.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751777Ab2HHG0g (ORCPT ); Wed, 8 Aug 2012 02:26:36 -0400 Received: by mail-pb0-f46.google.com with SMTP id rr13so950401pbb.19 for ; Tue, 07 Aug 2012 23:26:36 -0700 (PDT) In-Reply-To: <1344407156-25562-1-git-send-email-qemulist@gmail.com> Sender: kvm-owner@vger.kernel.org List-ID: From: Liu Ping Fan Using refcnt for mr, so we can separate mr's life cycle management from refered object. When mr->ref 0->1, inc the refered object. When mr->ref 1->0, dec the refered object. The refered object can be DeviceStae, another mr, or other opaque. Signed-off-by: Liu Ping Fan --- memory.c | 18 ++++++++++++++++++ memory.h | 5 +++++ 2 files changed, 23 insertions(+), 0 deletions(-) diff --git a/memory.c b/memory.c index 80c7529..5dc8b59 100644 --- a/memory.c +++ b/memory.c @@ -811,6 +811,7 @@ void memory_region_init(MemoryRegion *mr, if (size == UINT64_MAX) { mr->size = int128_2_64(); } + atomic_set(&mr->ref, 0); mr->life_ops = &nops; mr->addr = 0; mr->subpage = false; @@ -1090,6 +1091,23 @@ static const MemoryRegionOps reservation_ops = { .endianness = DEVICE_NATIVE_ENDIAN, }; +void memory_region_get(MemoryRegion *mr) +{ + if (atomic_add_and_return(1, &mr->ref) == 1) { + mr->life_ops->get(mr); + } +} + +void memory_region_put(MemoryRegion *mr) +{ + assert(atomic_read(&mr->ref) > 0); + + if (atomic_dec_and_test(&mr->ref)) { + /* to fix, using call_rcu( ,release) */ + mr->life_ops->put(mr); + } +} + void memory_region_init_reservation(MemoryRegion *mr, const char *name, uint64_t size) diff --git a/memory.h b/memory.h index 8fb543b..740f018 100644 --- a/memory.h +++ b/memory.h @@ -18,6 +18,7 @@ #include #include +#include "qemu/atomic.h" #include "qemu-common.h" #include "cpu-common.h" #include "targphys.h" @@ -26,6 +27,7 @@ #include "ioport.h" #include "int128.h" #include "qemu-thread.h" +#include "qemu/reclaimer.h" typedef struct MemoryRegionOps MemoryRegionOps; typedef struct MemoryRegionLifeOps MemoryRegionLifeOps; @@ -126,6 +128,7 @@ typedef struct MemoryRegionIoeventfd MemoryRegionIoeventfd; struct MemoryRegion { /* All fields are private - violators will be prosecuted */ const MemoryRegionOps *ops; + Atomic ref; MemoryRegionLifeOps *life_ops; void *opaque; MemoryRegion *parent; @@ -766,6 +769,8 @@ void memory_global_dirty_log_stop(void); void mtree_info(fprintf_function mon_printf, void *f); +void memory_region_get(MemoryRegion *mr); +void memory_region_put(MemoryRegion *mr); #endif #endif -- 1.7.4.4 From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([208.118.235.92]:43886) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Syzj4-0000sz-9Z for qemu-devel@nongnu.org; Wed, 08 Aug 2012 02:26:39 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1Syzj3-0002OQ-0W for qemu-devel@nongnu.org; Wed, 08 Aug 2012 02:26:38 -0400 Received: from mail-pb0-f45.google.com ([209.85.160.45]:47873) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Syzj2-0001rm-QQ for qemu-devel@nongnu.org; Wed, 08 Aug 2012 02:26:36 -0400 Received: by mail-pb0-f45.google.com with SMTP id rp12so493650pbb.4 for ; Tue, 07 Aug 2012 23:26:36 -0700 (PDT) From: Liu Ping Fan Date: Wed, 8 Aug 2012 14:25:47 +0800 Message-Id: <1344407156-25562-7-git-send-email-qemulist@gmail.com> In-Reply-To: <1344407156-25562-1-git-send-email-qemulist@gmail.com> References: <1344407156-25562-1-git-send-email-qemulist@gmail.com> Subject: [Qemu-devel] [PATCH 06/15] memory: use refcnt to manage MemoryRegion List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: qemu-devel@nongnu.org Cc: kvm@vger.kernel.org, Stefan Hajnoczi , Marcelo Tosatti , qemulist@gmail.com, Blue Swirl , Avi Kivity , Anthony Liguori , Jan Kiszka , Paolo Bonzini , =?UTF-8?q?Andreas=20F=C3=A4rber?= From: Liu Ping Fan Using refcnt for mr, so we can separate mr's life cycle management from refered object. When mr->ref 0->1, inc the refered object. When mr->ref 1->0, dec the refered object. The refered object can be DeviceStae, another mr, or other opaque. Signed-off-by: Liu Ping Fan --- memory.c | 18 ++++++++++++++++++ memory.h | 5 +++++ 2 files changed, 23 insertions(+), 0 deletions(-) diff --git a/memory.c b/memory.c index 80c7529..5dc8b59 100644 --- a/memory.c +++ b/memory.c @@ -811,6 +811,7 @@ void memory_region_init(MemoryRegion *mr, if (size == UINT64_MAX) { mr->size = int128_2_64(); } + atomic_set(&mr->ref, 0); mr->life_ops = &nops; mr->addr = 0; mr->subpage = false; @@ -1090,6 +1091,23 @@ static const MemoryRegionOps reservation_ops = { .endianness = DEVICE_NATIVE_ENDIAN, }; +void memory_region_get(MemoryRegion *mr) +{ + if (atomic_add_and_return(1, &mr->ref) == 1) { + mr->life_ops->get(mr); + } +} + +void memory_region_put(MemoryRegion *mr) +{ + assert(atomic_read(&mr->ref) > 0); + + if (atomic_dec_and_test(&mr->ref)) { + /* to fix, using call_rcu( ,release) */ + mr->life_ops->put(mr); + } +} + void memory_region_init_reservation(MemoryRegion *mr, const char *name, uint64_t size) diff --git a/memory.h b/memory.h index 8fb543b..740f018 100644 --- a/memory.h +++ b/memory.h @@ -18,6 +18,7 @@ #include #include +#include "qemu/atomic.h" #include "qemu-common.h" #include "cpu-common.h" #include "targphys.h" @@ -26,6 +27,7 @@ #include "ioport.h" #include "int128.h" #include "qemu-thread.h" +#include "qemu/reclaimer.h" typedef struct MemoryRegionOps MemoryRegionOps; typedef struct MemoryRegionLifeOps MemoryRegionLifeOps; @@ -126,6 +128,7 @@ typedef struct MemoryRegionIoeventfd MemoryRegionIoeventfd; struct MemoryRegion { /* All fields are private - violators will be prosecuted */ const MemoryRegionOps *ops; + Atomic ref; MemoryRegionLifeOps *life_ops; void *opaque; MemoryRegion *parent; @@ -766,6 +769,8 @@ void memory_global_dirty_log_stop(void); void mtree_info(fprintf_function mon_printf, void *f); +void memory_region_get(MemoryRegion *mr); +void memory_region_put(MemoryRegion *mr); #endif #endif -- 1.7.4.4