mirror of
https://github.com/Motorhead1991/qemu.git
synced 2025-08-01 23:03:54 -06:00
cputlb: Merge and move memory_notdirty_write_{prepare,complete}
Since 9458a9a1df
, all readers of the dirty bitmaps wait
for the rcu lock, which means that they wait until the end
of any executing TranslationBlock.
As a consequence, there is no need for the actual access
to happen in between the _prepare and _complete. Therefore,
we can improve things by merging the two functions into
notdirty_write and dropping the NotDirtyInfo structure.
In addition, the only users of notdirty_write are in cputlb.c,
so move the merged function there. Pass in the CPUIOTLBEntry
from which the ram_addr_t may be computed.
Reviewed-by: David Hildenbrand <david@redhat.com>
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
This commit is contained in:
parent
8f5db64153
commit
707526ad86
3 changed files with 42 additions and 143 deletions
|
@ -49,70 +49,5 @@ void address_space_dispatch_free(AddressSpaceDispatch *d);
|
|||
|
||||
void mtree_print_dispatch(struct AddressSpaceDispatch *d,
|
||||
MemoryRegion *root);
|
||||
|
||||
struct page_collection;
|
||||
|
||||
/* Opaque struct for passing info from memory_notdirty_write_prepare()
|
||||
* to memory_notdirty_write_complete(). Callers should treat all fields
|
||||
* as private, with the exception of @active.
|
||||
*
|
||||
* @active is a field which is not touched by either the prepare or
|
||||
* complete functions, but which the caller can use if it wishes to
|
||||
* track whether it has called prepare for this struct and so needs
|
||||
* to later call the complete function.
|
||||
*/
|
||||
typedef struct {
|
||||
CPUState *cpu;
|
||||
struct page_collection *pages;
|
||||
ram_addr_t ram_addr;
|
||||
vaddr mem_vaddr;
|
||||
unsigned size;
|
||||
bool active;
|
||||
} NotDirtyInfo;
|
||||
|
||||
/**
|
||||
* memory_notdirty_write_prepare: call before writing to non-dirty memory
|
||||
* @ndi: pointer to opaque NotDirtyInfo struct
|
||||
* @cpu: CPU doing the write
|
||||
* @mem_vaddr: virtual address of write
|
||||
* @ram_addr: the ram address of the write
|
||||
* @size: size of write in bytes
|
||||
*
|
||||
* Any code which writes to the host memory corresponding to
|
||||
* guest RAM which has been marked as NOTDIRTY must wrap those
|
||||
* writes in calls to memory_notdirty_write_prepare() and
|
||||
* memory_notdirty_write_complete():
|
||||
*
|
||||
* NotDirtyInfo ndi;
|
||||
* memory_notdirty_write_prepare(&ndi, ....);
|
||||
* ... perform write here ...
|
||||
* memory_notdirty_write_complete(&ndi);
|
||||
*
|
||||
* These calls will ensure that we flush any TCG translated code for
|
||||
* the memory being written, update the dirty bits and (if possible)
|
||||
* remove the slowpath callback for writing to the memory.
|
||||
*
|
||||
* This must only be called if we are using TCG; it will assert otherwise.
|
||||
*
|
||||
* We may take locks in the prepare call, so callers must ensure that
|
||||
* they don't exit (via longjump or otherwise) without calling complete.
|
||||
*
|
||||
* This call must only be made inside an RCU critical section.
|
||||
* (Note that while we're executing a TCG TB we're always in an
|
||||
* RCU critical section, which is likely to be the case for callers
|
||||
* of these functions.)
|
||||
*/
|
||||
void memory_notdirty_write_prepare(NotDirtyInfo *ndi,
|
||||
CPUState *cpu,
|
||||
vaddr mem_vaddr,
|
||||
ram_addr_t ram_addr,
|
||||
unsigned size);
|
||||
/**
|
||||
* memory_notdirty_write_complete: finish write to non-dirty memory
|
||||
* @ndi: pointer to the opaque NotDirtyInfo struct which was initialized
|
||||
* by memory_not_dirty_write_prepare().
|
||||
*/
|
||||
void memory_notdirty_write_complete(NotDirtyInfo *ndi);
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue