qcacld-3.0: Add LRO Statistics
Add the following statistics for LRO - packet count based on the number of packets aggregated - total number of LRO eligible and ineligible TCP packets - total number of packets aggregated - total number of flows flushed - number of times an LRO descriptor was not found Change-Id: Icea6b7745df9bda5b517c1a7f27c8395ede2cec6 CRs-Fixed: 1042116
This commit is contained in:

committed by
qcabuildsw

parent
3de9e373c9
commit
e7d442a315
@@ -69,6 +69,7 @@
|
|||||||
#define WLAN_DUMP_TX_FLOW_POOL_INFO 5
|
#define WLAN_DUMP_TX_FLOW_POOL_INFO 5
|
||||||
#define WLAN_TXRX_DESC_STATS 6
|
#define WLAN_TXRX_DESC_STATS 6
|
||||||
#define WLAN_HIF_STATS 7
|
#define WLAN_HIF_STATS 7
|
||||||
|
#define WLAN_LRO_STATS 8
|
||||||
#define WLAN_SCHEDULER_STATS 21
|
#define WLAN_SCHEDULER_STATS 21
|
||||||
#define WLAN_TX_QUEUE_STATS 22
|
#define WLAN_TX_QUEUE_STATS 22
|
||||||
#define WLAN_BUNDLE_STATS 23
|
#define WLAN_BUNDLE_STATS 23
|
||||||
|
@@ -97,16 +97,62 @@ struct hdd_lro_desc_info {
|
|||||||
struct hdd_lro_desc_pool lro_desc_pool;
|
struct hdd_lro_desc_pool lro_desc_pool;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* enum hdd_lro_pkt_aggr_bucket - idenitifies the bucket holding
|
||||||
|
* the count of the aggregated packets
|
||||||
|
* @HDD_LRO_BUCKET_0_7: identifies the packet count when the
|
||||||
|
* aggregate size is between 0 to 7 packets
|
||||||
|
* @HDD_LRO_BUCKET_8_15: identifies the packet count when the
|
||||||
|
* aggregate size is between 8 to 15 packets
|
||||||
|
* @HDD_LRO_BUCKET_16_23: identifies the packet count when the
|
||||||
|
* aggregate size is between 16 to 23 packets
|
||||||
|
* @HDD_LRO_BUCKET_24_31: identifies the packet count when the
|
||||||
|
* aggregate size is between 24 to 31 packets
|
||||||
|
* @HDD_LRO_BUCKET_32_39: identifies the packet count when the
|
||||||
|
* aggregate size is between 32 to 39 packets
|
||||||
|
* @HDD_LRO_BUCKET_40_47: identifies the packet count when the
|
||||||
|
* aggregate size is between 40 to 47 packets
|
||||||
|
* @HDD_LRO_BUCKET_48_OR_MORE: identifies the packet count when
|
||||||
|
* the aggregate size is 48 or more packets
|
||||||
|
* @HDD_LRO_BUCKET_MAX: identifies the packet count when the
|
||||||
|
* aggregate size is 48 or more packets
|
||||||
|
*/
|
||||||
|
enum hdd_lro_pkt_aggr_bucket {
|
||||||
|
HDD_LRO_BUCKET_0_7 = 0,
|
||||||
|
HDD_LRO_BUCKET_8_15 = 1,
|
||||||
|
HDD_LRO_BUCKET_16_23 = 2,
|
||||||
|
HDD_LRO_BUCKET_24_31 = 3,
|
||||||
|
HDD_LRO_BUCKET_32_39 = 4,
|
||||||
|
HDD_LRO_BUCKET_40_47 = 5,
|
||||||
|
HDD_LRO_BUCKET_48_OR_MORE = 6,
|
||||||
|
HDD_LRO_BUCKET_MAX = HDD_LRO_BUCKET_48_OR_MORE,
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* hdd_lro_stats - structure containing the LRO statistics
|
||||||
|
* information
|
||||||
|
* @pkt_aggr_hist: histogram of the number of aggregated packets
|
||||||
|
* @lro_eligible_tcp: number of LRO elgible TCP packets
|
||||||
|
* @lro_ineligible_tcp: number of LRO inelgible TCP packets
|
||||||
|
*/
|
||||||
|
struct hdd_lro_stats {
|
||||||
|
uint16_t pkt_aggr_hist[HDD_LRO_BUCKET_MAX + 1];
|
||||||
|
uint32_t lro_eligible_tcp;
|
||||||
|
uint32_t lro_ineligible_tcp;
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* hdd_lro_s - LRO information per HDD adapter
|
* hdd_lro_s - LRO information per HDD adapter
|
||||||
* @lro_mgr: LRO manager
|
* @lro_mgr: LRO manager
|
||||||
* @lro_desc_info: LRO descriptor information
|
* @lro_desc_info: LRO descriptor information
|
||||||
* @lro_mgr_arr_access_lock: Lock to access LRO manager array.
|
* @lro_mgr_arr_access_lock: Lock to access LRO manager array.
|
||||||
|
* @lro_stats: LRO statistics
|
||||||
*/
|
*/
|
||||||
struct hdd_lro_s {
|
struct hdd_lro_s {
|
||||||
struct net_lro_mgr *lro_mgr;
|
struct net_lro_mgr *lro_mgr;
|
||||||
struct hdd_lro_desc_info lro_desc_info;
|
struct hdd_lro_desc_info lro_desc_info;
|
||||||
qdf_spinlock_t lro_mgr_arr_access_lock;
|
qdf_spinlock_t lro_mgr_arr_access_lock;
|
||||||
|
struct hdd_lro_stats lro_stats;
|
||||||
};
|
};
|
||||||
|
|
||||||
int hdd_lro_init(hdd_context_t *hdd_ctx);
|
int hdd_lro_init(hdd_context_t *hdd_ctx);
|
||||||
@@ -121,6 +167,8 @@ enum hdd_lro_rx_status hdd_lro_rx(hdd_context_t *hdd_ctx,
|
|||||||
|
|
||||||
void hdd_lro_flush_all(hdd_context_t *hdd_ctx,
|
void hdd_lro_flush_all(hdd_context_t *hdd_ctx,
|
||||||
hdd_adapter_t *adapter);
|
hdd_adapter_t *adapter);
|
||||||
|
|
||||||
|
void hdd_lro_display_stats(hdd_context_t *hdd_ctx);
|
||||||
#else
|
#else
|
||||||
struct hdd_lro_s {};
|
struct hdd_lro_s {};
|
||||||
|
|
||||||
@@ -142,6 +190,14 @@ static inline int hdd_lro_init(hdd_context_t *hdd_ctx)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static inline void hdd_lro_disable(hdd_context_t *hdd_ctx,
|
static inline void hdd_lro_disable(hdd_context_t *hdd_ctx,
|
||||||
hdd_adapter_t *adapter){}
|
hdd_adapter_t *adapter)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void hdd_lro_display_stats(hdd_context_t *hdd_ctx)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
#endif /* FEATURE_LRO */
|
#endif /* FEATURE_LRO */
|
||||||
#endif /* __WLAN_HDD_LRO_H__ */
|
#endif /* __WLAN_HDD_LRO_H__ */
|
||||||
|
@@ -53,6 +53,14 @@
|
|||||||
(LRO_DESC | LRO_ELIGIBILITY_CHECKED | LRO_TCP_ACK_NUM | \
|
(LRO_DESC | LRO_ELIGIBILITY_CHECKED | LRO_TCP_ACK_NUM | \
|
||||||
LRO_TCP_DATA_CSUM | LRO_TCP_SEQ_NUM | LRO_TCP_WIN)
|
LRO_TCP_DATA_CSUM | LRO_TCP_SEQ_NUM | LRO_TCP_WIN)
|
||||||
|
|
||||||
|
#define LRO_HIST_UPDATE(lro_desc, adapter) \
|
||||||
|
do { \
|
||||||
|
uint8_t bucket = lro_desc->pkt_aggr_cnt >> 3; \
|
||||||
|
if (unlikely(bucket > HDD_LRO_BUCKET_MAX)) \
|
||||||
|
bucket = HDD_LRO_BUCKET_MAX; \
|
||||||
|
adapter->lro_info.lro_stats.pkt_aggr_hist[bucket]++; \
|
||||||
|
} while (0);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* hdd_lro_get_skb_header() - LRO callback function
|
* hdd_lro_get_skb_header() - LRO callback function
|
||||||
* @skb: network buffer
|
* @skb: network buffer
|
||||||
@@ -260,7 +268,7 @@ static int hdd_lro_desc_find(hdd_adapter_t *adapter,
|
|||||||
qdf_spin_unlock_bh(&free_pool->lro_pool_lock);
|
qdf_spin_unlock_bh(&free_pool->lro_pool_lock);
|
||||||
|
|
||||||
if (NULL == entry->lro_desc) {
|
if (NULL == entry->lro_desc) {
|
||||||
hdd_err("entry->lro_desc is NULL!\n");
|
hdd_err("entry->lro_desc is NULL!");
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -421,6 +429,9 @@ static void hdd_lro_flush_pkt(struct net_lro_mgr *lro_mgr,
|
|||||||
lro_desc = hdd_lro_get_desc(lro_mgr, lro_mgr->lro_arr, iph, tcph);
|
lro_desc = hdd_lro_get_desc(lro_mgr, lro_mgr->lro_arr, iph, tcph);
|
||||||
|
|
||||||
if (lro_desc) {
|
if (lro_desc) {
|
||||||
|
/* statistics */
|
||||||
|
LRO_HIST_UPDATE(lro_desc, adapter);
|
||||||
|
|
||||||
hdd_lro_desc_free(lro_desc, adapter);
|
hdd_lro_desc_free(lro_desc, adapter);
|
||||||
lro_flush_desc(lro_mgr, lro_desc);
|
lro_flush_desc(lro_mgr, lro_desc);
|
||||||
}
|
}
|
||||||
@@ -474,6 +485,8 @@ static void hdd_lro_flush(void *data)
|
|||||||
lro_flush_desc(
|
lro_flush_desc(
|
||||||
hdd_lro->lro_mgr,
|
hdd_lro->lro_mgr,
|
||||||
&hdd_lro->lro_mgr->lro_arr[i]);
|
&hdd_lro->lro_mgr->lro_arr[i]);
|
||||||
|
LRO_HIST_UPDATE((&hdd_lro->lro_mgr->lro_arr[i]),
|
||||||
|
adapter);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
qdf_spin_unlock_bh(&hdd_lro->lro_mgr_arr_access_lock);
|
qdf_spin_unlock_bh(&hdd_lro->lro_mgr_arr_access_lock);
|
||||||
@@ -556,6 +569,7 @@ int hdd_lro_enable(hdd_context_t *hdd_ctx,
|
|||||||
|
|
||||||
hdd_lro = &adapter->lro_info;
|
hdd_lro = &adapter->lro_info;
|
||||||
qdf_mem_zero((void *)hdd_lro, sizeof(struct hdd_lro_s));
|
qdf_mem_zero((void *)hdd_lro, sizeof(struct hdd_lro_s));
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Allocate all the LRO data structures at once and then carve
|
* Allocate all the LRO data structures at once and then carve
|
||||||
* them up as needed
|
* them up as needed
|
||||||
@@ -693,12 +707,107 @@ enum hdd_lro_rx_status hdd_lro_rx(hdd_context_t *hdd_ctx,
|
|||||||
}
|
}
|
||||||
|
|
||||||
status = HDD_LRO_RX;
|
status = HDD_LRO_RX;
|
||||||
|
adapter->lro_info.lro_stats.lro_eligible_tcp++;
|
||||||
} else {
|
} else {
|
||||||
hdd_lro_flush_pkt(adapter->lro_info.lro_mgr,
|
hdd_lro_flush_pkt(adapter->lro_info.lro_mgr,
|
||||||
iph, tcph, adapter);
|
iph, tcph, adapter);
|
||||||
|
adapter->lro_info.lro_stats.lro_ineligible_tcp++;
|
||||||
}
|
}
|
||||||
qdf_spin_unlock_bh(
|
qdf_spin_unlock_bh(
|
||||||
&hdd_lro->lro_mgr_arr_access_lock);
|
&hdd_lro->lro_mgr_arr_access_lock);
|
||||||
}
|
}
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* hdd_lro_bucket_to_string() - return string conversion of
|
||||||
|
* bucket
|
||||||
|
* @bucket: bucket
|
||||||
|
*
|
||||||
|
* This utility function helps log string conversion of bucket
|
||||||
|
* enum
|
||||||
|
*
|
||||||
|
* Return: string conversion of the LRO bucket, if match found;
|
||||||
|
* "Invalid" otherwise.
|
||||||
|
*/
|
||||||
|
static const char *hdd_lro_bucket_to_string(enum hdd_lro_pkt_aggr_bucket bucket)
|
||||||
|
{
|
||||||
|
switch (bucket) {
|
||||||
|
CASE_RETURN_STRING(HDD_LRO_BUCKET_0_7);
|
||||||
|
CASE_RETURN_STRING(HDD_LRO_BUCKET_8_15);
|
||||||
|
CASE_RETURN_STRING(HDD_LRO_BUCKET_16_23);
|
||||||
|
CASE_RETURN_STRING(HDD_LRO_BUCKET_24_31);
|
||||||
|
CASE_RETURN_STRING(HDD_LRO_BUCKET_32_39);
|
||||||
|
CASE_RETURN_STRING(HDD_LRO_BUCKET_40_47);
|
||||||
|
CASE_RETURN_STRING(HDD_LRO_BUCKET_48_OR_MORE);
|
||||||
|
default:
|
||||||
|
return "Invalid";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* wlan_hdd_display_lro_stats() - display LRO statistics
|
||||||
|
* @hdd_ctx: hdd context
|
||||||
|
*
|
||||||
|
* Return: none
|
||||||
|
*/
|
||||||
|
void hdd_lro_display_stats(hdd_context_t *hdd_ctx)
|
||||||
|
{
|
||||||
|
|
||||||
|
hdd_adapter_t *adapter = NULL;
|
||||||
|
hdd_adapter_list_node_t *adapter_node = NULL, *next = NULL;
|
||||||
|
QDF_STATUS status;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
if (!hdd_ctx->config->lro_enable) {
|
||||||
|
hdd_err("LRO Disabled");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
status = hdd_get_front_adapter(hdd_ctx, &adapter_node);
|
||||||
|
while (NULL != adapter_node && QDF_STATUS_SUCCESS == status) {
|
||||||
|
struct hdd_lro_stats *stats;
|
||||||
|
hdd_err("\nLRO statistics:");
|
||||||
|
|
||||||
|
adapter = adapter_node->pAdapter;
|
||||||
|
if (!adapter) {
|
||||||
|
status = hdd_get_next_adapter(hdd_ctx,
|
||||||
|
adapter_node, &next);
|
||||||
|
adapter_node = next;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
stats = &adapter->lro_info.lro_stats;
|
||||||
|
hdd_err("Session_id %d device mode %d",
|
||||||
|
adapter->sessionId, adapter->device_mode);
|
||||||
|
|
||||||
|
if (NL80211_IFTYPE_STATION != adapter->wdev.iftype) {
|
||||||
|
hdd_err("No LRO on interface type %d",
|
||||||
|
adapter->wdev.iftype);
|
||||||
|
status = hdd_get_next_adapter(hdd_ctx,
|
||||||
|
adapter_node, &next);
|
||||||
|
adapter_node = next;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i <= HDD_LRO_BUCKET_MAX; i++) {
|
||||||
|
if (stats && stats->pkt_aggr_hist)
|
||||||
|
hdd_err("bucket %s: %d packets",
|
||||||
|
hdd_lro_bucket_to_string(i),
|
||||||
|
stats->pkt_aggr_hist[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
hdd_err("LRO eligible TCP packets %d\n"
|
||||||
|
"LRO ineligible TCP packets %d",
|
||||||
|
stats->lro_eligible_tcp, stats->lro_ineligible_tcp);
|
||||||
|
|
||||||
|
if (adapter->lro_info.lro_mgr)
|
||||||
|
hdd_err("LRO manager aggr %lu flushed %lu no desc %lu",
|
||||||
|
adapter->lro_info.lro_mgr->stats.aggregated,
|
||||||
|
adapter->lro_info.lro_mgr->stats.flushed,
|
||||||
|
adapter->lro_info.lro_mgr->stats.no_desc);
|
||||||
|
|
||||||
|
status = hdd_get_next_adapter(hdd_ctx, adapter_node, &next);
|
||||||
|
adapter_node = next;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@@ -94,6 +94,7 @@
|
|||||||
#include "hif.h"
|
#include "hif.h"
|
||||||
#include "pld_common.h"
|
#include "pld_common.h"
|
||||||
#endif
|
#endif
|
||||||
|
#include "wlan_hdd_lro.h"
|
||||||
|
|
||||||
#define HDD_FINISH_ULA_TIME_OUT 800
|
#define HDD_FINISH_ULA_TIME_OUT 800
|
||||||
#define HDD_SET_MCBC_FILTERS_TO_FW 1
|
#define HDD_SET_MCBC_FILTERS_TO_FW 1
|
||||||
@@ -720,6 +721,9 @@ void hdd_wlan_dump_stats(hdd_adapter_t *adapter, int value)
|
|||||||
case WLAN_HIF_STATS:
|
case WLAN_HIF_STATS:
|
||||||
hdd_display_hif_stats();
|
hdd_display_hif_stats();
|
||||||
break;
|
break;
|
||||||
|
case WLAN_LRO_STATS:
|
||||||
|
hdd_lro_display_stats(hdd_ctx);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
ol_txrx_display_stats(value);
|
ol_txrx_display_stats(value);
|
||||||
break;
|
break;
|
||||||
|
Reference in New Issue
Block a user