Merge "qcacld-3.0: Send TX timeout event for TX data stall" into wlan-cld3.driver.lnx.2.0-dev

This commit is contained in:
CNSS_WLAN Service 2017-10-17 12:53:52 -07:00 • committed by Gerrit - the friendly Code Review server
commit aa625c5072
4 changed files with 74 additions and 50 deletions

View file

@ -127,6 +127,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)
@ -446,6 +449,11 @@ struct hdd_tx_rx_stats {
__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;
};
#ifdef WLAN_FEATURE_11W

View file

@ -1780,6 +1780,9 @@ static QDF_STATUS hdd_dis_connect_handler(struct hdd_adapter *adapter,
adapter->sessionId);
}
wlan_hdd_clear_link_layer_stats(adapter);
adapter->hdd_stats.hddTxRxStats.cont_txtimeout_cnt = 0;
/* Unblock anyone waiting for disconnect to complete */
complete(&adapter->disconnect_comp_var);

View file

@ -45,7 +45,7 @@
#include <cdp_txrx_peer_ops.h>
#include <cds_utils.h>
#include <cdp_txrx_flow_ctrl_v2.h>
#include <cdp_txrx_handle.h>
#include <cdp_txrx_misc.h>
#include <wlan_hdd_object_manager.h>
#include "wlan_p2p_ucfg_api.h"
#ifdef IPA_OFFLOAD
@ -293,6 +293,8 @@ static int __hdd_softap_hard_start_xmit(struct sk_buff *skb,
uint32_t num_seg;
++adapter->hdd_stats.hddTxRxStats.txXmitCalled;
adapter->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.
@ -503,30 +505,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
@ -542,6 +520,7 @@ static void __hdd_softap_tx_timeout(struct net_device *dev)
struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
struct hdd_context *hdd_ctx;
struct netdev_queue *txq;
void *soc = cds_get_context(QDF_MODULE_ID_SOC);
int i;
DPTRACE(qdf_dp_trace(NULL, QDF_DP_TRACE_HDD_SOFTAP_TX_TIMEOUT,
@ -574,7 +553,21 @@ static void __hdd_softap_tx_timeout(struct net_device *dev)
cdp_dump_flow_pool_info(cds_get_context(QDF_MODULE_ID_SOC));
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;
cdp_post_data_stall_event(soc,
DATA_STALL_LOG_INDICATOR_HOST_DRIVER,
DATA_STALL_LOG_HOST_SOFTAP_TX_TIMEOUT,
0xFF, 0xFF,
DATA_STALL_LOG_RECOVERY_TRIGGER_PDR);
}
}
/**

View file

@ -60,7 +60,7 @@
#include <cdp_txrx_flow_ctrl_v2.h>
#include "wlan_hdd_nan_datapath.h"
#include "pld_common.h"
#include <cdp_txrx_handle.h>
#include <cdp_txrx_misc.h>
#include "wlan_hdd_rx_monitor.h"
#include "wlan_hdd_power.h"
#include <wlan_hdd_tsf.h>
@ -583,6 +583,8 @@ static int __hdd_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
#endif
++adapter->hdd_stats.hddTxRxStats.txXmitCalled;
adapter->hdd_stats.hddTxRxStats.cont_txtimeout_cnt = 0;
if (cds_is_driver_recovering() || cds_is_driver_in_bad_state()) {
QDF_TRACE(QDF_MODULE_ID_HDD_DATA, QDF_TRACE_LEVEL_INFO_HIGH,
"Recovery in progress, dropping the packet");
@ -849,28 +851,6 @@ QDF_STATUS hdd_get_peer_sta_id(struct hdd_station_ctx *sta_ctx,
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
@ -886,6 +866,8 @@ static void __hdd_tx_timeout(struct net_device *dev)
struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
struct hdd_context *hdd_ctx;
struct netdev_queue *txq;
void *soc = cds_get_context(QDF_MODULE_ID_SOC);
u64 diff_jiffies;
int i = 0;
TX_TIMEOUT_TRACE(dev, QDF_MODULE_ID_HDD_DATA);
@ -912,7 +894,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);
cdp_dump_flow_pool_info(cds_get_context(QDF_MODULE_ID_SOC));
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;
cdp_post_data_stall_event(soc,
DATA_STALL_LOG_INDICATOR_HOST_DRIVER,
DATA_STALL_LOG_HOST_STA_TX_TIMEOUT,
0xFF, 0xFF,
DATA_STALL_LOG_RECOVERY_TRIGGER_PDR);
}
}
/**