Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

[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>

authored by

Santiago Leon and committed by
Jeff Garzik
60296d9e e2adbcb4

+30 -15
+29 -15
drivers/net/ibmveth.c
··· 621 621 unsigned long lpar_rc; 622 622 int nfrags = 0, curfrag; 623 623 unsigned long correlator; 624 + unsigned long flags; 624 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 633 if ((skb_shinfo(skb)->nr_frags + 1) > IbmVethMaxSendFrags) { 627 - adapter->stats.tx_dropped++; 628 - dev_kfree_skb(skb); 629 - return 0; 634 + tx_dropped++; 635 + goto out; 630 636 } 631 637 632 638 memset(&desc, 0, sizeof(desc)); ··· 651 645 652 646 if(dma_mapping_error(desc[0].fields.address)) { 653 647 ibmveth_error_printk("tx: unable to map initial fragment\n"); 654 - adapter->tx_map_failed++; 655 - adapter->stats.tx_dropped++; 656 - dev_kfree_skb(skb); 657 - return 0; 648 + tx_map_failed++; 649 + tx_dropped++; 650 + goto out; 658 651 } 659 652 660 653 curfrag = nfrags; ··· 670 665 671 666 if(dma_mapping_error(desc[curfrag+1].fields.address)) { 672 667 ibmveth_error_printk("tx: unable to map fragment %d\n", curfrag); 673 - adapter->tx_map_failed++; 674 - adapter->stats.tx_dropped++; 668 + tx_map_failed++; 669 + tx_dropped++; 675 670 /* Free all the mappings we just created */ 676 671 while(curfrag < nfrags) { 677 672 dma_unmap_single(&adapter->vdev->dev, ··· 680 675 DMA_TO_DEVICE); 681 676 curfrag++; 682 677 } 683 - dev_kfree_skb(skb); 684 - return 0; 678 + goto out; 685 679 } 686 680 } 687 681 ··· 705 701 ibmveth_error_printk("tx: desc[%i] valid=%d, len=%d, address=0x%d\n", i, 706 702 desc[i].fields.valid, desc[i].fields.length, desc[i].fields.address); 707 703 } 708 - adapter->tx_send_failed++; 709 - adapter->stats.tx_dropped++; 704 + tx_send_failed++; 705 + tx_dropped++; 710 706 } else { 711 - adapter->stats.tx_packets++; 712 - adapter->stats.tx_bytes += skb->len; 707 + tx_packets++; 708 + tx_bytes += skb->len; 713 709 netdev->trans_start = jiffies; 714 710 } 715 711 ··· 718 714 desc[nfrags].fields.address, 719 715 desc[nfrags].fields.length, DMA_TO_DEVICE); 720 716 } while(--nfrags >= 0); 717 + 718 + out: spin_lock_irqsave(&adapter->stats_lock, flags); 719 + adapter->stats.tx_dropped += tx_dropped; 720 + adapter->stats.tx_bytes += tx_bytes; 721 + adapter->stats.tx_packets += tx_packets; 722 + adapter->tx_send_failed += tx_send_failed; 723 + adapter->tx_map_failed += tx_map_failed; 724 + spin_unlock_irqrestore(&adapter->stats_lock, flags); 721 725 722 726 dev_kfree_skb(skb); 723 727 return 0; ··· 992 980 netdev->ethtool_ops = &netdev_ethtool_ops; 993 981 netdev->change_mtu = ibmveth_change_mtu; 994 982 SET_NETDEV_DEV(netdev, &dev->dev); 983 + netdev->features |= NETIF_F_LLTX; 984 + spin_lock_init(&adapter->stats_lock); 995 985 996 986 memcpy(&netdev->dev_addr, &adapter->mac_addr, netdev->addr_len); 997 987
+1
drivers/net/ibmveth.h
··· 131 131 u64 tx_linearize_failed; 132 132 u64 tx_map_failed; 133 133 u64 tx_send_failed; 134 + spinlock_t stats_lock; 134 135 }; 135 136 136 137 struct ibmveth_buf_desc_fields {