Commit 6eb5a7f1 authored by Alexander Duyck's avatar Alexander Duyck Committed by Jeff Garzik

igb: Improve multiqueue AIM support

Improve multiqueue performance
Change itr_val to reflect ITR timer value instead of ints/sec
Cleaned up AIM algorithms in general

Based on work by Mitch Williams
Signed-off-by: default avatarAlexander Duyck <alexander.h.duyck@intel.com>
Acked-by: default avatarMitch Williams <mitch.a.williams@intel.com>
Signed-off-by: default avatarJeff Kirsher <jeffrey.t.kirsher@intel.com>
Signed-off-by: default avatarJeff Garzik <jgarzik@redhat.com>
parent 9280fa52
...@@ -47,7 +47,9 @@ struct igb_adapter; ...@@ -47,7 +47,9 @@ struct igb_adapter;
#define IGB_MIN_DYN_ITR 3000 #define IGB_MIN_DYN_ITR 3000
#define IGB_MAX_DYN_ITR 96000 #define IGB_MAX_DYN_ITR 96000
#define IGB_START_ITR 6000
/* ((1000000000ns / (6000ints/s * 1024ns)) << 2 = 648 */
#define IGB_START_ITR 648
#define IGB_DYN_ITR_PACKET_THRESHOLD 2 #define IGB_DYN_ITR_PACKET_THRESHOLD 2
#define IGB_DYN_ITR_LENGTH_LOW 200 #define IGB_DYN_ITR_LENGTH_LOW 200
...@@ -170,9 +172,10 @@ struct igb_ring { ...@@ -170,9 +172,10 @@ struct igb_ring {
}; };
/* RX */ /* RX */
struct { struct {
int no_itr_adjust;
struct igb_queue_stats rx_stats; struct igb_queue_stats rx_stats;
struct napi_struct napi; struct napi_struct napi;
int set_itr;
struct igb_ring *buddy;
#ifdef CONFIG_IGB_LRO #ifdef CONFIG_IGB_LRO
struct net_lro_mgr lro_mgr; struct net_lro_mgr lro_mgr;
bool lro_used; bool lro_used;
...@@ -219,7 +222,6 @@ struct igb_adapter { ...@@ -219,7 +222,6 @@ struct igb_adapter {
u32 itr_setting; u32 itr_setting;
u16 tx_itr; u16 tx_itr;
u16 rx_itr; u16 rx_itr;
int set_itr;
struct work_struct reset_task; struct work_struct reset_task;
struct work_struct watchdog_task; struct work_struct watchdog_task;
......
...@@ -1861,6 +1861,8 @@ static int igb_set_coalesce(struct net_device *netdev, ...@@ -1861,6 +1861,8 @@ static int igb_set_coalesce(struct net_device *netdev,
struct ethtool_coalesce *ec) struct ethtool_coalesce *ec)
{ {
struct igb_adapter *adapter = netdev_priv(netdev); struct igb_adapter *adapter = netdev_priv(netdev);
struct e1000_hw *hw = &adapter->hw;
int i;
if ((ec->rx_coalesce_usecs > IGB_MAX_ITR_USECS) || if ((ec->rx_coalesce_usecs > IGB_MAX_ITR_USECS) ||
((ec->rx_coalesce_usecs > 3) && ((ec->rx_coalesce_usecs > 3) &&
...@@ -1869,13 +1871,16 @@ static int igb_set_coalesce(struct net_device *netdev, ...@@ -1869,13 +1871,16 @@ static int igb_set_coalesce(struct net_device *netdev,
return -EINVAL; return -EINVAL;
/* convert to rate of irq's per second */ /* convert to rate of irq's per second */
if (ec->rx_coalesce_usecs <= 3) if (ec->rx_coalesce_usecs && ec->rx_coalesce_usecs <= 3) {
adapter->itr_setting = ec->rx_coalesce_usecs; adapter->itr_setting = ec->rx_coalesce_usecs;
else adapter->itr = IGB_START_ITR;
adapter->itr_setting = (1000000 / ec->rx_coalesce_usecs); } else {
adapter->itr_setting = ec->rx_coalesce_usecs << 2;
adapter->itr = adapter->itr_setting;
}
if (netif_running(netdev)) for (i = 0; i < adapter->num_rx_queues; i++)
igb_reinit_locked(adapter); wr32(adapter->rx_ring[i].itr_register, adapter->itr);
return 0; return 0;
} }
...@@ -1888,7 +1893,7 @@ static int igb_get_coalesce(struct net_device *netdev, ...@@ -1888,7 +1893,7 @@ static int igb_get_coalesce(struct net_device *netdev,
if (adapter->itr_setting <= 3) if (adapter->itr_setting <= 3)
ec->rx_coalesce_usecs = adapter->itr_setting; ec->rx_coalesce_usecs = adapter->itr_setting;
else else
ec->rx_coalesce_usecs = 1000000 / adapter->itr_setting; ec->rx_coalesce_usecs = adapter->itr_setting >> 2;
return 0; return 0;
} }
......
This diff is collapsed.
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