From 96a1be4fcb3ecb21eced208e28e84e941349e476 Mon Sep 17 00:00:00 2001 From: Aniruddha Paul Date: Tue, 12 May 2020 19:55:22 +0530 Subject: [PATCH] qcacmn: Add histogram framework for DP path A new framework added to calculate the per packet level histogram Change-Id: Iac52f7a672fa2afe1d6aec26931a8bc3115c6a98 --- dp/inc/cdp_txrx_hist_struct.h | 89 +++++++++++++++++ dp/inc/cdp_txrx_stats_struct.h | 45 +++++++++ dp/wifi3.0/dp_hist.c | 176 +++++++++++++++++++++++++++++++++ dp/wifi3.0/dp_hist.h | 40 ++++++++ dp/wifi3.0/dp_types.h | 3 + 5 files changed, 353 insertions(+) create mode 100644 dp/inc/cdp_txrx_hist_struct.h create mode 100644 dp/wifi3.0/dp_hist.c create mode 100644 dp/wifi3.0/dp_hist.h diff --git a/dp/inc/cdp_txrx_hist_struct.h b/dp/inc/cdp_txrx_hist_struct.h new file mode 100644 index 0000000000..b62f52a8dc --- /dev/null +++ b/dp/inc/cdp_txrx_hist_struct.h @@ -0,0 +1,89 @@ +/* + * Copyright (c) 2020 The Linux Foundation. All rights reserved. + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/** + * @file cdp_txrx_hist_struct.h + * @brief Define the host data path histogram data types + */ +#ifndef _CDP_TXRX_HIST_STRUCT_H_ +#define _CDP_TXRX_HIST_STRUCT_H_ + +/* + * cdp_hist_bucket_index : Histogram Bucket + * @CDP_HIST_BUCKET_0: Bucket Index 0 + * @CDP_HIST_BUCKET_1: Bucket Index 1 + * @CDP_HIST_BUCKET_2: Bucket Index 2 + * @CDP_HIST_BUCKET_3: Bucket Index 3 + * @CDP_HIST_BUCKET_4: Bucket Index 4 + * @CDP_HIST_BUCKET_5: Bucket Index 5 + * @CDP_HIST_BUCKET_6: Bucket Index 6 + * @CDP_HIST_BUCKET_7: Bucket Index 7 + * @CDP_HIST_BUCKET_8: Bucket Index 8 + * @CDP_HIST_BUCKET_9: Bucket Index 9 + */ +enum cdp_hist_bucket_index { + CDP_HIST_BUCKET_0, + CDP_HIST_BUCKET_1, + CDP_HIST_BUCKET_2, + CDP_HIST_BUCKET_3, + CDP_HIST_BUCKET_4, + CDP_HIST_BUCKET_5, + CDP_HIST_BUCKET_6, + CDP_HIST_BUCKET_7, + CDP_HIST_BUCKET_8, + CDP_HIST_BUCKET_9, + CDP_HIST_BUCKET_MAX, +}; + +/* + * cdp_hist_types: Histogram Types + * @CDP_HIST_TYPE_SW_ENQEUE_DELAY: From stack to HW enqueue delay + * @CDP_HIST_TYPE_HW_COMP_DELAY: From HW enqueue to completion delay + * @CDP_HIST_TYPE_REAP_STACK: Rx HW reap to stack deliver delay + */ +enum cdp_hist_types { + CDP_HIST_TYPE_SW_ENQEUE_DELAY, + CDP_HIST_TYPE_HW_COMP_DELAY, + CDP_HIST_TYPE_REAP_STACK, + CDP_HIST_TYPE_MAX, +}; + +/* + * cdp_hist_bucket: Histogram Bucket + * @hist_type: Histogram type + * @freq: Frequency + */ +struct cdp_hist_bucket { + enum cdp_hist_types hist_type; + uint64_t freq[CDP_HIST_BUCKET_MAX]; +}; + +/* + * cdp_hist_stats : Histogram of a stats type + * @hist: Frequency distribution + * @max: Max frequency + * @min: Minimum frequency + * @avg: Average frequency + */ +struct cdp_hist_stats { + struct cdp_hist_bucket hist; + int max; + int min; + int avg; +}; +#endif /* _CDP_TXRX_HIST_STRUCT_H_ */ diff --git a/dp/inc/cdp_txrx_stats_struct.h b/dp/inc/cdp_txrx_stats_struct.h index c785b5ba41..0fcf3868c3 100644 --- a/dp/inc/cdp_txrx_stats_struct.h +++ b/dp/inc/cdp_txrx_stats_struct.h @@ -25,6 +25,7 @@ #define _CDP_TXRX_STATS_STRUCT_H_ #include +#include #define TXRX_STATS_LEVEL_OFF 0 #define TXRX_STATS_LEVEL_BASIC 1 @@ -76,6 +77,11 @@ #define CDP_MAX_TX_TQM_STATUS 9 /* max tx tqm completion status */ #define CDP_MAX_TX_HTT_STATUS 7 /* max tx htt completion status */ +/* + * Max of TxRx context + */ +#define CDP_MAX_TXRX_CTX CDP_MAX_RX_RINGS + /* TID level VoW stats macros * to add and get stats */ @@ -509,6 +515,45 @@ struct cdp_tid_stats { [CDP_MAX_DATA_TIDS]; }; +/* + * struct cdp_delay_tx_stats: Tx delay stats + * @tx_swq_delay: software enqueue delay + * @hwtx_delay: HW enque to completion delay + */ +struct cdp_delay_tx_stats { + struct cdp_hist_stats tx_swq_delay; + struct cdp_hist_stats hwtx_delay; +}; + +/* + * struct cdp_delay_rx_stats: Rx delay stats + * @to_stack_delay: To stack delay + */ +struct cdp_delay_rx_stats { + struct cdp_hist_stats to_stack_delay; +}; + +/* + * struct cdp_delay_tid_stats: Delay tid stats + * @tx_delay: Tx delay related stats + * @rx_delay: Rx delay related stats + */ +struct cdp_delay_tid_stats { + struct cdp_delay_tx_stats tx_delay; + struct cdp_delay_rx_stats rx_delay; +}; + +/* + * cdp_peer_ext_stats: Peer extended stats + * @delay_stats: Per TID delay stats + */ +struct cdp_peer_ext_stats { + struct cdp_delay_tid_stats delay_stats[CDP_MAX_DATA_TIDS] + [CDP_MAX_TXRX_CTX]; + + /*Customer can add MSDU level Tx/Rx stats */ +}; + /* struct cdp_pkt_info - packet info * @num: no of packets * @bytes: total no of bytes diff --git a/dp/wifi3.0/dp_hist.c b/dp/wifi3.0/dp_hist.c new file mode 100644 index 0000000000..899af49da8 --- /dev/null +++ b/dp/wifi3.0/dp_hist.c @@ -0,0 +1,176 @@ +/* + * Copyright (c) 2020 The Linux Foundation. All rights reserved. + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +#include +#include +#include +#include "dp_hist.h" + +/* + * dp_hist_sw_enq_dbucket: Sofware enqueue delay bucket in ms + * @index_0 = 0_1 ms + * @index_1 = 1_2 ms + * @index_2 = 2_3 ms + * @index_3 = 3_4 ms + * @index_4 = 4_5 ms + * @index_5 = 5_6 ms + * @index_6 = 6_7 ms + * @index_7 = 7_8 ms + * @index_8 = 8_9 ms + * @index_8 = 9+ ms + */ +static uint16_t dp_hist_sw_enq_dbucket[CDP_HIST_BUCKET_MAX] = { + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; + +/* + * cdp_hist_fw2hw_dbucket: HW enqueue to Completion Delay + * @index_0 = 0_10 ms + * @index_1 = 10_20 ms + * @index_2 = 20_30ms + * @index_3 = 30_40 ms + * @index_4 = 40_50 ms + * @index_5 = 50_60 ms + * @index_6 = 60_70 ms + * @index_7 = 70_80 ms + * @index_8 = 80_90 ms + * @index_9 = 90+ ms + */ +static uint16_t dp_hist_fw2hw_dbucket[CDP_HIST_BUCKET_MAX] = { + 0, 10, 20, 30, 40, 50, 60, 70, 80, 90}; + +/* + * dp_hist_reap2stack_bucket: Reap to stack bucket + * @index_0 = 0_5 ms + * @index_1 = 5_10 ms + * @index_2 = 10_15 ms + * @index_3 = 15_20 ms + * @index_4 = 20_25 ms + * @index_5 = 25_30 ms + * @index_6 = 30_35 ms + * @index_7 = 35_40 ms + * @index_8 = 40_45 ms + * @index_9 = 45+ ms + */ +static uint16_t dp_hist_reap2stack_bucket[CDP_HIST_BUCKET_MAX] = { + 0, 5, 10, 15, 20, 25, 30, 35, 40, 45}; + +/* + * dp_hist_find_bucket_idx: Find the bucket index + * @bucket_array: Bucket array + * @value: Frequency value + * + * Return: The bucket index + */ +static int dp_hist_find_bucket_idx(int16_t *bucket_array, int value) +{ + uint8_t idx = CDP_HIST_BUCKET_0; + + for (; idx < (CDP_HIST_BUCKET_MAX - 1); idx++) { + if (value < bucket_array[idx + 1]) + break; + } + + return idx; +} + +/* + * dp_hist_fill_buckets: Fill the histogram frequency buckets + * @hist_bucket: Histogram bukcets + * @value: Frequency value + * + * Return: void + */ +static void dp_hist_fill_buckets(struct cdp_hist_bucket *hist_bucket, int value) +{ + enum cdp_hist_types hist_type; + int idx = CDP_HIST_BUCKET_MAX; + + if (qdf_unlikely(!hist_bucket)) + return; + + hist_type = hist_bucket->hist_type; + + /* Identify the bucket the bucket and update. */ + switch (hist_type) { + case CDP_HIST_TYPE_SW_ENQEUE_DELAY: + idx = dp_hist_find_bucket_idx(&dp_hist_sw_enq_dbucket[0], + value); + break; + case CDP_HIST_TYPE_HW_COMP_DELAY: + idx = dp_hist_find_bucket_idx(&dp_hist_fw2hw_dbucket[0], + value); + break; + case CDP_HIST_TYPE_REAP_STACK: + idx = dp_hist_find_bucket_idx( + &dp_hist_reap2stack_bucket[0], value); + break; + default: + break; + } + + if (idx == CDP_HIST_BUCKET_MAX) + return; + + hist_bucket->freq[idx]++; +} + +/* + * dp_hist_update_stats: Update histogram stats + * @hist_stats: Hist stats object + * @value: Delay value + * + * Return: void + */ +void dp_hist_update_stats(struct cdp_hist_stats *hist_stats, int value) +{ + if (qdf_unlikely(!hist_stats)) + return; + + /* + * Fill the histogram buckets according to the delay + */ + dp_hist_fill_buckets(&hist_stats->hist, value); + + /* + * Compute the min, max and average. Average computed is weighted + * average + */ + if (value < hist_stats->min) + hist_stats->min = value; + + if (value > hist_stats->max) + hist_stats->max = value; + + if (qdf_unlikely(!hist_stats->avg)) + hist_stats->avg = value; + else + hist_stats->avg = hist_stats->avg + + ((value - hist_stats->avg) >> HIST_AVG_WEIGHT_DENOM); +} + +/* + * dp_hist_init(): Initialize the histogram object + * @hist_stats: Hist stats object + * @hist_type: Histogram type + */ +void dp_hist_init(struct cdp_hist_stats *hist_stats, + enum cdp_hist_types hist_type) +{ + qdf_mem_zero(hist_stats, sizeof(*hist_stats)); + hist_stats->hist.hist_type = hist_type; +} diff --git a/dp/wifi3.0/dp_hist.h b/dp/wifi3.0/dp_hist.h new file mode 100644 index 0000000000..6790d6408d --- /dev/null +++ b/dp/wifi3.0/dp_hist.h @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2020 The Linux Foundation. All rights reserved. + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/** + * @file dp_hist.h + * @brief: histogram header file + */ + +#ifndef __DP_HIST_H_ +#define __DP_HIST_H_ + +#define HIST_AVG_WEIGHT_DENOM 4 + +/* + * dp_hist_update_stats: Update histogram stats + * @hist_delay: Delay histogram + * @value: Delay value + * + * Return: void + */ +void dp_hist_update_stats(struct cdp_hist_stats *hist_stats, int value); +void dp_hist_init(struct cdp_hist_stats *hist_stats, + enum cdp_hist_types hist_type); + +#endif /* __DP_HIST_H_ */ diff --git a/dp/wifi3.0/dp_types.h b/dp/wifi3.0/dp_types.h index 7d827cc477..bbed472974 100644 --- a/dp/wifi3.0/dp_types.h +++ b/dp/wifi3.0/dp_types.h @@ -2275,6 +2275,9 @@ struct dp_peer { /* Peer Stats */ struct cdp_peer_stats stats; + /* Peer extended stats */ + struct cdp_peer_ext_stats *pext_stats; + TAILQ_HEAD(, dp_ast_entry) ast_entry_list; /* TBD */