diff options
| author | Himanshu Agarwal <himanaga@qti.qualcomm.com> | 2016-03-13 02:49:32 +0530 |
|---|---|---|
| committer | Anjaneedevi Kapparapu <akappa@codeaurora.org> | 2016-04-22 10:23:13 +0530 |
| commit | 89c770ddd30c4fa0dcfd5bdf61c5191eb811bfb4 (patch) | |
| tree | 854e6340651593eb0b4335aaf4739594f1c1b123 | |
| parent | 527d683f55c6295817123421d4f0e1ac6d3abc28 (diff) | |
qcacld-2.0: Update netif queue timestamp to avoid watchdog
Update netif queue timestamp while stopping queues
to avoid NETDEV watchdog.
Change-Id: Ie0c0af1fc585992f5f89c4c29006d4bafce390c3
CRs-Fixed: 988801
| -rw-r--r-- | CORE/CLD_TXRX/TLSHIM/tl_shim.c | 19 | ||||
| -rw-r--r-- | CORE/CLD_TXRX/TLSHIM/tl_shim.h | 3 | ||||
| -rw-r--r-- | CORE/CLD_TXRX/TXRX/ol_tx.h | 4 | ||||
| -rw-r--r-- | CORE/CLD_TXRX/TXRX/ol_tx_queue.c | 2 | ||||
| -rw-r--r-- | CORE/CLD_TXRX/TXRX/ol_txrx.c | 29 | ||||
| -rw-r--r-- | CORE/CLD_TXRX/TXRX/ol_txrx.h | 5 | ||||
| -rw-r--r-- | CORE/CLD_TXRX/TXRX/ol_txrx_types.h | 3 | ||||
| -rw-r--r-- | CORE/HDD/inc/wlan_hdd_main.h | 5 | ||||
| -rw-r--r-- | CORE/HDD/inc/wlan_hdd_tx_rx.h | 4 | ||||
| -rw-r--r-- | CORE/HDD/src/wlan_hdd_hostapd.c | 2 | ||||
| -rw-r--r-- | CORE/HDD/src/wlan_hdd_main.c | 2 | ||||
| -rw-r--r-- | CORE/HDD/src/wlan_hdd_softap_tx_rx.c | 17 | ||||
| -rw-r--r-- | CORE/HDD/src/wlan_hdd_tx_rx.c | 101 |
13 files changed, 185 insertions, 11 deletions
diff --git a/CORE/CLD_TXRX/TLSHIM/tl_shim.c b/CORE/CLD_TXRX/TLSHIM/tl_shim.c index 801d7c9decdc..2ccc71f0ca6d 100644 --- a/CORE/CLD_TXRX/TLSHIM/tl_shim.c +++ b/CORE/CLD_TXRX/TLSHIM/tl_shim.c @@ -43,6 +43,7 @@ #include "vos_utils.h" #include "wdi_out.h" #include "ol_rx_fwd.h" +#include "ol_txrx.h" #define TLSHIM_PEER_AUTHORIZE_WAIT 50 @@ -2665,3 +2666,21 @@ uint64_t tlshim_get_fwd_to_tx_packet_count(uint8_t session_id) { return ol_rx_get_fwd_to_tx_packet_count(session_id); } + +/* + * tlshim_get_ll_queue_pause_bitmap() - to obtain ll queue pause bitmap and + * last pause timestamp + * @session_id: vdev id + * @pause_bitmap: pointer to return ll queue pause bitmap + * @pause_timestamp: pointer to return pause timestamp to calling func. + * + * Return: status -> A_OK - for success, A_ERROR for failure + * + */ +A_STATUS tlshim_get_ll_queue_pause_bitmap(uint8_t session_id, + uint8_t *pause_bitmap, adf_os_time_t *pause_timestamp) +{ + return ol_txrx_get_ll_queue_pause_bitmap(session_id, + pause_bitmap, pause_timestamp); +} + diff --git a/CORE/CLD_TXRX/TLSHIM/tl_shim.h b/CORE/CLD_TXRX/TLSHIM/tl_shim.h index 5114b58bd33a..9a0c9ef03389 100644 --- a/CORE/CLD_TXRX/TLSHIM/tl_shim.h +++ b/CORE/CLD_TXRX/TLSHIM/tl_shim.h @@ -127,6 +127,9 @@ int tlshim_mgmt_roam_event_ind(void *context, u_int32_t vdev_id); void *tl_shim_get_vdev_by_addr(void *vos_context, uint8_t *mac_addr); void *tl_shim_get_vdev_by_sta_id(void *vos_context, uint8_t sta_id); uint64_t tlshim_get_fwd_to_tx_packet_count(uint8_t session_id); +int tlshim_get_ll_queue_pause_bitmap(uint8_t session_id, + uint8_t *pause_bitmap, __adf_time_t *pause_timestamp); + #ifdef QCA_SUPPORT_TXRX_VDEV_PAUSE_LL void tl_shim_set_peer_authorized_event(void *vos_ctx, v_U8_t session_id); diff --git a/CORE/CLD_TXRX/TXRX/ol_tx.h b/CORE/CLD_TXRX/TXRX/ol_tx.h index 65275eb0ea64..4b0280cfcfbe 100644 --- a/CORE/CLD_TXRX/TXRX/ol_tx.h +++ b/CORE/CLD_TXRX/TXRX/ol_tx.h @@ -125,4 +125,8 @@ ol_tx_pdev_ll_pause_queue_send_all(struct ol_txrx_pdev_t *pdev); struct ol_txrx_vdev_t * ol_txrx_get_vdev_from_vdev_id(uint8_t vdev_id); +ol_txrx_vdev_handle +ol_txrx_get_vdev_from_vdev_id(uint8_t vdev_id); + #endif /* _OL_TX__H_ */ + diff --git a/CORE/CLD_TXRX/TXRX/ol_tx_queue.c b/CORE/CLD_TXRX/TXRX/ol_tx_queue.c index b3dba2e31397..6e1d47d66d51 100644 --- a/CORE/CLD_TXRX/TXRX/ol_tx_queue.c +++ b/CORE/CLD_TXRX/TXRX/ol_tx_queue.c @@ -1052,6 +1052,8 @@ ol_txrx_vdev_pause(ol_txrx_vdev_handle vdev, u_int32_t reason) } else { adf_os_spin_lock_bh(&vdev->ll_pause.mutex); vdev->ll_pause.paused_reason |= reason; + vdev->ll_pause.pause_timestamp = + adf_os_gettimestamp(); vdev->ll_pause.q_pause_cnt++; vdev->ll_pause.is_q_paused = TRUE; adf_os_spin_unlock_bh(&vdev->ll_pause.mutex); diff --git a/CORE/CLD_TXRX/TXRX/ol_txrx.c b/CORE/CLD_TXRX/TXRX/ol_txrx.c index 280d6e62e29e..f0b2394070b9 100644 --- a/CORE/CLD_TXRX/TXRX/ol_txrx.c +++ b/CORE/CLD_TXRX/TXRX/ol_txrx.c @@ -1081,6 +1081,7 @@ ol_txrx_vdev_attach( adf_os_spinlock_init(&vdev->ll_pause.mutex); vdev->ll_pause.paused_reason = 0; + vdev->ll_pause.pause_timestamp = 0; #if defined(CONFIG_HL_SUPPORT) vdev->hl_paused_reason = 0; #endif @@ -2762,3 +2763,31 @@ void ol_txrx_clear_stats(struct ol_txrx_pdev_t *pdev, uint16_t value) } } +/* + * ol_txrx_get_ll_queue_pause_bitmap() - to obtain ll queue pause bitmap and + * last pause timestamp + * @vdev_id: vdev id + * @pause_bitmap: pointer to return ll queue pause bitmap + * @pause_timestamp: pointer to return pause timestamp to calling func. + * + * Return: status -> A_OK - for success, A_ERROR for failure + * + */ +A_STATUS ol_txrx_get_ll_queue_pause_bitmap(uint8_t vdev_id, + uint8_t *pause_bitmap, adf_os_time_t *pause_timestamp) +{ + ol_txrx_vdev_handle vdev = NULL; + + vdev = (ol_txrx_vdev_handle) ol_txrx_get_vdev_from_vdev_id(vdev_id); + if (!vdev) { + TXRX_PRINT(TXRX_PRINT_LEVEL_ERR, + "%s: vdev handle is NULL for vdev id %d", + __func__, vdev_id); + return A_ERROR; + } + + *pause_timestamp = vdev->ll_pause.pause_timestamp; + *pause_bitmap = vdev->ll_pause.paused_reason; + return A_OK; +} + diff --git a/CORE/CLD_TXRX/TXRX/ol_txrx.h b/CORE/CLD_TXRX/TXRX/ol_txrx.h index 95cfd1689486..2c45b8879ab9 100644 --- a/CORE/CLD_TXRX/TXRX/ol_txrx.h +++ b/CORE/CLD_TXRX/TXRX/ol_txrx.h @@ -59,4 +59,9 @@ ol_tx_desc_pool_size_hl(ol_pdev_handle ctrl_pdev); #ifdef CONFIG_TX_DESC_HI_PRIO_RESERVE #define TXRX_HL_TX_DESC_HI_PRIO_RESERVED 20 #endif + +A_STATUS +ol_txrx_get_ll_queue_pause_bitmap(uint8_t vdev_id, + uint8_t *pause_bitmap, adf_os_time_t *pause_timestamp); + #endif /* _OL_TXRX__H_ */ diff --git a/CORE/CLD_TXRX/TXRX/ol_txrx_types.h b/CORE/CLD_TXRX/TXRX/ol_txrx_types.h index 32ebe320f7eb..b1a1798ed85e 100644 --- a/CORE/CLD_TXRX/TXRX/ol_txrx_types.h +++ b/CORE/CLD_TXRX/TXRX/ol_txrx_types.h @@ -919,7 +919,8 @@ struct ol_txrx_vdev_t { adf_nbuf_t tail; int depth; } txq; - u_int32_t paused_reason; + uint32_t paused_reason; + uint64_t pause_timestamp; adf_os_spinlock_t mutex; adf_os_timer_t timer; int max_q_depth; diff --git a/CORE/HDD/inc/wlan_hdd_main.h b/CORE/HDD/inc/wlan_hdd_main.h index d6b9ebfca9db..c038b7dbff45 100644 --- a/CORE/HDD/inc/wlan_hdd_main.h +++ b/CORE/HDD/inc/wlan_hdd_main.h @@ -1141,6 +1141,11 @@ struct hdd_adapter_s #endif uint8_t addr_filter_pattern; + /* to store the time of last bug report generated in HDD */ + uint64_t last_tx_jiffies; + /* stores how many times timeout happens since last bug report generation */ + uint8_t bug_report_count; + v_BOOL_t higherDtimTransition; v_BOOL_t survey_idx; diff --git a/CORE/HDD/inc/wlan_hdd_tx_rx.h b/CORE/HDD/inc/wlan_hdd_tx_rx.h index 02d0507ba3be..9e46f119190d 100644 --- a/CORE/HDD/inc/wlan_hdd_tx_rx.h +++ b/CORE/HDD/inc/wlan_hdd_tx_rx.h @@ -78,6 +78,8 @@ #define HDD_ETH_HEADER_LEN 14 +#define HDD_BUG_REPORT_MIN_COUNT 3 +#define HDD_BUG_REPORT_MIN_TIME 300000 /* 5 minutes */ /*--------------------------------------------------------------------------- Type declarations -------------------------------------------------------------------------*/ @@ -270,6 +272,8 @@ static inline void wlan_hdd_log_eapol(struct sk_buff *skb, VOS_STATUS hdd_mon_rx_packet_cbk(v_VOID_t *vos_ctx, adf_nbuf_t rx_buf, uint8_t sta_id); +void wlan_display_tx_timeout_stats(hdd_adapter_t *adapter); + const char *hdd_reason_type_to_string(enum netif_reason_type reason); const char *hdd_action_type_to_string(enum netif_action_type action); void wlan_hdd_netif_queue_control(hdd_adapter_t *adapter, diff --git a/CORE/HDD/src/wlan_hdd_hostapd.c b/CORE/HDD/src/wlan_hdd_hostapd.c index 32b8d2013ccd..af22e5d91f19 100644 --- a/CORE/HDD/src/wlan_hdd_hostapd.c +++ b/CORE/HDD/src/wlan_hdd_hostapd.c @@ -7133,6 +7133,8 @@ hdd_adapter_t* hdd_wlan_create_ap_dev(hdd_context_t *pHddCtx, SET_NETDEV_DEV(pWlanHostapdDev, pHddCtx->parent_dev); spin_lock_init(&pHostapdAdapter->pause_map_lock); + pHostapdAdapter->last_tx_jiffies = jiffies; + pHostapdAdapter->bug_report_count = 0; } return pHostapdAdapter; } diff --git a/CORE/HDD/src/wlan_hdd_main.c b/CORE/HDD/src/wlan_hdd_main.c index fdd0ca492b71..2944b6ac054a 100644 --- a/CORE/HDD/src/wlan_hdd_main.c +++ b/CORE/HDD/src/wlan_hdd_main.c @@ -10138,6 +10138,8 @@ static hdd_adapter_t* hdd_alloc_station_adapter(hdd_context_t *pHddCtx, hdd_wmm_init( pAdapter ); hdd_adapter_runtime_suspend_init(pAdapter); spin_lock_init(&pAdapter->pause_map_lock); + pAdapter->last_tx_jiffies = jiffies; + pAdapter->bug_report_count = 0; } return pAdapter; diff --git a/CORE/HDD/src/wlan_hdd_softap_tx_rx.c b/CORE/HDD/src/wlan_hdd_softap_tx_rx.c index abe473dcc31c..0b4077c49474 100644 --- a/CORE/HDD/src/wlan_hdd_softap_tx_rx.c +++ b/CORE/HDD/src/wlan_hdd_softap_tx_rx.c @@ -464,11 +464,11 @@ static void __hdd_softap_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; + int i = 0; DPTRACE(adf_dp_trace(NULL, ADF_DP_TRACE_HDD_SOFTAP_TX_TIMEOUT, NULL, 0)); - VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR, - "%s: Transmission timeout occurred", __func__); hdd_ctx = WLAN_HDD_GET_CTX(adapter); if (hdd_ctx->isLogpInProgress) { @@ -483,6 +483,19 @@ static void __hdd_softap_tx_timeout(struct net_device *dev) * case of disassociation it is ok to ignore this. But if associated, we have * do possible recovery here. */ + + VOS_TRACE(VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR, + "%s: Transmission timeout occurred jiffies %lu trans_start %lu", + __func__, jiffies, dev->trans_start); + + for (i = 0; i < NUM_TX_QUEUES; i++) { + txq = netdev_get_tx_queue(dev, i); + VOS_TRACE(VOS_MODULE_ID_HDD_SAP_DATA, + VOS_TRACE_LEVEL_ERROR, + "Queue%d status: %d txq->trans_start %lu", + i, netif_tx_queue_stopped(txq), txq->trans_start); + } + wlan_display_tx_timeout_stats(adapter); } /** diff --git a/CORE/HDD/src/wlan_hdd_tx_rx.c b/CORE/HDD/src/wlan_hdd_tx_rx.c index 6896ae502df7..09cbd4b1039f 100644 --- a/CORE/HDD/src/wlan_hdd_tx_rx.c +++ b/CORE/HDD/src/wlan_hdd_tx_rx.c @@ -774,6 +774,64 @@ VOS_STATUS hdd_get_peer_sta_id(hdd_station_ctx_t *sta_ctx, } /** + * wlan_display_tx_timeout_stats() - HDD tx timeout stats display handler + * @adapter: hdd adapter + * + * Function called by tx timeout handler to display the stats when timeout + * occurs during trabsmission. + * + * Return: none + */ +void wlan_display_tx_timeout_stats(hdd_adapter_t *adapter) +{ + hdd_context_t *hdd_ctx = WLAN_HDD_GET_CTX(adapter); + uint8_t pause_bitmap = 0; + vos_time_t pause_timestamp = 0; + A_STATUS status; + + VOS_TRACE(VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_INFO, + "carrier state: %d", netif_carrier_ok(adapter->dev)); + + /* to display the neif queue pause/unpause history */ + wlan_hdd_display_netif_queue_history(hdd_ctx); + + /* to display the count of packets at diferent layers */ + adf_nbuf_tx_desc_count_display(); + + /* printing last 100 records from DPTRACE */ + adf_dp_trace_dump_all(100); + + /* to print the pause bitmap of local ll queues */ + status = tlshim_get_ll_queue_pause_bitmap(adapter->sessionId, + &pause_bitmap, &pause_timestamp); + if (status != A_OK) + hddLog(LOGE, FL("vdev is NULL for vdev id %d"), + adapter->sessionId); + else + hddLog(LOGE, + FL("LL vdev queues pause bitmap: %d, last pause timestamp %lu"), + pause_bitmap, pause_timestamp); + + /* + * To invoke the bug report to flush driver as well as fw logs + * when timeout happens. It happens when it has been more + * than 5 minutes and the timeout has happened at least 3 times + * since the last generation of bug report. + */ + adapter->bug_report_count++; + if (adapter->bug_report_count >= HDD_BUG_REPORT_MIN_COUNT && + (jiffies_to_msecs(jiffies - adapter->last_tx_jiffies) >= + HDD_BUG_REPORT_MIN_TIME)) { + adapter->bug_report_count = 0; + adapter->last_tx_jiffies = jiffies; + vos_flush_logs(WLAN_LOG_TYPE_FATAL, + WLAN_LOG_INDICATOR_HOST_DRIVER, + WLAN_LOG_REASON_HDD_TIME_OUT, + true); + } +} + +/** * __hdd_tx_timeout() - HDD tx timeout handler * @dev: pointer to net_device structure * @@ -816,12 +874,10 @@ static void __hdd_tx_timeout(struct net_device *dev) for (i = 0; i < NUM_TX_QUEUES; i++) { txq = netdev_get_tx_queue(dev, i); - hddLog(LOG1, FL("Queue%d status: %d txq->trans_start %lu"), + hddLog(LOGE, FL("Queue%d status: %d txq->trans_start %lu"), i, netif_tx_queue_stopped(txq), txq->trans_start); } - - VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_INFO, - "carrier state: %d", netif_carrier_ok(dev)); + wlan_display_tx_timeout_stats(pAdapter); } /** @@ -1458,6 +1514,27 @@ static void wlan_hdd_update_queue_oper_stats(hdd_adapter_t *adapter, } /** + * wlan_hdd_update_txq_timestamp() - update txq timestamp + * @dev: net device + * + * Return: none + */ +static void wlan_hdd_update_txq_timestamp(struct net_device *dev) +{ + struct netdev_queue *txq; + int i; + bool unlock; + + for (i = 0; i < NUM_TX_QUEUES; i++) { + txq = netdev_get_tx_queue(dev, i); + unlock = __netif_tx_trylock(txq); + txq_trans_update(txq); + if (unlock == true) + __netif_tx_unlock(txq); + } +} + +/** * wlan_hdd_netif_queue_control() - Use for netif_queue related actions * @adapter: adapter handle * @action: action type @@ -1489,8 +1566,10 @@ void wlan_hdd_netif_queue_control(hdd_adapter_t *adapter, case WLAN_STOP_ALL_NETIF_QUEUE: spin_lock_bh(&adapter->pause_map_lock); - if (!adapter->pause_map) + if (!adapter->pause_map) { netif_tx_stop_all_queues(adapter->dev); + wlan_hdd_update_txq_timestamp(adapter->dev); + } adapter->pause_map |= (1 << reason); spin_unlock_bh(&adapter->pause_map_lock); break; @@ -1513,8 +1592,10 @@ void wlan_hdd_netif_queue_control(hdd_adapter_t *adapter, case WLAN_STOP_ALL_NETIF_QUEUE_N_CARRIER: spin_lock_bh(&adapter->pause_map_lock); - if (!adapter->pause_map) + if (!adapter->pause_map) { netif_tx_stop_all_queues(adapter->dev); + wlan_hdd_update_txq_timestamp(adapter->dev); + } adapter->pause_map |= (1 << reason); netif_carrier_off(adapter->dev); spin_unlock_bh(&adapter->pause_map_lock); @@ -1531,16 +1612,20 @@ void wlan_hdd_netif_queue_control(hdd_adapter_t *adapter, case WLAN_NETIF_TX_DISABLE: spin_lock_bh(&adapter->pause_map_lock); - if (!adapter->pause_map) + if (!adapter->pause_map) { netif_tx_disable(adapter->dev); + wlan_hdd_update_txq_timestamp(adapter->dev); + } adapter->pause_map |= (1 << reason); spin_unlock_bh(&adapter->pause_map_lock); break; case WLAN_NETIF_TX_DISABLE_N_CARRIER: spin_lock_bh(&adapter->pause_map_lock); - if (!adapter->pause_map) + if (!adapter->pause_map) { netif_tx_disable(adapter->dev); + wlan_hdd_update_txq_timestamp(adapter->dev); + } adapter->pause_map |= (1 << reason); netif_carrier_off(adapter->dev); spin_unlock_bh(&adapter->pause_map_lock); |
