From patchwork Tue May 7 14:17:04 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Paolo Bonzini X-Patchwork-Id: 242354 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 7C17F2C015E for ; Wed, 8 May 2013 01:18:40 +1000 (EST) Received: from localhost ([::1]:44117 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1UZioB-0005La-4N for incoming@patchwork.ozlabs.org; Tue, 07 May 2013 10:23:59 -0400 Received: from eggs.gnu.org ([208.118.235.92]:57215) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1UZiiz-000141-Ux for qemu-devel@nongnu.org; Tue, 07 May 2013 10:18:40 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1UZiix-000613-U8 for qemu-devel@nongnu.org; Tue, 07 May 2013 10:18:37 -0400 Received: from mail-wi0-x233.google.com ([2a00:1450:400c:c05::233]:56476) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1UZiix-00060u-LC for qemu-devel@nongnu.org; Tue, 07 May 2013 10:18:35 -0400 Received: by mail-wi0-f179.google.com with SMTP id l13so691213wie.12 for ; Tue, 07 May 2013 07:18:35 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=x-received:sender:from:to:cc:subject:date:message-id:x-mailer :in-reply-to:references; bh=Lpr7pKoJXlVd8VedOPotP5+/SsHNa36C9xAfqswoUmQ=; b=t5HUtWQpBlBqF+rLDFTMEQKb7QOW1QkYJKOuCL0+FCfJ3owSIsACw32KWQfJvOaSSd MUBhc4UKtNoJpbYpEf70uKpltGtINNYeRwjxWduzr8cVZQDOoPi4a0ckfm5eOsSVsI91 USmpJOgIXxXnIbcg/iojMNw9uyjkCuvm9LQh5ymQRjzE+zMMcA2dPDLLSE7RfXz7ivRe CtRwiPduddgfG7LAibHakqNWPLqM0c2MRxQlwbRYnCEczxgY0MJWHiCQzJsAjG+kLsps JAK9fAE4zhBcEPch+pE0tmIPSaFIah4Ea4p9egeqZA7W3BorFN7VfKARPMOjc7qk0tWa umLQ== X-Received: by 10.194.11.70 with SMTP id o6mr3821146wjb.29.1367936314953; Tue, 07 May 2013 07:18:34 -0700 (PDT) Received: from localhost.localdomain (93-34-176-20.ip50.fastwebnet.it. [93.34.176.20]) by mx.google.com with ESMTPSA id ge7sm3335978wib.6.2013.05.07.07.18.32 for (version=TLSv1 cipher=RC4-SHA bits=128/128); Tue, 07 May 2013 07:18:33 -0700 (PDT) From: Paolo Bonzini To: qemu-devel@nongnu.org Date: Tue, 7 May 2013 16:17:04 +0200 Message-Id: <1367936238-12196-27-git-send-email-pbonzini@redhat.com> X-Mailer: git-send-email 1.7.1 In-Reply-To: <1367936238-12196-1-git-send-email-pbonzini@redhat.com> References: <1367936238-12196-1-git-send-email-pbonzini@redhat.com> X-detected-operating-system: by eggs.gnu.org: Error: Malformed IPv6 address (bad octet value). X-Received-From: 2a00:1450:400c:c05::233 Cc: aik@ozlabs.ru, jan.kiszka@siemens.com, qemulist@gmail.com, stefanha@redhat.com, david@gibson.dropbear.id.au Subject: [Qemu-devel] [PATCH 26/40] memory: add ref/unref calls 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 Add ref/unref calls at the following places: - places where memory regions are stashed by a listener and used outside the BQL (including in Xen or KVM). - memory_region_find callsites Signed-off-by: Paolo Bonzini --- exec.c | 6 +++++- hw/core/loader.c | 1 + hw/display/exynos4210_fimd.c | 6 ++++++ hw/display/framebuffer.c | 10 ++++++---- hw/i386/kvm/ioapic.c | 2 ++ hw/i386/kvmvapic.c | 1 + hw/misc/vfio.c | 2 ++ hw/virtio/dataplane/hostmem.c | 7 +++++++ hw/virtio/vhost.c | 2 ++ hw/virtio/virtio-balloon.c | 1 + hw/xen/xen_pt.c | 4 ++++ include/hw/virtio/dataplane/hostmem.h | 1 + kvm-all.c | 2 ++ memory.c | 16 ++++++++++++++++ target-arm/kvm.c | 2 ++ target-sparc/mmu_helper.c | 1 + xen-all.c | 2 ++ 17 files changed, 61 insertions(+), 5 deletions(-) diff --git a/exec.c b/exec.c index 03d6ea7..f163a55 100644 --- a/exec.c +++ b/exec.c @@ -761,12 +761,16 @@ static uint16_t phys_section_add(MemoryRegionSection *section) phys_sections_nb_alloc); } phys_sections[phys_sections_nb] = *section; + memory_region_ref(section->mr); return phys_sections_nb++; } static void phys_sections_clear(void) { - phys_sections_nb = 0; + while (phys_sections_nb > 0) { + MemoryRegionSection *section = &phys_sections[--phys_sections_nb]; + memory_region_unref(section->mr); + } } static void register_subpage(AddressSpaceDispatch *d, MemoryRegionSection *section) diff --git a/hw/core/loader.c b/hw/core/loader.c index 7507914..97e7ba2 100644 --- a/hw/core/loader.c +++ b/hw/core/loader.c @@ -727,6 +727,7 @@ int rom_load_all(void) addr += rom->romsize; section = memory_region_find(get_system_memory(), rom->addr, 1); rom->isrom = section.size && memory_region_is_rom(section.mr); + memory_region_unref(section.mr); } qemu_register_reset(rom_reset, NULL); roms_loaded = 1; diff --git a/hw/display/exynos4210_fimd.c b/hw/display/exynos4210_fimd.c index 6cb5016..afa2e54 100644 --- a/hw/display/exynos4210_fimd.c +++ b/hw/display/exynos4210_fimd.c @@ -1126,6 +1126,11 @@ static void fimd_update_memory_section(Exynos4210fimdState *s, unsigned win) /* Total number of bytes of virtual screen used by current window */ w->fb_len = fb_mapped_len = (w->virtpage_width + w->virtpage_offsize) * (w->rightbot_y - w->lefttop_y + 1); + + /* TODO: add .exit and unref the region there. Not needed yet since sysbus + * does not support hot-unplug. + */ + memory_region_unref(w->mem_section.mr); w->mem_section = memory_region_find(sysbus_address_space(&s->busdev), fb_start_addr, w->fb_len); assert(w->mem_section.mr); @@ -1154,6 +1159,7 @@ static void fimd_update_memory_section(Exynos4210fimdState *s, unsigned win) return; error_return: + memory_region_unref(w->mem_section.mr); w->mem_section.mr = NULL; w->mem_section.size = 0; w->host_fb_addr = NULL; diff --git a/hw/display/framebuffer.c b/hw/display/framebuffer.c index 6be31db..8288b93 100644 --- a/hw/display/framebuffer.c +++ b/hw/display/framebuffer.c @@ -54,10 +54,10 @@ void framebuffer_update_display( src_len = src_width * rows; mem_section = memory_region_find(address_space, base, src_len); + mem = mem_section.mr; if (mem_section.size != src_len || !memory_region_is_ram(mem_section.mr)) { - return; + goto out; } - mem = mem_section.mr; assert(mem); assert(mem_section.offset_within_address_space == base); @@ -67,10 +67,10 @@ void framebuffer_update_display( but it's not really worth it as dirty flag tracking will probably already have failed above. */ if (!src_base) - return; + goto out; if (src_len != src_width * rows) { cpu_physical_memory_unmap(src_base, src_len, 0, 0); - return; + goto out; } src = src_base; dest = surface_data(ds); @@ -107,4 +107,6 @@ void framebuffer_update_display( DIRTY_MEMORY_VGA); *first_row = first; *last_row = last; +out: + memory_region_unref(mem); } diff --git a/hw/i386/kvm/ioapic.c b/hw/i386/kvm/ioapic.c index a3bd519..e3c29da 100644 --- a/hw/i386/kvm/ioapic.c +++ b/hw/i386/kvm/ioapic.c @@ -107,6 +107,8 @@ static void kvm_ioapic_put(IOAPICCommonState *s) fprintf(stderr, "KVM_GET_IRQCHIP failed: %s\n", strerror(ret)); abort(); } + + memory_region_unref(mrs.mr); } static void kvm_ioapic_reset(DeviceState *dev) diff --git a/hw/i386/kvmvapic.c b/hw/i386/kvmvapic.c index 655483b..e375c1c 100644 --- a/hw/i386/kvmvapic.c +++ b/hw/i386/kvmvapic.c @@ -605,6 +605,7 @@ static void vapic_map_rom_writable(VAPICROMState *s) rom_size); memory_region_add_subregion_overlap(as, rom_paddr, &s->rom, 1000); s->rom_mapped_writable = true; + memory_region_unref(section.mr); } static int vapic_prepare(VAPICROMState *s) diff --git a/hw/misc/vfio.c b/hw/misc/vfio.c index 178dd11..0ae6878 100644 --- a/hw/misc/vfio.c +++ b/hw/misc/vfio.c @@ -1969,6 +1969,7 @@ static void vfio_listener_region_add(MemoryListener *listener, DPRINTF("region_add %"HWADDR_PRIx" - %"HWADDR_PRIx" [%p]\n", iova, end - 1, vaddr); + memory_region_ref(section->mr); ret = vfio_dma_map(container, iova, end - iova, vaddr, section->readonly); if (ret) { error_report("vfio_dma_map(%p, 0x%"HWADDR_PRIx", " @@ -2010,6 +2011,7 @@ static void vfio_listener_region_del(MemoryListener *listener, iova, end - 1); ret = vfio_dma_unmap(container, iova, end - iova); + memory_region_unref(section->mr); if (ret) { error_report("vfio_dma_unmap(%p, 0x%"HWADDR_PRIx", " "0x%"HWADDR_PRIx") = %d (%m)", diff --git a/hw/virtio/dataplane/hostmem.c b/hw/virtio/dataplane/hostmem.c index 37292ff..66829bb 100644 --- a/hw/virtio/dataplane/hostmem.c +++ b/hw/virtio/dataplane/hostmem.c @@ -64,8 +64,12 @@ out: static void hostmem_listener_commit(MemoryListener *listener) { HostMem *hostmem = container_of(listener, HostMem, listener); + int i; qemu_mutex_lock(&hostmem->current_regions_lock); + for (i = 0; i < hostmem->num_current_regions; i++) { + memory_region_unref(hostmem->current_regions[i].mr); + } g_free(hostmem->current_regions); hostmem->current_regions = hostmem->new_regions; hostmem->num_current_regions = hostmem->num_new_regions; @@ -92,8 +96,11 @@ static void hostmem_append_new_region(HostMem *hostmem, .guest_addr = section->offset_within_address_space, .size = section->size, .readonly = section->readonly, + .mr = section->mr, }; hostmem->num_new_regions++; + + memory_region_ref(section->mr); } static void hostmem_listener_append_region(MemoryListener *listener, diff --git a/hw/virtio/vhost.c b/hw/virtio/vhost.c index fbabf99..190522b 100644 --- a/hw/virtio/vhost.c +++ b/hw/virtio/vhost.c @@ -497,6 +497,7 @@ static void vhost_region_add(MemoryListener *listener, dev->mem_sections = g_renew(MemoryRegionSection, dev->mem_sections, dev->n_mem_sections); dev->mem_sections[dev->n_mem_sections - 1] = *section; + memory_region_ref(section->mr); vhost_set_memory(listener, section, true); } @@ -512,6 +513,7 @@ static void vhost_region_del(MemoryListener *listener, } vhost_set_memory(listener, section, false); + memory_region_unref(section->mr); for (i = 0; i < dev->n_mem_sections; ++i) { if (dev->mem_sections[i].offset_within_address_space == section->offset_within_address_space) { diff --git a/hw/virtio/virtio-balloon.c b/hw/virtio/virtio-balloon.c index d669756..fac8800 100644 --- a/hw/virtio/virtio-balloon.c +++ b/hw/virtio/virtio-balloon.c @@ -205,6 +205,7 @@ static void virtio_balloon_handle_output(VirtIODevice *vdev, VirtQueue *vq) addr = section.offset_within_region; balloon_page(memory_region_get_ram_ptr(section.mr) + addr, !!(vq == s->dvq)); + memory_region_unref(section.mr); } virtqueue_push(vq, &elem, offset); diff --git a/hw/xen/xen_pt.c b/hw/xen/xen_pt.c index c199818..be1fd52 100644 --- a/hw/xen/xen_pt.c +++ b/hw/xen/xen_pt.c @@ -606,6 +606,7 @@ static void xen_pt_region_add(MemoryListener *l, MemoryRegionSection *sec) XenPCIPassthroughState *s = container_of(l, XenPCIPassthroughState, memory_listener); + memory_region_ref(sec->mr); xen_pt_region_update(s, sec, true); } @@ -615,6 +616,7 @@ static void xen_pt_region_del(MemoryListener *l, MemoryRegionSection *sec) memory_listener); xen_pt_region_update(s, sec, false); + memory_region_unref(sec->mr); } static void xen_pt_io_region_add(MemoryListener *l, MemoryRegionSection *sec) @@ -622,6 +624,7 @@ static void xen_pt_io_region_add(MemoryListener *l, MemoryRegionSection *sec) XenPCIPassthroughState *s = container_of(l, XenPCIPassthroughState, io_listener); + memory_region_ref(sec->mr); xen_pt_region_update(s, sec, true); } @@ -631,6 +634,7 @@ static void xen_pt_io_region_del(MemoryListener *l, MemoryRegionSection *sec) io_listener); xen_pt_region_update(s, sec, false); + memory_region_unref(sec->mr); } static const MemoryListener xen_pt_memory_listener = { diff --git a/include/hw/virtio/dataplane/hostmem.h b/include/hw/virtio/dataplane/hostmem.h index b2cf093..2810f4b 100644 --- a/include/hw/virtio/dataplane/hostmem.h +++ b/include/hw/virtio/dataplane/hostmem.h @@ -18,6 +18,7 @@ #include "qemu/thread.h" typedef struct { + MemoryRegion *mr; void *host_addr; hwaddr guest_addr; uint64_t size; diff --git a/kvm-all.c b/kvm-all.c index 3a31602..1d876aa 100644 --- a/kvm-all.c +++ b/kvm-all.c @@ -766,6 +766,7 @@ static void kvm_set_phys_mem(MemoryRegionSection *section, bool add) static void kvm_region_add(MemoryListener *listener, MemoryRegionSection *section) { + memory_region_ref(section->mr); kvm_set_phys_mem(section, true); } @@ -773,6 +774,7 @@ static void kvm_region_del(MemoryListener *listener, MemoryRegionSection *section) { kvm_set_phys_mem(section, false); + memory_region_unref(section->mr); } static void kvm_log_sync(MemoryListener *listener, diff --git a/memory.c b/memory.c index c7ab19c..4b30c3f 100644 --- a/memory.c +++ b/memory.c @@ -145,6 +145,7 @@ static bool memory_listener_match(MemoryListener *listener, } \ } while (0) +/* No need to ref/unref .mr, the FlatRange keeps it alive. */ #define MEMORY_LISTENER_UPDATE_REGION(fr, as, dir, callback) \ MEMORY_LISTENER_CALL(callback, dir, (&(MemoryRegionSection) { \ .mr = (fr)->mr, \ @@ -260,11 +261,17 @@ static void flatview_insert(FlatView *view, unsigned pos, FlatRange *range) memmove(view->ranges + pos + 1, view->ranges + pos, (view->nr - pos) * sizeof(FlatRange)); view->ranges[pos] = *range; + memory_region_ref(range->mr); ++view->nr; } static void flatview_destroy(FlatView *view) { + int i; + + for (i = 0; i < view->nr; i++) { + memory_region_unref(view->ranges[i].mr); + } g_free(view->ranges); } @@ -763,6 +770,11 @@ static void memory_region_destructor_ram(MemoryRegion *mr) qemu_ram_free(mr->ram_addr); } +static void memory_region_destructor_alias(MemoryRegion *mr) +{ + memory_region_unref(mr->alias); +} + static void memory_region_destructor_ram_from_ptr(MemoryRegion *mr) { qemu_ram_free_from_ptr(mr->ram_addr); @@ -961,6 +973,8 @@ void memory_region_init_alias(MemoryRegion *mr, uint64_t size) { memory_region_init(mr, name, size); + memory_region_ref(orig); + mr->destructor = memory_region_destructor_alias; mr->alias = orig; mr->alias_offset = offset; } @@ -1539,6 +1553,8 @@ MemoryRegionSection memory_region_find(MemoryRegion *mr, ret.size = int128_get64(range.size); ret.offset_within_address_space = int128_get64(range.start); ret.readonly = fr->readonly; + memory_region_ref(ret.mr); + return ret; } diff --git a/target-arm/kvm.c b/target-arm/kvm.c index b7bdc03..b9051a4 100644 --- a/target-arm/kvm.c +++ b/target-arm/kvm.c @@ -127,6 +127,7 @@ static void kvm_arm_machine_init_done(Notifier *notifier, void *data) abort(); } } + memory_region_unref(kd->mr); g_free(kd); } } @@ -152,6 +153,7 @@ void kvm_arm_register_device(MemoryRegion *mr, uint64_t devid) kd->kda.id = devid; kd->kda.addr = -1; QSLIST_INSERT_HEAD(&kvm_devices_head, kd, entries); + memory_region_ref(kd->mr); } typedef struct Reg { diff --git a/target-sparc/mmu_helper.c b/target-sparc/mmu_helper.c index a9649ae..3c1ccc2 100644 --- a/target-sparc/mmu_helper.c +++ b/target-sparc/mmu_helper.c @@ -845,6 +845,7 @@ hwaddr cpu_get_phys_page_debug(CPUSPARCState *env, target_ulong addr) } } section = memory_region_find(get_system_memory(), phys_addr, 1); + memory_region_unref(section.mr); if (!section.size) { return -1; } diff --git a/xen-all.c b/xen-all.c index 539a154..2f24ced 100644 --- a/xen-all.c +++ b/xen-all.c @@ -459,6 +459,7 @@ static void xen_set_memory(struct MemoryListener *listener, static void xen_region_add(MemoryListener *listener, MemoryRegionSection *section) { + memory_region_ref(section->mr); xen_set_memory(listener, section, true); } @@ -466,6 +467,7 @@ static void xen_region_del(MemoryListener *listener, MemoryRegionSection *section) { xen_set_memory(listener, section, false); + memory_region_unref(section->mr); } static void xen_sync_dirty_bitmap(XenIOState *state,