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

ixgbe: Merge watchdog functionality into service task

This patch is meant to merge the functionality of the ixgbe watchdog task
into the service task. By doing this all link state functionality will be
controlled by a single task. As a result the reliability of the interface
will be improved as the likelihood of any race conditions is further
reduced.

Signed-off-by: Alexander Duyck <alexander.h.duyck@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>

authored by

Alexander Duyck and committed by
Jeff Kirsher
93c52dd0 7086400d

+218 -184
-2
drivers/net/ixgbe/ixgbe.h
··· 455 455 unsigned long link_check_timeout; 456 456 457 457 struct work_struct reset_task; 458 - struct work_struct watchdog_task; 459 458 struct work_struct fdir_reinit_task; 460 459 struct work_struct check_overtemp_task; 461 460 struct work_struct service_task; 462 - struct timer_list watchdog_timer; 463 461 struct timer_list service_timer; 464 462 u32 fdir_pballoc; 465 463 u32 atr_sample_rate;
+218 -182
drivers/net/ixgbe/ixgbe_main.c
··· 1900 1900 if (!test_bit(__IXGBE_DOWN, &adapter->state)) { 1901 1901 IXGBE_WRITE_REG(hw, IXGBE_EIMC, IXGBE_EIMC_LSC); 1902 1902 IXGBE_WRITE_FLUSH(hw); 1903 - schedule_work(&adapter->watchdog_task); 1903 + ixgbe_service_event_schedule(adapter); 1904 1904 } 1905 1905 } 1906 1906 ··· 3940 3940 * link up interrupt but shouldn't be a problem */ 3941 3941 adapter->flags |= IXGBE_FLAG_NEED_LINK_UPDATE; 3942 3942 adapter->link_check_timeout = jiffies; 3943 - mod_timer(&adapter->watchdog_timer, jiffies); 3944 3943 mod_timer(&adapter->service_timer, jiffies); 3945 3944 3946 3945 /* Set PF Reset Done bit so PF/VF Mail Ops can work */ ··· 4178 4179 4179 4180 netif_tx_stop_all_queues(netdev); 4180 4181 4181 - del_timer_sync(&adapter->watchdog_timer); 4182 - cancel_work_sync(&adapter->watchdog_task); 4183 4182 /* call carrier off first to avoid false dev_watchdog timeouts */ 4184 4183 netif_carrier_off(netdev); 4185 4184 netif_tx_disable(netdev); ··· 5954 5957 } 5955 5958 5956 5959 /** 5957 - * ixgbe_watchdog - Timer Call-back 5958 - * @data: pointer to adapter cast into an unsigned long 5959 - **/ 5960 - static void ixgbe_watchdog(unsigned long data) 5961 - { 5962 - struct ixgbe_adapter *adapter = (struct ixgbe_adapter *)data; 5963 - struct ixgbe_hw *hw = &adapter->hw; 5964 - u64 eics = 0; 5965 - int i; 5966 - 5967 - /* 5968 - * Do the watchdog outside of interrupt context due to the lovely 5969 - * delays that some of the newer hardware requires 5970 - */ 5971 - 5972 - if (test_bit(__IXGBE_DOWN, &adapter->state)) 5973 - goto watchdog_short_circuit; 5974 - 5975 - if (!(adapter->flags & IXGBE_FLAG_MSIX_ENABLED)) { 5976 - /* 5977 - * for legacy and MSI interrupts don't set any bits 5978 - * that are enabled for EIAM, because this operation 5979 - * would set *both* EIMS and EICS for any bit in EIAM 5980 - */ 5981 - IXGBE_WRITE_REG(hw, IXGBE_EICS, 5982 - (IXGBE_EICS_TCP_TIMER | IXGBE_EICS_OTHER)); 5983 - goto watchdog_reschedule; 5984 - } 5985 - 5986 - /* get one bit for every active tx/rx interrupt vector */ 5987 - for (i = 0; i < adapter->num_msix_vectors - NON_Q_VECTORS; i++) { 5988 - struct ixgbe_q_vector *qv = adapter->q_vector[i]; 5989 - if (qv->rxr_count || qv->txr_count) 5990 - eics |= ((u64)1 << i); 5991 - } 5992 - 5993 - /* Cause software interrupt to ensure rx rings are cleaned */ 5994 - ixgbe_irq_rearm_queues(adapter, eics); 5995 - 5996 - watchdog_reschedule: 5997 - /* Reset the timer */ 5998 - mod_timer(&adapter->watchdog_timer, round_jiffies(jiffies + 2 * HZ)); 5999 - 6000 - watchdog_short_circuit: 6001 - schedule_work(&adapter->watchdog_task); 6002 - } 6003 - 6004 - /** 6005 5960 * ixgbe_fdir_reinit_task - worker thread to reinit FDIR filter table 6006 5961 * @work: pointer to work_struct containing our data 6007 5962 **/ ··· 5977 6028 netif_tx_start_all_queues(adapter->netdev); 5978 6029 } 5979 6030 6031 + /** 6032 + * ixgbe_check_hang_subtask - check for hung queues and dropped interrupts 6033 + * @adapter - pointer to the device adapter structure 6034 + * 6035 + * This function serves two purposes. First it strobes the interrupt lines 6036 + * in order to make certain interrupts are occuring. Secondly it sets the 6037 + * bits needed to check for TX hangs. As a result we should immediately 6038 + * determine if a hang has occured. 6039 + */ 6040 + static void ixgbe_check_hang_subtask(struct ixgbe_adapter *adapter) 6041 + { 6042 + struct ixgbe_hw *hw = &adapter->hw; 6043 + u64 eics = 0; 6044 + int i; 6045 + 6046 + /* If we're down or resetting, just bail */ 6047 + if (test_bit(__IXGBE_DOWN, &adapter->state) || 6048 + test_bit(__IXGBE_RESETTING, &adapter->state)) 6049 + return; 6050 + 6051 + /* Force detection of hung controller */ 6052 + if (netif_carrier_ok(adapter->netdev)) { 6053 + for (i = 0; i < adapter->num_tx_queues; i++) 6054 + set_check_for_tx_hang(adapter->tx_ring[i]); 6055 + } 6056 + 6057 + if (!(adapter->flags & IXGBE_FLAG_MSIX_ENABLED)) { 6058 + /* 6059 + * for legacy and MSI interrupts don't set any bits 6060 + * that are enabled for EIAM, because this operation 6061 + * would set *both* EIMS and EICS for any bit in EIAM 6062 + */ 6063 + IXGBE_WRITE_REG(hw, IXGBE_EICS, 6064 + (IXGBE_EICS_TCP_TIMER | IXGBE_EICS_OTHER)); 6065 + } else { 6066 + /* get one bit for every active tx/rx interrupt vector */ 6067 + for (i = 0; i < adapter->num_msix_vectors - NON_Q_VECTORS; i++) { 6068 + struct ixgbe_q_vector *qv = adapter->q_vector[i]; 6069 + if (qv->rxr_count || qv->txr_count) 6070 + eics |= ((u64)1 << i); 6071 + } 6072 + } 6073 + 6074 + /* Cause software interrupt to ensure rings are cleaned */ 6075 + ixgbe_irq_rearm_queues(adapter, eics); 6076 + 6077 + } 6078 + 6079 + /** 6080 + * ixgbe_watchdog_update_link - update the link status 6081 + * @adapter - pointer to the device adapter structure 6082 + * @link_speed - pointer to a u32 to store the link_speed 6083 + **/ 6084 + static void ixgbe_watchdog_update_link(struct ixgbe_adapter *adapter) 6085 + { 6086 + struct ixgbe_hw *hw = &adapter->hw; 6087 + u32 link_speed = adapter->link_speed; 6088 + bool link_up = adapter->link_up; 6089 + int i; 6090 + 6091 + if (!(adapter->flags & IXGBE_FLAG_NEED_LINK_UPDATE)) 6092 + return; 6093 + 6094 + if (hw->mac.ops.check_link) { 6095 + hw->mac.ops.check_link(hw, &link_speed, &link_up, false); 6096 + } else { 6097 + /* always assume link is up, if no check link function */ 6098 + link_speed = IXGBE_LINK_SPEED_10GB_FULL; 6099 + link_up = true; 6100 + } 6101 + if (link_up) { 6102 + if (adapter->flags & IXGBE_FLAG_DCB_ENABLED) { 6103 + for (i = 0; i < MAX_TRAFFIC_CLASS; i++) 6104 + hw->mac.ops.fc_enable(hw, i); 6105 + } else { 6106 + hw->mac.ops.fc_enable(hw, 0); 6107 + } 6108 + } 6109 + 6110 + if (link_up || 6111 + time_after(jiffies, (adapter->link_check_timeout + 6112 + IXGBE_TRY_LINK_TIMEOUT))) { 6113 + adapter->flags &= ~IXGBE_FLAG_NEED_LINK_UPDATE; 6114 + IXGBE_WRITE_REG(hw, IXGBE_EIMS, IXGBE_EIMC_LSC); 6115 + IXGBE_WRITE_FLUSH(hw); 6116 + } 6117 + 6118 + adapter->link_up = link_up; 6119 + adapter->link_speed = link_speed; 6120 + } 6121 + 6122 + /** 6123 + * ixgbe_watchdog_link_is_up - update netif_carrier status and 6124 + * print link up message 6125 + * @adapter - pointer to the device adapter structure 6126 + **/ 6127 + static void ixgbe_watchdog_link_is_up(struct ixgbe_adapter *adapter) 6128 + { 6129 + struct net_device *netdev = adapter->netdev; 6130 + struct ixgbe_hw *hw = &adapter->hw; 6131 + u32 link_speed = adapter->link_speed; 6132 + bool flow_rx, flow_tx; 6133 + 6134 + /* only continue if link was previously down */ 6135 + if (netif_carrier_ok(netdev)) 6136 + return; 6137 + 6138 + adapter->flags2 &= ~IXGBE_FLAG2_SEARCH_FOR_SFP; 6139 + 6140 + switch (hw->mac.type) { 6141 + case ixgbe_mac_82598EB: { 6142 + u32 frctl = IXGBE_READ_REG(hw, IXGBE_FCTRL); 6143 + u32 rmcs = IXGBE_READ_REG(hw, IXGBE_RMCS); 6144 + flow_rx = !!(frctl & IXGBE_FCTRL_RFCE); 6145 + flow_tx = !!(rmcs & IXGBE_RMCS_TFCE_802_3X); 6146 + } 6147 + break; 6148 + case ixgbe_mac_X540: 6149 + case ixgbe_mac_82599EB: { 6150 + u32 mflcn = IXGBE_READ_REG(hw, IXGBE_MFLCN); 6151 + u32 fccfg = IXGBE_READ_REG(hw, IXGBE_FCCFG); 6152 + flow_rx = !!(mflcn & IXGBE_MFLCN_RFCE); 6153 + flow_tx = !!(fccfg & IXGBE_FCCFG_TFCE_802_3X); 6154 + } 6155 + break; 6156 + default: 6157 + flow_tx = false; 6158 + flow_rx = false; 6159 + break; 6160 + } 6161 + e_info(drv, "NIC Link is Up %s, Flow Control: %s\n", 6162 + (link_speed == IXGBE_LINK_SPEED_10GB_FULL ? 6163 + "10 Gbps" : 6164 + (link_speed == IXGBE_LINK_SPEED_1GB_FULL ? 6165 + "1 Gbps" : 6166 + (link_speed == IXGBE_LINK_SPEED_100_FULL ? 6167 + "100 Mbps" : 6168 + "unknown speed"))), 6169 + ((flow_rx && flow_tx) ? "RX/TX" : 6170 + (flow_rx ? "RX" : 6171 + (flow_tx ? "TX" : "None")))); 6172 + 6173 + netif_carrier_on(netdev); 6174 + #ifdef HAVE_IPLINK_VF_CONFIG 6175 + ixgbe_check_vf_rate_limit(adapter); 6176 + #endif /* HAVE_IPLINK_VF_CONFIG */ 6177 + } 6178 + 6179 + /** 6180 + * ixgbe_watchdog_link_is_down - update netif_carrier status and 6181 + * print link down message 6182 + * @adapter - pointer to the adapter structure 6183 + **/ 6184 + static void ixgbe_watchdog_link_is_down(struct ixgbe_adapter* adapter) 6185 + { 6186 + struct net_device *netdev = adapter->netdev; 6187 + struct ixgbe_hw *hw = &adapter->hw; 6188 + 6189 + adapter->link_up = false; 6190 + adapter->link_speed = 0; 6191 + 6192 + /* only continue if link was up previously */ 6193 + if (!netif_carrier_ok(netdev)) 6194 + return; 6195 + 6196 + /* poll for SFP+ cable when link is down */ 6197 + if (ixgbe_is_sfp(hw) && hw->mac.type == ixgbe_mac_82598EB) 6198 + adapter->flags2 |= IXGBE_FLAG2_SEARCH_FOR_SFP; 6199 + 6200 + e_info(drv, "NIC Link is Down\n"); 6201 + netif_carrier_off(netdev); 6202 + } 6203 + 6204 + /** 6205 + * ixgbe_watchdog_flush_tx - flush queues on link down 6206 + * @adapter - pointer to the device adapter structure 6207 + **/ 6208 + static void ixgbe_watchdog_flush_tx(struct ixgbe_adapter *adapter) 6209 + { 6210 + int i; 6211 + int some_tx_pending = 0; 6212 + 6213 + if (!netif_carrier_ok(adapter->netdev)) { 6214 + for (i = 0; i < adapter->num_tx_queues; i++) { 6215 + struct ixgbe_ring *tx_ring = adapter->tx_ring[i]; 6216 + if (tx_ring->next_to_use != tx_ring->next_to_clean) { 6217 + some_tx_pending = 1; 6218 + break; 6219 + } 6220 + } 6221 + 6222 + if (some_tx_pending) { 6223 + /* We've lost link, so the controller stops DMA, 6224 + * but we've got queued Tx work that's never going 6225 + * to get done, so reset controller to flush Tx. 6226 + * (Do the reset outside of interrupt context). 6227 + */ 6228 + schedule_work(&adapter->reset_task); 6229 + } 6230 + } 6231 + } 6232 + 5980 6233 static void ixgbe_spoof_check(struct ixgbe_adapter *adapter) 5981 6234 { 5982 6235 u32 ssvpc; ··· 6199 6048 e_warn(drv, "%d Spoofed packets detected\n", ssvpc); 6200 6049 } 6201 6050 6202 - static DEFINE_MUTEX(ixgbe_watchdog_lock); 6203 - 6204 6051 /** 6205 - * ixgbe_watchdog_task - worker thread to bring link up 6206 - * @work: pointer to work_struct containing our data 6052 + * ixgbe_watchdog_subtask - check and bring link up 6053 + * @adapter - pointer to the device adapter structure 6207 6054 **/ 6208 - static void ixgbe_watchdog_task(struct work_struct *work) 6055 + static void ixgbe_watchdog_subtask(struct ixgbe_adapter *adapter) 6209 6056 { 6210 - struct ixgbe_adapter *adapter = container_of(work, 6211 - struct ixgbe_adapter, 6212 - watchdog_task); 6213 - struct net_device *netdev = adapter->netdev; 6214 - struct ixgbe_hw *hw = &adapter->hw; 6215 - u32 link_speed; 6216 - bool link_up; 6217 - int i; 6218 - struct ixgbe_ring *tx_ring; 6219 - int some_tx_pending = 0; 6057 + /* if interface is down do nothing */ 6058 + if (test_bit(__IXGBE_DOWN, &adapter->state)) 6059 + return; 6220 6060 6221 - mutex_lock(&ixgbe_watchdog_lock); 6061 + ixgbe_watchdog_update_link(adapter); 6222 6062 6223 - link_up = adapter->link_up; 6224 - link_speed = adapter->link_speed; 6225 - 6226 - if (adapter->flags & IXGBE_FLAG_NEED_LINK_UPDATE) { 6227 - hw->mac.ops.check_link(hw, &link_speed, &link_up, false); 6228 - if (link_up) { 6229 - #ifdef CONFIG_DCB 6230 - if (adapter->flags & IXGBE_FLAG_DCB_ENABLED) { 6231 - for (i = 0; i < MAX_TRAFFIC_CLASS; i++) 6232 - hw->mac.ops.fc_enable(hw, i); 6233 - } else { 6234 - hw->mac.ops.fc_enable(hw, 0); 6235 - } 6236 - #else 6237 - hw->mac.ops.fc_enable(hw, 0); 6238 - #endif 6239 - } 6240 - 6241 - if (link_up || 6242 - time_after(jiffies, (adapter->link_check_timeout + 6243 - IXGBE_TRY_LINK_TIMEOUT))) { 6244 - adapter->flags &= ~IXGBE_FLAG_NEED_LINK_UPDATE; 6245 - IXGBE_WRITE_REG(hw, IXGBE_EIMS, IXGBE_EIMC_LSC); 6246 - } 6247 - adapter->link_up = link_up; 6248 - adapter->link_speed = link_speed; 6249 - } 6250 - 6251 - if (link_up) { 6252 - if (!netif_carrier_ok(netdev)) { 6253 - bool flow_rx, flow_tx; 6254 - 6255 - switch (hw->mac.type) { 6256 - case ixgbe_mac_82598EB: { 6257 - u32 frctl = IXGBE_READ_REG(hw, IXGBE_FCTRL); 6258 - u32 rmcs = IXGBE_READ_REG(hw, IXGBE_RMCS); 6259 - flow_rx = !!(frctl & IXGBE_FCTRL_RFCE); 6260 - flow_tx = !!(rmcs & IXGBE_RMCS_TFCE_802_3X); 6261 - } 6262 - break; 6263 - case ixgbe_mac_82599EB: 6264 - case ixgbe_mac_X540: { 6265 - u32 mflcn = IXGBE_READ_REG(hw, IXGBE_MFLCN); 6266 - u32 fccfg = IXGBE_READ_REG(hw, IXGBE_FCCFG); 6267 - flow_rx = !!(mflcn & IXGBE_MFLCN_RFCE); 6268 - flow_tx = !!(fccfg & IXGBE_FCCFG_TFCE_802_3X); 6269 - } 6270 - break; 6271 - default: 6272 - flow_tx = false; 6273 - flow_rx = false; 6274 - break; 6275 - } 6276 - 6277 - e_info(drv, "NIC Link is Up %s, Flow Control: %s\n", 6278 - (link_speed == IXGBE_LINK_SPEED_10GB_FULL ? 6279 - "10 Gbps" : 6280 - (link_speed == IXGBE_LINK_SPEED_1GB_FULL ? 6281 - "1 Gbps" : 6282 - (link_speed == IXGBE_LINK_SPEED_100_FULL ? 6283 - "100 Mbps" : 6284 - "unknown speed"))), 6285 - ((flow_rx && flow_tx) ? "RX/TX" : 6286 - (flow_rx ? "RX" : 6287 - (flow_tx ? "TX" : "None")))); 6288 - 6289 - netif_carrier_on(netdev); 6290 - ixgbe_check_vf_rate_limit(adapter); 6291 - } else { 6292 - /* Force detection of hung controller */ 6293 - for (i = 0; i < adapter->num_tx_queues; i++) { 6294 - tx_ring = adapter->tx_ring[i]; 6295 - set_check_for_tx_hang(tx_ring); 6296 - } 6297 - } 6298 - } else { 6299 - adapter->link_up = false; 6300 - adapter->link_speed = 0; 6301 - if (netif_carrier_ok(netdev)) { 6302 - e_info(drv, "NIC Link is Down\n"); 6303 - netif_carrier_off(netdev); 6304 - } 6305 - } 6306 - 6307 - if (!netif_carrier_ok(netdev)) { 6308 - for (i = 0; i < adapter->num_tx_queues; i++) { 6309 - tx_ring = adapter->tx_ring[i]; 6310 - if (tx_ring->next_to_use != tx_ring->next_to_clean) { 6311 - some_tx_pending = 1; 6312 - break; 6313 - } 6314 - } 6315 - 6316 - if (some_tx_pending) { 6317 - /* We've lost link, so the controller stops DMA, 6318 - * but we've got queued Tx work that's never going 6319 - * to get done, so reset controller to flush Tx. 6320 - * (Do the reset outside of interrupt context). 6321 - */ 6322 - schedule_work(&adapter->reset_task); 6323 - } 6324 - } 6063 + if (adapter->link_up) 6064 + ixgbe_watchdog_link_is_up(adapter); 6065 + else 6066 + ixgbe_watchdog_link_is_down(adapter); 6325 6067 6326 6068 ixgbe_spoof_check(adapter); 6327 6069 ixgbe_update_stats(adapter); 6328 - mutex_unlock(&ixgbe_watchdog_lock); 6070 + 6071 + ixgbe_watchdog_flush_tx(adapter); 6329 6072 } 6330 6073 6331 6074 /** ··· 6353 6308 6354 6309 ixgbe_sfp_detection_subtask(adapter); 6355 6310 ixgbe_sfp_link_config_subtask(adapter); 6311 + ixgbe_watchdog_subtask(adapter); 6312 + ixgbe_check_hang_subtask(adapter); 6356 6313 6357 6314 ixgbe_service_event_complete(adapter); 6358 6315 } ··· 7532 7485 7533 7486 setup_timer(&adapter->service_timer, &ixgbe_service_timer, 7534 7487 (unsigned long) adapter); 7535 - init_timer(&adapter->watchdog_timer); 7536 - adapter->watchdog_timer.function = ixgbe_watchdog; 7537 - adapter->watchdog_timer.data = (unsigned long)adapter; 7538 7488 7539 7489 INIT_WORK(&adapter->reset_task, ixgbe_reset_task); 7540 - INIT_WORK(&adapter->watchdog_task, ixgbe_watchdog_task); 7541 7490 7542 7491 INIT_WORK(&adapter->service_task, ixgbe_service_task); 7543 7492 clear_bit(__IXGBE_SERVICE_SCHED, &adapter->state); ··· 7686 7643 set_bit(__IXGBE_DOWN, &adapter->state); 7687 7644 cancel_work_sync(&adapter->service_task); 7688 7645 7689 - /* 7690 - * The timers may be rescheduled, so explicitly disable them 7691 - * from being rescheduled. 7692 - */ 7693 - del_timer_sync(&adapter->watchdog_timer); 7694 - 7695 - cancel_work_sync(&adapter->watchdog_task); 7696 7646 if (adapter->flags & IXGBE_FLAG_FDIR_HASH_CAPABLE || 7697 7647 adapter->flags & IXGBE_FLAG_FDIR_PERFECT_CAPABLE) 7698 7648 cancel_work_sync(&adapter->fdir_reinit_task);