WARNING - OLD ARCHIVES

This is an archived copy of the Xen.org mailing list, which we have preserved to ensure that existing links to archives are not broken. The live archive, which contains the latest emails, can be found at http://lists.xen.org/
   
 
 
Xen 
 
Home Products Support Community News
 
   
 

xen-devel

[Xen-devel] [PATCH] minios: Fix lost events

To: xen-devel@xxxxxxxxxxxxxxxxxxx
Subject: [Xen-devel] [PATCH] minios: Fix lost events
From: Samuel Thibault <samuel.thibault@xxxxxxxxxxxxx>
Date: Mon, 17 Mar 2008 19:29:48 +0000
Delivery-date: Mon, 17 Mar 2008 12:31:01 -0700
Envelope-to: www-data@xxxxxxxxxxxxxxxxxx
List-help: <mailto:xen-devel-request@lists.xensource.com?subject=help>
List-id: Xen developer discussion <xen-devel.lists.xensource.com>
List-post: <mailto:xen-devel@lists.xensource.com>
List-subscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-devel>, <mailto:xen-devel-request@lists.xensource.com?subject=subscribe>
List-unsubscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-devel>, <mailto:xen-devel-request@lists.xensource.com?subject=unsubscribe>
Mail-followup-to: Samuel Thibault <samuel.thibault@xxxxxxxxxxxxx>, xen-devel@xxxxxxxxxxxxxxxxxxx
Sender: xen-devel-bounces@xxxxxxxxxxxxxxxxxxx
User-agent: Mutt/1.5.12-2006-07-14
minios: Fix lost events

evtchn_bind_interdomain used to clear any already pending event before
binding a handler, because else the handler may be called before it is
ready. That however leads to missed events, which I had to workaround
for the HVM case.

This changes the semantics of bind_evtchn, and thus of all the
event channel binding functions (bind_virq, evtchn_alloc_unbound,
evtchn_bind_interdomain) into not unmasking the event itself, hence
letting the caller initialize properly before unmasking the port (e.g.
record the port number in an appropriate place).

Signed-off-by: Samuel Thibault <samuel.thibault@xxxxxxxxxxxxx>

diff -r c149cedf76b9 -r d4b232bea2eb extras/mini-os/arch/ia64/time.c
--- a/extras/mini-os/arch/ia64/time.c   Tue Mar 11 17:47:01 2008 +0000
+++ b/extras/mini-os/arch/ia64/time.c   Mon Mar 17 19:23:10 2008 +0000
@@ -246,7 +246,7 @@ init_time(void)
 {
        uint64_t new;
        efi_time_t tm;
-       int err = 0;
+       evtchn_port_t port = 0;
 
        printk("Initialising time\n");
        calculate_frequencies();
@@ -267,11 +267,12 @@ init_time(void)
        } else
                printk("efi_get_time() failed\n");
 
