From patchwork Wed Aug 8 06:25:47 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Liu Ping Fan X-Patchwork-Id: 1292711 Return-Path: X-Original-To: patchwork-kvm@patchwork.kernel.org Delivered-To: patchwork-process-083081@patchwork1.kernel.org Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by patchwork1.kernel.org (Postfix) with ESMTP id 7E3F63FC23 for ; Wed, 8 Aug 2012 06:26:43 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1757546Ab2HHG0k (ORCPT ); Wed, 8 Aug 2012 02:26:40 -0400 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) 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=BZp8LFDKRKQWq7kbiDBo6mMBlEJhGV1se5C2Lj7egZo=; b=S2AAJap8akuDyY7A7m7GTCYPQ0nl4m7ajuRVteOpBY5uM7djjuYTejL7KqCGZSxdCp 2t5FgHXrnydIKYPnAoO2jFnVOCfeMrV7uFul2fb55GXr1qJTcpUXlQvKg+1Ogtbd295G Rs9g3ojKsZh3PogwefZ15ygqj0ucTDaZ7ZMtQZtyyM8jpBJKll9qmMQSknZYZifA7yQu CAoIuvh/u586/9s4AdlgYydSW6sjeYQToDR9uLUqeILLxv2nJqr2buVfEhtagyS/9Qk7 dy+84Uy1kibfTEDlLvKD151Ti2UmqsbrvzxuqBAPLpIcTjLUuqLWKt709fqWXqBO+jmZ 4sxA== Received: by 10.68.236.67 with SMTP id us3mr33487275pbc.80.1344407196448; Tue, 07 Aug 2012 23:26:36 -0700 (PDT) Received: from localhost ([202.108.130.138]) by mx.google.com with ESMTPS id pg9sm12745399pbb.26.2012.08.07.23.26.33 (version=TLSv1/SSLv3 cipher=OTHER); Tue, 07 Aug 2012 23:26:35 -0700 (PDT) From: Liu Ping Fan To: qemu-devel@nongnu.org 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 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> X-Mailer: git-send-email 1.7.4.4 In-Reply-To: <1344407156-25562-1-git-send-email-qemulist@gmail.com> References: <1344407156-25562-1-git-send-email-qemulist@gmail.com> Sender: kvm-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: kvm@vger.kernel.org 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