diff options
author | Keir Fraser <keir.fraser@citrix.com> | 2008-03-18 11:29:18 +0000 |
---|---|---|
committer | Keir Fraser <keir.fraser@citrix.com> | 2008-03-18 11:29:18 +0000 |
commit | b9d1950675c67f10870debe164a226eef64f65d5 (patch) | |
tree | acd93ea007ed7289d7bacc728997d698e050c276 /extras/mini-os/netfront.c | |
parent | 62341d01ee88ecc87d6995000383446e3bf43ec7 (diff) | |
download | xen-b9d1950675c67f10870debe164a226eef64f65d5.tar.gz xen-b9d1950675c67f10870debe164a226eef64f65d5.tar.bz2 xen-b9d1950675c67f10870debe164a226eef64f65d5.zip |
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>
Diffstat (limited to 'extras/mini-os/netfront.c')
-rw-r--r-- | extras/mini-os/netfront.c | 20 |
1 files changed, 8 insertions, 12 deletions
diff --git a/extras/mini-os/netfront.c b/extras/mini-os/netfront.c index 095f55ca15..9b709d9826 100644 --- a/extras/mini-os/netfront.c +++ b/extras/mini-os/netfront.c @@ -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 *nodename, void (*thenetif_rx)(unsigned 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_dev *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(nodename); free(dev->backend); |