* [PATCH][12/17] USB virt 2.6 split driver---rbr mapper pool
@ 2005-11-21 13:19 harry
0 siblings, 0 replies; only message in thread
From: harry @ 2005-11-21 13:19 UTC (permalink / raw)
To: xen-devel
[-- Attachment #1: Type: text/plain, Size: 263 bytes --]
This patch implements the xenidc_rbr_mapper_pool which is a service for
mapping remote buffer references into the local address space for
interdomain bulk data transfer. This is used by the USB driver BE.
Signed-off-by: Harry Butterworth <butterwo@uk.ibm.com>
[-- Attachment #2: p12-rbr-mapper-pool.patch --]
[-- Type: text/x-patch, Size: 21991 bytes --]
diff -r d4ea70e2848e -r e4a76dd06289 linux-2.6-xen-sparse/drivers/xen/xenidc/Makefile
--- a/linux-2.6-xen-sparse/drivers/xen/xenidc/Makefile Mon Nov 21 11:04:23 2005
+++ b/linux-2.6-xen-sparse/drivers/xen/xenidc/Makefile Mon Nov 21 11:09:01 2005
@@ -17,3 +17,4 @@
xenidc-objs += xenidc_gateway_target_resource.o
xenidc-objs += xenidc_endpoint.o
xenidc-objs += xenidc_rbr_provider_pool.o
+xenidc-objs += xenidc_rbr_mapper_pool.o
diff -r d4ea70e2848e -r e4a76dd06289 linux-2.6-xen-sparse/include/asm-xen/xenidc_rbr_provider_pool.h
--- a/linux-2.6-xen-sparse/include/asm-xen/xenidc_rbr_provider_pool.h Mon Nov 21 11:04:23 2005
+++ b/linux-2.6-xen-sparse/include/asm-xen/xenidc_rbr_provider_pool.h Mon Nov 21 11:09:01 2005
@@ -57,6 +57,12 @@
XENIDC_LOCAL_BUFFER_REFERENCE_ACCESS_FLAGS_READ
#define XENIDC_CREATE_RBR_REQUEST_ELEMENT_ACCESS_FLAGS_WRITE \
XENIDC_LOCAL_BUFFER_REFERENCE_ACCESS_FLAGS_WRITE
+
+/* The client may create multiple remote buffer references with a single */
+/* request. This is required for the resource management strategy described */
+/* in the xenidc.h file. The parameters for each remote buffer reference */
+/* are passed using a xenidc_create_rbr_request_element structure. The */
+/* request has a list of these structures. */
/* The client may create multiple remote buffer references with a single */
/* request. This is required for the resource management strategy described */
diff -r d4ea70e2848e -r e4a76dd06289 linux-2.6-xen-sparse/drivers/xen/xenidc/xenidc_rbr_mapper_pool.c
--- /dev/null Mon Nov 21 11:04:23 2005
+++ b/linux-2.6-xen-sparse/drivers/xen/xenidc/xenidc_rbr_mapper_pool.c Mon Nov 21 11:09:01 2005
@@ -0,0 +1,370 @@
+/*****************************************************************************/
+/* Xen remote buffer reference mapper pool. */
+/* */
+/* Copyright (c) 2005 Harry Butterworth IBM Corporation */
+/* */
+/* This program is free software; you can redistribute it and/or modify it */
+/* under the terms of the GNU General Public License as published by the */
+/* Free Software Foundation; either version 2 of the License, or (at your */
+/* option) any later version. */
+/* */
+/* This program is distributed in the hope that it will be useful, but */
+/* WITHOUT ANY WARRANTY; without even the implied warranty of */
+/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General */
+/* Public License for more details. */
+/* */
+/* You should have received a copy of the GNU General Public License along */
+/* with this program; if not, write to the Free Software Foundation, Inc., */
+/* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+/* */
+/*****************************************************************************/
+
+#include <asm-xen/xenidc_rbr_mapper_pool.h>
+#include <linux/module.h>
+#include <linux/vmalloc.h>
+#include "xenidc_trace.h"
+
+static XENIDC_CALLBACK_SERIALISER(xenidc_rbr_mapper_pool_callback_serialiser);
+
+struct xenidc_rbr_mapper_pool_struct {
+ xenidc_buffer_resource_list anti_deadlock_resource_allocation;
+
+ xenidc_buffer_resource_provider *provider;
+
+ spinlock_t lock;
+
+ xenidc_buffer_resource_list head_request_required_resources;
+
+ struct list_head request_list;
+
+ int kicking_requests:1;
+ int head_request_required_resources_calculated:1;
+};
+
+static int xenidc_rbr_mapper_pool_init_or_exit
+ (xenidc_rbr_mapper_pool * pool, int exit) {
+ trace();
+
+ {
+ int return_value = 0;
+
+ if (exit) {
+ goto EXIT;
+ }
+
+ pool->provider = xenidc_allocate_buffer_resource_provider
+ (pool->anti_deadlock_resource_allocation);
+
+ if (pool->provider == NULL) {
+ goto EXIT_NO_PROVIDER;
+ }
+
+ spin_lock_init(&pool->lock);
+
+ INIT_LIST_HEAD(&pool->request_list);
+
+ pool->kicking_requests = 0;
+ pool->head_request_required_resources_calculated = 0;
+
+ return 0;
+
+ EXIT:
+
+ xenidc_free_buffer_resource_provider(pool->provider);
+
+ EXIT_NO_PROVIDER:
+
+ return return_value;
+ }
+}
+
+xenidc_rbr_mapper_pool *xenidc_allocate_rbr_mapper_pool
+ (xenidc_buffer_resource_list anti_deadlock_resource_allocation) {
+ trace();
+
+ {
+ xenidc_rbr_mapper_pool *pool = (xenidc_rbr_mapper_pool *)
+ vmalloc(sizeof(xenidc_rbr_mapper_pool));
+
+ if (pool != NULL) {
+ pool->anti_deadlock_resource_allocation =
+ anti_deadlock_resource_allocation;
+
+ if (xenidc_rbr_mapper_pool_init_or_exit(pool, 0) != 0) {
+ vfree(pool);
+
+ pool = NULL;
+ }
+ }
+
+ return pool;
+ }
+}
+
+void xenidc_free_rbr_mapper_pool(xenidc_rbr_mapper_pool * pool)
+{
+ trace();
+
+ (void)xenidc_rbr_mapper_pool_init_or_exit(pool, 1);
+
+ vfree(pool);
+}
+
+static void xenidc_rbr_mapper_pool_kick_requests(xenidc_rbr_mapper_pool * pool);
+
+void xenidc_rbr_mapper_pool_reserve_and_map_rbrs
+ (xenidc_rbr_mapper_pool * pool,
+ xenidc_reserve_and_map_rbr_request * request, xenidc_address address) {
+ trace();
+
+ /* MUST MAINTAIN RELATIVE REQUEST ORDER ON THE SUBMISSION PATH */
+
+ request->pool = pool;
+ request->address = address;
+
+ {
+ unsigned long flags;
+
+ spin_lock_irqsave(&pool->lock, flags);
+
+ list_add_tail
+ (xenidc_reserve_and_map_rbr_request_to_link(request),
+ &pool->request_list);
+
+ spin_unlock_irqrestore(&pool->lock, flags);
+ }
+
+ xenidc_rbr_mapper_pool_kick_requests(pool);
+}
+
+static int xenidc_rbr_mapper_pool_calculate_required_resources
+ (xenidc_reserve_and_map_rbr_request * request,
+ xenidc_buffer_resource_list * list) {
+ trace();
+
+ *list = xenidc_buffer_resource_list_null();
+
+ {
+ xenidc_map_rbr_request_element *element;
+
+ list_for_each_entry(element, &request->request_elements, link) {
+ xenidc_buffer_resource_list element_list;
+
+ if (xenidc_remote_buffer_reference_calculate_map_resources(&element->rbr, &request->address, &element_list)
+ != 0) {
+ return 1;
+ }
+
+ xenidc_buffer_resource_list_plus_equals(list,
+ &element_list);
+ }
+ }
+
+ return 0;
+}
+
+static void xenidc_rbr_mapper_pool_service_request
+ (xenidc_rbr_mapper_pool * pool,
+ xenidc_reserve_and_map_rbr_request * request) {
+ trace();
+
+ /* MUST MAINTAIN RELATIVE REQUEST ORDER ON THE SUBMISSION PATH */
+
+ {
+ int error = 0;
+
+ xenidc_map_rbr_request_element *element;
+
+ list_for_each_entry(element, &request->request_elements, link) {
+ if (!error) {
+ element->handle =
+ xenidc_remote_buffer_reference_map_rbr
+ (&element->rbr, &request->address,
+ pool->provider, &element->mapping,
+ element->access_flags);
+
+ if (element->handle == NULL) {
+ error = 1;
+ }
+ } else {
+ element->handle = NULL;
+ }
+ }
+
+ if (error) {
+ goto ERROR;
+ }
+ }
+
+ xenidc_callback_serialiser_complete_callback
+ (&xenidc_rbr_mapper_pool_callback_serialiser,
+ xenidc_reserve_and_map_rbr_request_to_map_callback(request),
+ XENIDC_ERROR_SUCCESS);
+
+ return;
+
+ ERROR:
+
+ {
+ xenidc_map_rbr_request_element *element;
+
+ list_for_each_entry(element, &request->request_elements, link) {
+ if (element->handle != NULL) {
+ xenidc_remote_buffer_reference_unmap_rbr
+ (element->handle);
+ }
+ }
+ }
+
+ xenidc_callback_serialiser_complete_callback
+ (&xenidc_rbr_mapper_pool_callback_serialiser,
+ xenidc_reserve_and_map_rbr_request_to_map_callback(request),
+ XENIDC_ERROR_INVALID_PARAMETER);
+}
+
+static void xenidc_rbr_mapper_pool_kick_requests(xenidc_rbr_mapper_pool * pool) {
+ trace();
+
+ /* MUST MAINTAIN RELATIVE REQUEST ORDER ON THE SUBMISSION PATH */
+
+ {
+ unsigned long flags;
+
+ spin_lock_irqsave(&pool->lock, flags);
+
+ while ((!pool->kicking_requests)
+ && (!list_empty(&pool->request_list))
+ ) {
+ xenidc_reserve_and_map_rbr_request *request =
+ xenidc_reserve_and_map_rbr_request_link_to
+ (pool->request_list.next);
+
+ if (!pool->head_request_required_resources_calculated) {
+ if ((xenidc_rbr_mapper_pool_calculate_required_resources(request, &pool->head_request_required_resources)
+ != 0)
+ ||
+ (!xenidc_buffer_resource_list_subset_of
+ (&pool->head_request_required_resources,
+ &pool->anti_deadlock_resource_allocation)
+ )
+ ) {
+ list_del_init
+ (xenidc_reserve_and_map_rbr_request_to_link
+ (request)
+ );
+
+ xenidc_callback_serialiser_complete_callback
+ (&xenidc_rbr_mapper_pool_callback_serialiser,
+ xenidc_reserve_and_map_rbr_request_to_map_callback
+ (request), XENIDC_ERROR_TOO_BIG);
+
+ continue;
+ }
+
+ pool->
+ head_request_required_resources_calculated =
+ 1;
+ }
+
+ {
+ xenidc_buffer_resource_list free_resources =
+ xenidc_buffer_resource_provider_query_free_resources
+ (pool->provider);
+
+ if (!xenidc_buffer_resource_list_subset_of
+ (&pool->head_request_required_resources,
+ &free_resources)
+ ) {
+ break;
+ }
+ }
+
+ list_del_init
+ (xenidc_reserve_and_map_rbr_request_to_link
+ (request));
+
+ pool->head_request_required_resources_calculated = 0;
+
+ pool->kicking_requests = 1;
+
+ spin_unlock_irqrestore(&pool->lock, flags);
+
+ xenidc_rbr_mapper_pool_service_request(pool, request);
+
+ spin_lock_irqsave(&pool->lock, flags);
+
+ pool->kicking_requests = 0;
+ }
+
+ spin_unlock_irqrestore(&pool->lock, flags);
+ }
+}
+
+void xenidc_rbr_mapper_pool_abort_reserve_and_map_rbrs
+ (xenidc_reserve_and_map_rbr_request * request, xenidc_error error) {
+ trace();
+
+ {
+ xenidc_rbr_mapper_pool *pool = request->pool;
+
+ unsigned long flags;
+
+ spin_lock_irqsave(&pool->lock, flags);
+
+ {
+ xenidc_reserve_and_map_rbr_request *queued_request;
+
+ list_for_each_entry
+ (queued_request,
+ &pool->request_list,
+ XENIDC_RESERVE_AND_MAP_RBR_REQUEST_LINK) {
+ if (request == queued_request) {
+ list_del_init
+ (xenidc_reserve_and_map_rbr_request_to_link
+ (request)
+ );
+
+ pool->
+ head_request_required_resources_calculated
+ = 0;
+
+ xenidc_callback_serialiser_complete_callback
+ (&xenidc_rbr_mapper_pool_callback_serialiser,
+ xenidc_reserve_and_map_rbr_request_to_map_callback
+ (request), error);
+
+ break;
+ }
+ }
+ }
+
+ spin_unlock_irqrestore(&pool->lock, flags);
+ }
+}
+
+void xenidc_rbr_mapper_pool_unmap_and_unreserve_rbrs
+ (xenidc_reserve_and_map_rbr_request * request) {
+ trace();
+
+ {
+ xenidc_map_rbr_request_element *element;
+
+ list_for_each_entry(element, &request->request_elements, link) {
+ xenidc_remote_buffer_reference_unmap_rbr(element->
+ handle);
+ }
+ }
+
+ xenidc_rbr_mapper_pool_kick_requests(request->pool);
+
+ xenidc_callback_serialiser_complete_callback
+ (&xenidc_rbr_mapper_pool_callback_serialiser,
+ xenidc_reserve_and_map_rbr_request_to_unmap_callback(request),
+ XENIDC_ERROR_SUCCESS);
+}
+
+EXPORT_SYMBOL(xenidc_allocate_rbr_mapper_pool);
+EXPORT_SYMBOL(xenidc_free_rbr_mapper_pool);
+EXPORT_SYMBOL(xenidc_rbr_mapper_pool_reserve_and_map_rbrs);
+EXPORT_SYMBOL(xenidc_rbr_mapper_pool_abort_reserve_and_map_rbrs);
+EXPORT_SYMBOL(xenidc_rbr_mapper_pool_unmap_and_unreserve_rbrs);
diff -r d4ea70e2848e -r e4a76dd06289 linux-2.6-xen-sparse/include/asm-xen/xenidc_rbr_mapper_pool.h
--- /dev/null Mon Nov 21 11:04:23 2005
+++ b/linux-2.6-xen-sparse/include/asm-xen/xenidc_rbr_mapper_pool.h Mon Nov 21 11:09:01 2005
@@ -0,0 +1,213 @@
+/*****************************************************************************/
+/* Xen inter-domain communication remote buffer reference mapper pool. This */
+/* provides a service used by clients to map buffers referenced by remote */
+/* buffer references into the local address space. */
+/* */
+/* Copyright (c) 2005 Harry Butterworth IBM Corporation */
+/* */
+/* This program is free software; you can redistribute it and/or modify it */
+/* under the terms of the GNU General Public License as published by the */
+/* Free Software Foundation; either version 2 of the License, or (at your */
+/* option) any later version. */
+/* */
+/* This program is distributed in the hope that it will be useful, but */
+/* WITHOUT ANY WARRANTY; without even the implied warranty of */
+/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General */
+/* Public License for more details. */
+/* */
+/* You should have received a copy of the GNU General Public License along */
+/* with this program; if not, write to the Free Software Foundation, Inc., */
+/* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+/* */
+/*****************************************************************************/
+
+#ifndef __ASM_XEN_XENIDC_RBR_MAPPER_POOL_H__
+#define __ASM_XEN_XENIDC_RBR_MAPPER_POOL_H__
+
+#include "xenidc_callback.h"
+#include "xenidc_remote_buffer_reference.h"
+
+/* The client uses a xenidc_rbr_mapper_pool to map buffers referenced by */
+/* remote buffer references into the local address space. */
+
+typedef struct xenidc_rbr_mapper_pool_struct xenidc_rbr_mapper_pool;
+
+/* The client uses xenidc_allocate_rbr_mapper_pool to allocate a */
+/* xenidc_rbr_mapper_pool and its minimum resource allocation. This function */
+/* returns NULL if the pool cannot be allocated or the anti-deadlock */
+/* allocation fails. */
+
+extern xenidc_rbr_mapper_pool *xenidc_allocate_rbr_mapper_pool
+ (xenidc_buffer_resource_list anti_deadlock_resource_allocation);
+
+/* The client calls xenidc_free_rbr_mapper_pool to free the pool and the */
+/* pools resource allocation. The client must quiesce all use of the pool */
+/* before attempting to free it. */
+
+extern void xenidc_free_rbr_mapper_pool(xenidc_rbr_mapper_pool * pool);
+
+/* The client may request read or write or read write access to buffers when */
+/* mapping them. The requested access must be a subset of the access */
+/* granted by the owner of the buffer for mapping to be sucessful. */
+
+#define XENIDC_MAP_RBR_REQUEST_ELEMENT_ACCESS_FLAGS_READ \
+XENIDC_REMOTE_BUFFER_REFERENCE_ACCESS_FLAGS_READ
+#define XENIDC_MAP_RBR_REQUEST_ELEMENT_ACCESS_FLAGS_WRITE \
+XENIDC_REMOTE_BUFFER_REFERENCE_ACCESS_FLAGS_WRITE
+
+/* Requests to map buffers consist of a list of elements, one for each */
+/* buffer to be mapped. This is necessary for the resource management */
+/* strategy described in the xenidc.h header file. */
+
+typedef struct xenidc_map_rbr_request_element_struct
+ xenidc_map_rbr_request_element;
+
+/* The client is responsible for allocating the request elements. */
+
+struct xenidc_map_rbr_request_element_struct {
+ struct list_head link;
+ xenidc_remote_buffer_reference rbr;
+ int access_flags;
+ void *mapping;
+ xenidc_buffer_mappable_class **handle;
+};
+
+/* The client must initialise the request element before first use. */
+
+static inline void xenidc_map_rbr_request_element_init
+ (xenidc_map_rbr_request_element * element) {
+ memset(element, 0, sizeof(*element));
+
+ INIT_LIST_HEAD(&element->link);
+}
+
+/* The client sets a remote buffer reference in the element. This */
+/* references a buffer to be mapped when the request is submitted. */
+
+static inline void xenidc_map_rbr_request_element_set_rbr
+ (xenidc_map_rbr_request_element * element,
+ xenidc_remote_buffer_reference rbr, int access_flags) {
+ element->rbr = rbr;
+ element->access_flags = access_flags;
+}
+
+/* Request elements are added to a list in the request. */
+/* xenidc_map_rbr_request_element_ensure_removed may be called after the */
+/* element is initialised to ensure that the element is no longer present on */
+/* a request list. */
+
+static inline void xenidc_map_rbr_request_element_ensure_removed
+ (xenidc_map_rbr_request_element * element) {
+ list_del_init(&element->link);
+}
+
+/* The client is responsible for allocating the request. */
+
+typedef struct xenidc_reserve_and_map_rbr_request_struct
+ xenidc_reserve_and_map_rbr_request;
+
+struct xenidc_reserve_and_map_rbr_request_struct {
+ xenidc_callback map_callback;
+ xenidc_callback unmap_callback;
+ xenidc_rbr_mapper_pool *pool;
+ xenidc_address address;
+ struct list_head request_elements;
+};
+
+/* The request contains two callbacks, the map callback is for the */
+/* completion of the map operation; the unmap callback is for the completion */
+/* of the unmap operation. The callbacks contain links which are for use by */
+/* the current owner of the request. */
+
+#define XENIDC_RESERVE_AND_MAP_RBR_REQUEST_LINK \
+map_callback.XENIDC_CALLBACK_LINK
+
+static inline xenidc_callback
+ *xenidc_reserve_and_map_rbr_request_to_map_callback
+ (xenidc_reserve_and_map_rbr_request * request) {
+ return &request->map_callback;
+}
+
+static inline xenidc_reserve_and_map_rbr_request
+ *xenidc_reserve_and_map_rbr_request_map_callback_to(xenidc_callback *
+ callback) {
+ return container_of(callback, xenidc_reserve_and_map_rbr_request,
+ map_callback);
+}
+
+static inline xenidc_callback
+ *xenidc_reserve_and_map_rbr_request_to_unmap_callback
+ (xenidc_reserve_and_map_rbr_request * request) {
+ return &request->unmap_callback;
+}
+
+static inline xenidc_reserve_and_map_rbr_request
+ *xenidc_reserve_and_map_rbr_request_unmap_callback_to(xenidc_callback *
+ callback) {
+ return container_of(callback, xenidc_reserve_and_map_rbr_request,
+ unmap_callback);
+}
+
+static inline struct list_head *xenidc_reserve_and_map_rbr_request_to_link
+ (xenidc_reserve_and_map_rbr_request * request) {
+ return xenidc_callback_to_link
+ (xenidc_reserve_and_map_rbr_request_to_map_callback(request));
+}
+
+static inline xenidc_reserve_and_map_rbr_request
+ *xenidc_reserve_and_map_rbr_request_link_to(struct list_head *link)
+{
+ return xenidc_reserve_and_map_rbr_request_map_callback_to
+ (xenidc_callback_link_to(link));
+}
+
+/* The client initialises the request with callback functions for the map */
+/* and unmap callbacks. */
+
+static inline void xenidc_reserve_and_map_rbr_request_init
+ (xenidc_reserve_and_map_rbr_request * request,
+ xenidc_callback_function * map_callback,
+ xenidc_callback_function * unmap_callback) {
+ xenidc_callback_init(&request->map_callback, map_callback);
+ xenidc_callback_init(&request->unmap_callback, unmap_callback);
+
+ INIT_LIST_HEAD(&request->request_elements);
+}
+
+/* The client adds elements to the request before submitting it and may only */
+/* remove elements after completion of the unmap callback or a sucessful */
+/* abort. */
+
+static inline void xenidc_reserve_and_map_rbr_request_add_element
+ (xenidc_reserve_and_map_rbr_request * request,
+ xenidc_map_rbr_request_element * element) {
+ list_add(&element->link, &request->request_elements);
+}
+
+/* The client calls xenidc_rbr_mapper_pool_reserve_and_map_rbrs to reserve */
+/* the resources and map the remote buffer references of the element list. */
+/* The map callback is completed when the mapping has been performed or if */
+/* it fails. Check the map callback's error value to see if the mapping was */
+/* successful. */
+
+extern void xenidc_rbr_mapper_pool_reserve_and_map_rbrs
+ (xenidc_rbr_mapper_pool * pool,
+ xenidc_reserve_and_map_rbr_request * request, xenidc_address address);
+
+/* The client calls xenidc_rbr_mapper_pool_abort_reserve_and_map_rbrs to */
+/* abort an outstanding map request. After abort call, the request will */
+/* either complete successfully (completion may have already been scheduled) */
+/* or will complete with the provided error value after having been aborted. */
+
+extern void xenidc_rbr_mapper_pool_abort_reserve_and_map_rbrs
+ (xenidc_reserve_and_map_rbr_request * request, xenidc_error error);
+
+/* The client calls xenidc_rbr_mapper_pool_unmap_and_unreserve_rbrs to unmap */
+/* the buffers and free and unreserve the resources used by the map call. */
+/* The client should only call thsi function when the map operation was */
+/* successful; not if it failed or was successfully aborted. */
+
+extern void xenidc_rbr_mapper_pool_unmap_and_unreserve_rbrs
+ (xenidc_reserve_and_map_rbr_request * request);
+
+#endif
[-- Attachment #3: Type: text/plain, Size: 138 bytes --]
_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xensource.com
http://lists.xensource.com/xen-devel
^ permalink raw reply [flat|nested] only message in thread
only message in thread, other threads:[~2005-11-21 13:19 UTC | newest]
Thread overview: (only message) (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2005-11-21 13:19 [PATCH][12/17] USB virt 2.6 split driver---rbr mapper pool harry
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.