[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

 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.