From: Igor Mammedov <imammedo@redhat.com>
To: qemu-devel@nongnu.org
Cc: mst@redhat.com
Subject: [Qemu-devel] [PATCH for-2.5 4/4] vhost: simplify/speedify vhost_dev_unassign_memory()
Date: Tue, 28 Jul 2015 16:52:53 +0200 [thread overview]
Message-ID: <1438095173-7417-5-git-send-email-imammedo@redhat.com> (raw)
In-Reply-To: <1438095173-7417-1-git-send-email-imammedo@redhat.com>
beside reducing code size 2x times, it also makes
function faster and easier to read.
Signed-off-by: Igor Mammedov <imammedo@redhat.com>
---
hw/virtio/vhost.c | 111 ++++++++++++++++++------------------------------------
1 file changed, 37 insertions(+), 74 deletions(-)
diff --git a/hw/virtio/vhost.c b/hw/virtio/vhost.c
index 5b8598b..e2585e3 100644
--- a/hw/virtio/vhost.c
+++ b/hw/virtio/vhost.c
@@ -160,91 +160,54 @@ static int memory_range_bsearch(const struct vhost_dev *dev,
return start;
}
-/* Assign/unassign. Keep an unsorted array of non-overlapping
- * memory regions in dev->mem. */
static void vhost_dev_unassign_memory(struct vhost_dev *dev,
uint64_t start_addr,
uint64_t size)
{
- int from, to, n = dev->mem->nregions;
- /* Track overlapping/split regions for sanity checking. */
- int overlap_start = 0, overlap_end = 0, overlap_middle = 0, split = 0;
-
- for (from = 0, to = 0; from < n; ++from, ++to) {
- struct vhost_memory_region *reg = dev->mem->regions + to;
- uint64_t reglast;
- uint64_t memlast;
- uint64_t change;
-
- /* clone old region */
- if (to != from) {
- memcpy(reg, dev->mem->regions + from, sizeof *reg);
- }
-
- /* No overlap is simple */
- if (!ranges_overlap(reg->guest_phys_addr, reg->memory_size,
- start_addr, size)) {
- continue;
- }
-
- /* Split only happens if supplied region
- * is in the middle of an existing one. Thus it can not
- * overlap with any other existing region. */
- assert(!split);
+ uint64_t reglast, memlast;
+ struct vhost_memory_region *reg;
+ int idx = memory_range_bsearch(dev, start_addr);
- reglast = range_get_last(reg->guest_phys_addr, reg->memory_size);
- memlast = range_get_last(start_addr, size);
+ if (idx == dev->mem->nregions) { /* not found any range */
+ return;
+ }
- /* Remove whole region */
- if (start_addr <= reg->guest_phys_addr && memlast >= reglast) {
- --dev->mem->nregions;
- --to;
- ++overlap_middle;
- continue;
- }
+ reg = dev->mem->regions + idx;
+ reglast = range_get_last(reg->guest_phys_addr, reg->memory_size);
+ memlast = range_get_last(start_addr, size);
- /* Shrink region */
- if (memlast >= reglast) {
- reg->memory_size = start_addr - reg->guest_phys_addr;
- assert(reg->memory_size);
- assert(!overlap_end);
- ++overlap_end;
- continue;
- }
+ /* Remove whole region */
+ if (start_addr == reg->guest_phys_addr && memlast == reglast) {
+ memmove(reg, reg + 1, (dev->mem->nregions - idx - 1) *
+ sizeof dev->mem->regions[0]);
+ dev->mem->nregions--;
+ return;
+ }
- /* Shift region */
- if (start_addr <= reg->guest_phys_addr) {
- change = memlast + 1 - reg->guest_phys_addr;
- reg->memory_size -= change;
- reg->guest_phys_addr += change;
- reg->userspace_addr += change;
- assert(reg->memory_size);
- assert(!overlap_start);
- ++overlap_start;
- continue;
- }
+ /* Split region */
+ if (start_addr > reg->guest_phys_addr && memlast < reglast) {
+ memmove(reg + 1, reg, (dev->mem->nregions - idx) *
+ sizeof dev->mem->regions[0]);
+ reg->guest_phys_addr = memlast + 1;
+ reg->memory_size = reglast - reg->guest_phys_addr + 1;
+ reg++;
+ reg->memory_size = start_addr - reg->guest_phys_addr;
+ dev->mem->nregions++;
+ return;
+ }
- /* This only happens if supplied region
- * is in the middle of an existing one. Thus it can not
- * overlap with any other existing region. */
- assert(!overlap_start);
- assert(!overlap_end);
- assert(!overlap_middle);
- /* Split region: shrink first part, shift second part. */
- memcpy(dev->mem->regions + n, reg, sizeof *reg);
+ /* Shrink region */
+ if (memlast == reglast) { /* shrink end side */
reg->memory_size = start_addr - reg->guest_phys_addr;
- assert(reg->memory_size);
- change = memlast + 1 - reg->guest_phys_addr;
- reg = dev->mem->regions + n;
- reg->memory_size -= change;
- assert(reg->memory_size);
- reg->guest_phys_addr += change;
- reg->userspace_addr += change;
- /* Never add more than 1 region */
- assert(dev->mem->nregions == n);
- ++dev->mem->nregions;
- ++split;
+ return;
+ } else if (start_addr == reg->guest_phys_addr) { /* shrink start side */
+ reg->guest_phys_addr = memlast + 1;
+ reg->memory_size = reglast - reg->guest_phys_addr + 1;
+ return;
}
+ /* there shouldn't be any overlapped ranges by now */
+ assert(!ranges_overlap(reg->guest_phys_addr, reg->memory_size,
+ start_addr, size));
}
/* Called after unassign, so no regions overlap the given range. */
--
1.8.3.1
next prev parent reply other threads:[~2015-07-28 14:53 UTC|newest]
Thread overview: 8+ messages / expand[flat|nested] mbox.gz Atom feed top
2015-07-28 14:52 [Qemu-devel] [PATCH for-2.5 0/4] vhost: cleanups and switching to sorted memory map Igor Mammedov
2015-07-28 14:52 ` [Qemu-devel] [PATCH for-2.5 1/4] vhost: codding style fix tab indents Igor Mammedov
2015-07-28 16:12 ` Peter Maydell
2015-07-28 14:52 ` [Qemu-devel] [PATCH for-2.5 2/4] vhost: simplify/speedify vhost_dev_assign_memory() Igor Mammedov
2015-07-28 14:52 ` [Qemu-devel] [PATCH for-2.5 3/4] vhost: switch region lookup from linear to bsearch Igor Mammedov
2015-07-28 14:52 ` Igor Mammedov [this message]
2015-08-12 7:33 ` [Qemu-devel] [PATCH for-2.5 0/4] vhost: cleanups and switching to sorted memory map Michael S. Tsirkin
2015-08-31 12:35 ` Igor Mammedov
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=1438095173-7417-5-git-send-email-imammedo@redhat.com \
--to=imammedo@redhat.com \
--cc=mst@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).