Commit 30eba97a authored by Ayyappan Veeraiyan's avatar Ayyappan Veeraiyan Committed by Jeff Garzik

ixgbe: Introduce Multiqueue TX

Now that the irq vector code is in place, we can add the conditional
multiqueue TX code in the driver. This requires the optional
CONFIG_NETDEVICES_MULTIQUEUE=y and will not be enabled without
it.
Signed-off-by: default avatarAyyappan Veeraiyan <ayyappan.veeraiyan@intel.com>
Signed-off-by: default avatarAuke Kok <auke-jan.h.kok@intel.com>
Acked-by: default avatarWaskiewicz Jr, Peter P <peter.p.waskiewicz.jr@intel.com>
Signed-off-by: default avatarJeff Garzik <jeff@garzik.org>
parent 021230d4
...@@ -246,13 +246,26 @@ static int ixgbe_set_tx_csum(struct net_device *netdev, u32 data) ...@@ -246,13 +246,26 @@ static int ixgbe_set_tx_csum(struct net_device *netdev, u32 data)
static int ixgbe_set_tso(struct net_device *netdev, u32 data) static int ixgbe_set_tso(struct net_device *netdev, u32 data)
{ {
if (data) { if (data) {
netdev->features |= NETIF_F_TSO; netdev->features |= NETIF_F_TSO;
netdev->features |= NETIF_F_TSO6; netdev->features |= NETIF_F_TSO6;
} else { } else {
#ifdef CONFIG_NETDEVICES_MULTIQUEUE
struct ixgbe_adapter *adapter = netdev_priv(netdev);
int i;
#endif
netif_stop_queue(netdev);
#ifdef CONFIG_NETDEVICES_MULTIQUEUE
for (i = 0; i < adapter->num_tx_queues; i++)
netif_stop_subqueue(netdev, i);
#endif
netdev->features &= ~NETIF_F_TSO; netdev->features &= ~NETIF_F_TSO;
netdev->features &= ~NETIF_F_TSO6; netdev->features &= ~NETIF_F_TSO6;
#ifdef CONFIG_NETDEVICES_MULTIQUEUE
for (i = 0; i < adapter->num_tx_queues; i++)
netif_start_subqueue(netdev, i);
#endif
netif_start_queue(netdev);
} }
return 0; return 0;
} }
......
...@@ -256,16 +256,28 @@ static bool ixgbe_clean_tx_irq(struct ixgbe_adapter *adapter, ...@@ -256,16 +256,28 @@ static bool ixgbe_clean_tx_irq(struct ixgbe_adapter *adapter,
* sees the new next_to_clean. * sees the new next_to_clean.
*/ */
smp_mb(); smp_mb();
#ifdef CONFIG_NETDEVICES_MULTIQUEUE
if (__netif_subqueue_stopped(netdev, tx_ring->queue_index) &&
!test_bit(__IXGBE_DOWN, &adapter->state)) {
netif_wake_subqueue(netdev, tx_ring->queue_index);
adapter->restart_queue++;
}
#else
if (netif_queue_stopped(netdev) && if (netif_queue_stopped(netdev) &&
!test_bit(__IXGBE_DOWN, &adapter->state)) { !test_bit(__IXGBE_DOWN, &adapter->state)) {
netif_wake_queue(netdev); netif_wake_queue(netdev);
adapter->restart_queue++; adapter->restart_queue++;
} }
#endif
} }
if (adapter->detect_tx_hung) if (adapter->detect_tx_hung)
if (ixgbe_check_tx_hang(adapter, tx_ring, eop, eop_desc)) if (ixgbe_check_tx_hang(adapter, tx_ring, eop, eop_desc))
#ifdef CONFIG_NETDEVICES_MULTIQUEUE
netif_stop_subqueue(netdev, tx_ring->queue_index);
#else
netif_stop_queue(netdev); netif_stop_queue(netdev);
#endif
if (total_tx_packets >= tx_ring->work_limit) if (total_tx_packets >= tx_ring->work_limit)
IXGBE_WRITE_REG(&adapter->hw, IXGBE_EICS, tx_ring->eims_value); IXGBE_WRITE_REG(&adapter->hw, IXGBE_EICS, tx_ring->eims_value);
...@@ -1812,7 +1824,11 @@ static void __devinit ixgbe_set_num_queues(struct ixgbe_adapter *adapter) ...@@ -1812,7 +1824,11 @@ static void __devinit ixgbe_set_num_queues(struct ixgbe_adapter *adapter)
case (IXGBE_FLAG_RSS_ENABLED): case (IXGBE_FLAG_RSS_ENABLED):
rss_m = 0xF; rss_m = 0xF;
nrq = rss_i; nrq = rss_i;
#ifdef CONFIG_NETDEVICES_MULTIQUEUE
ntq = rss_i;
#else
ntq = 1; ntq = 1;
#endif
break; break;
case 0: case 0:
default: default:
...@@ -1986,6 +2002,10 @@ try_msi: ...@@ -1986,6 +2002,10 @@ try_msi:
} }
out: out:
#ifdef CONFIG_NETDEVICES_MULTIQUEUE
/* Notify the stack of the (possibly) reduced Tx Queue count. */
adapter->netdev->egress_subqueue_count = adapter->num_tx_queues;
#endif
return err; return err;
} }
...@@ -2504,6 +2524,9 @@ static void ixgbe_watchdog(unsigned long data) ...@@ -2504,6 +2524,9 @@ static void ixgbe_watchdog(unsigned long data)
struct net_device *netdev = adapter->netdev; struct net_device *netdev = adapter->netdev;
bool link_up; bool link_up;
u32 link_speed = 0; u32 link_speed = 0;
#ifdef CONFIG_NETDEVICES_MULTIQUEUE
int i;
#endif
adapter->hw.mac.ops.check_link(&adapter->hw, &(link_speed), &link_up); adapter->hw.mac.ops.check_link(&adapter->hw, &(link_speed), &link_up);
...@@ -2525,6 +2548,10 @@ static void ixgbe_watchdog(unsigned long data) ...@@ -2525,6 +2548,10 @@ static void ixgbe_watchdog(unsigned long data)
netif_carrier_on(netdev); netif_carrier_on(netdev);
netif_wake_queue(netdev); netif_wake_queue(netdev);
#ifdef CONFIG_NETDEVICES_MULTIQUEUE
for (i = 0; i < adapter->num_tx_queues; i++)
netif_wake_subqueue(netdev, i);
#endif
} else { } else {
/* Force detection of hung controller */ /* Force detection of hung controller */
adapter->detect_tx_hung = true; adapter->detect_tx_hung = true;
...@@ -2568,7 +2595,6 @@ static int ixgbe_tso(struct ixgbe_adapter *adapter, ...@@ -2568,7 +2595,6 @@ static int ixgbe_tso(struct ixgbe_adapter *adapter,
struct ixgbe_tx_buffer *tx_buffer_info; struct ixgbe_tx_buffer *tx_buffer_info;
u32 vlan_macip_lens = 0, type_tucmd_mlhl = 0; u32 vlan_macip_lens = 0, type_tucmd_mlhl = 0;
u32 mss_l4len_idx = 0, l4len; u32 mss_l4len_idx = 0, l4len;
*hdr_len = 0;
if (skb_is_gso(skb)) { if (skb_is_gso(skb)) {
if (skb_header_cloned(skb)) { if (skb_header_cloned(skb)) {
...@@ -2852,7 +2878,11 @@ static int __ixgbe_maybe_stop_tx(struct net_device *netdev, ...@@ -2852,7 +2878,11 @@ static int __ixgbe_maybe_stop_tx(struct net_device *netdev,
{ {
struct ixgbe_adapter *adapter = netdev_priv(netdev); struct ixgbe_adapter *adapter = netdev_priv(netdev);
#ifdef CONFIG_NETDEVICES_MULTIQUEUE
netif_stop_subqueue(netdev, tx_ring->queue_index);
#else
netif_stop_queue(netdev); netif_stop_queue(netdev);
#endif
/* Herbert's original patch had: /* Herbert's original patch had:
* smp_mb__after_netif_stop_queue(); * smp_mb__after_netif_stop_queue();
* but since that doesn't exist yet, just open code it. */ * but since that doesn't exist yet, just open code it. */
...@@ -2864,7 +2894,11 @@ static int __ixgbe_maybe_stop_tx(struct net_device *netdev, ...@@ -2864,7 +2894,11 @@ static int __ixgbe_maybe_stop_tx(struct net_device *netdev,
return -EBUSY; return -EBUSY;
/* A reprieve! - use start_queue because it doesn't call schedule */ /* A reprieve! - use start_queue because it doesn't call schedule */
#ifdef CONFIG_NETDEVICES_MULTIQUEUE
netif_wake_subqueue(netdev, tx_ring->queue_index);
#else
netif_wake_queue(netdev); netif_wake_queue(netdev);
#endif
++adapter->restart_queue; ++adapter->restart_queue;
return 0; return 0;
} }
...@@ -2885,15 +2919,18 @@ static int ixgbe_xmit_frame(struct sk_buff *skb, struct net_device *netdev) ...@@ -2885,15 +2919,18 @@ static int ixgbe_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
unsigned int len = skb->len; unsigned int len = skb->len;
unsigned int first; unsigned int first;
unsigned int tx_flags = 0; unsigned int tx_flags = 0;
u8 hdr_len; u8 hdr_len = 0;
int tso; int r_idx = 0, tso;
unsigned int mss = 0; unsigned int mss = 0;
int count = 0; int count = 0;
unsigned int f; unsigned int f;
unsigned int nr_frags = skb_shinfo(skb)->nr_frags; unsigned int nr_frags = skb_shinfo(skb)->nr_frags;
len -= skb->data_len; len -= skb->data_len;
#ifdef CONFIG_NETDEVICES_MULTIQUEUE
r_idx = (adapter->num_tx_queues - 1) & skb->queue_mapping;
#endif
tx_ring = &adapter->tx_ring[r_idx];
tx_ring = adapter->tx_ring;
if (skb->len <= 0) { if (skb->len <= 0) {
dev_kfree_skb(skb); dev_kfree_skb(skb);
...@@ -3078,7 +3115,11 @@ static int __devinit ixgbe_probe(struct pci_dev *pdev, ...@@ -3078,7 +3115,11 @@ static int __devinit ixgbe_probe(struct pci_dev *pdev,
pci_set_master(pdev); pci_set_master(pdev);
#ifdef CONFIG_NETDEVICES_MULTIQUEUE
netdev = alloc_etherdev_mq(sizeof(struct ixgbe_adapter), MAX_TX_QUEUES);
#else
netdev = alloc_etherdev(sizeof(struct ixgbe_adapter)); netdev = alloc_etherdev(sizeof(struct ixgbe_adapter));
#endif
if (!netdev) { if (!netdev) {
err = -ENOMEM; err = -ENOMEM;
goto err_alloc_etherdev; goto err_alloc_etherdev;
...@@ -3164,6 +3205,9 @@ static int __devinit ixgbe_probe(struct pci_dev *pdev, ...@@ -3164,6 +3205,9 @@ static int __devinit ixgbe_probe(struct pci_dev *pdev,
if (pci_using_dac) if (pci_using_dac)
netdev->features |= NETIF_F_HIGHDMA; netdev->features |= NETIF_F_HIGHDMA;
#ifdef CONFIG_NETDEVICES_MULTIQUEUE
netdev->features |= NETIF_F_MULTI_QUEUE;
#endif
/* make sure the EEPROM is good */ /* make sure the EEPROM is good */
if (ixgbe_validate_eeprom_checksum(hw, NULL) < 0) { if (ixgbe_validate_eeprom_checksum(hw, NULL) < 0) {
...@@ -3231,6 +3275,10 @@ static int __devinit ixgbe_probe(struct pci_dev *pdev, ...@@ -3231,6 +3275,10 @@ static int __devinit ixgbe_probe(struct pci_dev *pdev,
netif_carrier_off(netdev); netif_carrier_off(netdev);
netif_stop_queue(netdev); netif_stop_queue(netdev);
#ifdef CONFIG_NETDEVICES_MULTIQUEUE
for (i = 0; i < adapter->num_tx_queues; i++)
netif_stop_subqueue(netdev, i);
#endif
ixgbe_napi_add_all(adapter); ixgbe_napi_add_all(adapter);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment