debuggers.hg
changeset 17257:ea5ee63548e4
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@eu.citrix.com>
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@eu.citrix.com>
author | Keir Fraser <keir.fraser@citrix.com> |
---|---|
date | Tue Mar 18 11:29:18 2008 +0000 (2008-03-18) |
parents | b543b4b759ba |
children | d0a538659726 |
files | extras/mini-os/arch/ia64/time.c extras/mini-os/arch/x86/time.c extras/mini-os/blkfront.c extras/mini-os/console/xencons_ring.c extras/mini-os/events.c extras/mini-os/fbfront.c extras/mini-os/fs-front.c extras/mini-os/netfront.c extras/mini-os/xenbus/xenbus.c tools/libxc/xc_minios.c |
line diff
1.1 --- a/extras/mini-os/arch/ia64/time.c Tue Mar 18 11:28:14 2008 +0000 1.2 +++ b/extras/mini-os/arch/ia64/time.c Tue Mar 18 11:29:18 2008 +0000 1.3 @@ -246,7 +246,7 @@ init_time(void) 1.4 { 1.5 uint64_t new; 1.6 efi_time_t tm; 1.7 - int err = 0; 1.8 + evtchn_port_t port = 0; 1.9 1.10 printk("Initialising time\n"); 1.11 calculate_frequencies(); 1.12 @@ -267,11 +267,12 @@ init_time(void) 1.13 } else 1.14 printk("efi_get_time() failed\n"); 1.15 1.16 - err = bind_virq(VIRQ_ITC, timer_interrupt, NULL); 1.17 - if (err == -1) { 1.18 - printk("XEN timer request chn bind failed %i\n", err); 1.19 + port = bind_virq(VIRQ_ITC, timer_interrupt, NULL); 1.20 + if (port == -1) { 1.21 + printk("XEN timer request chn bind failed %i\n", port); 1.22 return; 1.23 } 1.24 + unmask_evtchn(port); 1.25 itc_alt = ia64_get_itc(); 1.26 itc_at_boot = itc_alt; 1.27 new = ia64_get_itc() + itm_val;
2.1 --- a/extras/mini-os/arch/x86/time.c Tue Mar 18 11:28:14 2008 +0000 2.2 +++ b/extras/mini-os/arch/x86/time.c Tue Mar 18 11:29:18 2008 +0000 2.3 @@ -222,6 +222,8 @@ static void timer_handler(evtchn_port_t 2.4 2.5 void init_time(void) 2.6 { 2.7 + evtchn_port_t port; 2.8 printk("Initialising timer interface\n"); 2.9 - bind_virq(VIRQ_TIMER, &timer_handler, NULL); 2.10 + port = bind_virq(VIRQ_TIMER, &timer_handler, NULL); 2.11 + unmask_evtchn(port); 2.12 }
3.1 --- a/extras/mini-os/blkfront.c Tue Mar 18 11:28:14 2008 +0000 3.2 +++ b/extras/mini-os/blkfront.c Tue Mar 18 11:29:18 2008 +0000 3.3 @@ -43,7 +43,7 @@ struct blkfront_dev { 3.4 3.5 struct blkif_front_ring ring; 3.6 grant_ref_t ring_ref; 3.7 - evtchn_port_t evtchn, local_port; 3.8 + evtchn_port_t evtchn; 3.9 blkif_vdev_t handle; 3.10 3.11 char *nodename; 3.12 @@ -92,14 +92,9 @@ struct blkfront_dev *init_blkfront(char 3.13 dev = malloc(sizeof(*dev)); 3.14 dev->nodename = strdup(nodename); 3.15 3.16 - evtchn_alloc_unbound_t op; 3.17 - op.dom = DOMID_SELF; 3.18 snprintf(path, sizeof(path), "%s/backend-id", nodename); 3.19 - dev->dom = op.remote_dom = xenbus_read_integer(path); 3.20 - HYPERVISOR_event_channel_op(EVTCHNOP_alloc_unbound, &op); 3.21 - clear_evtchn(op.port); /* Without, handler gets invoked now! */ 3.22 - dev->local_port = bind_evtchn(op.port, blkfront_handler, dev); 3.23 - dev->evtchn=op.port; 3.24 + dev->dom = xenbus_read_integer(path); 3.25 + evtchn_alloc_unbound(dev->dom, blkfront_handler, dev, &dev->evtchn); 3.26 3.27 s = (struct blkif_sring*) alloc_page(); 3.28 memset(s,0,PAGE_SIZE); 3.29 @@ -194,6 +189,7 @@ done: 3.30 snprintf(path, sizeof(path), "%s/feature-flush-cache", dev->backend); 3.31 dev->flush = xenbus_read_integer(path); 3.32 } 3.33 + unmask_evtchn(dev->evtchn); 3.34 3.35 printk("%u sectors of %u bytes\n", dev->sectors, dev->sector_size); 3.36 printk("**************************\n"); 3.37 @@ -219,7 +215,7 @@ void shutdown_blkfront(struct blkfront_d 3.38 err = xenbus_printf(XBT_NIL, nodename, "state", "%u", 6); 3.39 xenbus_wait_for_value(path,"6"); 3.40 3.41 - unbind_evtchn(dev->local_port); 3.42 + unbind_evtchn(dev->evtchn); 3.43 3.44 free(nodename); 3.45 free(dev->backend);
4.1 --- a/extras/mini-os/console/xencons_ring.c Tue Mar 18 11:28:14 2008 +0000 4.2 +++ b/extras/mini-os/console/xencons_ring.c Tue Mar 18 11:29:18 2008 +0000 4.3 @@ -86,6 +86,7 @@ int xencons_ring_init(void) 4.4 printk("XEN console request chn bind failed %i\n", err); 4.5 return err; 4.6 } 4.7 + unmask_evtchn(start_info.console.domU.evtchn); 4.8 4.9 /* In case we have in-flight data after save/restore... */ 4.10 notify_daemon();
5.1 --- a/extras/mini-os/events.c Tue Mar 18 11:28:14 2008 +0000 5.2 +++ b/extras/mini-os/events.c Tue Mar 18 11:29:18 2008 +0000 5.3 @@ -87,9 +87,6 @@ evtchn_port_t bind_evtchn(evtchn_port_t 5.4 wmb(); 5.5 ev_actions[port].handler = handler; 5.6 5.7 - /* Finally unmask the port */ 5.8 - unmask_evtchn(port); 5.9 - 5.10 return port; 5.11 } 5.12 5.13 @@ -191,8 +188,7 @@ int evtchn_bind_interdomain(domid_t pal, 5.14 if (err) 5.15 return err; 5.16 set_bit(op.local_port,bound_ports); 5.17 - evtchn_port_t port = op.local_port; 5.18 - clear_evtchn(port); /* Without, handler gets invoked now! */ 5.19 + evtchn_port_t port = op.local_port; 5.20 *local_port = bind_evtchn(port, handler, data); 5.21 return err; 5.22 }
6.1 --- a/extras/mini-os/fbfront.c Tue Mar 18 11:28:14 2008 +0000 6.2 +++ b/extras/mini-os/fbfront.c Tue Mar 18 11:29:18 2008 +0000 6.3 @@ -26,7 +26,7 @@ struct kbdfront_dev { 6.4 domid_t dom; 6.5 6.6 struct xenkbd_page *page; 6.7 - evtchn_port_t evtchn, local_port; 6.8 + evtchn_port_t evtchn; 6.9 6.10 char *nodename; 6.11 char *backend; 6.12 @@ -68,14 +68,9 @@ struct kbdfront_dev *init_kbdfront(char 6.13 dev = malloc(sizeof(*dev)); 6.14 dev->nodename = strdup(nodename); 6.15 6.16 - evtchn_alloc_unbound_t op; 6.17 - op.dom = DOMID_SELF; 6.18 snprintf(path, sizeof(path), "%s/backend-id", nodename); 6.19 - dev->dom = op.remote_dom = xenbus_read_integer(path); 6.20 - HYPERVISOR_event_channel_op(EVTCHNOP_alloc_unbound, &op); 6.21 - clear_evtchn(op.port); /* Without, handler gets invoked now! */ 6.22 - dev->local_port = bind_evtchn(op.port, kbdfront_handler, dev); 6.23 - dev->evtchn=op.port; 6.24 + dev->dom = xenbus_read_integer(path); 6.25 + evtchn_alloc_unbound(dev->dom, kbdfront_handler, dev, &dev->evtchn); 6.26 6.27 dev->page = s = (struct xenkbd_page*) alloc_page(); 6.28 memset(s,0,PAGE_SIZE); 6.29 @@ -151,6 +146,7 @@ done: 6.30 6.31 err = xenbus_printf(XBT_NIL, nodename, "state", "%u", 4); /* connected */ 6.32 } 6.33 + unmask_evtchn(dev->evtchn); 6.34 6.35 printk("************************** KBDFRONT\n"); 6.36 6.37 @@ -208,7 +204,7 @@ void shutdown_kbdfront(struct kbdfront_d 6.38 err = xenbus_printf(XBT_NIL, nodename, "state", "%u", 6); 6.39 xenbus_wait_for_value(path,"6"); 6.40 6.41 - unbind_evtchn(dev->local_port); 6.42 + unbind_evtchn(dev->evtchn); 6.43 6.44 free_pages(dev->page,0); 6.45 free(nodename); 6.46 @@ -241,7 +237,7 @@ struct fbfront_dev { 6.47 domid_t dom; 6.48 6.49 struct xenfb_page *page; 6.50 - evtchn_port_t evtchn, local_port; 6.51 + evtchn_port_t evtchn; 6.52 6.53 char *nodename; 6.54 char *backend; 6.55 @@ -281,14 +277,9 @@ struct fbfront_dev *init_fbfront(char *n 6.56 dev = malloc(sizeof(*dev)); 6.57 dev->nodename = strdup(nodename); 6.58 6.59 - evtchn_alloc_unbound_t op; 6.60 - op.dom = DOMID_SELF; 6.61 snprintf(path, sizeof(path), "%s/backend-id", nodename); 6.62 - dev->dom = op.remote_dom = xenbus_read_integer(path); 6.63 - HYPERVISOR_event_channel_op(EVTCHNOP_alloc_unbound, &op); 6.64 - clear_evtchn(op.port); /* Without, handler gets invoked now! */ 6.65 - dev->local_port = bind_evtchn(op.port, fbfront_handler, dev); 6.66 - dev->evtchn=op.port; 6.67 + dev->dom = xenbus_read_integer(path); 6.68 + evtchn_alloc_unbound(dev->dom, fbfront_handler, dev, &dev->evtchn); 6.69 6.70 dev->page = s = (struct xenfb_page*) alloc_page(); 6.71 memset(s,0,PAGE_SIZE); 6.72 @@ -397,6 +388,7 @@ done: 6.73 6.74 err = xenbus_printf(XBT_NIL, nodename, "state", "%u", 4); /* connected */ 6.75 } 6.76 + unmask_evtchn(dev->evtchn); 6.77 6.78 printk("************************** FBFRONT\n"); 6.79 6.80 @@ -462,7 +454,7 @@ void shutdown_fbfront(struct fbfront_dev 6.81 err = xenbus_printf(XBT_NIL, nodename, "state", "%u", 6); 6.82 xenbus_wait_for_value(path,"6"); 6.83 6.84 - unbind_evtchn(dev->local_port); 6.85 + unbind_evtchn(dev->evtchn); 6.86 6.87 free_pages(dev->page,0); 6.88 free(nodename);
7.1 --- a/extras/mini-os/fs-front.c Tue Mar 18 11:28:14 2008 +0000 7.2 +++ b/extras/mini-os/fs-front.c Tue Mar 18 11:29:18 2008 +0000 7.3 @@ -943,6 +943,7 @@ static int init_fs_import(struct fs_impo 7.4 //ANY_CPU, 7.5 import, 7.6 &import->local_port)); 7.7 + unmask_evtchn(import->local_port); 7.8 7.9 7.10 self_id = get_self_id();
8.1 --- a/extras/mini-os/netfront.c Tue Mar 18 11:28:14 2008 +0000 8.2 +++ b/extras/mini-os/netfront.c Tue Mar 18 11:29:18 2008 +0000 8.3 @@ -48,7 +48,7 @@ struct netfront_dev { 8.4 struct netif_rx_front_ring rx; 8.5 grant_ref_t tx_ring_ref; 8.6 grant_ref_t rx_ring_ref; 8.7 - evtchn_port_t evtchn, local_port; 8.8 + evtchn_port_t evtchn; 8.9 8.10 char *nodename; 8.11 char *backend; 8.12 @@ -301,19 +301,14 @@ struct netfront_dev *init_netfront(char 8.13 dev->rx_buffers[i].page = (char*)alloc_page(); 8.14 } 8.15 8.16 - evtchn_alloc_unbound_t op; 8.17 - op.dom = DOMID_SELF; 8.18 snprintf(path, sizeof(path), "%s/backend-id", nodename); 8.19 - dev->dom = op.remote_dom = xenbus_read_integer(path); 8.20 - HYPERVISOR_event_channel_op(EVTCHNOP_alloc_unbound, &op); 8.21 - clear_evtchn(op.port); /* Without, handler gets invoked now! */ 8.22 + dev->dom = xenbus_read_integer(path); 8.23 #ifdef HAVE_LIBC 8.24 if (thenetif_rx == NETIF_SELECT_RX) 8.25 - dev->local_port = bind_evtchn(op.port, netfront_select_handler, dev); 8.26 + evtchn_alloc_unbound(dev->dom, netfront_select_handler, dev, &dev->evtchn); 8.27 else 8.28 #endif 8.29 - dev->local_port = bind_evtchn(op.port, netfront_handler, dev); 8.30 - dev->evtchn=op.port; 8.31 + evtchn_alloc_unbound(dev->dom, netfront_handler, dev, &dev->evtchn); 8.32 8.33 txs = (struct netif_tx_sring*) alloc_page(); 8.34 rxs = (struct netif_rx_sring *) alloc_page(); 8.35 @@ -388,9 +383,9 @@ done: 8.36 msg = xenbus_read(XBT_NIL, path, &mac); 8.37 8.38 if ((dev->backend == NULL) || (mac == NULL)) { 8.39 - struct evtchn_close op = { dev->local_port }; 8.40 + struct evtchn_close op = { dev->evtchn }; 8.41 printk("%s: backend/mac failed\n", __func__); 8.42 - unbind_evtchn(dev->local_port); 8.43 + unbind_evtchn(dev->evtchn); 8.44 HYPERVISOR_event_channel_op(EVTCHNOP_close, &op); 8.45 return NULL; 8.46 } 8.47 @@ -412,6 +407,7 @@ done: 8.48 printk("**************************\n"); 8.49 8.50 init_rx_buffers(dev); 8.51 + unmask_evtchn(dev->evtchn); 8.52 8.53 /* Special conversion specifier 'hh' needed for __ia64__. Without 8.54 this mini-os panics with 'Unaligned reference'. */ 8.55 @@ -460,7 +456,7 @@ void shutdown_netfront(struct netfront_d 8.56 err = xenbus_printf(XBT_NIL, nodename, "state", "%u", 6); 8.57 xenbus_wait_for_value(path,"6"); 8.58 8.59 - unbind_evtchn(dev->local_port); 8.60 + unbind_evtchn(dev->evtchn); 8.61 8.62 free(nodename); 8.63 free(dev->backend);
9.1 --- a/extras/mini-os/xenbus/xenbus.c Tue Mar 18 11:28:14 2008 +0000 9.2 +++ b/extras/mini-os/xenbus/xenbus.c Tue Mar 18 11:29:18 2008 +0000 9.3 @@ -257,6 +257,7 @@ void init_xenbus(void) 9.4 err = bind_evtchn(start_info.store_evtchn, 9.5 xenbus_evtchn_handler, 9.6 NULL); 9.7 + unmask_evtchn(start_info.store_evtchn); 9.8 DEBUG("xenbus on irq %d\n", err); 9.9 } 9.10
10.1 --- a/tools/libxc/xc_minios.c Tue Mar 18 11:28:14 2008 +0000 10.2 +++ b/tools/libxc/xc_minios.c Tue Mar 18 11:29:18 2008 +0000 10.3 @@ -165,14 +165,6 @@ static int port_alloc(int xce_handle) { 10.4 return i; 10.5 } 10.6 10.7 -static void poke_port(int xce_handle, evtchn_port_t port) 10.8 -{ 10.9 - shared_info_t *s = HYPERVISOR_shared_info; 10.10 - printk("poking port %d\n", port); 10.11 - synch_set_bit(port, &s->evtchn_pending[0]); 10.12 - xc_evtchn_unmask(xce_handle, port); 10.13 -} 10.14 - 10.15 static void evtchn_handler(evtchn_port_t port, struct pt_regs *regs, void *data) 10.16 { 10.17 int xce_handle = (intptr_t) data; 10.18 @@ -211,6 +203,7 @@ evtchn_port_or_error_t xc_evtchn_bind_un 10.19 } 10.20 files[xce_handle].evtchn.ports[i].bound = 1; 10.21 files[xce_handle].evtchn.ports[i].port = port; 10.22 + unmask_evtchn(port); 10.23 return port; 10.24 } 10.25 10.26 @@ -235,9 +228,7 @@ evtchn_port_or_error_t xc_evtchn_bind_in 10.27 } 10.28 files[xce_handle].evtchn.ports[i].bound = 1; 10.29 files[xce_handle].evtchn.ports[i].port = local_port; 10.30 -/* Poke port on start: HVM won't send an event for the very first request since 10.31 - * we were not ready yet */ 10.32 - poke_port(xce_handle, local_port); 10.33 + unmask_evtchn(local_port); 10.34 return local_port; 10.35 } 10.36 10.37 @@ -275,6 +266,7 @@ evtchn_port_or_error_t xc_evtchn_bind_vi 10.38 } 10.39 files[xce_handle].evtchn.ports[i].bound = 1; 10.40 files[xce_handle].evtchn.ports[i].port = port; 10.41 + unmask_evtchn(port); 10.42 return port; 10.43 } 10.44