diff options
author | Brett Creeley <brett.creeley@intel.com> | 2018-12-19 13:03:29 -0500 |
---|---|---|
committer | Jeff Kirsher <jeffrey.t.kirsher@intel.com> | 2019-01-15 14:29:16 -0500 |
commit | 63f545ed1285a5f904c260ff22c958609c3c11c5 (patch) | |
tree | 28e93dc5f427de3efb9bd4e352a165ab90f33dab /drivers/net/ethernet/intel/ice/ice_lib.c | |
parent | 9be1d6f8c33731acd67586a4e40c0f3d56a23366 (diff) |
ice: Add support for adaptive interrupt moderation
Currently the driver does not support adaptive/dynamic interrupt
moderation. This patch adds support for this. Also, adaptive/dynamic
interrupt moderation is turned on by default upon driver load.
In order to support adaptive interrupt moderation, two functions were
added, ice_update_itr() and ice_itr_divisor(). These are used to
determine the current packet load and to determine a divisor based
on link speed respectively.
This patch also adds the ICE_ITR_GRAN_S define that is used in the
hot-path when setting a new ITR value. The shift is used to pet two
birds with one hand, set the ITR value while re-enabling the
interrupt. Also, the ICE_ITR_GRAN_S is defined as 1 because the device
has a ITR granularity of 2usecs.
Signed-off-by: Brett Creeley <brett.creeley@intel.com>
Signed-off-by: Anirudh Venkataramanan <anirudh.venkataramanan@intel.com>
Tested-by: Andrew Bowers <andrewx.bowers@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
Diffstat (limited to 'drivers/net/ethernet/intel/ice/ice_lib.c')
-rw-r--r-- | drivers/net/ethernet/intel/ice/ice_lib.c | 24 |
1 files changed, 18 insertions, 6 deletions
diff --git a/drivers/net/ethernet/intel/ice/ice_lib.c b/drivers/net/ethernet/intel/ice/ice_lib.c index a1f523a9d39d..27c3760ae5cb 100644 --- a/drivers/net/ethernet/intel/ice/ice_lib.c +++ b/drivers/net/ethernet/intel/ice/ice_lib.c | |||
@@ -1717,22 +1717,34 @@ static u32 ice_intrl_usec_to_reg(u8 intrl, u8 gran) | |||
1717 | static void | 1717 | static void |
1718 | ice_cfg_itr(struct ice_hw *hw, struct ice_q_vector *q_vector, u16 vector) | 1718 | ice_cfg_itr(struct ice_hw *hw, struct ice_q_vector *q_vector, u16 vector) |
1719 | { | 1719 | { |
1720 | u8 itr_gran = hw->itr_gran; | ||
1721 | |||
1722 | if (q_vector->num_ring_rx) { | 1720 | if (q_vector->num_ring_rx) { |
1723 | struct ice_ring_container *rc = &q_vector->rx; | 1721 | struct ice_ring_container *rc = &q_vector->rx; |
1724 | 1722 | ||
1725 | rc->itr = ITR_TO_REG(ICE_DFLT_RX_ITR, itr_gran); | 1723 | /* if this value is set then don't overwrite with default */ |
1724 | if (!rc->itr_setting) | ||
1725 | rc->itr_setting = ICE_DFLT_RX_ITR; | ||
1726 | |||
1727 | rc->target_itr = ITR_TO_REG(rc->itr_setting); | ||
1728 | rc->next_update = jiffies + 1; | ||
1729 | rc->current_itr = rc->target_itr; | ||
1726 | rc->latency_range = ICE_LOW_LATENCY; | 1730 | rc->latency_range = ICE_LOW_LATENCY; |
1727 | wr32(hw, GLINT_ITR(rc->itr_idx, vector), rc->itr); | 1731 | wr32(hw, GLINT_ITR(rc->itr_idx, vector), |
1732 | ITR_REG_ALIGN(rc->current_itr) >> ICE_ITR_GRAN_S); | ||
1728 | } | 1733 | } |
1729 | 1734 | ||
1730 | if (q_vector->num_ring_tx) { | 1735 | if (q_vector->num_ring_tx) { |
1731 | struct ice_ring_container *rc = &q_vector->tx; | 1736 | struct ice_ring_container *rc = &q_vector->tx; |
1732 | 1737 | ||
1733 | rc->itr = ITR_TO_REG(ICE_DFLT_TX_ITR, itr_gran); | 1738 | /* if this value is set then don't overwrite with default */ |
1739 | if (!rc->itr_setting) | ||
1740 | rc->itr_setting = ICE_DFLT_TX_ITR; | ||
1741 | |||
1742 | rc->target_itr = ITR_TO_REG(rc->itr_setting); | ||
1743 | rc->next_update = jiffies + 1; | ||
1744 | rc->current_itr = rc->target_itr; | ||
1734 | rc->latency_range = ICE_LOW_LATENCY; | 1745 | rc->latency_range = ICE_LOW_LATENCY; |
1735 | wr32(hw, GLINT_ITR(rc->itr_idx, vector), rc->itr); | 1746 | wr32(hw, GLINT_ITR(rc->itr_idx, vector), |
1747 | ITR_REG_ALIGN(rc->current_itr) >> ICE_ITR_GRAN_S); | ||
1736 | } | 1748 | } |
1737 | } | 1749 | } |
1738 | 1750 | ||