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_TXRX_DESC_STATS 6
|
||||
#define WLAN_HIF_STATS 7
|
||||
#define WLAN_LRO_STATS 8
|
||||
#define WLAN_SCHEDULER_STATS 21
|
||||
#define WLAN_TX_QUEUE_STATS 22
|
||||
#define WLAN_BUNDLE_STATS 23
|
||||
|
@@ -97,16 +97,62 @@ struct hdd_lro_desc_info {
|
||||
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
|
||||
* @lro_mgr: LRO manager
|
||||
* @lro_desc_info: LRO descriptor information
|
||||
* @lro_mgr_arr_access_lock: Lock to access LRO manager array.
|
||||
* @lro_stats: LRO statistics
|
||||
*/
|
||||
struct hdd_lro_s {
|
||||
struct net_lro_mgr *lro_mgr;
|
||||
struct hdd_lro_desc_info lro_desc_info;
|
||||
qdf_spinlock_t lro_mgr_arr_access_lock;
|
||||
struct hdd_lro_stats lro_stats;
|
||||
};
|
||||
|
||||
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,
|
||||
hdd_adapter_t *adapter);
|
||||
|
||||
void hdd_lro_display_stats(hdd_context_t *hdd_ctx);
|
||||
#else
|
||||
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,
|
||||
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 /* __WLAN_HDD_LRO_H__ */
|
||||
|
@@ -53,6 +53,14 @@
|
||||
(LRO_DESC | LRO_ELIGIBILITY_CHECKED | LRO_TCP_ACK_NUM | \
|
||||
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
|
||||
* @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);
|
||||
|
||||
if (NULL == entry->lro_desc) {
|
||||
hdd_err("entry->lro_desc is NULL!\n");
|
||||
hdd_err("entry->lro_desc is NULL!");
|
||||
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);
|
||||
|
||||
if (lro_desc) {
|
||||
/* statistics */
|
||||
LRO_HIST_UPDATE(lro_desc, adapter);
|
||||
|
||||
hdd_lro_desc_free(lro_desc, adapter);
|
||||
lro_flush_desc(lro_mgr, lro_desc);
|
||||
}
|
||||
@@ -474,6 +485,8 @@ static void hdd_lro_flush(void *data)
|
||||
lro_flush_desc(
|
||||
hdd_lro->lro_mgr,
|
||||
&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);
|
||||
@@ -556,6 +569,7 @@ int hdd_lro_enable(hdd_context_t *hdd_ctx,
|
||||
|
||||
hdd_lro = &adapter->lro_info;
|
||||
qdf_mem_zero((void *)hdd_lro, sizeof(struct hdd_lro_s));
|
||||
|
||||
/*
|
||||
* Allocate all the LRO data structures at once and then carve
|
||||
* 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;
|
||||
adapter->lro_info.lro_stats.lro_eligible_tcp++;
|
||||
} else {
|
||||
hdd_lro_flush_pkt(adapter->lro_info.lro_mgr,
|
||||
iph, tcph, adapter);
|
||||
adapter->lro_info.lro_stats.lro_ineligible_tcp++;
|
||||
}
|
||||
qdf_spin_unlock_bh(
|
||||
&hdd_lro->lro_mgr_arr_access_lock);
|
||||
}
|
||||
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 "pld_common.h"
|
||||
#endif
|
||||
#include "wlan_hdd_lro.h"
|
||||
|
||||
#define HDD_FINISH_ULA_TIME_OUT 800
|
||||
#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:
|
||||
hdd_display_hif_stats();
|
||||
break;
|
||||
case WLAN_LRO_STATS:
|
||||
hdd_lro_display_stats(hdd_ctx);
|
||||
break;
|
||||
default:
|
||||
ol_txrx_display_stats(value);
|
||||
break;
|
||||
|
Reference in New Issue
Block a user