diff options
author | Alexander Duyck <alexander.h.duyck@intel.com> | 2011-08-26 03:45:20 -0400 |
---|---|---|
committer | Jeff Kirsher <jeffrey.t.kirsher@intel.com> | 2011-10-08 01:34:13 -0400 |
commit | 81c2fc22323f461aee30cf7028a79eb67426e4b6 (patch) | |
tree | 07fd37eb5ca417ca24a25bb1615183944fd13a1a /drivers/net/ethernet/intel/igb/igb_main.c | |
parent | 7af40ad909e3e92a1cbb728999c427d2fa3b381d (diff) |
igb: Use node specific allocations for the q_vectors and rings
This change is meant to update the ring and vector allocations so that they
are per node instead of allocating everything on the node that
ifconfig/modprobe is called on. By doing this we can cut down
significantly on cross node traffic.
Signed-off-by: Alexander Duyck <alexander.h.duyck@intel.com>
Tested-by: Aaron Brown <aaron.f.brown@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
Diffstat (limited to 'drivers/net/ethernet/intel/igb/igb_main.c')
-rw-r--r-- | drivers/net/ethernet/intel/igb/igb_main.c | 80 |
1 files changed, 75 insertions, 5 deletions
diff --git a/drivers/net/ethernet/intel/igb/igb_main.c b/drivers/net/ethernet/intel/igb/igb_main.c index 1c234f03b21c..287be855107a 100644 --- a/drivers/net/ethernet/intel/igb/igb_main.c +++ b/drivers/net/ethernet/intel/igb/igb_main.c | |||
@@ -687,41 +687,68 @@ static int igb_alloc_queues(struct igb_adapter *adapter) | |||
687 | { | 687 | { |
688 | struct igb_ring *ring; | 688 | struct igb_ring *ring; |
689 | int i; | 689 | int i; |
690 | int orig_node = adapter->node; | ||
690 | 691 | ||
691 | for (i = 0; i < adapter->num_tx_queues; i++) { | 692 | for (i = 0; i < adapter->num_tx_queues; i++) { |
692 | ring = kzalloc(sizeof(struct igb_ring), GFP_KERNEL); | 693 | if (orig_node == -1) { |
694 | int cur_node = next_online_node(adapter->node); | ||
695 | if (cur_node == MAX_NUMNODES) | ||
696 | cur_node = first_online_node; | ||
697 | adapter->node = cur_node; | ||
698 | } | ||
699 | ring = kzalloc_node(sizeof(struct igb_ring), GFP_KERNEL, | ||
700 | adapter->node); | ||
701 | if (!ring) | ||
702 | ring = kzalloc(sizeof(struct igb_ring), GFP_KERNEL); | ||
693 | if (!ring) | 703 | if (!ring) |
694 | goto err; | 704 | goto err; |
695 | ring->count = adapter->tx_ring_count; | 705 | ring->count = adapter->tx_ring_count; |
696 | ring->queue_index = i; | 706 | ring->queue_index = i; |
697 | ring->dev = &adapter->pdev->dev; | 707 | ring->dev = &adapter->pdev->dev; |
698 | ring->netdev = adapter->netdev; | 708 | ring->netdev = adapter->netdev; |
709 | ring->numa_node = adapter->node; | ||
699 | /* For 82575, context index must be unique per ring. */ | 710 | /* For 82575, context index must be unique per ring. */ |
700 | if (adapter->hw.mac.type == e1000_82575) | 711 | if (adapter->hw.mac.type == e1000_82575) |
701 | ring->flags = IGB_RING_FLAG_TX_CTX_IDX; | 712 | ring->flags = IGB_RING_FLAG_TX_CTX_IDX; |
702 | adapter->tx_ring[i] = ring; | 713 | adapter->tx_ring[i] = ring; |
703 | } | 714 | } |
715 | /* Restore the adapter's original node */ | ||
716 | adapter->node = orig_node; | ||
704 | 717 | ||
705 | for (i = 0; i < adapter->num_rx_queues; i++) { | 718 | for (i = 0; i < adapter->num_rx_queues; i++) { |
706 | ring = kzalloc(sizeof(struct igb_ring), GFP_KERNEL); | 719 | if (orig_node == -1) { |
720 | int cur_node = next_online_node(adapter->node); | ||
721 | if (cur_node == MAX_NUMNODES) | ||
722 | cur_node = first_online_node; | ||
723 | adapter->node = cur_node; | ||
724 | } | ||
725 | ring = kzalloc_node(sizeof(struct igb_ring), GFP_KERNEL, | ||
726 | adapter->node); | ||
727 | if (!ring) | ||
728 | ring = kzalloc(sizeof(struct igb_ring), GFP_KERNEL); | ||
707 | if (!ring) | 729 | if (!ring) |
708 | goto err; | 730 | goto err; |
709 | ring->count = adapter->rx_ring_count; | 731 | ring->count = adapter->rx_ring_count; |
710 | ring->queue_index = i; | 732 | ring->queue_index = i; |
711 | ring->dev = &adapter->pdev->dev; | 733 | ring->dev = &adapter->pdev->dev; |
712 | ring->netdev = adapter->netdev; | 734 | ring->netdev = adapter->netdev; |
735 | ring->numa_node = adapter->node; | ||
713 | ring->flags = IGB_RING_FLAG_RX_CSUM; /* enable rx checksum */ | 736 | ring->flags = IGB_RING_FLAG_RX_CSUM; /* enable rx checksum */ |
714 | /* set flag indicating ring supports SCTP checksum offload */ | 737 | /* set flag indicating ring supports SCTP checksum offload */ |
715 | if (adapter->hw.mac.type >= e1000_82576) | 738 | if (adapter->hw.mac.type >= e1000_82576) |
716 | ring->flags |= IGB_RING_FLAG_RX_SCTP_CSUM; | 739 | ring->flags |= IGB_RING_FLAG_RX_SCTP_CSUM; |
717 | adapter->rx_ring[i] = ring; | 740 | adapter->rx_ring[i] = ring; |
718 | } | 741 | } |
742 | /* Restore the adapter's original node */ | ||
743 | adapter->node = orig_node; | ||
719 | 744 | ||
720 | igb_cache_ring_register(adapter); | 745 | igb_cache_ring_register(adapter); |
721 | 746 | ||
722 | return 0; | 747 | return 0; |
723 | 748 | ||
724 | err: | 749 | err: |
750 | /* Restore the adapter's original node */ | ||
751 | adapter->node = orig_node; | ||
725 | igb_free_queues(adapter); | 752 | igb_free_queues(adapter); |
726 | 753 | ||
727 | return -ENOMEM; | 754 | return -ENOMEM; |
@@ -1087,9 +1114,24 @@ static int igb_alloc_q_vectors(struct igb_adapter *adapter) | |||
1087 | struct igb_q_vector *q_vector; | 1114 | struct igb_q_vector *q_vector; |
1088 | struct e1000_hw *hw = &adapter->hw; | 1115 | struct e1000_hw *hw = &adapter->hw; |
1089 | int v_idx; | 1116 | int v_idx; |
1117 | int orig_node = adapter->node; | ||
1090 | 1118 | ||
1091 | for (v_idx = 0; v_idx < adapter->num_q_vectors; v_idx++) { | 1119 | for (v_idx = 0; v_idx < adapter->num_q_vectors; v_idx++) { |
1092 | q_vector = kzalloc(sizeof(struct igb_q_vector), GFP_KERNEL); | 1120 | if ((adapter->num_q_vectors == (adapter->num_rx_queues + |
1121 | adapter->num_tx_queues)) && | ||
1122 | (adapter->num_rx_queues == v_idx)) | ||
1123 | adapter->node = orig_node; | ||
1124 | if (orig_node == -1) { | ||
1125 | int cur_node = next_online_node(adapter->node); | ||
1126 | if (cur_node == MAX_NUMNODES) | ||
1127 | cur_node = first_online_node; | ||
1128 | adapter->node = cur_node; | ||
1129 | } | ||
1130 | q_vector = kzalloc_node(sizeof(struct igb_q_vector), GFP_KERNEL, | ||
1131 | adapter->node); | ||
1132 | if (!q_vector) | ||
1133 | q_vector = kzalloc(sizeof(struct igb_q_vector), | ||
1134 | GFP_KERNEL); | ||
1093 | if (!q_vector) | 1135 | if (!q_vector) |
1094 | goto err_out; | 1136 | goto err_out; |
1095 | q_vector->adapter = adapter; | 1137 | q_vector->adapter = adapter; |
@@ -1098,9 +1140,14 @@ static int igb_alloc_q_vectors(struct igb_adapter *adapter) | |||
1098 | netif_napi_add(adapter->netdev, &q_vector->napi, igb_poll, 64); | 1140 | netif_napi_add(adapter->netdev, &q_vector->napi, igb_poll, 64); |
1099 | adapter->q_vector[v_idx] = q_vector; | 1141 | adapter->q_vector[v_idx] = q_vector; |
1100 | } | 1142 | } |
1143 | /* Restore the adapter's original node */ | ||
1144 | adapter->node = orig_node; | ||
1145 | |||
1101 | return 0; | 1146 | return 0; |
1102 | 1147 | ||
1103 | err_out: | 1148 | err_out: |
1149 | /* Restore the adapter's original node */ | ||
1150 | adapter->node = orig_node; | ||
1104 | igb_free_q_vectors(adapter); | 1151 | igb_free_q_vectors(adapter); |
1105 | return -ENOMEM; | 1152 | return -ENOMEM; |
1106 | } | 1153 | } |
@@ -2409,6 +2456,8 @@ static int __devinit igb_sw_init(struct igb_adapter *adapter) | |||
2409 | VLAN_HLEN; | 2456 | VLAN_HLEN; |
2410 | adapter->min_frame_size = ETH_ZLEN + ETH_FCS_LEN; | 2457 | adapter->min_frame_size = ETH_ZLEN + ETH_FCS_LEN; |
2411 | 2458 | ||
2459 | adapter->node = -1; | ||
2460 | |||
2412 | spin_lock_init(&adapter->stats64_lock); | 2461 | spin_lock_init(&adapter->stats64_lock); |
2413 | #ifdef CONFIG_PCI_IOV | 2462 | #ifdef CONFIG_PCI_IOV |
2414 | switch (hw->mac.type) { | 2463 | switch (hw->mac.type) { |
@@ -2579,10 +2628,13 @@ static int igb_close(struct net_device *netdev) | |||
2579 | int igb_setup_tx_resources(struct igb_ring *tx_ring) | 2628 | int igb_setup_tx_resources(struct igb_ring *tx_ring) |
2580 | { | 2629 | { |
2581 | struct device *dev = tx_ring->dev; | 2630 | struct device *dev = tx_ring->dev; |
2631 | int orig_node = dev_to_node(dev); | ||
2582 | int size; | 2632 | int size; |
2583 | 2633 | ||
2584 | size = sizeof(struct igb_tx_buffer) * tx_ring->count; | 2634 | size = sizeof(struct igb_tx_buffer) * tx_ring->count; |
2585 | tx_ring->tx_buffer_info = vzalloc(size); | 2635 | tx_ring->tx_buffer_info = vzalloc_node(size, tx_ring->numa_node); |
2636 | if (!tx_ring->tx_buffer_info) | ||
2637 | tx_ring->tx_buffer_info = vzalloc(size); | ||
2586 | if (!tx_ring->tx_buffer_info) | 2638 | if (!tx_ring->tx_buffer_info) |
2587 | goto err; | 2639 | goto err; |
2588 | 2640 | ||
@@ -2590,16 +2642,24 @@ int igb_setup_tx_resources(struct igb_ring *tx_ring) | |||
2590 | tx_ring->size = tx_ring->count * sizeof(union e1000_adv_tx_desc); | 2642 | tx_ring->size = tx_ring->count * sizeof(union e1000_adv_tx_desc); |
2591 | tx_ring->size = ALIGN(tx_ring->size, 4096); | 2643 | tx_ring->size = ALIGN(tx_ring->size, 4096); |
2592 | 2644 | ||
2645 | set_dev_node(dev, tx_ring->numa_node); | ||
2593 | tx_ring->desc = dma_alloc_coherent(dev, | 2646 | tx_ring->desc = dma_alloc_coherent(dev, |
2594 | tx_ring->size, | 2647 | tx_ring->size, |
2595 | &tx_ring->dma, | 2648 | &tx_ring->dma, |
2596 | GFP_KERNEL); | 2649 | GFP_KERNEL); |
2650 | set_dev_node(dev, orig_node); | ||
2651 | if (!tx_ring->desc) | ||
2652 | tx_ring->desc = dma_alloc_coherent(dev, | ||
2653 | tx_ring->size, | ||
2654 | &tx_ring->dma, | ||
2655 | GFP_KERNEL); | ||
2597 | 2656 | ||
2598 | if (!tx_ring->desc) | 2657 | if (!tx_ring->desc) |
2599 | goto err; | 2658 | goto err; |
2600 | 2659 | ||
2601 | tx_ring->next_to_use = 0; | 2660 | tx_ring->next_to_use = 0; |
2602 | tx_ring->next_to_clean = 0; | 2661 | tx_ring->next_to_clean = 0; |
2662 | |||
2603 | return 0; | 2663 | return 0; |
2604 | 2664 | ||
2605 | err: | 2665 | err: |
@@ -2722,10 +2782,13 @@ static void igb_configure_tx(struct igb_adapter *adapter) | |||
2722 | int igb_setup_rx_resources(struct igb_ring *rx_ring) | 2782 | int igb_setup_rx_resources(struct igb_ring *rx_ring) |
2723 | { | 2783 | { |
2724 | struct device *dev = rx_ring->dev; | 2784 | struct device *dev = rx_ring->dev; |
2785 | int orig_node = dev_to_node(dev); | ||
2725 | int size, desc_len; | 2786 | int size, desc_len; |
2726 | 2787 | ||
2727 | size = sizeof(struct igb_rx_buffer) * rx_ring->count; | 2788 | size = sizeof(struct igb_rx_buffer) * rx_ring->count; |
2728 | rx_ring->rx_buffer_info = vzalloc(size); | 2789 | rx_ring->rx_buffer_info = vzalloc_node(size, rx_ring->numa_node); |
2790 | if (!rx_ring->rx_buffer_info) | ||
2791 | rx_ring->rx_buffer_info = vzalloc(size); | ||
2729 | if (!rx_ring->rx_buffer_info) | 2792 | if (!rx_ring->rx_buffer_info) |
2730 | goto err; | 2793 | goto err; |
2731 | 2794 | ||
@@ -2735,10 +2798,17 @@ int igb_setup_rx_resources(struct igb_ring *rx_ring) | |||
2735 | rx_ring->size = rx_ring->count * desc_len; | 2798 | rx_ring->size = rx_ring->count * desc_len; |
2736 | rx_ring->size = ALIGN(rx_ring->size, 4096); | 2799 | rx_ring->size = ALIGN(rx_ring->size, 4096); |
2737 | 2800 | ||
2801 | set_dev_node(dev, rx_ring->numa_node); | ||
2738 | rx_ring->desc = dma_alloc_coherent(dev, | 2802 | rx_ring->desc = dma_alloc_coherent(dev, |
2739 | rx_ring->size, | 2803 | rx_ring->size, |
2740 | &rx_ring->dma, | 2804 | &rx_ring->dma, |
2741 | GFP_KERNEL); | 2805 | GFP_KERNEL); |
2806 | set_dev_node(dev, orig_node); | ||
2807 | if (!rx_ring->desc) | ||
2808 | rx_ring->desc = dma_alloc_coherent(dev, | ||
2809 | rx_ring->size, | ||
2810 | &rx_ring->dma, | ||
2811 | GFP_KERNEL); | ||
2742 | 2812 | ||
2743 | if (!rx_ring->desc) | 2813 | if (!rx_ring->desc) |
2744 | goto err; | 2814 | goto err; |