Skip to content

Commit

Permalink
igb: Use node specific allocations for the q_vectors and rings
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Alexander Duyck authored and Jeff Kirsher committed Oct 8, 2011
1 parent 7af40ad commit 81c2fc2
Show file tree
Hide file tree
Showing 2 changed files with 79 additions and 5 deletions.
4 changes: 4 additions & 0 deletions drivers/net/ethernet/intel/igb/igb.h
Original file line number Diff line number Diff line change
Expand Up @@ -185,6 +185,8 @@ struct igb_q_vector {
u16 cpu;
u16 tx_work_limit;

int numa_node;

u16 itr_val;
u8 set_itr;
void __iomem *itr_register;
Expand Down Expand Up @@ -232,6 +234,7 @@ struct igb_ring {
};
/* Items past this point are only used during ring alloc / free */
dma_addr_t dma; /* phys address of the ring */
int numa_node; /* node to alloc ring memory on */
};

#define IGB_RING_FLAG_RX_CSUM 0x00000001 /* RX CSUM enabled */
Expand Down Expand Up @@ -341,6 +344,7 @@ struct igb_adapter {
int vf_rate_link_speed;
u32 rss_queues;
u32 wvbr;
int node;
};

#define IGB_FLAG_HAS_MSI (1 << 0)
Expand Down
80 changes: 75 additions & 5 deletions drivers/net/ethernet/intel/igb/igb_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -687,41 +687,68 @@ static int igb_alloc_queues(struct igb_adapter *adapter)
{
struct igb_ring *ring;
int i;
int orig_node = adapter->node;

for (i = 0; i < adapter->num_tx_queues; i++) {
ring = kzalloc(sizeof(struct igb_ring), GFP_KERNEL);
if (orig_node == -1) {
int cur_node = next_online_node(adapter->node);
if (cur_node == MAX_NUMNODES)
cur_node = first_online_node;
adapter->node = cur_node;
}
ring = kzalloc_node(sizeof(struct igb_ring), GFP_KERNEL,
adapter->node);
if (!ring)
ring = kzalloc(sizeof(struct igb_ring), GFP_KERNEL);
if (!ring)
goto err;
ring->count = adapter->tx_ring_count;
ring->queue_index = i;
ring->dev = &adapter->pdev->dev;
ring->netdev = adapter->netdev;
ring->numa_node = adapter->node;
/* For 82575, context index must be unique per ring. */
if (adapter->hw.mac.type == e1000_82575)
ring->flags = IGB_RING_FLAG_TX_CTX_IDX;
adapter->tx_ring[i] = ring;
}
/* Restore the adapter's original node */
adapter->node = orig_node;

for (i = 0; i < adapter->num_rx_queues; i++) {
ring = kzalloc(sizeof(struct igb_ring), GFP_KERNEL);
if (orig_node == -1) {
int cur_node = next_online_node(adapter->node);
if (cur_node == MAX_NUMNODES)
cur_node = first_online_node;
adapter->node = cur_node;
}
ring = kzalloc_node(sizeof(struct igb_ring), GFP_KERNEL,
adapter->node);
if (!ring)
ring = kzalloc(sizeof(struct igb_ring), GFP_KERNEL);
if (!ring)
goto err;
ring->count = adapter->rx_ring_count;
ring->queue_index = i;
ring->dev = &adapter->pdev->dev;
ring->netdev = adapter->netdev;
ring->numa_node = adapter->node;
ring->flags = IGB_RING_FLAG_RX_CSUM; /* enable rx checksum */
/* set flag indicating ring supports SCTP checksum offload */
if (adapter->hw.mac.type >= e1000_82576)
ring->flags |= IGB_RING_FLAG_RX_SCTP_CSUM;
adapter->rx_ring[i] = ring;
}
/* Restore the adapter's original node */
adapter->node = orig_node;

igb_cache_ring_register(adapter);

return 0;

err:
/* Restore the adapter's original node */
adapter->node = orig_node;
igb_free_queues(adapter);

return -ENOMEM;
Expand Down Expand Up @@ -1087,9 +1114,24 @@ static int igb_alloc_q_vectors(struct igb_adapter *adapter)
struct igb_q_vector *q_vector;
struct e1000_hw *hw = &adapter->hw;
int v_idx;
int orig_node = adapter->node;

for (v_idx = 0; v_idx < adapter->num_q_vectors; v_idx++) {
q_vector = kzalloc(sizeof(struct igb_q_vector), GFP_KERNEL);
if ((adapter->num_q_vectors == (adapter->num_rx_queues +
adapter->num_tx_queues)) &&
(adapter->num_rx_queues == v_idx))
adapter->node = orig_node;
if (orig_node == -1) {
int cur_node = next_online_node(adapter->node);
if (cur_node == MAX_NUMNODES)
cur_node = first_online_node;
adapter->node = cur_node;
}
q_vector = kzalloc_node(sizeof(struct igb_q_vector), GFP_KERNEL,
adapter->node);
if (!q_vector)
q_vector = kzalloc(sizeof(struct igb_q_vector),
GFP_KERNEL);
if (!q_vector)
goto err_out;
q_vector->adapter = adapter;
Expand All @@ -1098,9 +1140,14 @@ static int igb_alloc_q_vectors(struct igb_adapter *adapter)
netif_napi_add(adapter->netdev, &q_vector->napi, igb_poll, 64);
adapter->q_vector[v_idx] = q_vector;
}
/* Restore the adapter's original node */
adapter->node = orig_node;

return 0;

err_out:
/* Restore the adapter's original node */
adapter->node = orig_node;
igb_free_q_vectors(adapter);
return -ENOMEM;
}
Expand Down Expand Up @@ -2409,6 +2456,8 @@ static int __devinit igb_sw_init(struct igb_adapter *adapter)
VLAN_HLEN;
adapter->min_frame_size = ETH_ZLEN + ETH_FCS_LEN;

