[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-devel] [PATCH 24/24] [xen-unstable.hg] remove arbitrary limit in minios on number of event channels it can use
Changes the minios evtchn implementation to use a list instead of an array. This allows it to grow as necessary to support any number of ports. Unfortunately, it's still limited by NR_EVS in events.c. Signed-off-by: Diego Ongaro <diego.ongaro@xxxxxxxxxx> Signed-off-by: Alex Zeffertt <alex.zeffertt@xxxxxxxxxxxxx> --- diff -r 62b77e8a4dda extras/mini-os/include/lib.h --- a/extras/mini-os/include/lib.h Wed Mar 18 17:17:12 2009 +0000 +++ b/extras/mini-os/include/lib.h Wed Mar 18 17:22:52 2009 +0000 @@ -60,6 +60,7 @@ #include <xen/xen.h> #include <xen/event_channel.h> #include "gntmap.h" +#include "list.h" #ifdef HAVE_LIBC #include <stdio.h> @@ -147,7 +148,12 @@ FTYPE_FB, }; -#define MAX_EVTCHN_PORTS 16 +struct evtchn_port_info { + struct minios_list_head list; + evtchn_port_t port; + unsigned long pending; + int bound; +}; extern struct file { enum fd_type type; @@ -162,13 +168,7 @@ off_t offset; } file; struct { - /* To each event channel FD is associated a series of ports which - * wakes select for this FD. */ - struct { - evtchn_port_t port; - unsigned long pending; - int bound; - } ports[MAX_EVTCHN_PORTS]; + struct minios_list_head ports; } evtchn; struct gntmap gntmap; struct { diff -r 62b77e8a4dda tools/libxc/xc_minios.c --- a/tools/libxc/xc_minios.c Wed Mar 18 17:17:12 2009 +0000 +++ b/tools/libxc/xc_minios.c Wed Mar 18 17:22:52 2009 +0000 @@ -134,23 +134,41 @@ do_exit(); } +/* XXX Note: This is not threadsafe */ +static struct evtchn_port_info* port_alloc(int xce_handle) { + struct evtchn_port_info *port_info; + port_info = malloc(sizeof(struct evtchn_port_info)); + if (port_info == NULL) + return NULL; + port_info->pending = 0; + port_info->port = -1; + port_info->bound = 0; + + minios_list_add(&port_info->list, &files[xce_handle].evtchn.ports); + return port_info; +} + +static void port_dealloc(struct evtchn_port_info *port_info) { + if (port_info->bound) + unbind_evtchn(port_info->port); + minios_list_del(&port_info->list); + free(port_info); +} + int xc_evtchn_open(void) { - int fd = alloc_fd(FTYPE_EVTCHN), i; - for (i = 0; i < MAX_EVTCHN_PORTS; i++) { - files[fd].evtchn.ports[i].port = -1; - files[fd].evtchn.ports[i].bound = 0; - } + int fd = alloc_fd(FTYPE_EVTCHN); + MINIOS_INIT_LIST_HEAD(&files[fd].evtchn.ports); printf("evtchn_open() -> %d\n", fd); return fd; } int xc_evtchn_close(int xce_handle) { - int i; - for (i = 0; i < MAX_EVTCHN_PORTS; i++) - if (files[xce_handle].evtchn.ports[i].bound) - unbind_evtchn(files[xce_handle].evtchn.ports[i].port); + struct evtchn_port_info *port_info, *tmp; + minios_list_for_each_entry_safe(port_info, tmp, &files[xce_handle].evtchn.ports, list) + port_dealloc(port_info); + files[xce_handle].type = FTYPE_NONE; return 0; } @@ -173,47 +191,34 @@ return ret; } -/* XXX Note: This is not threadsafe */ -static int port_alloc(int xce_handle) { - int i; - for (i= 0; i < MAX_EVTCHN_PORTS; i++) - if (files[xce_handle].evtchn.ports[i].port == -1) - break; - if (i == MAX_EVTCHN_PORTS) { - printf("Too many ports in xc handle\n"); - errno = EMFILE; - return -1; - } - files[xce_handle].evtchn.ports[i].pending = 0; - return i; -} - static void evtchn_handler(evtchn_port_t port, struct pt_regs *regs, void *data) { int xce_handle = (intptr_t) data; - int i; + struct evtchn_port_info *port_info; assert(files[xce_handle].type == FTYPE_EVTCHN); mask_evtchn(port); - for (i= 0; i < MAX_EVTCHN_PORTS; i++) - if (files[xce_handle].evtchn.ports[i].port == port) - break; - if (i == MAX_EVTCHN_PORTS) { - printk("Unknown port for handle %d\n", xce_handle); - return; + minios_list_for_each_entry(port_info, &files[xce_handle].evtchn.ports, list) { + if (port_info->port == port) + goto found; } - files[xce_handle].evtchn.ports[i].pending = 1; + printk("Unknown port for handle %d\n", xce_handle); + return; + +found: + port_info->pending = 1; files[xce_handle].read = 1; wake_up(&event_queue); } evtchn_port_or_error_t xc_evtchn_bind_unbound_port(int xce_handle, int domid) { - int ret, i; + struct evtchn_port_info *port_info; + int ret; evtchn_port_t port; assert(get_current() == main_thread); - i = port_alloc(xce_handle); - if (i == -1) + port_info = port_alloc(xce_handle); + if (port_info == NULL) return -1; printf("xc_evtchn_bind_unbound_port(%d)", domid); @@ -221,11 +226,12 @@ printf(" = %d\n", ret); if (ret < 0) { + port_dealloc(port_info); errno = -ret; return -1; } - files[xce_handle].evtchn.ports[i].bound = 1; - files[xce_handle].evtchn.ports[i].port = port; + port_info->bound = 1; + port_info->port = port; unmask_evtchn(port); return port; } @@ -233,12 +239,13 @@ evtchn_port_or_error_t xc_evtchn_bind_interdomain(int xce_handle, int domid, evtchn_port_t remote_port) { + struct evtchn_port_info *port_info; evtchn_port_t local_port; - int ret, i; + int ret; assert(get_current() == main_thread); - i = port_alloc(xce_handle); - if (i == -1) + port_info = port_alloc(xce_handle); + if (port_info == NULL) return -1; printf("xc_evtchn_bind_interdomain(%d, %"PRId32")", domid, remote_port); @@ -246,70 +253,69 @@ printf(" = %d\n", ret); if (ret < 0) { + port_dealloc(port_info); errno = -ret; return -1; } - files[xce_handle].evtchn.ports[i].bound = 1; - files[xce_handle].evtchn.ports[i].port = local_port; + port_info->bound = 1; + port_info->port = local_port; unmask_evtchn(local_port); return local_port; } int xc_evtchn_unbind(int xce_handle, evtchn_port_t port) { - int i; - for (i = 0; i < MAX_EVTCHN_PORTS; i++) - if (files[xce_handle].evtchn.ports[i].port == port) { - files[xce_handle].evtchn.ports[i].port = -1; - break; - } - if (i == MAX_EVTCHN_PORTS) { - printf("Warning: couldn't find port %"PRId32" for xc handle %x\n", port, xce_handle); - errno = -EINVAL; - return -1; + struct evtchn_port_info *port_info; + + minios_list_for_each_entry(port_info, &files[xce_handle].evtchn.ports, list) { + if (port_info->port == port) { + port_dealloc(port_info); + return 0; + } } - files[xce_handle].evtchn.ports[i].bound = 0; - unbind_evtchn(port); - return 0; + printf("Warning: couldn't find port %"PRId32" for xc handle %x\n", port, xce_handle); + errno = -EINVAL; + return -1; } evtchn_port_or_error_t xc_evtchn_bind_virq(int xce_handle, unsigned int virq) { + struct evtchn_port_info *port_info; evtchn_port_t port; - int i; assert(get_current() == main_thread); - i = port_alloc(xce_handle); - if (i == -1) + port_info = port_alloc(xce_handle); + if (port_info == NULL) return -1; printf("xc_evtchn_bind_virq(%d)", virq); port = bind_virq(virq, evtchn_handler, (void*)(intptr_t)xce_handle); if (port < 0) { + port_dealloc(port_info); errno = -port; return -1; } - files[xce_handle].evtchn.ports[i].bound = 1; - files[xce_handle].evtchn.ports[i].port = port; + port_info->bound = 1; + port_info->port = port; unmask_evtchn(port); return port; } evtchn_port_or_error_t xc_evtchn_pending(int xce_handle) { - int i; + struct evtchn_port_info *port_info; unsigned long flags; evtchn_port_t ret = -1; local_irq_save(flags); files[xce_handle].read = 0; - for (i = 0; i < MAX_EVTCHN_PORTS; i++) { - evtchn_port_t port = files[xce_handle].evtchn.ports[i].port; - if (port != -1 && files[xce_handle].evtchn.ports[i].pending) { + + minios_list_for_each_entry(port_info, &files[xce_handle].evtchn.ports, list) { + if (port_info->port != -1 && port_info->pending) { if (ret == -1) { - ret = port; - files[xce_handle].evtchn.ports[i].pending = 0; + ret = port_info->port; + port_info->pending = 0; } else { files[xce_handle].read = 1; break; _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxxxxxxxx http://lists.xensource.com/xen-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |