aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/ethernet/intel/igb
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2014-08-25 18:51:53 -0400
committerDavid S. Miller <davem@davemloft.net>2014-08-25 19:29:42 -0400
commit0b725a2ca61bedc33a2a63d0451d528b268cf975 (patch)
treeefe818013ee258eeff23f83ca0c8d01b5117a316 /drivers/net/ethernet/intel/igb
parent44a52ffd6402a19544fb9dee081730d36d413202 (diff)
net: Remove ndo_xmit_flush netdev operation, use signalling instead.
As reported by Jesper Dangaard Brouer, for high packet rates the overhead of having another indirect call in the TX path is non-trivial. There is the indirect call itself, and then there is all of the reloading of the state to refetch the tail pointer value and then write the device register. Move to a more passive scheme, which requires very light modifications to the device drivers. The signal is a new skb->xmit_more value, if it is non-zero it means that more SKBs are pending to be transmitted on the same queue as the current SKB. And therefore, the driver may elide the tail pointer update. Right now skb->xmit_more is always zero. Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/ethernet/intel/igb')
-rw-r--r--drivers/net/ethernet/intel/igb/igb_main.c36
1 files changed, 12 insertions, 24 deletions
diff --git a/drivers/net/ethernet/intel/igb/igb_main.c b/drivers/net/ethernet/intel/igb/igb_main.c
index b9c020a05fb8..89c29b40d61c 100644
--- a/drivers/net/ethernet/intel/igb/igb_main.c
+++ b/drivers/net/ethernet/intel/igb/igb_main.c
@@ -136,7 +136,6 @@ static void igb_update_phy_info(unsigned long);
136static void igb_watchdog(unsigned long); 136static void igb_watchdog(unsigned long);
137static void igb_watchdog_task(struct work_struct *); 137static void igb_watchdog_task(struct work_struct *);
138static netdev_tx_t igb_xmit_frame(struct sk_buff *skb, struct net_device *); 138static netdev_tx_t igb_xmit_frame(struct sk_buff *skb, struct net_device *);
139static void igb_xmit_flush(struct net_device *netdev, u16 queue);
140static struct rtnl_link_stats64 *igb_get_stats64(struct net_device *dev, 139static struct rtnl_link_stats64 *igb_get_stats64(struct net_device *dev,
141 struct rtnl_link_stats64 *stats); 140 struct rtnl_link_stats64 *stats);
142static int igb_change_mtu(struct net_device *, int); 141static int igb_change_mtu(struct net_device *, int);
@@ -2076,7 +2075,6 @@ static const struct net_device_ops igb_netdev_ops = {
2076 .ndo_open = igb_open, 2075 .ndo_open = igb_open,
2077 .ndo_stop = igb_close, 2076 .ndo_stop = igb_close,
2078 .ndo_start_xmit = igb_xmit_frame, 2077 .ndo_start_xmit = igb_xmit_frame,
2079 .ndo_xmit_flush = igb_xmit_flush,
2080 .ndo_get_stats64 = igb_get_stats64, 2078 .ndo_get_stats64 = igb_get_stats64,
2081 .ndo_set_rx_mode = igb_set_rx_mode, 2079 .ndo_set_rx_mode = igb_set_rx_mode,
2082 .ndo_set_mac_address = igb_set_mac, 2080 .ndo_set_mac_address = igb_set_mac,
@@ -4917,6 +4915,14 @@ static void igb_tx_map(struct igb_ring *tx_ring,
4917 4915
4918 tx_ring->next_to_use = i; 4916 tx_ring->next_to_use = i;
4919 4917
4918 if (!skb->xmit_more) {
4919 writel(i, tx_ring->tail);
4920
4921 /* we need this if more than one processor can write to our tail
4922 * at a time, it synchronizes IO on IA64/Altix systems
4923 */
4924 mmiowb();
4925 }
4920 return; 4926 return;
4921 4927
4922dma_error: 4928dma_error:
@@ -5052,20 +5058,17 @@ out_drop:
5052 return NETDEV_TX_OK; 5058 return NETDEV_TX_OK;
5053} 5059}
5054 5060
5055static struct igb_ring *__igb_tx_queue_mapping(struct igb_adapter *adapter, unsigned int r_idx) 5061static inline struct igb_ring *igb_tx_queue_mapping(struct igb_adapter *adapter,
5062 struct sk_buff *skb)
5056{ 5063{
5064 unsigned int r_idx = skb->queue_mapping;
5065
5057 if (r_idx >= adapter->num_tx_queues) 5066 if (r_idx >= adapter->num_tx_queues)
5058 r_idx = r_idx % adapter->num_tx_queues; 5067 r_idx = r_idx % adapter->num_tx_queues;
5059 5068
5060 return adapter->tx_ring[r_idx]; 5069 return adapter->tx_ring[r_idx];
5061} 5070}
5062 5071
5063static inline struct igb_ring *igb_tx_queue_mapping(struct igb_adapter *adapter,
5064 struct sk_buff *skb)
5065{
5066 return __igb_tx_queue_mapping(adapter, skb->queue_mapping);
5067}
5068
5069static netdev_tx_t igb_xmit_frame(struct sk_buff *skb, 5072static netdev_tx_t igb_xmit_frame(struct sk_buff *skb,
5070 struct net_device *netdev) 5073 struct net_device *netdev)
5071{ 5074{
@@ -5094,21 +5097,6 @@ static netdev_tx_t igb_xmit_frame(struct sk_buff *skb,
5094 return igb_xmit_frame_ring(skb, igb_tx_queue_mapping(adapter, skb)); 5097 return igb_xmit_frame_ring(skb, igb_tx_queue_mapping(adapter, skb));
5095} 5098}
5096 5099
5097static void igb_xmit_flush(struct net_device *netdev, u16 queue)
5098{
5099 struct igb_adapter *adapter = netdev_priv(netdev);
5100 struct igb_ring *tx_ring;
5101
5102 tx_ring = __igb_tx_queue_mapping(adapter, queue);
5103
5104 writel(tx_ring->next_to_use, tx_ring->tail);
5105
5106 /* we need this if more than one processor can write to our tail
5107 * at a time, it synchronizes IO on IA64/Altix systems
5108 */
5109 mmiowb();
5110}
5111
5112/** 5100/**
5113 * igb_tx_timeout - Respond to a Tx Hang 5101 * igb_tx_timeout - Respond to a Tx Hang
5114 * @netdev: network interface device structure 5102 * @netdev: network interface device structure