diff options
| author | CNSS_WLAN Service <cnssbldsw@qualcomm.com> | 2017-09-01 20:54:19 -0700 |
|---|---|---|
| committer | Gerrit - the friendly Code Review server <code-review@localhost> | 2017-09-01 20:54:19 -0700 |
| commit | 4e5f013d7cb472d37af7a1e362e887ca65e68b6b (patch) | |
| tree | 13baa83bc6926bb7e55608b47916d80ca5856810 | |
| parent | 11f69018a680dc175618c5f5969d569396c1a2ec (diff) | |
| parent | 38ed038b3c59d8ee80aa5203837d66f101a03ae3 (diff) | |
Merge "qcacld-3.0: Send TX timeout event for TX data stall" into wlan-cld3.driver.lnx.1.1
| -rw-r--r-- | core/hdd/inc/wlan_hdd_main.h | 8 | ||||
| -rw-r--r-- | core/hdd/src/wlan_hdd_assoc.c | 2 | ||||
| -rw-r--r-- | core/hdd/src/wlan_hdd_softap_tx_rx.c | 42 | ||||
| -rw-r--r-- | core/hdd/src/wlan_hdd_tx_rx.c | 64 |
4 files changed, 68 insertions, 48 deletions
diff --git a/core/hdd/inc/wlan_hdd_main.h b/core/hdd/inc/wlan_hdd_main.h index e28aceed91a6..467855a812d2 100644 --- a/core/hdd/inc/wlan_hdd_main.h +++ b/core/hdd/inc/wlan_hdd_main.h @@ -89,6 +89,9 @@ #else #define HDD_TX_TIMEOUT msecs_to_jiffies(5000) #endif + +#define HDD_TX_STALL_THRESHOLD 4 + /** Hdd Default MTU */ #define HDD_DEFAULT_MTU (1500) @@ -470,6 +473,11 @@ typedef struct hdd_tx_rx_stats_s { __u32 txflow_pause_cnt; __u32 txflow_unpause_cnt; __u32 txflow_timer_cnt; + + /*tx timeout stats*/ + __u32 tx_timeout_cnt; + __u32 cont_txtimeout_cnt; + u64 jiffies_last_txtimeout; } hdd_tx_rx_stats_t; #ifdef WLAN_FEATURE_11W diff --git a/core/hdd/src/wlan_hdd_assoc.c b/core/hdd/src/wlan_hdd_assoc.c index 672d52c59756..cc0ef6b03eee 100644 --- a/core/hdd/src/wlan_hdd_assoc.c +++ b/core/hdd/src/wlan_hdd_assoc.c @@ -1713,6 +1713,8 @@ static QDF_STATUS hdd_dis_connect_handler(hdd_adapter_t *pAdapter, pAdapter->dad = false; + pAdapter->hdd_stats.hddTxRxStats.cont_txtimeout_cnt = 0; + /* Unblock anyone waiting for disconnect to complete */ complete(&pAdapter->disconnect_comp_var); hdd_print_bss_info(pHddStaCtx); diff --git a/core/hdd/src/wlan_hdd_softap_tx_rx.c b/core/hdd/src/wlan_hdd_softap_tx_rx.c index b0aade85a0a5..c3caee5153bf 100644 --- a/core/hdd/src/wlan_hdd_softap_tx_rx.c +++ b/core/hdd/src/wlan_hdd_softap_tx_rx.c @@ -255,6 +255,8 @@ static int __hdd_softap_hard_start_xmit(struct sk_buff *skb, uint32_t num_seg; ++pAdapter->hdd_stats.hddTxRxStats.txXmitCalled; + pAdapter->hdd_stats.hddTxRxStats.cont_txtimeout_cnt = 0; + /* Prevent this function from being called during SSR since TL * context may not be reinitialized at this time which may * lead to a crash. @@ -478,30 +480,6 @@ int hdd_softap_hard_start_xmit(struct sk_buff *skb, struct net_device *dev) return ret; } -#ifdef FEATURE_WLAN_DIAG_SUPPORT -/** - * hdd_wlan_datastall_sap_event()- Send SAP datastall information - * - * This Function send send SAP datastall diag event - * - * Return: void. - */ -static void hdd_wlan_datastall_sap_event(void) -{ - WLAN_HOST_DIAG_EVENT_DEF(sap_data_stall, - struct host_event_wlan_datastall); - qdf_mem_zero(&sap_data_stall, sizeof(sap_data_stall)); - sap_data_stall.reason = SOFTAP_TX_TIMEOUT; - WLAN_HOST_DIAG_EVENT_REPORT(&sap_data_stall, - EVENT_WLAN_SOFTAP_DATASTALL); -} -#else -static inline void hdd_wlan_datastall_sap_event(void) -{ - -} -#endif - /** * __hdd_softap_tx_timeout() - TX timeout handler * @dev: pointer to network device @@ -548,7 +526,21 @@ static void __hdd_softap_tx_timeout(struct net_device *dev) ol_tx_dump_flow_pool_info(); QDF_TRACE(QDF_MODULE_ID_HDD_DATA, QDF_TRACE_LEVEL_DEBUG, "carrier state: %d", netif_carrier_ok(dev)); - hdd_wlan_datastall_sap_event(); + + ++adapter->hdd_stats.hddTxRxStats.tx_timeout_cnt; + ++adapter->hdd_stats.hddTxRxStats.cont_txtimeout_cnt; + + if (adapter->hdd_stats.hddTxRxStats.cont_txtimeout_cnt > + HDD_TX_STALL_THRESHOLD) { + QDF_TRACE(QDF_MODULE_ID_HDD_DATA, QDF_TRACE_LEVEL_ERROR, + "Detected data stall due to continuous TX timeouts"); + adapter->hdd_stats.hddTxRxStats.cont_txtimeout_cnt = 0; + ol_txrx_post_data_stall_event( + DATA_STALL_LOG_INDICATOR_HOST_DRIVER, + DATA_STALL_LOG_HOST_SOFTAP_TX_TIMEOUT, + 0xFF, 0xFF, + DATA_STALL_LOG_RECOVERY_TRIGGER_PDR); + } } /** diff --git a/core/hdd/src/wlan_hdd_tx_rx.c b/core/hdd/src/wlan_hdd_tx_rx.c index 4c6c8d9df30a..7d7444df4e29 100644 --- a/core/hdd/src/wlan_hdd_tx_rx.c +++ b/core/hdd/src/wlan_hdd_tx_rx.c @@ -508,6 +508,7 @@ static int __hdd_hard_start_xmit(struct sk_buff *skb, struct net_device *dev) wlan_hdd_latency_opt(pAdapter, skb); ++pAdapter->hdd_stats.hddTxRxStats.txXmitCalled; + pAdapter->hdd_stats.hddTxRxStats.cont_txtimeout_cnt = 0; if (QDF_NBUF_CB_GET_PACKET_TYPE(skb) == QDF_NBUF_CB_PACKET_TYPE_ARP) { is_arp = true; @@ -805,28 +806,6 @@ QDF_STATUS hdd_get_peer_sta_id(hdd_station_ctx_t *pHddStaCtx, return QDF_STATUS_E_FAILURE; } -#ifdef FEATURE_WLAN_DIAG_SUPPORT -/** - * hdd_wlan_datastall_sta_event()- send sta datastall information - * - * This Function send send sta datastall status diag event - * - * Return: void. - */ -static void hdd_wlan_datastall_sta_event(void) -{ - WLAN_HOST_DIAG_EVENT_DEF(sta_data_stall, - struct host_event_wlan_datastall); - qdf_mem_zero(&sta_data_stall, sizeof(sta_data_stall)); - sta_data_stall.reason = STA_TX_TIMEOUT; - WLAN_HOST_DIAG_EVENT_REPORT(&sta_data_stall, EVENT_WLAN_STA_DATASTALL); -} -#else -static inline void hdd_wlan_datastall_sta_event(void) -{ -} -#endif - /** * __hdd_tx_timeout() - TX timeout handler * @dev: pointer to network device @@ -842,6 +821,7 @@ static void __hdd_tx_timeout(struct net_device *dev) hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev); hdd_context_t *hdd_ctx; struct netdev_queue *txq; + u64 diff_jiffies; int i = 0; TX_TIMEOUT_TRACE(dev, QDF_MODULE_ID_HDD_DATA); @@ -867,7 +847,45 @@ static void __hdd_tx_timeout(struct net_device *dev) hdd_ctx = WLAN_HDD_GET_CTX(adapter); wlan_hdd_display_netif_queue_history(hdd_ctx); ol_tx_dump_flow_pool_info(); - hdd_wlan_datastall_sta_event(); + + ++adapter->hdd_stats.hddTxRxStats.tx_timeout_cnt; + ++adapter->hdd_stats.hddTxRxStats.cont_txtimeout_cnt; + + diff_jiffies = jiffies - + adapter->hdd_stats.hddTxRxStats.jiffies_last_txtimeout; + + if ((adapter->hdd_stats.hddTxRxStats.cont_txtimeout_cnt > 1) && + (diff_jiffies > (HDD_TX_TIMEOUT * 2))) { + /* + * In case when there is no traffic is running, it may + * possible tx time-out may once happen and later system + * recovered then continuous tx timeout count has to be + * reset as it is gets modified only when traffic is running. + * If over a period of time if this count reaches to threshold + * then host triggers a false subsystem restart. In genuine + * time out case kernel will call the tx time-out back to back + * at interval of HDD_TX_TIMEOUT. Here now check if previous + * TX TIME out has occurred more than twice of HDD_TX_TIMEOUT + * back then host may recovered here from data stall. + */ + adapter->hdd_stats.hddTxRxStats.cont_txtimeout_cnt = 0; + QDF_TRACE(QDF_MODULE_ID_HDD_DATA, QDF_TRACE_LEVEL_DEBUG, + "Reset continous tx timeout stat"); + } + + adapter->hdd_stats.hddTxRxStats.jiffies_last_txtimeout = jiffies; + + if (adapter->hdd_stats.hddTxRxStats.cont_txtimeout_cnt > + HDD_TX_STALL_THRESHOLD) { + QDF_TRACE(QDF_MODULE_ID_HDD_DATA, QDF_TRACE_LEVEL_ERROR, + "Data stall due to continuous TX timeouts"); + adapter->hdd_stats.hddTxRxStats.cont_txtimeout_cnt = 0; + ol_txrx_post_data_stall_event( + DATA_STALL_LOG_INDICATOR_HOST_DRIVER, + DATA_STALL_LOG_HOST_STA_TX_TIMEOUT, + 0xFF, 0xFF, + DATA_STALL_LOG_RECOVERY_TRIGGER_PDR); + } } /** |
