Skip to content

Commit

Permalink
memory: Flush coalesced MMIO on selected region access
Browse files Browse the repository at this point in the history
Instead of flushing pending coalesced MMIO requests on every vmexit,
this provides a mechanism to selectively flush when memory regions
related to the coalesced one are accessed. This first of all includes
the coalesced region itself but can also applied to other regions, e.g.
of the same device, by calling memory_region_set_flush_coalesced.

Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
Signed-off-by: Marcelo Tosatti <mtosatti@redhat.com>
  • Loading branch information
jan-kiszka authored and matosatti committed Sep 11, 2012
1 parent 8732fbd commit d410515
Show file tree
Hide file tree
Showing 2 changed files with 50 additions and 0 deletions.
24 changes: 24 additions & 0 deletions memory.c
Expand Up @@ -311,6 +311,9 @@ static void memory_region_read_accessor(void *opaque,
MemoryRegion *mr = opaque;
uint64_t tmp;

if (mr->flush_coalesced_mmio) {
qemu_flush_coalesced_mmio_buffer();
}
tmp = mr->ops->read(mr->opaque, addr, size);
*value |= (tmp & mask) << shift;
}
Expand All @@ -325,6 +328,9 @@ static void memory_region_write_accessor(void *opaque,
MemoryRegion *mr = opaque;
uint64_t tmp;

if (mr->flush_coalesced_mmio) {
qemu_flush_coalesced_mmio_buffer();
}
tmp = (*value >> shift) & mask;
mr->ops->write(mr->opaque, addr, tmp, size);
}
Expand Down Expand Up @@ -826,6 +832,7 @@ void memory_region_init(MemoryRegion *mr,
mr->dirty_log_mask = 0;
mr->ioeventfd_nb = 0;
mr->ioeventfds = NULL;
mr->flush_coalesced_mmio = false;
}

static bool memory_region_access_valid(MemoryRegion *mr,
Expand Down Expand Up @@ -1176,12 +1183,16 @@ void memory_region_add_coalescing(MemoryRegion *mr,
cmr->addr = addrrange_make(int128_make64(offset), int128_make64(size));
QTAILQ_INSERT_TAIL(&mr->coalesced, cmr, link);
memory_region_update_coalesced_range(mr);
memory_region_set_flush_coalesced(mr);
}

void memory_region_clear_coalescing(MemoryRegion *mr)
{
CoalescedMemoryRange *cmr;

qemu_flush_coalesced_mmio_buffer();
mr->flush_coalesced_mmio = false;

while (!QTAILQ_EMPTY(&mr->coalesced)) {
cmr = QTAILQ_FIRST(&mr->coalesced);
QTAILQ_REMOVE(&mr->coalesced, cmr, link);
Expand All @@ -1190,6 +1201,19 @@ void memory_region_clear_coalescing(MemoryRegion *mr)
memory_region_update_coalesced_range(mr);
}

void memory_region_set_flush_coalesced(MemoryRegion *mr)
{
mr->flush_coalesced_mmio = true;
}

void memory_region_clear_flush_coalesced(MemoryRegion *mr)
{
qemu_flush_coalesced_mmio_buffer();
if (QTAILQ_EMPTY(&mr->coalesced)) {
mr->flush_coalesced_mmio = false;
}
}

void memory_region_add_eventfd(MemoryRegion *mr,
target_phys_addr_t addr,
unsigned size,
Expand Down
26 changes: 26 additions & 0 deletions memory.h
Expand Up @@ -133,6 +133,7 @@ struct MemoryRegion {
bool enabled;
bool rom_device;
bool warning_printed; /* For reservations */
bool flush_coalesced_mmio;
MemoryRegion *alias;
target_phys_addr_t alias_offset;
unsigned priority;
Expand Down Expand Up @@ -520,6 +521,31 @@ void memory_region_add_coalescing(MemoryRegion *mr,
*/
void memory_region_clear_coalescing(MemoryRegion *mr);

/**
* memory_region_set_flush_coalesced: Enforce memory coalescing flush before
* accesses.
*
* Ensure that pending coalesced MMIO request are flushed before the memory
* region is accessed. This property is automatically enabled for all regions
* passed to memory_region_set_coalescing() and memory_region_add_coalescing().
*
* @mr: the memory region to be updated.
*/
void memory_region_set_flush_coalesced(MemoryRegion *mr);

/**
* memory_region_clear_flush_coalesced: Disable memory coalescing flush before
* accesses.
*
* Clear the automatic coalesced MMIO flushing enabled via
* memory_region_set_flush_coalesced. Note that this service has no effect on
* memory regions that have MMIO coalescing enabled for themselves. For them,
* automatic flushing will stop once coalescing is disabled.
*
* @mr: the memory region to be updated.
*/
void memory_region_clear_flush_coalesced(MemoryRegion *mr);

/**
* memory_region_add_eventfd: Request an eventfd to be triggered when a word
* is written to a location.
Expand Down

0 comments on commit d410515

Please sign in to comment.