From: "Longpeng(Mike)" via <qemu-devel@nongnu.org>
To: <pbonzini@redhat.com>, <peterx@redhat.com>, <david@redhat.com>,
<philmd@linaro.org>, <mst@redhat.com>, <jasowang@redhat.com>
Cc: <qemu-devel@nongnu.org>, <eperezma@redhat.com>,
<arei.gonglei@huawei.com>, <yechuan@huawei.com>,
Longpeng <longpeng2@huawei.com>
Subject: [PATCH] memory: avoid unnecessary iteration when updating ioeventfds
Date: Tue, 28 Feb 2023 22:25:14 +0800 [thread overview]
Message-ID: <20230228142514.2582-1-longpeng2@huawei.com> (raw)
From: Longpeng <longpeng2@huawei.com>
When updating ioeventfds, we need to iterate all address spaces and
iterate all flat ranges of each address space. There is so much
redundant process that a FlatView would be iterated for so many times
during one commit (memory_region_transaction_commit).
We can mark a FlatView as UPDATED and then skip it in the next iteration
and clear the UPDATED flag at the end of the commit. The overhead can
be significantly reduced.
For example, a VM with 16 vdpa net devices and each one has 65 vectors,
can reduce the time spent on memory_region_transaction_commit by 95%.
Signed-off-by: Longpeng <longpeng2@huawei.com>
---
include/exec/memory.h | 2 ++
softmmu/memory.c | 28 +++++++++++++++++++++++++++-
2 files changed, 29 insertions(+), 1 deletion(-)
diff --git a/include/exec/memory.h b/include/exec/memory.h
index 2e602a2fad..974eabf765 100644
--- a/include/exec/memory.h
+++ b/include/exec/memory.h
@@ -1093,6 +1093,8 @@ struct FlatView {
unsigned nr_allocated;
struct AddressSpaceDispatch *dispatch;
MemoryRegion *root;
+#define FLATVIEW_FLAG_IOEVENTFD_UPDATED (1 << 0)
+ unsigned flags;
};
static inline FlatView *address_space_to_flatview(AddressSpace *as)
diff --git a/softmmu/memory.c b/softmmu/memory.c
index 9d64efca26..71ff996712 100644
--- a/softmmu/memory.c
+++ b/softmmu/memory.c
@@ -815,6 +815,15 @@ FlatView *address_space_get_flatview(AddressSpace *as)
return view;
}
+static void address_space_reset_view_flags(AddressSpace *as, unsigned mask)
+{
+ FlatView *view = address_space_get_flatview(as);
+
+ if (view->flags & mask) {
+ view->flags &= ~mask;
+ }
+}
+
static void address_space_update_ioeventfds(AddressSpace *as)
{
FlatView *view;
@@ -825,6 +834,12 @@ static void address_space_update_ioeventfds(AddressSpace *as)
AddrRange tmp;
unsigned i;
+ view = address_space_get_flatview(as);
+ if (view->flags & FLATVIEW_FLAG_IOEVENTFD_UPDATED) {
+ return;
+ }
+ view->flags |= FLATVIEW_FLAG_IOEVENTFD_UPDATED;
+
/*
* It is likely that the number of ioeventfds hasn't changed much, so use
* the previous size as the starting value, with some headroom to avoid
@@ -833,7 +848,6 @@ static void address_space_update_ioeventfds(AddressSpace *as)
ioeventfd_max = QEMU_ALIGN_UP(as->ioeventfd_nb, 4);
ioeventfds = g_new(MemoryRegionIoeventfd, ioeventfd_max);
- view = address_space_get_flatview(as);
FOR_EACH_FLAT_RANGE(fr, view) {
for (i = 0; i < fr->mr->ioeventfd_nb; ++i) {
tmp = addrrange_shift(fr->mr->ioeventfds[i].addr,
@@ -1086,6 +1100,15 @@ void memory_region_transaction_begin(void)
++memory_region_transaction_depth;
}
+static inline void address_space_update_ioeventfds_finish(void)
+{
+ AddressSpace *as;
+
+ QTAILQ_FOREACH(as, &address_spaces, address_spaces_link) {
+ address_space_reset_view_flags(as, FLATVIEW_FLAG_IOEVENTFD_UPDATED);
+ }
+}
+
void memory_region_transaction_commit(void)
{
AddressSpace *as;
@@ -1106,12 +1129,14 @@ void memory_region_transaction_commit(void)
}
memory_region_update_pending = false;
ioeventfd_update_pending = false;
+ address_space_update_ioeventfds_finish();
MEMORY_LISTENER_CALL_GLOBAL(commit, Forward);
} else if (ioeventfd_update_pending) {
QTAILQ_FOREACH(as, &address_spaces, address_spaces_link) {
address_space_update_ioeventfds(as);
}
ioeventfd_update_pending = false;
+ address_space_update_ioeventfds_finish();
}
}
}
@@ -3076,6 +3101,7 @@ void address_space_init(AddressSpace *as, MemoryRegion *root, const char *name)
as->name = g_strdup(name ? name : "anonymous");
address_space_update_topology(as);
address_space_update_ioeventfds(as);
+ address_space_reset_view_flags(as, FLATVIEW_FLAG_IOEVENTFD_UPDATED);
}
static void do_address_space_destroy(AddressSpace *as)
--
2.23.0
next reply other threads:[~2023-02-28 14:26 UTC|newest]
Thread overview: 5+ messages / expand[flat|nested] mbox.gz Atom feed top
2023-02-28 14:25 Longpeng(Mike) via [this message]
2023-02-28 17:16 ` [PATCH] memory: avoid unnecessary iteration when updating ioeventfds David Hildenbrand
2023-03-01 8:36 ` Jason Wang
2023-03-05 21:27 ` Peter Xu
2023-03-06 3:46 ` Jason Wang
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=20230228142514.2582-1-longpeng2@huawei.com \
--to=qemu-devel@nongnu.org \
--cc=arei.gonglei@huawei.com \
--cc=david@redhat.com \
--cc=eperezma@redhat.com \
--cc=jasowang@redhat.com \
--cc=longpeng2@huawei.com \
--cc=mst@redhat.com \
--cc=pbonzini@redhat.com \
--cc=peterx@redhat.com \
--cc=philmd@linaro.org \
--cc=yechuan@huawei.com \
/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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.