提交 d034acf1 编写于 作者: A Alexander Duyck 提交者: Jeff Kirsher

ixgbe: Merge ATR reinit into the service task

This change merges the ATR table reinitialization into the service task.
This is yet another opportunity to avoid any race conditions as we don't
want to be attempting to reinitialize the table during a possible reset.

In addition this change adds a counter for table reinitialization so that
it can be tracked as part of the regular statistics.
Signed-off-by: NAlexander Duyck <alexander.h.duyck@intel.com>
Tested-by: NEvan Swanson <evan.swanson@intel.com>
Signed-off-by: NJeff Kirsher <jeffrey.t.kirsher@intel.com>
上级 c83c6cbd
...@@ -382,6 +382,7 @@ struct ixgbe_adapter { ...@@ -382,6 +382,7 @@ struct ixgbe_adapter {
#define IXGBE_FLAG2_SEARCH_FOR_SFP (u32)(1 << 4) #define IXGBE_FLAG2_SEARCH_FOR_SFP (u32)(1 << 4)
#define IXGBE_FLAG2_SFP_NEEDS_RESET (u32)(1 << 5) #define IXGBE_FLAG2_SFP_NEEDS_RESET (u32)(1 << 5)
#define IXGBE_FLAG2_RESET_REQUESTED (u32)(1 << 6) #define IXGBE_FLAG2_RESET_REQUESTED (u32)(1 << 6)
#define IXGBE_FLAG2_FDIR_REQUIRES_REINIT (u32)(1 << 7)
unsigned long active_vlans[BITS_TO_LONGS(VLAN_N_VID)]; unsigned long active_vlans[BITS_TO_LONGS(VLAN_N_VID)];
u16 bd_number; u16 bd_number;
...@@ -455,12 +456,12 @@ struct ixgbe_adapter { ...@@ -455,12 +456,12 @@ struct ixgbe_adapter {
bool link_up; bool link_up;
unsigned long link_check_timeout; unsigned long link_check_timeout;
struct work_struct fdir_reinit_task;
struct work_struct check_overtemp_task; struct work_struct check_overtemp_task;
struct work_struct service_task; struct work_struct service_task;
struct timer_list service_timer; struct timer_list service_timer;
u32 fdir_pballoc; u32 fdir_pballoc;
u32 atr_sample_rate; u32 atr_sample_rate;
unsigned long fdir_overflow; /* number of times ATR was backed off */
spinlock_t fdir_perfect_lock; spinlock_t fdir_perfect_lock;
#ifdef IXGBE_FCOE #ifdef IXGBE_FCOE
struct ixgbe_fcoe fcoe; struct ixgbe_fcoe fcoe;
......
...@@ -84,6 +84,7 @@ static struct ixgbe_stats ixgbe_gstrings_stats[] = { ...@@ -84,6 +84,7 @@ static struct ixgbe_stats ixgbe_gstrings_stats[] = {
{"hw_rsc_flushed", IXGBE_STAT(rsc_total_flush)}, {"hw_rsc_flushed", IXGBE_STAT(rsc_total_flush)},
{"fdir_match", IXGBE_STAT(stats.fdirmatch)}, {"fdir_match", IXGBE_STAT(stats.fdirmatch)},
{"fdir_miss", IXGBE_STAT(stats.fdirmiss)}, {"fdir_miss", IXGBE_STAT(stats.fdirmiss)},
{"fdir_overflow", IXGBE_STAT(fdir_overflow)},
{"rx_fifo_errors", IXGBE_NETDEV_STAT(rx_fifo_errors)}, {"rx_fifo_errors", IXGBE_NETDEV_STAT(rx_fifo_errors)},
{"rx_missed_errors", IXGBE_NETDEV_STAT(rx_missed_errors)}, {"rx_missed_errors", IXGBE_NETDEV_STAT(rx_missed_errors)},
{"tx_aborted_errors", IXGBE_NETDEV_STAT(tx_aborted_errors)}, {"tx_aborted_errors", IXGBE_NETDEV_STAT(tx_aborted_errors)},
......
...@@ -1950,16 +1950,20 @@ static irqreturn_t ixgbe_msix_lsc(int irq, void *data) ...@@ -1950,16 +1950,20 @@ static irqreturn_t ixgbe_msix_lsc(int irq, void *data)
case ixgbe_mac_X540: case ixgbe_mac_X540:
/* Handle Flow Director Full threshold interrupt */ /* Handle Flow Director Full threshold interrupt */
if (eicr & IXGBE_EICR_FLOW_DIR) { if (eicr & IXGBE_EICR_FLOW_DIR) {
int reinit_count = 0;
int i; int i;
IXGBE_WRITE_REG(hw, IXGBE_EICR, IXGBE_EICR_FLOW_DIR);
/* Disable transmits before FDIR Re-initialization */
netif_tx_stop_all_queues(netdev);
for (i = 0; i < adapter->num_tx_queues; i++) { for (i = 0; i < adapter->num_tx_queues; i++) {
struct ixgbe_ring *tx_ring = struct ixgbe_ring *ring = adapter->tx_ring[i];
adapter->tx_ring[i];
if (test_and_clear_bit(__IXGBE_TX_FDIR_INIT_DONE, if (test_and_clear_bit(__IXGBE_TX_FDIR_INIT_DONE,
&tx_ring->state)) &ring->state))
schedule_work(&adapter->fdir_reinit_task); reinit_count++;
}
if (reinit_count) {
/* no more flow director interrupts until after init */
IXGBE_WRITE_REG(hw, IXGBE_EIMC, IXGBE_EIMC_FLOW_DIR);
eicr &= ~IXGBE_EICR_FLOW_DIR;
adapter->flags2 |= IXGBE_FLAG2_FDIR_REQUIRES_REINIT;
ixgbe_service_event_schedule(adapter);
} }
} }
break; break;
...@@ -4198,7 +4202,8 @@ void ixgbe_down(struct ixgbe_adapter *adapter) ...@@ -4198,7 +4202,8 @@ void ixgbe_down(struct ixgbe_adapter *adapter)
ixgbe_napi_disable_all(adapter); ixgbe_napi_disable_all(adapter);
adapter->flags2 &= ~IXGBE_FLAG2_RESET_REQUESTED; adapter->flags2 &= ~(IXGBE_FLAG2_FDIR_REQUIRES_REINIT |
IXGBE_FLAG2_RESET_REQUESTED);
adapter->flags &= ~IXGBE_FLAG_NEED_LINK_UPDATE; adapter->flags &= ~IXGBE_FLAG_NEED_LINK_UPDATE;
del_timer_sync(&adapter->service_timer); del_timer_sync(&adapter->service_timer);
...@@ -4212,13 +4217,6 @@ void ixgbe_down(struct ixgbe_adapter *adapter) ...@@ -4212,13 +4217,6 @@ void ixgbe_down(struct ixgbe_adapter *adapter)
free_cpumask_var(q_vector->affinity_mask); free_cpumask_var(q_vector->affinity_mask);
} }
if (adapter->flags & IXGBE_FLAG_FDIR_HASH_CAPABLE ||
adapter->flags & IXGBE_FLAG_FDIR_PERFECT_CAPABLE)
cancel_work_sync(&adapter->fdir_reinit_task);
if (adapter->flags2 & IXGBE_FLAG2_TEMP_SENSOR_CAPABLE)
cancel_work_sync(&adapter->check_overtemp_task);
/* disable transmits in the hardware now that interrupts are off */ /* disable transmits in the hardware now that interrupts are off */
for (i = 0; i < adapter->num_tx_queues; i++) { for (i = 0; i < adapter->num_tx_queues; i++) {
u8 reg_idx = adapter->tx_ring[i]->reg_idx; u8 reg_idx = adapter->tx_ring[i]->reg_idx;
...@@ -5950,27 +5948,39 @@ void ixgbe_update_stats(struct ixgbe_adapter *adapter) ...@@ -5950,27 +5948,39 @@ void ixgbe_update_stats(struct ixgbe_adapter *adapter)
} }
/** /**
* ixgbe_fdir_reinit_task - worker thread to reinit FDIR filter table * ixgbe_fdir_reinit_subtask - worker thread to reinit FDIR filter table
* @work: pointer to work_struct containing our data * @adapter - pointer to the device adapter structure
**/ **/
static void ixgbe_fdir_reinit_task(struct work_struct *work) static void ixgbe_fdir_reinit_subtask(struct ixgbe_adapter *adapter)
{ {
struct ixgbe_adapter *adapter = container_of(work,
struct ixgbe_adapter,
fdir_reinit_task);
struct ixgbe_hw *hw = &adapter->hw; struct ixgbe_hw *hw = &adapter->hw;
int i; int i;
if (!(adapter->flags2 & IXGBE_FLAG2_FDIR_REQUIRES_REINIT))
return;
adapter->flags2 &= ~IXGBE_FLAG2_FDIR_REQUIRES_REINIT;
/* if interface is down do nothing */
if (test_bit(__IXGBE_DOWN, &adapter->state))
return;
/* do nothing if we are not using signature filters */
if (!(adapter->flags & IXGBE_FLAG_FDIR_HASH_CAPABLE))
return;
adapter->fdir_overflow++;
if (ixgbe_reinit_fdir_tables_82599(hw) == 0) { if (ixgbe_reinit_fdir_tables_82599(hw) == 0) {
for (i = 0; i < adapter->num_tx_queues; i++) for (i = 0; i < adapter->num_tx_queues; i++)
set_bit(__IXGBE_TX_FDIR_INIT_DONE, set_bit(__IXGBE_TX_FDIR_INIT_DONE,
&(adapter->tx_ring[i]->state)); &(adapter->tx_ring[i]->state));
/* re-enable flow director interrupts */
IXGBE_WRITE_REG(hw, IXGBE_EIMS, IXGBE_EIMS_FLOW_DIR);
} else { } else {
e_err(probe, "failed to finish FDIR re-initialization, " e_err(probe, "failed to finish FDIR re-initialization, "
"ignored adding FDIR ATR filters\n"); "ignored adding FDIR ATR filters\n");
} }
/* Done FDIR Re-initialization, enable transmits */
netif_tx_start_all_queues(adapter->netdev);
} }
/** /**
...@@ -6370,6 +6380,7 @@ static void ixgbe_service_task(struct work_struct *work) ...@@ -6370,6 +6380,7 @@ static void ixgbe_service_task(struct work_struct *work)
ixgbe_sfp_detection_subtask(adapter); ixgbe_sfp_detection_subtask(adapter);
ixgbe_sfp_link_config_subtask(adapter); ixgbe_sfp_link_config_subtask(adapter);
ixgbe_watchdog_subtask(adapter); ixgbe_watchdog_subtask(adapter);
ixgbe_fdir_reinit_subtask(adapter);
ixgbe_check_hang_subtask(adapter); ixgbe_check_hang_subtask(adapter);
ixgbe_service_event_complete(adapter); ixgbe_service_event_complete(adapter);
...@@ -7637,10 +7648,6 @@ static int __devinit ixgbe_probe(struct pci_dev *pdev, ...@@ -7637,10 +7648,6 @@ static int __devinit ixgbe_probe(struct pci_dev *pdev,
/* carrier off reporting is important to ethtool even BEFORE open */ /* carrier off reporting is important to ethtool even BEFORE open */
netif_carrier_off(netdev); netif_carrier_off(netdev);
if (adapter->flags & IXGBE_FLAG_FDIR_HASH_CAPABLE ||
adapter->flags & IXGBE_FLAG_FDIR_PERFECT_CAPABLE)
INIT_WORK(&adapter->fdir_reinit_task, ixgbe_fdir_reinit_task);
if (adapter->flags2 & IXGBE_FLAG2_TEMP_SENSOR_CAPABLE) if (adapter->flags2 & IXGBE_FLAG2_TEMP_SENSOR_CAPABLE)
INIT_WORK(&adapter->check_overtemp_task, INIT_WORK(&adapter->check_overtemp_task,
ixgbe_check_overtemp_task); ixgbe_check_overtemp_task);
...@@ -7700,12 +7707,8 @@ static void __devexit ixgbe_remove(struct pci_dev *pdev) ...@@ -7700,12 +7707,8 @@ static void __devexit ixgbe_remove(struct pci_dev *pdev)
set_bit(__IXGBE_DOWN, &adapter->state); set_bit(__IXGBE_DOWN, &adapter->state);
cancel_work_sync(&adapter->service_task); cancel_work_sync(&adapter->service_task);
if (adapter->flags & IXGBE_FLAG_FDIR_HASH_CAPABLE ||
adapter->flags & IXGBE_FLAG_FDIR_PERFECT_CAPABLE)
cancel_work_sync(&adapter->fdir_reinit_task);
if (adapter->flags2 & IXGBE_FLAG2_TEMP_SENSOR_CAPABLE) if (adapter->flags2 & IXGBE_FLAG2_TEMP_SENSOR_CAPABLE)
cancel_work_sync(&adapter->check_overtemp_task); cancel_work_sync(&adapter->check_overtemp_task);
#ifdef CONFIG_IXGBE_DCA #ifdef CONFIG_IXGBE_DCA
if (adapter->flags & IXGBE_FLAG_DCA_ENABLED) { if (adapter->flags & IXGBE_FLAG_DCA_ENABLED) {
adapter->flags &= ~IXGBE_FLAG_DCA_ENABLED; adapter->flags &= ~IXGBE_FLAG_DCA_ENABLED;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册