Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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: Alexander Duyck <alexander.h.duyck@intel.com>
Tested-by: Evan Swanson <evan.swanson@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>

authored by

Alexander Duyck and committed by
Jeff Kirsher
d034acf1 c83c6cbd

+37 -32
+2 -1
drivers/net/ixgbe/ixgbe.h
··· 382 382 #define IXGBE_FLAG2_SEARCH_FOR_SFP (u32)(1 << 4) 383 383 #define IXGBE_FLAG2_SFP_NEEDS_RESET (u32)(1 << 5) 384 384 #define IXGBE_FLAG2_RESET_REQUESTED (u32)(1 << 6) 385 + #define IXGBE_FLAG2_FDIR_REQUIRES_REINIT (u32)(1 << 7) 385 386 386 387 unsigned long active_vlans[BITS_TO_LONGS(VLAN_N_VID)]; 387 388 u16 bd_number; ··· 456 455 bool link_up; 457 456 unsigned long link_check_timeout; 458 457 459 - struct work_struct fdir_reinit_task; 460 458 struct work_struct check_overtemp_task; 461 459 struct work_struct service_task; 462 460 struct timer_list service_timer; 463 461 u32 fdir_pballoc; 464 462 u32 atr_sample_rate; 463 + unsigned long fdir_overflow; /* number of times ATR was backed off */ 465 464 spinlock_t fdir_perfect_lock; 466 465 #ifdef IXGBE_FCOE 467 466 struct ixgbe_fcoe fcoe;
+1
drivers/net/ixgbe/ixgbe_ethtool.c
··· 84 84 {"hw_rsc_flushed", IXGBE_STAT(rsc_total_flush)}, 85 85 {"fdir_match", IXGBE_STAT(stats.fdirmatch)}, 86 86 {"fdir_miss", IXGBE_STAT(stats.fdirmiss)}, 87 + {"fdir_overflow", IXGBE_STAT(fdir_overflow)}, 87 88 {"rx_fifo_errors", IXGBE_NETDEV_STAT(rx_fifo_errors)}, 88 89 {"rx_missed_errors", IXGBE_NETDEV_STAT(rx_missed_errors)}, 89 90 {"tx_aborted_errors", IXGBE_NETDEV_STAT(tx_aborted_errors)},
+34 -31
drivers/net/ixgbe/ixgbe_main.c
··· 1950 1950 case ixgbe_mac_X540: 1951 1951 /* Handle Flow Director Full threshold interrupt */ 1952 1952 if (eicr & IXGBE_EICR_FLOW_DIR) { 1953 + int reinit_count = 0; 1953 1954 int i; 1954 - IXGBE_WRITE_REG(hw, IXGBE_EICR, IXGBE_EICR_FLOW_DIR); 1955 - /* Disable transmits before FDIR Re-initialization */ 1956 - netif_tx_stop_all_queues(netdev); 1957 1955 for (i = 0; i < adapter->num_tx_queues; i++) { 1958 - struct ixgbe_ring *tx_ring = 1959 - adapter->tx_ring[i]; 1956 + struct ixgbe_ring *ring = adapter->tx_ring[i]; 1960 1957 if (test_and_clear_bit(__IXGBE_TX_FDIR_INIT_DONE, 1961 - &tx_ring->state)) 1962 - schedule_work(&adapter->fdir_reinit_task); 1958 + &ring->state)) 1959 + reinit_count++; 1960 + } 1961 + if (reinit_count) { 1962 + /* no more flow director interrupts until after init */ 1963 + IXGBE_WRITE_REG(hw, IXGBE_EIMC, IXGBE_EIMC_FLOW_DIR); 1964 + eicr &= ~IXGBE_EICR_FLOW_DIR; 1965 + adapter->flags2 |= IXGBE_FLAG2_FDIR_REQUIRES_REINIT; 1966 + ixgbe_service_event_schedule(adapter); 1963 1967 } 1964 1968 } 1965 1969 break; ··· 4202 4198 4203 4199 ixgbe_napi_disable_all(adapter); 4204 4200 4205 - adapter->flags2 &= ~IXGBE_FLAG2_RESET_REQUESTED; 4201 + adapter->flags2 &= ~(IXGBE_FLAG2_FDIR_REQUIRES_REINIT | 4202 + IXGBE_FLAG2_RESET_REQUESTED); 4206 4203 adapter->flags &= ~IXGBE_FLAG_NEED_LINK_UPDATE; 4207 4204 4208 4205 del_timer_sync(&adapter->service_timer); ··· 4216 4211 /* release the CPU mask memory */ 4217 4212 free_cpumask_var(q_vector->affinity_mask); 4218 4213 } 4219 - 4220 - if (adapter->flags & IXGBE_FLAG_FDIR_HASH_CAPABLE || 4221 - adapter->flags & IXGBE_FLAG_FDIR_PERFECT_CAPABLE) 4222 - cancel_work_sync(&adapter->fdir_reinit_task); 4223 - 4224 - if (adapter->flags2 & IXGBE_FLAG2_TEMP_SENSOR_CAPABLE) 4225 - cancel_work_sync(&adapter->check_overtemp_task); 4226 4214 4227 4215 /* disable transmits in the hardware now that interrupts are off */ 4228 4216 for (i = 0; i < adapter->num_tx_queues; i++) { ··· 5948 5950 } 5949 5951 5950 5952 /** 5951 - * ixgbe_fdir_reinit_task - worker thread to reinit FDIR filter table 5952 - * @work: pointer to work_struct containing our data 5953 + * ixgbe_fdir_reinit_subtask - worker thread to reinit FDIR filter table 5954 + * @adapter - pointer to the device adapter structure 5953 5955 **/ 5954 - static void ixgbe_fdir_reinit_task(struct work_struct *work) 5956 + static void ixgbe_fdir_reinit_subtask(struct ixgbe_adapter *adapter) 5955 5957 { 5956 - struct ixgbe_adapter *adapter = container_of(work, 5957 - struct ixgbe_adapter, 5958 - fdir_reinit_task); 5959 5958 struct ixgbe_hw *hw = &adapter->hw; 5960 5959 int i; 5960 + 5961 + if (!(adapter->flags2 & IXGBE_FLAG2_FDIR_REQUIRES_REINIT)) 5962 + return; 5963 + 5964 + adapter->flags2 &= ~IXGBE_FLAG2_FDIR_REQUIRES_REINIT; 5965 + 5966 + /* if interface is down do nothing */ 5967 + if (test_bit(__IXGBE_DOWN, &adapter->state)) 5968 + return; 5969 + 5970 + /* do nothing if we are not using signature filters */ 5971 + if (!(adapter->flags & IXGBE_FLAG_FDIR_HASH_CAPABLE)) 5972 + return; 5973 + 5974 + adapter->fdir_overflow++; 5961 5975 5962 5976 if (ixgbe_reinit_fdir_tables_82599(hw) == 0) { 5963 5977 for (i = 0; i < adapter->num_tx_queues; i++) 5964 5978 set_bit(__IXGBE_TX_FDIR_INIT_DONE, 5965 5979 &(adapter->tx_ring[i]->state)); 5980 + /* re-enable flow director interrupts */ 5981 + IXGBE_WRITE_REG(hw, IXGBE_EIMS, IXGBE_EIMS_FLOW_DIR); 5966 5982 } else { 5967 5983 e_err(probe, "failed to finish FDIR re-initialization, " 5968 5984 "ignored adding FDIR ATR filters\n"); 5969 5985 } 5970 - /* Done FDIR Re-initialization, enable transmits */ 5971 - netif_tx_start_all_queues(adapter->netdev); 5972 5986 } 5973 5987 5974 5988 /** ··· 6380 6370 ixgbe_sfp_detection_subtask(adapter); 6381 6371 ixgbe_sfp_link_config_subtask(adapter); 6382 6372 ixgbe_watchdog_subtask(adapter); 6373 + ixgbe_fdir_reinit_subtask(adapter); 6383 6374 ixgbe_check_hang_subtask(adapter); 6384 6375 6385 6376 ixgbe_service_event_complete(adapter); ··· 7648 7637 /* carrier off reporting is important to ethtool even BEFORE open */ 7649 7638 netif_carrier_off(netdev); 7650 7639 7651 - if (adapter->flags & IXGBE_FLAG_FDIR_HASH_CAPABLE || 7652 - adapter->flags & IXGBE_FLAG_FDIR_PERFECT_CAPABLE) 7653 - INIT_WORK(&adapter->fdir_reinit_task, ixgbe_fdir_reinit_task); 7654 - 7655 7640 if (adapter->flags2 & IXGBE_FLAG2_TEMP_SENSOR_CAPABLE) 7656 7641 INIT_WORK(&adapter->check_overtemp_task, 7657 7642 ixgbe_check_overtemp_task); ··· 7707 7700 set_bit(__IXGBE_DOWN, &adapter->state); 7708 7701 cancel_work_sync(&adapter->service_task); 7709 7702 7710 - if (adapter->flags & IXGBE_FLAG_FDIR_HASH_CAPABLE || 7711 - adapter->flags & IXGBE_FLAG_FDIR_PERFECT_CAPABLE) 7712 - cancel_work_sync(&adapter->fdir_reinit_task); 7713 7703 if (adapter->flags2 & IXGBE_FLAG2_TEMP_SENSOR_CAPABLE) 7714 7704 cancel_work_sync(&adapter->check_overtemp_task); 7715 - 7716 7705 #ifdef CONFIG_IXGBE_DCA 7717 7706 if (adapter->flags & IXGBE_FLAG_DCA_ENABLED) { 7718 7707 adapter->flags &= ~IXGBE_FLAG_DCA_ENABLED;