adapter->node = -1;

spin_lock_init(&adapter->stats64_lock);
#ifdef CONFIG_PCI_IOV
switch (hw->mac.type) {
Expand Down Expand Up @@ -2579,27 +2628,38 @@ static int igb_close(struct net_device *netdev)
int igb_setup_tx_resources(struct igb_ring *tx_ring)
{
struct device *dev = tx_ring->dev;
int orig_node = dev_to_node(dev);
int size;

size = sizeof(struct igb_tx_buffer) * tx_ring->count;
tx_ring->tx_buffer_info = vzalloc(size);
tx_ring->tx_buffer_info = vzalloc_node(size, tx_ring->numa_node);
if (!tx_ring->tx_buffer_info)
tx_ring->tx_buffer_info = vzalloc(size);
if (!tx_ring->tx_buffer_info)
goto err;

/* round up to nearest 4K */
tx_ring->size = tx_ring->count * sizeof(union e1000_adv_tx_desc);
tx_ring->size = ALIGN(tx_ring->size, 4096);

set_dev_node(dev, tx_ring->numa_node);
tx_ring->desc = dma_alloc_coherent(dev,
tx_ring->size,
&tx_ring->dma,
GFP_KERNEL);
set_dev_node(dev, orig_node);
if (!tx_ring->desc)
tx_ring->desc = dma_alloc_coherent(dev,
tx_ring->size,
&tx_ring->dma,
GFP_KERNEL);

if (!tx_ring->desc)
goto err;

tx_ring->next_to_use = 0;
tx_ring->next_to_clean = 0;

return 0;

err:
Expand Down Expand Up @@ -2722,10 +2782,13 @@ static void igb_configure_tx(struct igb_adapter *adapter)
int igb_setup_rx_resources(struct igb_ring *rx_ring)
{
struct device *dev = rx_ring->dev;
int orig_node = dev_to_node(dev);
int size, desc_len;

size = sizeof(struct igb_rx_buffer) * rx_ring->count;
rx_ring->rx_buffer_info = vzalloc(size);
rx_ring->rx_buffer_info = vzalloc_node(size, rx_ring->numa_node);
if (!rx_ring->rx_buffer_info)
rx_ring->rx_buffer_info = vzalloc(size);
if (!rx_ring->rx_buffer_info)
goto err;

Expand All @@ -2735,10 +2798,17 @@ int igb_setup_rx_resources(struct igb_ring *rx_ring)
rx_ring->size = rx_ring->count * desc_len;
rx_ring->size = ALIGN(rx_ring->size, 4096);

set_dev_node(dev, rx_ring->numa_node);
rx_ring->desc = dma_alloc_coherent(dev,
rx_ring->size,
&rx_ring->dma,
GFP_KERNEL);
set_dev_node(dev, orig_node);
if (!rx_ring->desc)
rx_ring->desc = dma_alloc_coherent(dev,
rx_ring->size,
&rx_ring->dma,
GFP_KERNEL);

if (!rx_ring->desc)
goto err;
Expand Down

0 comments on commit 81c2fc2

Please sign in to comment.