From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mailman by lists.gnu.org with tmda-scanned (Exim 4.43) id 1LQ2tl-0003Cn-14 for qemu-devel@nongnu.org; Thu, 22 Jan 2009 11:59:21 -0500 Received: from exim by lists.gnu.org with spam-scanned (Exim 4.43) id 1LQ2tk-0003CG-D0 for qemu-devel@nongnu.org; Thu, 22 Jan 2009 11:59:20 -0500 Received: from [199.232.76.173] (port=53701 helo=monty-python.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1LQ2tk-0003C7-8T for qemu-devel@nongnu.org; Thu, 22 Jan 2009 11:59:20 -0500 Received: from savannah.gnu.org ([199.232.41.3]:37256 helo=sv.gnu.org) by monty-python.gnu.org with esmtps (TLS-1.0:RSA_AES_256_CBC_SHA1:32) (Exim 4.60) (envelope-from ) id 1LQ2tj-000419-PD for qemu-devel@nongnu.org; Thu, 22 Jan 2009 11:59:19 -0500 Received: from cvs.savannah.gnu.org ([199.232.41.69]) by sv.gnu.org with esmtp (Exim 4.63) (envelope-from ) id 1LQ2tg-0003KV-Rn for qemu-devel@nongnu.org; Thu, 22 Jan 2009 16:59:16 +0000 Received: from aliguori by cvs.savannah.gnu.org with local (Exim 4.63) (envelope-from ) id 1LQ2tg-0003KR-Kd for qemu-devel@nongnu.org; Thu, 22 Jan 2009 16:59:16 +0000 MIME-Version: 1.0 Errors-To: aliguori Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit From: Anthony Liguori Message-Id: Date: Thu, 22 Jan 2009 16:59:16 +0000 Subject: [Qemu-devel] [6395] Add map client retry notification (Avi Kivity) Reply-To: qemu-devel@nongnu.org List-Id: qemu-devel.nongnu.org List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: qemu-devel@nongnu.org Revision: 6395 http://svn.sv.gnu.org/viewvc/?view=rev&root=qemu&revision=6395 Author: aliguori Date: 2009-01-22 16:59:16 +0000 (Thu, 22 Jan 2009) Log Message: ----------- 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 Signed-off-by: Anthony Liguori Modified Paths: -------------- trunk/cpu-all.h trunk/exec.c Modified: trunk/cpu-all.h =================================================================== --- trunk/cpu-all.h 2009-01-22 16:59:11 UTC (rev 6394) +++ trunk/cpu-all.h 2009-01-22 16:59:16 UTC (rev 6395) @@ -928,6 +928,8 @@ 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); Modified: trunk/exec.c =================================================================== --- trunk/exec.c 2009-01-22 16:59:11 UTC (rev 6394) +++ trunk/exec.c 2009-01-22 16:59:16 UTC (rev 6395) @@ -3053,10 +3053,49 @@ 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 @@ } qemu_free(bounce.buffer); bounce.buffer = NULL; + cpu_notify_map_clients(); } /* warning: addr must be aligned */