qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
From: "Philippe Mathieu-Daudé" <philmd@linaro.org>
To: qemu-devel@nongnu.org
Cc: "Mattias Nissler" <mnissler@rivosinc.com>,
	"Peter Xu" <peterx@redhat.com>,
	"Jonathan Cameron" <Jonathan.Cameron@huawei.com>,
	"Philippe Mathieu-Daudé" <philmd@linaro.org>
Subject: [PULL 08/26] system/physmem: Per-AddressSpace bounce buffering
Date: Wed,  8 May 2024 19:44:52 +0200	[thread overview]
Message-ID: <20240508174510.60470-9-philmd@linaro.org> (raw)
In-Reply-To: <20240508174510.60470-1-philmd@linaro.org>

From: Mattias Nissler <mnissler@rivosinc.com>

Instead of using a single global bounce buffer, give each AddressSpace
its own bounce buffer. The MapClient callback mechanism moves to
AddressSpace accordingly.

This is in preparation for generalizing bounce buffer handling further
to allow multiple bounce buffers, with a total allocation limit
configured per AddressSpace.

Reviewed-by: Peter Xu <peterx@redhat.com>
Tested-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
Signed-off-by: Mattias Nissler <mnissler@rivosinc.com>
Message-ID: <20240507094210.300566-2-mnissler@rivosinc.com>
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
[PMD: Split patch, part 2/2]
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
---
 include/exec/memory.h | 19 +++++++++++
 system/memory.c       |  7 +++++
 system/physmem.c      | 73 ++++++++++++++++---------------------------
 3 files changed, 53 insertions(+), 46 deletions(-)

diff --git a/include/exec/memory.h b/include/exec/memory.h
index e1e0c5a3de..d417d7f363 100644
--- a/include/exec/memory.h
+++ b/include/exec/memory.h
@@ -1112,6 +1112,19 @@ struct MemoryListener {
     QTAILQ_ENTRY(MemoryListener) link_as;
 };
 
+typedef struct AddressSpaceMapClient {
+    QEMUBH *bh;
+    QLIST_ENTRY(AddressSpaceMapClient) link;
+} AddressSpaceMapClient;
+
+typedef struct {
+    MemoryRegion *mr;
+    void *buffer;
+    hwaddr addr;
+    hwaddr len;
+    bool in_use;
+} BounceBuffer;
+
 /**
  * struct AddressSpace: describes a mapping of addresses to #MemoryRegion objects
  */
@@ -1129,6 +1142,12 @@ struct AddressSpace {
     struct MemoryRegionIoeventfd *ioeventfds;
     QTAILQ_HEAD(, MemoryListener) listeners;
     QTAILQ_ENTRY(AddressSpace) address_spaces_link;
+
+    /* Bounce buffer to use for this address space. */
+    BounceBuffer bounce;
+    /* List of callbacks to invoke when buffers free up */
+    QemuMutex map_client_list_lock;
+    QLIST_HEAD(, AddressSpaceMapClient) map_client_list;
 };
 
 typedef struct AddressSpaceDispatch AddressSpaceDispatch;
diff --git a/system/memory.c b/system/memory.c
index 49f1cb2c38..642a449f8c 100644
--- a/system/memory.c
+++ b/system/memory.c
@@ -3174,6 +3174,9 @@ void address_space_init(AddressSpace *as, MemoryRegion *root, const char *name)
     as->ioeventfds = NULL;
     QTAILQ_INIT(&as->listeners);
     QTAILQ_INSERT_TAIL(&address_spaces, as, address_spaces_link);
+    as->bounce.in_use = false;
+    qemu_mutex_init(&as->map_client_list_lock);
+    QLIST_INIT(&as->map_client_list);
     as->name = g_strdup(name ? name : "anonymous");
     address_space_update_topology(as);
     address_space_update_ioeventfds(as);
