aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSantiago Leon <santil@us.ibm.com>2005-10-26 12:47:16 -0400
committerJeff Garzik <jgarzik@pobox.com>2005-10-28 16:07:30 -0400
commit60296d9e4be1cd9e096f7804ce6e839e0cbd97cf (patch)
tree40372d93b1c99a0e488adedbbd8c843c26807058
parente2adbcb480992de8a01acf9218e8bbd9b507fc6f (diff)
[PATCH] ibmveth lockless TX
This patch adds the lockless TX feature to the ibmveth driver. The hypervisor has its own locking so the only change that is necessary is to protect the statistics counters. Signed-off-by: Santiago Leon <santil@us.ibm.com> Signed-off-by: Jeff Garzik <jgarzik@pobox.com>
-rw-r--r--drivers/net/ibmveth.c44
-rw-r--r--drivers/net/ibmveth.h1
2 files changed, 30 insertions, 15 deletions
diff --git a/drivers/net/ibmveth.c b/drivers/net/ibmveth.c
index aea1598b2253..987bcba01889 100644
--- a/drivers/net/ibmveth.c
+++ b/drivers/net/ibmveth.c
@@ -621,12 +621,18 @@ static int ibmveth_start_xmit(struct sk_buff *skb, struct net_device *netdev)
621 unsigned long lpar_rc; 621 unsigned long lpar_rc;
622 int nfrags = 0, curfrag; 622 int nfrags = 0, curfrag;
623 unsigned long correlator; 623 unsigned long correlator;
624 unsigned long flags;
624 unsigned int retry_count; 625 unsigned int retry_count;
626 unsigned int tx_dropped = 0;
627 unsigned int tx_bytes = 0;
628 unsigned int tx_packets = 0;
629 unsigned int tx_send_failed = 0;
630 unsigned int tx_map_failed = 0;
631
625 632
626 if ((skb_shinfo(skb)->nr_frags + 1) > IbmVethMaxSendFrags) { 633 if ((skb_shinfo(skb)->nr_frags + 1) > IbmVethMaxSendFrags) {
627 adapter->stats.tx_dropped++; 634 tx_dropped++;
628 dev_kfree_skb(skb); 635 goto out;
629 return 0;
630 } 636 }
631 637
632 memset(&desc, 0, sizeof(desc)); 638 memset(&desc, 0, sizeof(desc));
@@ -645,10 +651,9 @@ static int ibmveth_start_xmit(struct sk_buff *skb, struct net_device *netdev)
645 651
646 if(dma_mapping_error(desc[0].fields.address)) { 652 if(dma_mapping_error(desc[0].fields.address)) {
647 ibmveth_error_printk("tx: unable to map initial fragment\n"); 653 ibmveth_error_printk("tx: unable to map initial fragment\n");
648 adapter->tx_map_failed++; 654 tx_map_failed++;
649 adapter->stats.tx_dropped++; 655 tx_dropped++;
650 dev_kfree_skb(skb); 656 goto out;
651 return 0;
652 } 657 }
653 658
654 curfrag = nfrags; 659 curfrag = nfrags;
@@ -665,8 +670,8 @@ static int ibmveth_start_xmit(struct sk_buff *skb, struct net_device *netdev)
665 670
666 if(dma_mapping_error(desc[curfrag+1].fields.address)) { 671 if(dma_mapping_error(desc[curfrag+1].fields.address)) {
667 ibmveth_error_printk("tx: unable to map fragment %d\n", curfrag); 672 ibmveth_error_printk("tx: unable to map fragment %d\n", curfrag);
668 adapter->tx_map_failed++; 673 tx_map_failed++;
669 adapter->stats.tx_dropped++; 674 tx_dropped++;
670 /* Free all the mappings we just created */ 675 /* Free all the mappings we just created */
671 while(curfrag < nfrags) { 676 while(curfrag < nfrags) {
672 dma_unmap_single(&adapter->vdev->dev, 677 dma_unmap_single(&adapter->vdev->dev,
@@ -675,8 +680,7 @@ static int ibmveth_start_xmit(struct sk_buff *skb, struct net_device *netdev)
675 DMA_TO_DEVICE); 680 DMA_TO_DEVICE);
676 curfrag++; 681 curfrag++;
677 } 682 }
678 dev_kfree_skb(skb); 683 goto out;
679 return 0;
680 } 684 }
681 } 685 }
682 686
@@ -701,11 +705,11 @@ static int ibmveth_start_xmit(struct sk_buff *skb, struct net_device *netdev)
701 ibmveth_error_printk("tx: desc[%i] valid=%d, len=%d, address=0x%d\n", i, 705 ibmveth_error_printk("tx: desc[%i] valid=%d, len=%d, address=0x%d\n", i,
702 desc[i].fields.valid, desc[i].fields.length, desc[i].fields.address); 706 desc[i].fields.valid, desc[i].fields.length, desc[i].fields.address);
703 } 707 }
704 adapter->tx_send_failed++; 708 tx_send_failed++;
705 adapter->stats.tx_dropped++; 709 tx_dropped++;
706 } else { 710 } else {
707 adapter->stats.tx_packets++; 711 tx_packets++;
708 adapter->stats.tx_bytes += skb->len; 712 tx_bytes += skb->len;
709 netdev->trans_start = jiffies; 713 netdev->trans_start = jiffies;
710 } 714 }
711 715
@@ -715,6 +719,14 @@ static int ibmveth_start_xmit(struct sk_buff *skb, struct net_device *netdev)
715 desc[nfrags].fields.length, DMA_TO_DEVICE); 719 desc[nfrags].fields.length, DMA_TO_DEVICE);
716 } while(--nfrags >= 0); 720 } while(--nfrags >= 0);
717 721
722out: spin_lock_irqsave(&adapter->stats_lock, flags);
723 adapter->stats.tx_dropped += tx_dropped;
724 adapter->stats.tx_bytes += tx_bytes;
725 adapter->stats.tx_packets += tx_packets;
726 adapter->tx_send_failed += tx_send_failed;
727 adapter->tx_map_failed += tx_map_failed;
728 spin_unlock_irqrestore(&adapter->stats_lock, flags);
729
718 dev_kfree_skb(skb); 730 dev_kfree_skb(skb);
719 return 0; 731 return 0;
720} 732}
@@ -980,6 +992,8 @@ static int __devinit ibmveth_probe(struct vio_dev *dev, const struct vio_device_
980 netdev->ethtool_ops = &netdev_ethtool_ops; 992 netdev->ethtool_ops = &netdev_ethtool_ops;
981 netdev->change_mtu = ibmveth_change_mtu; 993 netdev->change_mtu = ibmveth_change_mtu;
982 SET_NETDEV_DEV(netdev, &dev->dev); 994 SET_NETDEV_DEV(netdev, &dev->dev);
995 netdev->features |= NETIF_F_LLTX;
996 spin_lock_init(&adapter->stats_lock);
983 997
984 memcpy(&netdev->dev_addr, &adapter->mac_addr, netdev->addr_len); 998 memcpy(&netdev->dev_addr, &adapter->mac_addr, netdev->addr_len);
985 999
diff --git a/drivers/net/ibmveth.h b/drivers/net/ibmveth.h
index a3ea02937d63..46919a814fca 100644
--- a/drivers/net/ibmveth.h
+++ b/drivers/net/ibmveth.h
@@ -131,6 +131,7 @@ struct ibmveth_adapter {
131 u64 tx_linearize_failed; 131 u64 tx_linearize_failed;
132 u64 tx_map_failed; 132 u64 tx_map_failed;
133 u64 tx_send_failed; 133 u64 tx_send_failed;
134 spinlock_t stats_lock;
134}; 135};
135 136
136struct ibmveth_buf_desc_fields { 137struct ibmveth_buf_desc_fields {