Skip to content

Commit

Permalink
ixgbe: Allow tx itr specific settings
Browse files Browse the repository at this point in the history
Allow the user to set Tx specific itr values.  This only makes sense
when there are separate vectors for Tx and Rx.  When the queues are
doubled up RxTx on the vectors, we still only use the rx itr value.

Signed-off-by: Shannon Nelson <shannon.nelson@intel.com>
Acked-by: Peter P Waskiewicz Jr <peter.p.waskiewicz.jr@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
Nelson, Shannon authored and David S. Miller committed Sep 21, 2009
1 parent 0a1f87c commit f7554a2
Show file tree
Hide file tree
Showing 3 changed files with 83 additions and 29 deletions.
6 changes: 4 additions & 2 deletions drivers/net/ixgbe/ixgbe.h
Original file line number Diff line number Diff line change
Expand Up @@ -267,7 +267,8 @@ struct ixgbe_adapter {
enum ixgbe_fc_mode last_lfc_mode;

/* Interrupt Throttle Rate */
u32 itr_setting;
u32 rx_itr_setting;
u32 tx_itr_setting;
u16 eitr_low;
u16 eitr_high;

Expand Down Expand Up @@ -351,7 +352,8 @@ struct ixgbe_adapter {
struct ixgbe_hw_stats stats;

/* Interrupt Throttle Rate */
u32 eitr_param;
u32 rx_eitr_param;
u32 tx_eitr_param;

unsigned long state;
u64 tx_busy;
Expand Down
75 changes: 61 additions & 14 deletions drivers/net/ixgbe/ixgbe_ethtool.c
Original file line number Diff line number Diff line change
Expand Up @@ -1929,7 +1929,7 @@ static int ixgbe_get_coalesce(struct net_device *netdev,
ec->tx_max_coalesced_frames_irq = adapter->tx_ring[0].work_limit;

/* only valid if in constant ITR mode */
switch (adapter->itr_setting) {
switch (adapter->rx_itr_setting) {
case 0:
/* throttling disabled */
ec->rx_coalesce_usecs = 0;
Expand All @@ -1940,9 +1940,25 @@ static int ixgbe_get_coalesce(struct net_device *netdev,
break;
default:
/* fixed interrupt rate mode */
ec->rx_coalesce_usecs = 1000000/adapter->eitr_param;
ec->rx_coalesce_usecs = 1000000/adapter->rx_eitr_param;
break;
}

/* only valid if in constant ITR mode */
switch (adapter->tx_itr_setting) {
case 0:
/* throttling disabled */
ec->tx_coalesce_usecs = 0;
break;
case 1:
/* dynamic ITR mode */
ec->tx_coalesce_usecs = 1;
break;
default:
ec->tx_coalesce_usecs = 1000000/adapter->tx_eitr_param;
break;
}

return 0;
}

Expand All @@ -1953,6 +1969,14 @@ static int ixgbe_set_coalesce(struct net_device *netdev,
struct ixgbe_q_vector *q_vector;
int i;

/*
* don't accept tx specific changes if we've got mixed RxTx vectors
* test and jump out here if needed before changing the rx numbers
*/
if ((1000000/ec->tx_coalesce_usecs) != adapter->tx_eitr_param &&
adapter->q_vector[0]->txr_count && adapter->q_vector[0]->rxr_count)
return -EINVAL;

if (ec->tx_max_coalesced_frames_irq)
adapter->tx_ring[0].work_limit = ec->tx_max_coalesced_frames_irq;

Expand All @@ -1963,26 +1987,49 @@ static int ixgbe_set_coalesce(struct net_device *netdev,
return -EINVAL;

/* store the value in ints/second */
adapter->eitr_param = 1000000/ec->rx_coalesce_usecs;
adapter->rx_eitr_param = 1000000/ec->rx_coalesce_usecs;

/* static value of interrupt rate */
adapter->itr_setting = adapter->eitr_param;
adapter->rx_itr_setting = adapter->rx_eitr_param;
/* clear the lower bit as its used for dynamic state */
adapter->itr_setting &= ~1;
adapter->rx_itr_setting &= ~1;
} else if (ec->rx_coalesce_usecs == 1) {
/* 1 means dynamic mode */
adapter->eitr_param = 20000;
adapter->itr_setting = 1;
adapter->rx_eitr_param = 20000;
adapter->rx_itr_setting = 1;
} else {
/*
* any other value means disable eitr, which is best
* served by setting the interrupt rate very high
*/
if (adapter->flags2 & IXGBE_FLAG2_RSC_ENABLED)
adapter->eitr_param = IXGBE_MAX_RSC_INT_RATE;
adapter->rx_eitr_param = IXGBE_MAX_RSC_INT_RATE;
else
adapter->eitr_param = IXGBE_MAX_INT_RATE;
adapter->itr_setting = 0;
adapter->rx_eitr_param = IXGBE_MAX_INT_RATE;
adapter->rx_itr_setting = 0;
}

if (ec->tx_coalesce_usecs > 1) {
/* check the limits */
if ((1000000/ec->tx_coalesce_usecs > IXGBE_MAX_INT_RATE) ||
(1000000/ec->tx_coalesce_usecs < IXGBE_MIN_INT_RATE))
return -EINVAL;

/* store the value in ints/second */
adapter->tx_eitr_param = 1000000/ec->tx_coalesce_usecs;

/* static value of interrupt rate */
adapter->tx_itr_setting = adapter->tx_eitr_param;

/* clear the lower bit as its used for dynamic state */
adapter->tx_itr_setting &= ~1;
} else if (ec->tx_coalesce_usecs == 1) {
/* 1 means dynamic mode */
adapter->tx_eitr_param = 10000;
adapter->tx_itr_setting = 1;
} else {
adapter->tx_eitr_param = IXGBE_MAX_INT_RATE;
adapter->tx_itr_setting = 0;
}

/* MSI/MSIx Interrupt Mode */
Expand All @@ -1992,17 +2039,17 @@ static int ixgbe_set_coalesce(struct net_device *netdev,
for (i = 0; i < num_vectors; i++) {
q_vector = adapter->q_vector[i];
if (q_vector->txr_count && !q_vector->rxr_count)
/* tx vector gets half the rate */
q_vector->eitr = (adapter->eitr_param >> 1);
/* tx only */
q_vector->eitr = adapter->tx_eitr_param;
else
/* rx only or mixed */
q_vector->eitr = adapter->eitr_param;
q_vector->eitr = adapter->rx_eitr_param;
ixgbe_write_eitr(q_vector);
}
/* Legacy Interrupt Mode */
} else {
q_vector = adapter->q_vector[0];
q_vector->eitr = adapter->eitr_param;
q_vector->eitr = adapter->rx_eitr_param;
ixgbe_write_eitr(q_vector);
}

Expand Down
31 changes: 18 additions & 13 deletions drivers/net/ixgbe/ixgbe_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -926,12 +926,12 @@ static void ixgbe_configure_msix(struct ixgbe_adapter *adapter)
r_idx + 1);
}

/* if this is a tx only vector halve the interrupt rate */
if (q_vector->txr_count && !q_vector->rxr_count)
q_vector->eitr = (adapter->eitr_param >> 1);
/* tx only */
q_vector->eitr = adapter->tx_eitr_param;
else if (q_vector->rxr_count)
/* rx only */
q_vector->eitr = adapter->eitr_param;
/* rx or mixed */
q_vector->eitr = adapter->rx_eitr_param;

ixgbe_write_eitr(q_vector);
}
Expand Down Expand Up @@ -1359,7 +1359,7 @@ static int ixgbe_clean_rxonly(struct napi_struct *napi, int budget)
/* If all Rx work done, exit the polling mode */
if (work_done < budget) {
napi_complete(napi);
if (adapter->itr_setting & 1)
if (adapter->rx_itr_setting & 1)
ixgbe_set_itr_msix(q_vector);
if (!test_bit(__IXGBE_DOWN, &adapter->state))
ixgbe_irq_enable_queues(adapter,
Expand Down Expand Up @@ -1420,7 +1420,7 @@ static int ixgbe_clean_rxtx_many(struct napi_struct *napi, int budget)
/* If all Rx work done, exit the polling mode */
if (work_done < budget) {
napi_complete(napi);
if (adapter->itr_setting & 1)
if (adapter->rx_itr_setting & 1)
ixgbe_set_itr_msix(q_vector);
if (!test_bit(__IXGBE_DOWN, &adapter->state))
ixgbe_irq_enable_queues(adapter,
Expand Down Expand Up @@ -1458,10 +1458,10 @@ static int ixgbe_clean_txonly(struct napi_struct *napi, int budget)
if (!ixgbe_clean_tx_irq(q_vector, tx_ring))
work_done = budget;

/* If all Rx work done, exit the polling mode */
/* If all Tx work done, exit the polling mode */
if (work_done < budget) {
napi_complete(napi);
if (adapter->itr_setting & 1)
if (adapter->tx_itr_setting & 1)
ixgbe_set_itr_msix(q_vector);
if (!test_bit(__IXGBE_DOWN, &adapter->state))
ixgbe_irq_enable_queues(adapter, ((u64)1 << q_vector->v_idx));
Expand Down Expand Up @@ -1848,7 +1848,7 @@ static void ixgbe_configure_msi_and_legacy(struct ixgbe_adapter *adapter)
struct ixgbe_hw *hw = &adapter->hw;

IXGBE_WRITE_REG(hw, IXGBE_EITR(0),
EITR_INTS_PER_SEC_TO_REG(adapter->eitr_param));
EITR_INTS_PER_SEC_TO_REG(adapter->rx_eitr_param));

ixgbe_set_ivar(adapter, 0, 0, 0);
ixgbe_set_ivar(adapter, 1, 0, 0);
Expand Down Expand Up @@ -2991,7 +2991,7 @@ static int ixgbe_poll(struct napi_struct *napi, int budget)
/* If budget not fully consumed, exit the polling mode */
if (work_done < budget) {
napi_complete(napi);
if (adapter->itr_setting & 1)
if (adapter->rx_itr_setting & 1)
ixgbe_set_itr(adapter);
if (!test_bit(__IXGBE_DOWN, &adapter->state))
ixgbe_irq_enable_queues(adapter, IXGBE_EIMS_RTX_QUEUE);
Expand Down Expand Up @@ -3601,7 +3601,10 @@ static int ixgbe_alloc_q_vectors(struct ixgbe_adapter *adapter)
if (!q_vector)
goto err_out;
q_vector->adapter = adapter;
q_vector->eitr = adapter->eitr_param;
if (q_vector->txr_count && !q_vector->rxr_count)
q_vector->eitr = adapter->tx_eitr_param;
else
q_vector->eitr = adapter->rx_eitr_param;
q_vector->v_idx = q_idx;
netif_napi_add(adapter->netdev, &q_vector->napi, (*poll), 64);
adapter->q_vector[q_idx] = q_vector;
Expand Down Expand Up @@ -3870,8 +3873,10 @@ static int __devinit ixgbe_sw_init(struct ixgbe_adapter *adapter)
hw->fc.disable_fc_autoneg = false;

/* enable itr by default in dynamic mode */
adapter->itr_setting = 1;
adapter->eitr_param = 20000;
adapter->rx_itr_setting = 1;
adapter->rx_eitr_param = 20000;
adapter->tx_itr_setting = 1;
adapter->tx_eitr_param = 10000;

/* set defaults for eitr in MegaBytes */
adapter->eitr_low = 10;
Expand Down

0 comments on commit f7554a2

Please sign in to comment.