@@ -3181,6 +3184,10 @@ void address_space_init(AddressSpace *as, MemoryRegion *root, const char *name)
 
 static void do_address_space_destroy(AddressSpace *as)
 {
+    assert(!qatomic_read(&as->bounce.in_use));
+    assert(QLIST_EMPTY(&as->map_client_list));
+    qemu_mutex_destroy(&as->map_client_list_lock);
+
     assert(QTAILQ_EMPTY(&as->listeners));
 
     flatview_unref(as->current_map);
diff --git a/system/physmem.c b/system/physmem.c
index b76b3d2184..342b7a8fd4 100644
--- a/system/physmem.c
+++ b/system/physmem.c
@@ -3047,26 +3047,8 @@ void cpu_flush_icache_range(hwaddr start, hwaddr len)
                                      NULL, len, FLUSH_CACHE);
 }
 
-typedef struct {
-    MemoryRegion *mr;
-    void *buffer;
-    hwaddr addr;
-    hwaddr len;
-    bool in_use;
-} BounceBuffer;
-
-static BounceBuffer bounce;
-
-typedef struct MapClient {
-    QEMUBH *bh;
-    QLIST_ENTRY(MapClient) link;
-} MapClient;
-
-QemuMutex map_client_list_lock;
-static QLIST_HEAD(, MapClient) map_client_list
-    = QLIST_HEAD_INITIALIZER(map_client_list);
-
-static void address_space_unregister_map_client_do(MapClient *client)
+static void
+address_space_unregister_map_client_do(AddressSpaceMapClient *client)
 {
     QLIST_REMOVE(client, link);
     g_free(client);
@@ -3074,10 +3056,10 @@ static void address_space_unregister_map_client_do(MapClient *client)
 
 static void address_space_notify_map_clients_locked(AddressSpace *as)
 {
-    MapClient *client;
+    AddressSpaceMapClient *client;
 
-    while (!QLIST_EMPTY(&map_client_list)) {
-        client = QLIST_FIRST(&map_client_list);
+    while (!QLIST_EMPTY(&as->map_client_list)) {
+        client = QLIST_FIRST(&as->map_client_list);
         qemu_bh_schedule(client->bh);
         address_space_unregister_map_client_do(client);
     }
@@ -3085,14 +3067,14 @@ static void address_space_notify_map_clients_locked(AddressSpace *as)
 
 void address_space_register_map_client(AddressSpace *as, QEMUBH *bh)
 {
-    MapClient *client = g_malloc(sizeof(*client));
+    AddressSpaceMapClient *client = g_malloc(sizeof(*client));
 
-    QEMU_LOCK_GUARD(&map_client_list_lock);
+    QEMU_LOCK_GUARD(&as->map_client_list_lock);
     client->bh = bh;
-    QLIST_INSERT_HEAD(&map_client_list, client, link);
+    QLIST_INSERT_HEAD(&as->map_client_list, client, link);
     /* Write map_client_list before reading in_use.  */
     smp_mb();
-    if (!qatomic_read(&bounce.in_use)) {
+    if (!qatomic_read(&as->bounce.in_use)) {
         address_space_notify_map_clients_locked(as);
     }
 }
@@ -3110,15 +3092,14 @@ void cpu_exec_init_all(void)
     finalize_target_page_bits();
     io_mem_init();
     memory_map_init();
-    qemu_mutex_init(&map_client_list_lock);
 }
 
 void address_space_unregister_map_client(AddressSpace *as, QEMUBH *bh)
 {
-    MapClient *client;
+    AddressSpaceMapClient *client;
 
-    QEMU_LOCK_GUARD(&map_client_list_lock);
-    QLIST_FOREACH(client, &map_client_list, link) {
+    QEMU_LOCK_GUARD(&as->map_client_list_lock);
+    QLIST_FOREACH(client, &as->map_client_list, link) {
         if (client->bh == bh) {
             address_space_unregister_map_client_do(client);
             break;
@@ -3128,7 +3109,7 @@ void address_space_unregister_map_client(AddressSpace *as, QEMUBH *bh)
 
 static void address_space_notify_map_clients(AddressSpace *as)
 {
-    QEMU_LOCK_GUARD(&map_client_list_lock);
+    QEMU_LOCK_GUARD(&as->map_client_list_lock);
     address_space_notify_map_clients_locked(as);
 }
 
@@ -3220,25 +3201,25 @@ void *address_space_map(AddressSpace *as,
     mr = flatview_translate(fv, addr, &xlat, &l, is_write, attrs);
 
     if (!memory_access_is_direct(mr, is_write)) {
-        if (qatomic_xchg(&bounce.in_use, true)) {
+        if (qatomic_xchg(&as->bounce.in_use, true)) {
             *plen = 0;
             return NULL;
         }
         /* Avoid unbounded allocations */
         l = MIN(l, TARGET_PAGE_SIZE);
-        bounce.buffer = qemu_memalign(TARGET_PAGE_SIZE, l);
-        bounce.addr = addr;
-        bounce.len = l;
+        as->bounce.buffer = qemu_memalign(TARGET_PAGE_SIZE, l);
+        as->bounce.addr = addr;
+        as->bounce.len = l;
 
         memory_region_ref(mr);
-        bounce.mr = mr;
+        as->bounce.mr = mr;
         if (!is_write) {
             flatview_read(fv, addr, MEMTXATTRS_UNSPECIFIED,
-                               bounce.buffer, l);
+                          as->bounce.buffer, l);
         }
 
         *plen = l;
-        return bounce.buffer;
+        return as->bounce.buffer;
     }
 
 
@@ -3256,7 +3237,7 @@ void *address_space_map(AddressSpace *as,
 void address_space_unmap(AddressSpace *as, void *buffer, hwaddr len,
                          bool is_write, hwaddr access_len)
 {
-    if (buffer != bounce.buffer) {
+    if (buffer != as->bounce.buffer) {
         MemoryRegion *mr;
         ram_addr_t addr1;
 
@@ -3272,14 +3253,14 @@ void address_space_unmap(AddressSpace *as, void *buffer, hwaddr len,
         return;
     }
     if (is_write) {
-        address_space_write(as, bounce.addr, MEMTXATTRS_UNSPECIFIED,
-                            bounce.buffer, access_len);
+        address_space_write(as, as->bounce.addr, MEMTXATTRS_UNSPECIFIED,
+                            as->bounce.buffer, access_len);
     }
-    qemu_vfree(bounce.buffer);
-    bounce.buffer = NULL;
-    memory_region_unref(bounce.mr);
+    qemu_vfree(as->bounce.buffer);
+    as->bounce.buffer = NULL;
+    memory_region_unref(as->bounce.mr);
     /* Clear in_use before reading map_client_list.  */
-    qatomic_set_mb(&bounce.in_use, false);
+    qatomic_set_mb(&as->bounce.in_use, false);
     address_space_notify_map_clients(as);
 }
 
-- 
2.41.0



  parent reply	other threads:[~2024-05-08 17:47 UTC|newest]

Thread overview: 29+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2024-05-08 17:44 [PULL 00/26] Misc HW patches for 2024-05-08 Philippe Mathieu-Daudé
2024-05-08 17:44 ` [PULL 01/26] block/qcow2-bitmap: Replace g_memdup() by g_memdup2() Philippe Mathieu-Daudé
2024-05-08 17:44 ` [PULL 02/26] target/ppc: " Philippe Mathieu-Daudé
2024-05-08 17:44 ` [PULL 03/26] hw/hppa/machine: " Philippe Mathieu-Daudé
2024-05-08 17:44 ` [PULL 04/26] hw/ppc/spapr_pci: " Philippe Mathieu-Daudé
2024-05-08 17:44 ` [PULL 05/26] hw/remote/vfio-user: Fix config space access byte order Philippe Mathieu-Daudé
2024-05-10  8:18   ` Michael Tokarev
2024-05-10  9:54     ` Philippe Mathieu-Daudé
2024-05-08 17:44 ` [PULL 06/26] system/physmem: Replace qemu_mutex_lock() calls with QEMU_LOCK_GUARD Philippe Mathieu-Daudé
2024-05-08 17:44 ` [PULL 07/26] system/physmem: Propagate AddressSpace to MapClient helpers Philippe Mathieu-Daudé
2024-05-08 17:44 ` Philippe Mathieu-Daudé [this message]
2024-05-08 17:44 ` [PULL 09/26] hw/i386/pc: Allow to compile without CONFIG_FDC_ISA Philippe Mathieu-Daudé
2024-05-08 17:44 ` [PULL 10/26] hw/i386/Kconfig: Allow to compile Q35 without FDC_ISA Philippe Mathieu-Daudé
2024-05-08 17:44 ` [PULL 11/26] hw/i386: Add the possibility to use i440fx and isapc without FDC Philippe Mathieu-Daudé
2024-05-08 17:44 ` [PULL 12/26] hw/i386/x86: Eliminate two if statements in x86_bios_rom_init() Philippe Mathieu-Daudé
2024-05-08 17:44 ` [PULL 13/26] hw/i386: Have x86_bios_rom_init() take X86MachineState rather than MachineState Philippe Mathieu-Daudé
2024-05-08 17:44 ` [PULL 14/26] hw/i386/x86: Don't leak "isa-bios" memory regions Philippe Mathieu-Daudé
2024-05-08 17:44 ` [PULL 15/26] hw/usb/dev-network: Remove unused struct 'rndis_config_parameter' Philippe Mathieu-Daudé
2024-05-08 17:45 ` [PULL 16/26] hw/gpio: Handle clock migration in STM32L4x5 gpios Philippe Mathieu-Daudé
2024-05-08 17:45 ` [PULL 17/26] hw/ppc: Deprecate 'ref405ep' machine and 405 CPUs Philippe Mathieu-Daudé
2024-05-08 17:45 ` [PULL 18/26] hw/loongarch: move memory map to boot.c Philippe Mathieu-Daudé
2024-05-08 17:45 ` [PULL 19/26] hw/loongarch/virt: Fix memory leak Philippe Mathieu-Daudé
2024-05-08 17:45 ` [PULL 20/26] hw/loongarch: Rename LOONGARCH_MACHINE with LOONGARCH_VIRT_MACHINE Philippe Mathieu-Daudé
2024-05-08 17:45 ` [PULL 21/26] hw/loongarch: Rename LoongArchMachineState with LoongArchVirtMachineState Philippe Mathieu-Daudé
2024-05-08 17:45 ` [PULL 22/26] hw/mips/loongson3_virt: Emulate suspend function Philippe Mathieu-Daudé
2024-05-08 17:45 ` [PULL 23/26] hw/intc/loongarch_ipi: Remove pointless MAX_CPU check Philippe Mathieu-Daudé
2024-05-08 17:45 ` [PULL 24/26] hw/intc/loongarch_ipi: Rename as loongson_ipi Philippe Mathieu-Daudé
2024-05-08 17:45 ` [PULL 25/26] hw/intc/loongson_ipi: Implement IOCSR address space for MIPS Philippe Mathieu-Daudé
2024-05-08 17:45 ` [PULL 26/26] misc: Use QEMU header path relative to include/ directory Philippe Mathieu-Daudé

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20240508174510.60470-9-philmd@linaro.org \
    --to=philmd@linaro.org \
    --cc=Jonathan.Cameron@huawei.com \
    --cc=mnissler@rivosinc.com \
    --cc=peterx@redhat.com \
    --cc=qemu-devel@nongnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).