Add map client retry notification (Avi Kivity)

The target memory mapping API may fail if the bounce buffer resources
are exhausted.  Add a notification mechanism to allow clients to retry
the mapping operation when resources become available again.

Signed-off-by: Avi Kivity <avi@redhat.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>


git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@6395 c046a42c-6fe2-441c-8c8c-71466251a162
This commit is contained in:
aliguori 2009-01-22 16:59:16 +00:00
parent 6d16c2f88f
commit ba223c29da
2 changed files with 42 additions and 0 deletions

View File

@ -928,6 +928,8 @@ void *cpu_physical_memory_map(target_phys_addr_t addr,
int is_write);
void cpu_physical_memory_unmap(void *buffer, target_phys_addr_t len,
int is_write, target_phys_addr_t access_len);
void *cpu_register_map_client(void *opaque, void (*callback)(void *opaque));
void cpu_unregister_map_client(void *cookie);
uint32_t ldub_phys(target_phys_addr_t addr);
uint32_t lduw_phys(target_phys_addr_t addr);

40
exec.c
View File

@ -3053,10 +3053,49 @@ typedef struct {
static BounceBuffer bounce;
typedef struct MapClient {
void *opaque;
void (*callback)(void *opaque);
LIST_ENTRY(MapClient) link;
} MapClient;
static LIST_HEAD(map_client_list, MapClient) map_client_list
= LIST_HEAD_INITIALIZER(map_client_list);
void *cpu_register_map_client(void *opaque, void (*callback)(void *opaque))
{
MapClient *client = qemu_malloc(sizeof(*client));
client->opaque = opaque;
client->callback = callback;
LIST_INSERT_HEAD(&map_client_list, client, link);
return client;
}
void cpu_unregister_map_client(void *_client)
{
MapClient *client = (MapClient *)_client;
LIST_REMOVE(client, link);
}
static void cpu_notify_map_clients(void)
{
MapClient *client;
while (!LIST_EMPTY(&map_client_list)) {
client = LIST_FIRST(&map_client_list);
client->callback(client->opaque);
LIST_REMOVE(client, link);
}
}
/* Map a physical memory region into a host virtual address.
* May map a subset of the requested range, given by and returned in *plen.
* May return NULL if resources needed to perform the mapping are exhausted.
* Use only for reads OR writes - not for read-modify-write operations.
* Use cpu_register_map_client() to know when retrying the map operation is
* likely to succeed.
*/
void *cpu_physical_memory_map(target_phys_addr_t addr,
target_phys_addr_t *plen,
@ -3146,6 +3185,7 @@ void cpu_physical_memory_unmap(void *buffer, target_phys_addr_t len,
}
qemu_free(bounce.buffer);
bounce.buffer = NULL;
cpu_notify_map_clients();
}
/* warning: addr must be aligned */