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-changelog

[Xen-changelog] [xen-unstable] minios: Fix lost events

To: xen-changelog@xxxxxxxxxxxxxxxxxxx
Subject: [Xen-changelog] [xen-unstable] minios: Fix lost events
From: Xen patchbot-unstable <patchbot-unstable@xxxxxxxxxxxxxxxxxxx>
Date: Thu, 20 Mar 2008 05:40:33 -0700
Delivery-date: Thu, 20 Mar 2008 05:42:38 -0700
Envelope-to: www-data@xxxxxxxxxxxxxxxxxx
List-help: <mailto:xen-changelog-request@lists.xensource.com?subject=help>
List-id: BK change log <xen-changelog.lists.xensource.com>
List-post: <mailto:xen-changelog@lists.xensource.com>
List-subscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=subscribe>
List-unsubscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=unsubscribe>
Reply-to: xen-devel@xxxxxxxxxxxxxxxxxxx
Sender: xen-changelog-bounces@xxxxxxxxxxxxxxxxxxx
# HG changeset patch
# User Keir Fraser <keir.fraser@xxxxxxxxxx>
# Date 1205839758 0
# Node ID ea5ee63548e4eb8ad0d1e8bd744727569e48d19b
# Parent  b543b4b759ba87289105e99559425272edfb5b40
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>
---
 extras/mini-os/arch/ia64/time.c       |    9 +++++----
 extras/mini-os/arch/x86/time.c        |    6 ++++--
 extras/mini-os/blkfront.c             |   14 +++++---------
 extras/mini-os/console/xencons_ring.c |    1 +
 extras/mini-os/events.c               |    6 +-----
 extras/mini-os/fbfront.c              |   28 ++++++++++------------------
 extras/mini-os/fs-front.c             |    1 +
 extras/mini-os/netfront.c             |   20 ++++++++------------
 extras/mini-os/xenbus/xenbus.c        |    1 +
 tools/libxc/xc_minios.c               |   14 +++-----------
 10 files changed, 39 insertions(+), 61 deletions(-)

diff -r b543b4b759ba -r ea5ee63548e4 extras/mini-os/arch/ia64/time.c
--- a/extras/mini-os/arch/ia64/time.c   Tue Mar 18 11:28:14 2008 +0000
+++ b/extras/mini-os/arch/ia64/time.c   Tue Mar 18 11:29:18 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 b543b4b759ba -r ea5ee63548e4 extras/mini-os/arch/x86/time.c
--- a/extras/mini-os/arch/x86/time.c    Tue Mar 18 11:28:14 2008 +0000
+++ b/extras/mini-os/arch/x86/time.c    Tue Mar 18 11:29:18 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 b543b4b759ba -r ea5ee63548e4 extras/mini-os/blkfront.c
--- a/extras/mini-os/blkfront.c Tue Mar 18 11:28:14 2008 +0000
+++ b/extras/mini-os/blkfront.c Tue Mar 18 11:29:18 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 b543b4b759ba -r ea5ee63548e4 extras/mini-os/console/xencons_ring.c
--- a/extras/mini-os/console/xencons_ring.c     Tue Mar 18 11:28:14 2008 +0000
+++ b/extras/mini-os/console/xencons_ring.c     Tue Mar 18 11:29:18 2008 +0000
@@ -86,6 +86,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 b543b4b759ba -r ea5ee63548e4 extras/mini-os/events.c
--- a/extras/mini-os/events.c   Tue Mar 18 11:28:14 2008 +0000
+++ b/extras/mini-os/events.c   Tue Mar 18 11:29:18 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 b543b4b759ba -r ea5ee63548e4 extras/mini-os/fbfront.c
--- a/extras/mini-os/fbfront.c  Tue Mar 18 11:28:14 2008 +0000
+++ b/extras/mini-os/fbfront.c  Tue Mar 18 11:29:18 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;
@@ -281,14 +277,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);
@@ -397,6 +388,7 @@ done:
 
         err = xenbus_printf(XBT_NIL, nodename, "state", "%u", 4); /* connected 
*/
     }
+    unmask_evtchn(dev->evtchn);
 
     printk("************************** FBFRONT\n");
 
@@ -462,7 +454,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 b543b4b759ba -r ea5ee63548e4 extras/mini-os/fs-front.c
--- a/extras/mini-os/fs-front.c Tue Mar 18 11:28:14 2008 +0000
+++ b/extras/mini-os/fs-front.c Tue Mar 18 11:29:18 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 b543b4b759ba -r ea5ee63548e4 extras/mini-os/netfront.c
--- a/extras/mini-os/netfront.c Tue Mar 18 11:28:14 2008 +0000
+++ b/extras/mini-os/netfront.c Tue Mar 18 11:29:18 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 b543b4b759ba -r ea5ee63548e4 extras/mini-os/xenbus/xenbus.c
--- a/extras/mini-os/xenbus/xenbus.c    Tue Mar 18 11:28:14 2008 +0000
+++ b/extras/mini-os/xenbus/xenbus.c    Tue Mar 18 11:29:18 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 b543b4b759ba -r ea5ee63548e4 tools/libxc/xc_minios.c
--- a/tools/libxc/xc_minios.c   Tue Mar 18 11:28:14 2008 +0000
+++ b/tools/libxc/xc_minios.c   Tue Mar 18 11:29:18 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-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog

<Prev in Thread] Current Thread [Next in Thread>
  • [Xen-changelog] [xen-unstable] minios: Fix lost events, Xen patchbot-unstable <=