-       err = bind_virq(VIRQ_ITC, timer_interrupt, NULL);
-       if (err == -1) {
-               printk("XEN timer request chn bind failed %i\n", err);
+       port = bind_virq(VIRQ_ITC, timer_interrupt, NULL);
+       if (port == -1) {
+               printk("XEN timer request chn bind failed %i\n", port);
                return;
        }
+        unmask_evtchn(port);
        itc_alt = ia64_get_itc();
        itc_at_boot = itc_alt;
        new = ia64_get_itc() + itm_val;
diff -r c149cedf76b9 -r d4b232bea2eb extras/mini-os/arch/x86/time.c
--- a/extras/mini-os/arch/x86/time.c    Tue Mar 11 17:47:01 2008 +0000
+++ b/extras/mini-os/arch/x86/time.c    Mon Mar 17 19:23:10 2008 +0000
@@ -222,6 +222,8 @@ static void timer_handler(evtchn_port_t 
 
 void init_time(void)
 {
+    evtchn_port_t port;
     printk("Initialising timer interface\n");
-    bind_virq(VIRQ_TIMER, &timer_handler, NULL);
+    port = bind_virq(VIRQ_TIMER, &timer_handler, NULL);
+    unmask_evtchn(port);
 }
diff -r c149cedf76b9 -r d4b232bea2eb extras/mini-os/blkfront.c
--- a/extras/mini-os/blkfront.c Tue Mar 11 17:47:01 2008 +0000
+++ b/extras/mini-os/blkfront.c Mon Mar 17 19:23:10 2008 +0000
@@ -43,7 +43,7 @@ struct blkfront_dev {
 
     struct blkif_front_ring ring;
     grant_ref_t ring_ref;
-    evtchn_port_t evtchn, local_port;
+    evtchn_port_t evtchn;
     blkif_vdev_t handle;
 
     char *nodename;
@@ -92,14 +92,9 @@ struct blkfront_dev *init_blkfront(char 
     dev = malloc(sizeof(*dev));
     dev->nodename = strdup(nodename);
 
-    evtchn_alloc_unbound_t op;
-    op.dom = DOMID_SELF;
     snprintf(path, sizeof(path), "%s/backend-id", nodename);
-    dev->dom = op.remote_dom = xenbus_read_integer(path); 
-    HYPERVISOR_event_channel_op(EVTCHNOP_alloc_unbound, &op);
-    clear_evtchn(op.port);        /* Without, handler gets invoked now! */
-    dev->local_port = bind_evtchn(op.port, blkfront_handler, dev);
-    dev->evtchn=op.port;
+    dev->dom = xenbus_read_integer(path); 
+    evtchn_alloc_unbound(dev->dom, blkfront_handler, dev, &dev->evtchn);
 
     s = (struct blkif_sring*) alloc_page();
     memset(s,0,PAGE_SIZE);
@@ -194,6 +189,7 @@ done:
         snprintf(path, sizeof(path), "%s/feature-flush-cache", dev->backend);
         dev->flush = xenbus_read_integer(path);
     }
+    unmask_evtchn(dev->evtchn);
 
     printk("%u sectors of %u bytes\n", dev->sectors, dev->sector_size);
     printk("**************************\n");
@@ -219,7 +215,7 @@ void shutdown_blkfront(struct blkfront_d
     err = xenbus_printf(XBT_NIL, nodename, "state", "%u", 6);
     xenbus_wait_for_value(path,"6");
 
-    unbind_evtchn(dev->local_port);
+    unbind_evtchn(dev->evtchn);
 
     free(nodename);
     free(dev->backend);
diff -r c149cedf76b9 -r d4b232bea2eb extras/mini-os/console/xencons_ring.c
--- a/extras/mini-os/console/xencons_ring.c     Tue Mar 11 17:47:01 2008 +0000
+++ b/extras/mini-os/console/xencons_ring.c     Mon Mar 17 19:23:10 2008 +0000
@@ -91,6 +91,7 @@ int xencons_ring_init(void)
                printk("XEN console request chn bind failed %i\n", err);
                return err;
        }
+        unmask_evtchn(start_info.console.domU.evtchn);
 
        /* In case we have in-flight data after save/restore... */
        notify_daemon();
diff -r c149cedf76b9 -r d4b232bea2eb extras/mini-os/events.c
--- a/extras/mini-os/events.c   Tue Mar 11 17:47:01 2008 +0000
+++ b/extras/mini-os/events.c   Mon Mar 17 19:23:10 2008 +0000
@@ -86,9 +86,6 @@ evtchn_port_t bind_evtchn(evtchn_port_t 
        ev_actions[port].data = data;
        wmb();
        ev_actions[port].handler = handler;
-
-       /* Finally unmask the port */
-       unmask_evtchn(port);
 
        return port;
 }
@@ -191,8 +188,7 @@ int evtchn_bind_interdomain(domid_t pal,
     if (err)
                return err;
     set_bit(op.local_port,bound_ports);
-       evtchn_port_t port = op.local_port;
-    clear_evtchn(port);              /* Without, handler gets invoked now! */
+    evtchn_port_t port = op.local_port;
     *local_port = bind_evtchn(port, handler, data);
     return err;
 }
diff -r c149cedf76b9 -r d4b232bea2eb extras/mini-os/fbfront.c
--- a/extras/mini-os/fbfront.c  Tue Mar 11 17:47:01 2008 +0000
+++ b/extras/mini-os/fbfront.c  Mon Mar 17 19:23:10 2008 +0000
@@ -26,7 +26,7 @@ struct kbdfront_dev {
     domid_t dom;
 
     struct xenkbd_page *page;
-    evtchn_port_t evtchn, local_port;
+    evtchn_port_t evtchn;
 
     char *nodename;
     char *backend;
@@ -68,14 +68,9 @@ struct kbdfront_dev *init_kbdfront(char 
     dev = malloc(sizeof(*dev));
     dev->nodename = strdup(nodename);
 
-    evtchn_alloc_unbound_t op;
-    op.dom = DOMID_SELF;
     snprintf(path, sizeof(path), "%s/backend-id", nodename);
-    dev->dom = op.remote_dom = xenbus_read_integer(path); 
-    HYPERVISOR_event_channel_op(EVTCHNOP_alloc_unbound, &op);
-    clear_evtchn(op.port);        /* Without, handler gets invoked now! */
-    dev->local_port = bind_evtchn(op.port, kbdfront_handler, dev);
-    dev->evtchn=op.port;
+    dev->dom = xenbus_read_integer(path); 
+    evtchn_alloc_unbound(dev->dom, kbdfront_handler, dev, &dev->evtchn);
 
     dev->page = s = (struct xenkbd_page*) alloc_page();
     memset(s,0,PAGE_SIZE);
@@ -151,6 +146,7 @@ done:
 
         err = xenbus_printf(XBT_NIL, nodename, "state", "%u", 4); /* connected 
*/
     }
+    unmask_evtchn(dev->evtchn);
 
     printk("************************** KBDFRONT\n");
 
@@ -208,7 +204,7 @@ void shutdown_kbdfront(struct kbdfront_d
     err = xenbus_printf(XBT_NIL, nodename, "state", "%u", 6);
     xenbus_wait_for_value(path,"6");
 
-    unbind_evtchn(dev->local_port);
+    unbind_evtchn(dev->evtchn);
 
     free_pages(dev->page,0);
     free(nodename);
@@ -241,7 +237,7 @@ struct fbfront_dev {
     domid_t dom;
 
     struct xenfb_page *page;
-    evtchn_port_t evtchn, local_port;
+    evtchn_port_t evtchn;
 
     char *nodename;
     char *backend;
@@ -282,14 +278,9 @@ struct fbfront_dev *init_fbfront(char *n
     dev = malloc(sizeof(*dev));
     dev->nodename = strdup(nodename);
 
-    evtchn_alloc_unbound_t op;
-    op.dom = DOMID_SELF;
     snprintf(path, sizeof(path), "%s/backend-id", nodename);
-    dev->dom = op.remote_dom = xenbus_read_integer(path); 
-    HYPERVISOR_event_channel_op(EVTCHNOP_alloc_unbound, &op);
-    clear_evtchn(op.port);        /* Without, handler gets invoked now! */
-    dev->local_port = bind_evtchn(op.port, fbfront_handler, dev);
-    dev->evtchn=op.port;
+    dev->dom = xenbus_read_integer(path); 
+    evtchn_alloc_unbound(dev->dom, fbfront_handler, dev, &dev->evtchn);
 
     dev->page = s = (struct xenfb_page*) alloc_page();
     memset(s,0,PAGE_SIZE);
@@ -399,6 +390,7 @@ done:
 
         err = xenbus_printf(XBT_NIL, nodename, "state", "%u", 4); /* connected 
*/
     }
+    unmask_evtchn(dev->evtchn);
 
     printk("************************** FBFRONT\n");
 
@@ -485,7 +477,7 @@ void shutdown_fbfront(struct fbfront_dev
     err = xenbus_printf(XBT_NIL, nodename, "state", "%u", 6);
     xenbus_wait_for_value(path,"6");
 
-    unbind_evtchn(dev->local_port);
+    unbind_evtchn(dev->evtchn);
 
     free_pages(dev->page,0);
     free(nodename);
diff -r c149cedf76b9 -r d4b232bea2eb extras/mini-os/fs-front.c
--- a/extras/mini-os/fs-front.c Tue Mar 11 17:47:01 2008 +0000
+++ b/extras/mini-os/fs-front.c Mon Mar 17 19:23:10 2008 +0000
@@ -943,6 +943,7 @@ static int init_fs_import(struct fs_impo
                                 //ANY_CPU, 
                                 import, 
                                 &import->local_port));
+    unmask_evtchn(import->local_port);
 
     
     self_id = get_self_id(); 
diff -r c149cedf76b9 -r d4b232bea2eb extras/mini-os/netfront.c
--- a/extras/mini-os/netfront.c Tue Mar 11 17:47:01 2008 +0000
+++ b/extras/mini-os/netfront.c Mon Mar 17 19:23:10 2008 +0000
@@ -48,7 +48,7 @@ struct netfront_dev {
     struct netif_rx_front_ring rx;
     grant_ref_t tx_ring_ref;
     grant_ref_t rx_ring_ref;
-    evtchn_port_t evtchn, local_port;
+    evtchn_port_t evtchn;
 
     char *nodename;
     char *backend;
@@ -301,19 +301,14 @@ struct netfront_dev *init_netfront(char 
         dev->rx_buffers[i].page = (char*)alloc_page();
     }
 
-    evtchn_alloc_unbound_t op;
-    op.dom = DOMID_SELF;
     snprintf(path, sizeof(path), "%s/backend-id", nodename);
-    dev->dom = op.remote_dom = xenbus_read_integer(path);
-    HYPERVISOR_event_channel_op(EVTCHNOP_alloc_unbound, &op);
-    clear_evtchn(op.port);        /* Without, handler gets invoked now! */
+    dev->dom = xenbus_read_integer(path);
 #ifdef HAVE_LIBC
     if (thenetif_rx == NETIF_SELECT_RX)
-       dev->local_port = bind_evtchn(op.port, netfront_select_handler, dev);
+        evtchn_alloc_unbound(dev->dom, netfront_select_handler, dev, 
&dev->evtchn);
     else
 #endif
-       dev->local_port = bind_evtchn(op.port, netfront_handler, dev);
-    dev->evtchn=op.port;
+        evtchn_alloc_unbound(dev->dom, netfront_handler, dev, &dev->evtchn);
 
     txs = (struct netif_tx_sring*) alloc_page();
     rxs = (struct netif_rx_sring *) alloc_page();
@@ -388,9 +383,9 @@ done:
     msg = xenbus_read(XBT_NIL, path, &mac);
 
     if ((dev->backend == NULL) || (mac == NULL)) {
-        struct evtchn_close op = { dev->local_port };
+        struct evtchn_close op = { dev->evtchn };
         printk("%s: backend/mac failed\n", __func__);
-        unbind_evtchn(dev->local_port);
+        unbind_evtchn(dev->evtchn);
         HYPERVISOR_event_channel_op(EVTCHNOP_close, &op);
         return NULL;
     }
@@ -412,6 +407,7 @@ done:
     printk("**************************\n");
 
     init_rx_buffers(dev);
+    unmask_evtchn(dev->evtchn);
 
         /* Special conversion specifier 'hh' needed for __ia64__. Without
            this mini-os panics with 'Unaligned reference'. */
@@ -460,7 +456,7 @@ void shutdown_netfront(struct netfront_d
     err = xenbus_printf(XBT_NIL, nodename, "state", "%u", 6);
     xenbus_wait_for_value(path,"6");
 
-    unbind_evtchn(dev->local_port);
+    unbind_evtchn(dev->evtchn);
 
     free(nodename);
     free(dev->backend);
diff -r c149cedf76b9 -r d4b232bea2eb extras/mini-os/xenbus/xenbus.c
--- a/extras/mini-os/xenbus/xenbus.c    Tue Mar 11 17:47:01 2008 +0000
+++ b/extras/mini-os/xenbus/xenbus.c    Mon Mar 17 19:23:10 2008 +0000
@@ -257,6 +257,7 @@ void init_xenbus(void)
     err = bind_evtchn(start_info.store_evtchn,
                      xenbus_evtchn_handler,
               NULL);
+    unmask_evtchn(start_info.store_evtchn);
     DEBUG("xenbus on irq %d\n", err);
 }
 
diff -r c149cedf76b9 -r d4b232bea2eb tools/libxc/xc_minios.c
--- a/tools/libxc/xc_minios.c   Tue Mar 11 17:47:01 2008 +0000
+++ b/tools/libxc/xc_minios.c   Mon Mar 17 19:23:10 2008 +0000
@@ -165,14 +165,6 @@ static int port_alloc(int xce_handle) {
     return i;
 }
 
-static void poke_port(int xce_handle, evtchn_port_t port)
-{
-    shared_info_t *s = HYPERVISOR_shared_info;
-    printk("poking port %d\n", port);
-    synch_set_bit(port, &s->evtchn_pending[0]);
-    xc_evtchn_unmask(xce_handle, port);
-}
-
 static void evtchn_handler(evtchn_port_t port, struct pt_regs *regs, void 
*data)
 {
     int xce_handle = (intptr_t) data;
@@ -211,6 +203,7 @@ evtchn_port_or_error_t xc_evtchn_bind_un
     }
     files[xce_handle].evtchn.ports[i].bound = 1;
     files[xce_handle].evtchn.ports[i].port = port;
+    unmask_evtchn(port);
     return port;
 }
 
@@ -235,9 +228,7 @@ evtchn_port_or_error_t xc_evtchn_bind_in
     }
     files[xce_handle].evtchn.ports[i].bound = 1;
     files[xce_handle].evtchn.ports[i].port = local_port;
-/* Poke port on start: HVM won't send an event for the very first request since
- * we were not ready yet */
-    poke_port(xce_handle, local_port);
+    unmask_evtchn(local_port);
     return local_port;
 }
 
@@ -275,6 +266,7 @@ evtchn_port_or_error_t xc_evtchn_bind_vi
     }
     files[xce_handle].evtchn.ports[i].bound = 1;
     files[xce_handle].evtchn.ports[i].port = port;
+    unmask_evtchn(port);
     return port;
 }
 

_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-devel

<Prev in Thread] Current Thread [Next in Thread>
  • [Xen-devel] [PATCH] minios: Fix lost events, Samuel Thibault <=