提交 a203ac70 编写于 作者: P Paolo Bonzini

memory: extract first iteration of address_space_read and address_space_write

We want to inline the case where there is only one iteration, because
then the compiler can also inline the memcpy.  As a start, extract
everything after the first address_space_translate call.
Signed-off-by: NPaolo Bonzini <pbonzini@redhat.com>
上级 eb7eeb88
...@@ -2468,22 +2468,19 @@ static bool prepare_mmio_access(MemoryRegion *mr) ...@@ -2468,22 +2468,19 @@ static bool prepare_mmio_access(MemoryRegion *mr)
return release_lock; return release_lock;
} }
MemTxResult address_space_write(AddressSpace *as, hwaddr addr, MemTxAttrs attrs, /* Called within RCU critical section. */
const uint8_t *buf, int len) static MemTxResult address_space_write_continue(AddressSpace *as, hwaddr addr,
MemTxAttrs attrs,
const uint8_t *buf,
int len, hwaddr addr1,
hwaddr l, MemoryRegion *mr)
{ {
hwaddr l;
uint8_t *ptr; uint8_t *ptr;
uint64_t val; uint64_t val;
hwaddr addr1;
MemoryRegion *mr;
MemTxResult result = MEMTX_OK; MemTxResult result = MEMTX_OK;
bool release_lock = false; bool release_lock = false;
rcu_read_lock(); for (;;) {
while (len > 0) {
l = len;
mr = address_space_translate(as, addr, &addr1, &l, true);
if (!memory_access_is_direct(mr, true)) { if (!memory_access_is_direct(mr, true)) {
release_lock |= prepare_mmio_access(mr); release_lock |= prepare_mmio_access(mr);
l = memory_access_size(mr, l, addr1); l = memory_access_size(mr, l, addr1);
...@@ -2533,28 +2530,50 @@ MemTxResult address_space_write(AddressSpace *as, hwaddr addr, MemTxAttrs attrs, ...@@ -2533,28 +2530,50 @@ MemTxResult address_space_write(AddressSpace *as, hwaddr addr, MemTxAttrs attrs,
len -= l; len -= l;
buf += l; buf += l;
addr += l; addr += l;
if (!len) {
break;
}
l = len;
mr = address_space_translate(as, addr, &addr1, &l, true);
} }
rcu_read_unlock();
return result; return result;
} }
MemTxResult address_space_read(AddressSpace *as, hwaddr addr, MemTxAttrs attrs, MemTxResult address_space_write(AddressSpace *as, hwaddr addr, MemTxAttrs attrs,
uint8_t *buf, int len) const uint8_t *buf, int len)
{ {
hwaddr l; hwaddr l;
uint8_t *ptr;
uint64_t val;
hwaddr addr1; hwaddr addr1;
MemoryRegion *mr; MemoryRegion *mr;
MemTxResult result = MEMTX_OK; MemTxResult result = MEMTX_OK;
bool release_lock = false;
rcu_read_lock(); if (len > 0) {
while (len > 0) { rcu_read_lock();
l = len; l = len;
mr = address_space_translate(as, addr, &addr1, &l, false); mr = address_space_translate(as, addr, &addr1, &l, true);
result = address_space_write_continue(as, addr, attrs, buf, len,
addr1, l, mr);
rcu_read_unlock();
}
return result;
}
/* Called within RCU critical section. */
MemTxResult address_space_read_continue(AddressSpace *as, hwaddr addr,
MemTxAttrs attrs, uint8_t *buf,
int len, hwaddr addr1, hwaddr l,
MemoryRegion *mr)
{
uint8_t *ptr;
uint64_t val;
MemTxResult result = MEMTX_OK;
bool release_lock = false;
for (;;) {
if (!memory_access_is_direct(mr, false)) { if (!memory_access_is_direct(mr, false)) {
/* I/O case */ /* I/O case */
release_lock |= prepare_mmio_access(mr); release_lock |= prepare_mmio_access(mr);
...@@ -2601,8 +2620,34 @@ MemTxResult address_space_read(AddressSpace *as, hwaddr addr, MemTxAttrs attrs, ...@@ -2601,8 +2620,34 @@ MemTxResult address_space_read(AddressSpace *as, hwaddr addr, MemTxAttrs attrs,
len -= l; len -= l;
buf += l; buf += l;
addr += l; addr += l;
if (!len) {
break;
}
l = len;
mr = address_space_translate(as, addr, &addr1, &l, false);
}
return result;
}
MemTxResult address_space_read(AddressSpace *as, hwaddr addr, MemTxAttrs attrs,
uint8_t *buf, int len)
{
hwaddr l;
hwaddr addr1;
MemoryRegion *mr;
MemTxResult result = MEMTX_OK;
if (len > 0) {
rcu_read_lock();
l = len;
mr = address_space_translate(as, addr, &addr1, &l, false);
result = address_space_read_continue(as, addr, attrs, buf, len,
addr1, l, mr);
rcu_read_unlock();
} }
rcu_read_unlock();
return result; return result;
} }
......
...@@ -1366,6 +1366,12 @@ void address_space_unmap(AddressSpace *as, void *buffer, hwaddr len, ...@@ -1366,6 +1366,12 @@ void address_space_unmap(AddressSpace *as, void *buffer, hwaddr len,
int is_write, hwaddr access_len); int is_write, hwaddr access_len);
/* Internal functions, part of the implementation of address_space_read. */
MemTxResult address_space_read_continue(AddressSpace *as, hwaddr addr,
MemTxAttrs attrs, uint8_t *buf,
int len, hwaddr addr1, hwaddr l,
MemoryRegion *mr);
#endif #endif
#endif #endif
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册