From patchwork Tue Sep 2 08:42:52 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Peter Crosthwaite X-Patchwork-Id: 385017 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.gnu.org (lists.gnu.org [IPv6:2001:4830:134:3::11]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id A663A14012B for ; Tue, 2 Sep 2014 18:44:03 +1000 (EST) Received: from localhost ([::1]:36667 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1XOjh3-00044C-Ld for incoming@patchwork.ozlabs.org; Tue, 02 Sep 2014 04:44:01 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:53319) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1XOjgg-0003lA-KE for qemu-devel@nongnu.org; Tue, 02 Sep 2014 04:43:44 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1XOjga-0002IR-Am for qemu-devel@nongnu.org; Tue, 02 Sep 2014 04:43:38 -0400 Received: from mail-pd0-f171.google.com ([209.85.192.171]:54437) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1XOjga-0002IN-5V for qemu-devel@nongnu.org; Tue, 02 Sep 2014 04:43:32 -0400 Received: by mail-pd0-f171.google.com with SMTP id y13so8049445pdi.30 for ; Tue, 02 Sep 2014 01:43:26 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:sender:from:to:cc:subject:date:message-id :in-reply-to:references; bh=3/M3LQhR+n2mOPQVn19X/tOch1X4s7vq1lObyxt2LiY=; b=UjZBmf1DlxFm9yvOOJqwkDZO7SjivMMH5LQBnarPAKgTSKlaok6a69LJKFZvYvTK5a zJjifeoXoopw1b1zw0HU/VLA2E1gDLnDYyUw8BJ7Ti2B/WF4ss8/PZiCKmQzDFz8KR14 S3/IAozZQMiFmlKnSzmKztZk9I3dq8VpZyaEwoRmF4+AyFezwiiXGtniarNk/fxbWjbA KUgklEUN9kXx32F6coob6YumXYrc50haj8EmwFB5K3y8a9VayPjZpDViWvZHiTuRNadz TmN2LC1iUhodvfaiR9h91QYFLJCeBqgxrwhStJsUjFkRd1CJ5SRwMheBgmLpgWHYSkTQ FHDQ== X-Gm-Message-State: ALoCoQmZrGpbmstL0OJH3RVue9hL5/U8Ch5AwhkLbAwHH8LClhYo0sqLjO/Hgwe2yyJcR7ASIi8k X-Received: by 10.68.190.229 with SMTP id gt5mr45200898pbc.15.1409647405371; Tue, 02 Sep 2014 01:43:25 -0700 (PDT) Received: from localhost ([149.199.62.254]) by mx.google.com with ESMTPSA id dh14sm9702010pac.17.2014.09.02.01.43.23 for (version=TLSv1.2 cipher=RC4-SHA bits=128/128); Tue, 02 Sep 2014 01:43:24 -0700 (PDT) From: Peter Crosthwaite To: qemu-devel@nongnu.org Date: Tue, 2 Sep 2014 01:42:52 -0700 Message-Id: X-Mailer: git-send-email 2.1.0.1.g27b9230 In-Reply-To: References: X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 209.85.192.171 Cc: edgar.iglesias@xilinx.com, pbonzini@redhat.com, afaerber@suse.de, peter.maydell@linaro.org Subject: [Qemu-devel] [PATCH v1 3/6] memory: Add address_space_init_shareable() 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 This will either create a new AS or return a pointer to an already existing equivalent one. Both name and root mr must match. The motivation is to reuse address spaces as much as possible. It's going to be quite common that bus masters out in device land have pointers to the same memory region for their mastering yet each will need to create its own address space. Let the memory API implement sharing for them. Aside from the perf optimisations, this should reduce the amount of redundant output on info mtree as well. Thee returned value will be malloced, but the malloc will be automatically freed when the AS runs out of refs. Signed-off-by: Peter Crosthwaite --- We could change the equivalency test only match mr to support device specific naming of these shared ASes. The singleton AS can ultimately only have one name however. So perhaps some strcatting each time a new sharer is added to the share. That or first-in-best-dressed. Changed since v1: Implement ref counting and garbage collection. include/exec/memory.h | 3 +++ memory.c | 25 +++++++++++++++++++++++++ 2 files changed, 28 insertions(+) diff --git a/include/exec/memory.h b/include/exec/memory.h index 18cb6b2..cbd7336 100644 --- a/include/exec/memory.h +++ b/include/exec/memory.h @@ -208,6 +208,7 @@ struct AddressSpace { char *name; MemoryRegion *root; int ref_count; + bool malloced; struct FlatView *current_map; int ioeventfd_nb; struct MemoryRegionIoeventfd *ioeventfds; @@ -977,6 +978,8 @@ void mtree_info(fprintf_function mon_printf, void *f); */ void address_space_init(AddressSpace *as, MemoryRegion *root, const char *name); +AddressSpace *address_space_init_shareable(MemoryRegion *root, + const char *name); /** * address_space_destroy: destroy an address space diff --git a/memory.c b/memory.c index 27beef1..08ab918 100644 --- a/memory.c +++ b/memory.c @@ -1932,6 +1932,7 @@ void address_space_init(AddressSpace *as, MemoryRegion *root, const char *name) memory_region_transaction_begin(); as->ref_count = 1; as->root = root; + as->malloced = false; as->current_map = g_new(FlatView, 1); flatview_init(as->current_map); as->ioeventfd_nb = 0; @@ -1943,6 +1944,27 @@ void address_space_init(AddressSpace *as, MemoryRegion *root, const char *name) memory_region_transaction_commit(); } +AddressSpace *address_space_init_shareable(MemoryRegion *root, const char *name) +{ + AddressSpace *as; + + if (!root) { + return NULL; + } + + QTAILQ_FOREACH(as, &address_spaces, address_spaces_link) { + if (root == as->root && !strcmp(name ? name : "anonymous", as->name)) { + as->ref_count++; + return as; + } + } + + as = g_malloc0(sizeof *as); + address_space_init(as, root, name); + as->malloced = true; + return as; +} + void address_space_destroy(AddressSpace *as) { MemoryListener *listener; @@ -1965,6 +1987,9 @@ void address_space_destroy(AddressSpace *as) flatview_unref(as->current_map); g_free(as->name); g_free(as->ioeventfds); + if (as->malloced) { + g_free(as); + } } bool io_mem_read(MemoryRegion *mr, hwaddr addr, uint64_t *pval, unsigned size)