summaryrefslogtreecommitdiff
path: root/include/exec/memory.h
diff options
context:
space:
mode:
authorPaolo Bonzini <pbonzini@redhat.com>2016-09-22 16:23:06 +0200
committerPaolo Bonzini <pbonzini@redhat.com>2016-10-24 15:27:19 +0200
commit9a54635dcb51a3fcf7507af630168f514a8cd4e7 (patch)
tree522b330a6579147d2d9c65a807ea804b1d48e240 /include/exec/memory.h
parentd45fa784cd0c111131696808d1168259d66b7519 (diff)
downloadqemu-9a54635dcb51a3fcf7507af630168f514a8cd4e7.zip
memory: add a per-AddressSpace list of listeners
This speeds up MEMORY_LISTENER_CALL noticeably. Right now, with many PCI devices you have N regions added to M AddressSpaces (M = # PCI devices with bus-master enabled) and each call looks up the whole listener list, with at least M listeners in it. Because most of the regions in N are BARs, which are also roughly proportional to M, the whole thing is O(M^3). This changes it to O(M^2), which is the best we can do without rewriting the whole thing. Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Diffstat (limited to 'include/exec/memory.h')
-rw-r--r--include/exec/memory.h3
1 files changed, 2 insertions, 1 deletions
diff --git a/include/exec/memory.h b/include/exec/memory.h
index 39f34108fb..79ccaaba1f 100644
--- a/include/exec/memory.h
+++ b/include/exec/memory.h
@@ -257,6 +257,7 @@ struct MemoryListener {
unsigned priority;
AddressSpace *address_space;
QTAILQ_ENTRY(MemoryListener) link;
+ QTAILQ_ENTRY(MemoryListener) link_as;
};
/**
@@ -278,7 +279,7 @@ struct AddressSpace {
struct AddressSpaceDispatch *dispatch;
struct AddressSpaceDispatch *next_dispatch;
MemoryListener dispatch_listener;
-
+ QTAILQ_HEAD(memory_listeners_as, MemoryListener) listeners;
QTAILQ_ENTRY(AddressSpace) address_spaces_link;
};