Yoshiaki Tamura
2009-Mar-12 01:21 UTC
[Xen-devel] [RFC][PATCH 11/13] Kemari: XenbusStateAttached handler for netback
References: <49B86208.2020205@lab.ntt.co.jp> In-Reply-To: <49B86208.2020205@lab.ntt.co.jp> Content-Type: text/plain; charset=ISO-2022-JP Content-Transfer-Encoding: 7bit This is an updated version of the following patch. No major changes. http://lists.xensource.com/archives/html/xen-devel/2009-03/msg00380.html Signed-off-by: Yoshi Tamura <tamura.yoshiaki@lab.ntt.co.jp> Signed-off-by: Yoshisato Yanagisawa <yanagisawa.yoshisato@lab.ntt.co.jp> --- drivers/xen/netback/common.h | 2 drivers/xen/netback/interface.c | 58 +++++++++++++++++++++ drivers/xen/netback/xenbus.c | 109 ++++++++++++++++++++++++++++++++++++++++ 3 files changed, 169 insertions(+) diff -r 0430b1dbfb3a -r e183d2114ea1 drivers/xen/netback/common.h --- a/drivers/xen/netback/common.h Fri Mar 06 12:51:33 2009 +0000 +++ b/drivers/xen/netback/common.h Tue Mar 10 15:40:44 2009 +0900 @@ -185,6 +185,8 @@ netif_t *netif_alloc(domid_t domid, unsi netif_t *netif_alloc(domid_t domid, unsigned int handle); int netif_map(netif_t *netif, unsigned long tx_ring_ref, unsigned long rx_ring_ref, unsigned int evtchn); +int netif_attach(netif_t *netif, unsigned long tx_ring_ref, + unsigned long rx_ring_ref, unsigned int evtchn); #define netif_get(_b) (atomic_inc(&(_b)->refcnt)) #define netif_put(_b) \ diff -r 0430b1dbfb3a -r e183d2114ea1 drivers/xen/netback/interface.c --- a/drivers/xen/netback/interface.c Fri Mar 06 12:51:33 2009 +0000 +++ b/drivers/xen/netback/interface.c Tue Mar 10 15:40:44 2009 +0900 @@ -358,6 +358,64 @@ err_rx: return err; } +int netif_attach(netif_t *netif, unsigned long tx_ring_ref, + unsigned long rx_ring_ref, unsigned int evtchn) +{ + int err = -ENOMEM; + netif_tx_sring_t *txs; + netif_rx_sring_t *rxs; + + /* Already connected through? */ + if (netif->irq) + return 0; + + netif->tx_comms_area = alloc_vm_area(PAGE_SIZE); + if (netif->tx_comms_area == NULL) + return -ENOMEM; + netif->rx_comms_area = alloc_vm_area(PAGE_SIZE); + if (netif->rx_comms_area == NULL) + goto err_rx; + + err = map_frontend_pages(netif, tx_ring_ref, rx_ring_ref); + if (err) + goto err_map; + + err = bind_interdomain_evtchn_to_irqhandler( + netif->domid, evtchn, netif_be_int, 0, + netif->dev->name, netif); + if (err < 0) + goto err_hypervisor; + netif->irq = err; + disable_irq(netif->irq); + + txs = (netif_tx_sring_t *)netif->tx_comms_area->addr; + BACK_RING_ATTACH(&netif->tx, txs, PAGE_SIZE); + + rxs = (netif_rx_sring_t *) + ((char *)netif->rx_comms_area->addr); + BACK_RING_ATTACH(&netif->rx, rxs, PAGE_SIZE); + + netif->rx.req_cons = netif->rx.sring->rsp_prod; + netif->rx_req_cons_peek = netif->rx.req_cons; + + netif_get(netif); + + rtnl_lock(); + netback_carrier_on(netif); + if (netif_running(netif->dev)) + __netif_up(netif); + rtnl_unlock(); + + return 0; +err_hypervisor: + unmap_frontend_pages(netif); +err_map: + free_vm_area(netif->rx_comms_area); +err_rx: + free_vm_area(netif->tx_comms_area); + return err; +} + void netif_disconnect(netif_t *netif) { if (netback_carrier_ok(netif)) { diff -r 0430b1dbfb3a -r e183d2114ea1 drivers/xen/netback/xenbus.c --- a/drivers/xen/netback/xenbus.c Fri Mar 06 12:51:33 2009 +0000 +++ b/drivers/xen/netback/xenbus.c Tue Mar 10 15:40:44 2009 +0900 @@ -30,7 +30,9 @@ static int connect_rings(struct backend_info *); +static int attach_rings(struct backend_info *); static void connect(struct backend_info *); +static void attach(struct backend_info *); static void backend_create_netif(struct backend_info *be); static int netback_remove(struct xenbus_device *dev) @@ -240,6 +242,12 @@ static void frontend_changed(struct xenb connect(be); break; + case XenbusStateAttached: + backend_create_netif(be); + if (be->netif) + attach(be); + break; + case XenbusStateClosing: if (be->netif) { kobject_uevent(&dev->dev.kobj, KOBJ_OFFLINE); @@ -348,6 +356,29 @@ static void connect(struct backend_info netif_wake_queue(be->netif->dev); } +static void attach(struct backend_info *be) +{ + int err; + struct xenbus_device *dev = be->dev; + + err = attach_rings(be); + if (err) + return; + + err = xen_net_read_mac(dev, be->netif->fe_dev_addr); + if (err) { + xenbus_dev_fatal(dev, err, "parsing %s/mac", dev->nodename); + return; + } + + xen_net_read_rate(dev, &be->netif->credit_bytes, + &be->netif->credit_usec); + be->netif->remaining_credit = be->netif->credit_bytes; + + xenbus_switch_state(dev, XenbusStateAttached); + + netif_wake_queue(be->netif->dev); +} static int connect_rings(struct backend_info *be) { @@ -428,6 +459,84 @@ static int connect_rings(struct backend_ return 0; } +static int attach_rings(struct backend_info *be) +{ + struct xenbus_device *dev = be->dev; + unsigned long tx_ring_ref, rx_ring_ref; + unsigned int evtchn, rx_copy; + int err; + int val; + + DPRINTK(""); + + err = xenbus_gather(XBT_NIL, dev->otherend, + "tx-ring-ref", "%lu", &tx_ring_ref, + "rx-ring-ref", "%lu", &rx_ring_ref, + "event-channel", "%u", &evtchn, NULL); + if (err) { + xenbus_dev_fatal(dev, err, + "reading %s/ring-ref and event-channel", + dev->otherend); + return err; + } + + err = xenbus_scanf(XBT_NIL, dev->otherend, "request-rx-copy", "%u", + &rx_copy); + if (err == -ENOENT) { + err = 0; + rx_copy = 0; + } + if (err < 0) { + xenbus_dev_fatal(dev, err, "reading %s/request-rx-copy", + dev->otherend); + return err; + } + be->netif->copying_receiver = !!rx_copy; + + if (be->netif->dev->tx_queue_len != 0) { + if (xenbus_scanf(XBT_NIL, dev->otherend, + "feature-rx-notify", "%d", &val) < 0) + val = 0; + if (val) + be->netif->can_queue = 1; + else + /* Must be non-zero for pfifo_fast to work. */ + be->netif->dev->tx_queue_len = 1; + } + + if (xenbus_scanf(XBT_NIL, dev->otherend, "feature-sg", "%d", &val) < 0) + val = 0; + if (val) { + be->netif->features |= NETIF_F_SG; + be->netif->dev->features |= NETIF_F_SG; + } + + if (xenbus_scanf(XBT_NIL, dev->otherend, "feature-gso-tcpv4", "%d", + &val) < 0) + val = 0; + if (val) { + be->netif->features |= NETIF_F_TSO; + be->netif->dev->features |= NETIF_F_TSO; + } + + if (xenbus_scanf(XBT_NIL, dev->otherend, "feature-no-csum-offload", + "%d", &val) < 0) + val = 0; + if (val) { + be->netif->features &= ~NETIF_F_IP_CSUM; + be->netif->dev->features &= ~NETIF_F_IP_CSUM; + } + + /* Map the shared frame, irq etc. */ + err = netif_attach(be->netif, tx_ring_ref, rx_ring_ref, evtchn); + if (err) { + xenbus_dev_fatal(dev, err, + "mapping shared-frames %lu/%lu port %u", + tx_ring_ref, rx_ring_ref, evtchn); + return err; + } + return 0; +} /* ** Driver Registration ** */ _______________________________________________ Xen-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel