aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/xen-netfront.c
diff options
context:
space:
mode:
authorWei Liu <wei.liu2@citrix.com>2013-05-22 02:34:46 -0400
committerDavid S. Miller <davem@davemloft.net>2013-05-23 21:40:37 -0400
commitd634bf2cb96639b7eddb646dc1fc17b1bc6e567f (patch)
treee02f4cd79084a55e5f29c081751e7db5df815d17 /drivers/net/xen-netfront.c
parente1f00a69ec26e3eb9847c61c665b8fb3f0c6b477 (diff)
xen-netfront: split event channels support for Xen frontend driver
This patch adds a new feature called feature-split-event-channels for netfront, enabling it to handle TX and RX events separately. If netback does not support this feature, it falls back to use single event channel. If netfront fails to setup split event channels, it will try falling back to single event channel. Signed-off-by: Wei Liu <wei.liu2@citrix.com> Reviewed-by: David Vrabel <david.vrabel@citrix.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/xen-netfront.c')
-rw-r--r--drivers/net/xen-netfront.c178
1 files changed, 149 insertions, 29 deletions
diff --git a/drivers/net/xen-netfront.c b/drivers/net/xen-netfront.c
index 5770e3b0ba73..62238a08cb51 100644
--- a/drivers/net/xen-netfront.c
+++ b/drivers/net/xen-netfront.c
@@ -85,7 +85,15 @@ struct netfront_info {
85 85
86 struct napi_struct napi; 86 struct napi_struct napi;
87 87
88 unsigned int evtchn; 88 /* Split event channels support, tx_* == rx_* when using
89 * single event channel.
90 */
91 unsigned int tx_evtchn, rx_evtchn;
92 unsigned int tx_irq, rx_irq;
93 /* Only used when split event channels support is enabled */
94 char tx_irq_name[IFNAMSIZ+4]; /* DEVNAME-tx */
95 char rx_irq_name[IFNAMSIZ+4]; /* DEVNAME-rx */
96
89 struct xenbus_device *xbdev; 97 struct xenbus_device *xbdev;
90 98
91 spinlock_t tx_lock; 99 spinlock_t tx_lock;
@@ -330,7 +338,7 @@ no_skb:
330 push: 338 push:
331 RING_PUSH_REQUESTS_AND_CHECK_NOTIFY(&np->rx, notify); 339 RING_PUSH_REQUESTS_AND_CHECK_NOTIFY(&np->rx, notify);
332 if (notify) 340 if (notify)
333 notify_remote_via_irq(np->netdev->irq); 341 notify_remote_via_irq(np->rx_irq);
334} 342}
335 343
336static int xennet_open(struct net_device *dev) 344static int xennet_open(struct net_device *dev)
@@ -623,7 +631,7 @@ static int xennet_start_xmit(struct sk_buff *skb, struct net_device *dev)
623 631
624 RING_PUSH_REQUESTS_AND_CHECK_NOTIFY(&np->tx, notify); 632 RING_PUSH_REQUESTS_AND_CHECK_NOTIFY(&np->tx, notify);
625 if (notify) 633 if (notify)
626 notify_remote_via_irq(np->netdev->irq); 634 notify_remote_via_irq(np->tx_irq);
627 635
628 u64_stats_update_begin(&stats->syncp); 636 u64_stats_update_begin(&stats->syncp);
629 stats->tx_bytes += skb->len; 637 stats->tx_bytes += skb->len;
@@ -1254,23 +1262,35 @@ static int xennet_set_features(struct net_device *dev,
1254 return 0; 1262 return 0;
1255} 1263}
1256 1264
1257static irqreturn_t xennet_interrupt(int irq, void *dev_id) 1265static irqreturn_t xennet_tx_interrupt(int irq, void *dev_id)
1258{ 1266{
1259 struct net_device *dev = dev_id; 1267 struct netfront_info *np = dev_id;
1260 struct netfront_info *np = netdev_priv(dev); 1268 struct net_device *dev = np->netdev;
1261 unsigned long flags; 1269 unsigned long flags;
1262 1270
1263 spin_lock_irqsave(&np->tx_lock, flags); 1271 spin_lock_irqsave(&np->tx_lock, flags);
1272 xennet_tx_buf_gc(dev);
1273 spin_unlock_irqrestore(&np->tx_lock, flags);
1264 1274
1265 if (likely(netif_carrier_ok(dev))) { 1275 return IRQ_HANDLED;
1266 xennet_tx_buf_gc(dev); 1276}
1267 /* Under tx_lock: protects access to rx shared-ring indexes. */ 1277
1268 if (RING_HAS_UNCONSUMED_RESPONSES(&np->rx)) 1278static irqreturn_t xennet_rx_interrupt(int irq, void *dev_id)
1279{
1280 struct netfront_info *np = dev_id;
1281 struct net_device *dev = np->netdev;
1282
1283 if (likely(netif_carrier_ok(dev) &&
1284 RING_HAS_UNCONSUMED_RESPONSES(&np->rx)))
1269 napi_schedule(&np->napi); 1285 napi_schedule(&np->napi);
1270 }
1271 1286
1272 spin_unlock_irqrestore(&np->tx_lock, flags); 1287 return IRQ_HANDLED;
1288}
1273 1289
1290static irqreturn_t xennet_interrupt(int irq, void *dev_id)
1291{
1292 xennet_tx_interrupt(irq, dev_id);
1293 xennet_rx_interrupt(irq, dev_id);
1274 return IRQ_HANDLED; 1294 return IRQ_HANDLED;
1275} 1295}
1276 1296
@@ -1451,9 +1471,14 @@ static void xennet_disconnect_backend(struct netfront_info *info)
1451 spin_unlock_irq(&info->tx_lock); 1471 spin_unlock_irq(&info->tx_lock);
1452 spin_unlock_bh(&info->rx_lock); 1472 spin_unlock_bh(&info->rx_lock);
1453 1473
1454 if (info->netdev->irq) 1474 if (info->tx_irq && (info->tx_irq == info->rx_irq))
1455 unbind_from_irqhandler(info->netdev->irq, info->netdev); 1475 unbind_from_irqhandler(info->tx_irq, info);
1456 info->evtchn = info->netdev->irq = 0; 1476 if (info->tx_irq && (info->tx_irq != info->rx_irq)) {
1477 unbind_from_irqhandler(info->tx_irq, info);
1478 unbind_from_irqhandler(info->rx_irq, info);
1479 }
1480 info->tx_evtchn = info->rx_evtchn = 0;
1481 info->tx_irq = info->rx_irq = 0;
1457 1482
1458 /* End access and free the pages */ 1483 /* End access and free the pages */
1459 xennet_end_access(info->tx_ring_ref, info->tx.sring); 1484 xennet_end_access(info->tx_ring_ref, info->tx.sring);
@@ -1503,12 +1528,82 @@ static int xen_net_read_mac(struct xenbus_device *dev, u8 mac[])
1503 return 0; 1528 return 0;
1504} 1529}
1505 1530
1531static int setup_netfront_single(struct netfront_info *info)
1532{
1533 int err;
1534
1535 err = xenbus_alloc_evtchn(info->xbdev, &info->tx_evtchn);
1536 if (err < 0)
1537 goto fail;
1538
1539 err = bind_evtchn_to_irqhandler(info->tx_evtchn,
1540 xennet_interrupt,
1541 0, info->netdev->name, info);
1542 if (err < 0)
1543 goto bind_fail;
1544 info->rx_evtchn = info->tx_evtchn;
1545 info->rx_irq = info->tx_irq = err;
1546
1547 return 0;
1548
1549bind_fail:
1550 xenbus_free_evtchn(info->xbdev, info->tx_evtchn);
1551 info->tx_evtchn = 0;
1552fail:
1553 return err;
1554}
1555
1556static int setup_netfront_split(struct netfront_info *info)
1557{
1558 int err;
1559
1560 err = xenbus_alloc_evtchn(info->xbdev, &info->tx_evtchn);
1561 if (err < 0)
1562 goto fail;
1563 err = xenbus_alloc_evtchn(info->xbdev, &info->rx_evtchn);
1564 if (err < 0)
1565 goto alloc_rx_evtchn_fail;
1566
1567 snprintf(info->tx_irq_name, sizeof(info->tx_irq_name),
1568 "%s-tx", info->netdev->name);
1569 err = bind_evtchn_to_irqhandler(info->tx_evtchn,
1570 xennet_tx_interrupt,
1571 0, info->tx_irq_name, info);
1572 if (err < 0)
1573 goto bind_tx_fail;
1574 info->tx_irq = err;
1575
1576 snprintf(info->rx_irq_name, sizeof(info->rx_irq_name),
1577 "%s-rx", info->netdev->name);
1578 err = bind_evtchn_to_irqhandler(info->rx_evtchn,
1579 xennet_rx_interrupt,
1580 0, info->rx_irq_name, info);
1581 if (err < 0)
1582 goto bind_rx_fail;
1583 info->rx_irq = err;
1584
1585 return 0;
1586
1587bind_rx_fail:
1588 unbind_from_irqhandler(info->tx_irq, info);
1589 info->tx_irq = 0;
1590bind_tx_fail:
1591 xenbus_free_evtchn(info->xbdev, info->rx_evtchn);
1592 info->rx_evtchn = 0;
1593alloc_rx_evtchn_fail:
1594 xenbus_free_evtchn(info->xbdev, info->tx_evtchn);
1595 info->tx_evtchn = 0;
1596fail:
1597 return err;
1598}
1599
1506static int setup_netfront(struct xenbus_device *dev, struct netfront_info *info) 1600static int setup_netfront(struct xenbus_device *dev, struct netfront_info *info)
1507{ 1601{
1508 struct xen_netif_tx_sring *txs; 1602 struct xen_netif_tx_sring *txs;
1509 struct xen_netif_rx_sring *rxs; 1603 struct xen_netif_rx_sring *rxs;
1510 int err; 1604 int err;
1511 struct net_device *netdev = info->netdev; 1605 struct net_device *netdev = info->netdev;
1606 unsigned int feature_split_evtchn;
1512 1607
1513 info->tx_ring_ref = GRANT_INVALID_REF; 1608 info->tx_ring_ref = GRANT_INVALID_REF;
1514 info->rx_ring_ref = GRANT_INVALID_REF; 1609 info->rx_ring_ref = GRANT_INVALID_REF;
@@ -1516,6 +1611,12 @@ static int setup_netfront(struct xenbus_device *dev, struct netfront_info *info)
1516 info->tx.sring = NULL; 1611 info->tx.sring = NULL;
1517 netdev->irq = 0; 1612 netdev->irq = 0;
1518 1613
1614 err = xenbus_scanf(XBT_NIL, info->xbdev->otherend,
1615 "feature-split-event-channels", "%u",
1616 &feature_split_evtchn);
1617 if (err < 0)
1618 feature_split_evtchn = 0;
1619
1519 err = xen_net_read_mac(dev, netdev->dev_addr); 1620 err = xen_net_read_mac(dev, netdev->dev_addr);
1520 if (err) { 1621 if (err) {
1521 xenbus_dev_fatal(dev, err, "parsing %s/mac", dev->nodename); 1622 xenbus_dev_fatal(dev, err, "parsing %s/mac", dev->nodename);
@@ -1550,22 +1651,23 @@ static int setup_netfront(struct xenbus_device *dev, struct netfront_info *info)
1550 goto grant_rx_ring_fail; 1651 goto grant_rx_ring_fail;
1551 info->rx_ring_ref = err; 1652 info->rx_ring_ref = err;
1552 1653
1553 err = xenbus_alloc_evtchn(dev, &info->evtchn); 1654 if (feature_split_evtchn)
1655 err = setup_netfront_split(info);
1656 /* setup single event channel if
1657 * a) feature-split-event-channels == 0
1658 * b) feature-split-event-channels == 1 but failed to setup
1659 */
1660 if (!feature_split_evtchn || (feature_split_evtchn && err))
1661 err = setup_netfront_single(info);
1662
1554 if (err) 1663 if (err)
1555 goto alloc_evtchn_fail; 1664 goto alloc_evtchn_fail;
1556 1665
1557 err = bind_evtchn_to_irqhandler(info->evtchn, xennet_interrupt,
1558 0, netdev->name, netdev);
1559 if (err < 0)
1560 goto bind_fail;
1561 netdev->irq = err;
1562 return 0; 1666 return 0;
1563 1667
1564 /* If we fail to setup netfront, it is safe to just revoke access to 1668 /* If we fail to setup netfront, it is safe to just revoke access to
1565 * granted pages because backend is not accessing it at this point. 1669 * granted pages because backend is not accessing it at this point.
1566 */ 1670 */
1567bind_fail:
1568 xenbus_free_evtchn(dev, info->evtchn);
1569alloc_evtchn_fail: 1671alloc_evtchn_fail:
1570 gnttab_end_foreign_access_ref(info->rx_ring_ref, 0); 1672 gnttab_end_foreign_access_ref(info->rx_ring_ref, 0);
1571grant_rx_ring_fail: 1673grant_rx_ring_fail:
@@ -1610,11 +1712,27 @@ again:
1610 message = "writing rx ring-ref"; 1712 message = "writing rx ring-ref";
1611 goto abort_transaction; 1713 goto abort_transaction;
1612 } 1714 }
1613 err = xenbus_printf(xbt, dev->nodename, 1715
1614 "event-channel", "%u", info->evtchn); 1716 if (info->tx_evtchn == info->rx_evtchn) {
1615 if (err) { 1717 err = xenbus_printf(xbt, dev->nodename,
1616 message = "writing event-channel"; 1718 "event-channel", "%u", info->tx_evtchn);
1617 goto abort_transaction; 1719 if (err) {
1720 message = "writing event-channel";
1721 goto abort_transaction;
1722 }
1723 } else {
1724 err = xenbus_printf(xbt, dev->nodename,
1725 "event-channel-tx", "%u", info->tx_evtchn);
1726 if (err) {
1727 message = "writing event-channel-tx";
1728 goto abort_transaction;
1729 }
1730 err = xenbus_printf(xbt, dev->nodename,
1731 "event-channel-rx", "%u", info->rx_evtchn);
1732 if (err) {
1733 message = "writing event-channel-rx";
1734 goto abort_transaction;
1735 }
1618 } 1736 }
1619 1737
1620 err = xenbus_printf(xbt, dev->nodename, "request-rx-copy", "%u", 1738 err = xenbus_printf(xbt, dev->nodename, "request-rx-copy", "%u",
@@ -1727,7 +1845,9 @@ static int xennet_connect(struct net_device *dev)
1727 * packets. 1845 * packets.
1728 */ 1846 */
1729 netif_carrier_on(np->netdev); 1847 netif_carrier_on(np->netdev);
1730 notify_remote_via_irq(np->netdev->irq); 1848 notify_remote_via_irq(np->tx_irq);
1849 if (np->tx_irq != np->rx_irq)
1850 notify_remote_via_irq(np->rx_irq);
1731 xennet_tx_buf_gc(dev); 1851 xennet_tx_buf_gc(dev);
1732 xennet_alloc_rx_buffers(dev); 1852 xennet_alloc_rx_buffers(dev);
1733 1853