aboutsummaryrefslogtreecommitdiffstats
path: root/extras/mini-os/netfront.c
diff options
context:
space:
mode:
authorKeir Fraser <keir.fraser@citrix.com>2008-03-18 11:29:18 +0000
committerKeir Fraser <keir.fraser@citrix.com>2008-03-18 11:29:18 +0000
commitb9d1950675c67f10870debe164a226eef64f65d5 (patch)
treeacd93ea007ed7289d7bacc728997d698e050c276 /extras/mini-os/netfront.c
parent62341d01ee88ecc87d6995000383446e3bf43ec7 (diff)
downloadxen-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.c20
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);