qcacld-3.0: init/deinit tx_rx_histogram along with hdd_bus_bandwidth

hdd_txrx_hist histogram is accessed in hdd_pld_request_bus_bandwidth.
init/deinit tx_rx_histogram along with init/deinit of hdd_bus_bandwidth
Without this in FTM mode where hdd_txrx_hist memeber is accessed without
allocating memory for it. This results in uninitialized NULL dereference
assert

Change-Id: I3b8d80b71f4c37da4a0dafc4a7b91f8ca16bbab3
CRs-Fixed: 3110416
This commit is contained in:
Prakash Manjunathappa 2022-01-19 23:57:40 -08:00 committed by Madan Koyyalamudi
parent cc6aa888fb
commit dd8fef0fb1
3 changed files with 84 additions and 29 deletions

View File

@ -3713,6 +3713,7 @@ static int hdd_update_country_code(struct hdd_context *hdd_ctx)
return hdd_reg_set_country(hdd_ctx, country_code);
}
#ifdef WLAN_FEATURE_DP_BUS_BANDWIDTH
/**
* wlan_hdd_init_tx_rx_histogram() - init tx/rx histogram stats
* @hdd_ctx: hdd context
@ -3743,6 +3744,7 @@ static void wlan_hdd_deinit_tx_rx_histogram(struct hdd_context *hdd_ctx)
qdf_mem_free(hdd_ctx->hdd_txrx_hist);
hdd_ctx->hdd_txrx_hist = NULL;
}
#endif /*WLAN_FEATURE_DP_BUS_BANDWIDTH*/
#ifdef WLAN_NS_OFFLOAD
/**
@ -4199,8 +4201,6 @@ int hdd_wlan_start_modules(struct hdd_context *hdd_ctx, bool reinit)
hdd_skip_acs_scan_timer_init(hdd_ctx);
wlan_hdd_init_tx_rx_histogram(hdd_ctx);
hdd_set_hif_init_phase(hif_ctx, false);
hdd_hif_set_enable_detection(hif_ctx, true);
@ -10727,12 +10727,17 @@ int hdd_bus_bandwidth_init(struct hdd_context *hdd_ctx)
{
QDF_STATUS status;
if (QDF_GLOBAL_FTM_MODE == hdd_get_conparam())
return QDF_STATUS_SUCCESS;
hdd_enter();
qdf_spinlock_create(&hdd_ctx->bus_bw_lock);
hdd_pm_qos_add_request(hdd_ctx);
wlan_hdd_init_tx_rx_histogram(hdd_ctx);
status = qdf_periodic_work_create(&hdd_ctx->bus_bw_work,
hdd_bus_bw_work_handler,
hdd_ctx);
@ -10744,6 +10749,9 @@ int hdd_bus_bandwidth_init(struct hdd_context *hdd_ctx)
void hdd_bus_bandwidth_deinit(struct hdd_context *hdd_ctx)
{
if (QDF_GLOBAL_FTM_MODE == hdd_get_conparam())
return;
hdd_enter();
/* it is expecting the timer has been stopped or not started
@ -10752,6 +10760,7 @@ void hdd_bus_bandwidth_deinit(struct hdd_context *hdd_ctx)
QDF_BUG(!qdf_periodic_work_stop_sync(&hdd_ctx->bus_bw_work));
qdf_periodic_work_destroy(&hdd_ctx->bus_bw_work);
wlan_hdd_deinit_tx_rx_histogram(hdd_ctx);
qdf_spinlock_destroy(&hdd_ctx->bus_bw_lock);
hdd_pm_qos_remove_request(hdd_ctx);
@ -10877,7 +10886,7 @@ void hdd_adapter_feature_update_work_deinit(struct hdd_adapter *adapter)
hdd_exit();
}
static uint8_t *convert_level_to_string(uint32_t level)
static uint8_t *hdd_tp_level_to_str(uint32_t level)
{
switch (level) {
/* initialize the wlan sub system */
@ -11026,30 +11035,25 @@ void wlan_hdd_display_tx_rx_histogram(struct hdd_context *hdd_ctx)
hdd_nofl_debug("Total entries: %d Current index: %d",
NUM_TX_RX_HISTOGRAM, hdd_ctx->hdd_txrx_hist_idx);
hdd_nofl_debug("[index][timestamp]: interval_rx, interval_tx, bus_bw_level, RX TP Level, TX TP Level, Rx:Tx pm_qos");
if (hdd_ctx->hdd_txrx_hist) {
hdd_nofl_debug("[index][timestamp]: interval_rx, interval_tx, bus_bw_level, RX TP Level, TX TP Level, Rx:Tx pm_qos");
for (i = 0; i < NUM_TX_RX_HISTOGRAM; i++) {
/* using hdd_log to avoid printing function name */
if (hdd_ctx->hdd_txrx_hist[i].qtime > 0)
for (i = 0; i < NUM_TX_RX_HISTOGRAM; i++) {
struct hdd_tx_rx_histogram *hist;
/* using hdd_log to avoid printing function name */
if (hdd_ctx->hdd_txrx_hist[i].qtime <= 0)
continue;
hist = &hdd_ctx->hdd_txrx_hist[i];
hdd_nofl_debug("[%3d][%15llu]: %6llu, %6llu, %s, %s, %s, %s:%s",
i, hdd_ctx->hdd_txrx_hist[i].qtime,
hdd_ctx->hdd_txrx_hist[i].interval_rx,
hdd_ctx->hdd_txrx_hist[i].interval_tx,
convert_level_to_string(
hdd_ctx->hdd_txrx_hist[i].
next_vote_level),
convert_level_to_string(
hdd_ctx->hdd_txrx_hist[i].
next_rx_level),
convert_level_to_string(
hdd_ctx->hdd_txrx_hist[i].
next_tx_level),
hdd_ctx->hdd_txrx_hist[i].is_rx_pm_qos_high ?
"HIGH" : "LOW",
hdd_ctx->hdd_txrx_hist[i].is_tx_pm_qos_high ?
"HIGH" : "LOW");
if (hdd_ctx->hdd_txrx_hist[i].qtime <= 0)
continue;
i, hist->qtime, hist->interval_rx,
hist->interval_tx,
pld_bus_width_type_to_str(hist->next_vote_level),
hdd_tp_level_to_str(hist->next_rx_level),
hdd_tp_level_to_str(hist->next_tx_level),
hist->is_rx_pm_qos_high ? "HIGH" : "LOW",
hist->is_tx_pm_qos_high ? "HIGH" : "LOW");
}
}
}
@ -11062,8 +11066,10 @@ void wlan_hdd_display_tx_rx_histogram(struct hdd_context *hdd_ctx)
void wlan_hdd_clear_tx_rx_histogram(struct hdd_context *hdd_ctx)
{
hdd_ctx->hdd_txrx_hist_idx = 0;
qdf_mem_zero(hdd_ctx->hdd_txrx_hist,
(sizeof(struct hdd_tx_rx_histogram) * NUM_TX_RX_HISTOGRAM));
if (hdd_ctx->hdd_txrx_hist)
qdf_mem_zero(hdd_ctx->hdd_txrx_hist,
(sizeof(struct hdd_tx_rx_histogram) *
NUM_TX_RX_HISTOGRAM));
}
/* length of the netif queue log needed per adapter */
@ -14681,8 +14687,6 @@ int hdd_wlan_stop_modules(struct hdd_context *hdd_ctx, bool ftm_mode)
if (hdd_get_conparam() == QDF_GLOBAL_EPPING_MODE)
break;
wlan_hdd_deinit_tx_rx_histogram(hdd_ctx);
hdd_skip_acs_scan_timer_deinit(hdd_ctx);
hdd_disable_power_management(hdd_ctx);
@ -16140,6 +16144,9 @@ bool hdd_is_any_adapter_connected(struct hdd_context *hdd_ctx)
#ifdef WLAN_FEATURE_DP_BUS_BANDWIDTH
static void __hdd_bus_bw_compute_timer_start(struct hdd_context *hdd_ctx)
{
if (hdd_get_conparam() == QDF_GLOBAL_FTM_MODE)
return;
qdf_periodic_work_start(&hdd_ctx->bus_bw_work,
hdd_ctx->config->bus_bw_compute_interval);
hdd_ctx->bw_vote_time = qdf_get_log_timestamp();
@ -16168,6 +16175,9 @@ static void __hdd_bus_bw_compute_timer_stop(struct hdd_context *hdd_ctx)
{
bool is_any_adapter_conn = hdd_is_any_adapter_connected(hdd_ctx);
if (hdd_get_conparam() == QDF_GLOBAL_FTM_MODE)
return;
if (!qdf_periodic_work_stop_sync(&hdd_ctx->bus_bw_work))
goto exit;
@ -16220,6 +16230,9 @@ void hdd_bus_bw_compute_prev_txrx_stats(struct hdd_adapter *adapter)
{
struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
if (hdd_get_conparam() == QDF_GLOBAL_FTM_MODE)
return;
qdf_spin_lock_bh(&hdd_ctx->bus_bw_lock);
adapter->prev_tx_packets = adapter->stats.tx_packets;
adapter->prev_rx_packets = adapter->stats.rx_packets;
@ -16235,6 +16248,9 @@ void hdd_bus_bw_compute_reset_prev_txrx_stats(struct hdd_adapter *adapter)
{
struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
if (hdd_get_conparam() == QDF_GLOBAL_FTM_MODE)
return;
qdf_spin_lock_bh(&hdd_ctx->bus_bw_lock);
adapter->prev_tx_packets = 0;
adapter->prev_rx_packets = 0;

View File

@ -78,6 +78,7 @@ enum pld_bus_type {
* @PLD_BUS_WIDTH_MEDIUM: vote for medium bus bandwidth
* @PLD_BUS_WIDTH_HIGH: vote for high bus bandwidth
* @PLD_BUS_WIDTH_VERY_HIGH: vote for very high bus bandwidth
* @PLD_BUS_WIDTH_ULTRA_HIGH: vote for ultra high bus bandwidth
* @PLD_BUS_WIDTH_LOW_LATENCY: vote for low latency bus bandwidth
*/
enum pld_bus_width_type {
@ -87,9 +88,12 @@ enum pld_bus_width_type {
PLD_BUS_WIDTH_MEDIUM,
PLD_BUS_WIDTH_HIGH,
PLD_BUS_WIDTH_VERY_HIGH,
PLD_BUS_WIDTH_ULTRA_HIGH,
PLD_BUS_WIDTH_MAX,
PLD_BUS_WIDTH_LOW_LATENCY,
};
#define PLD_MAX_FILE_NAME NAME_MAX
/**
@ -942,6 +946,15 @@ int pld_thermal_register(struct device *dev, unsigned long state, int mon_id);
*/
void pld_thermal_unregister(struct device *dev, int mon_id);
/**
* pld_bus_width_type_to_str() - Helper function to convert PLD bandwidth level
* to string
* @level: PLD bus width level
*
* Return: String corresponding to input "level"
*/
const char *pld_bus_width_type_to_str(enum pld_bus_width_type level);
/**
* pld_get_thermal_state() - Get the current thermal state from the PLD
* @dev: The device structure

View File

@ -3154,6 +3154,32 @@ void pld_thermal_unregister(struct device *dev, int mon_id)
}
}
const char *pld_bus_width_type_to_str(enum pld_bus_width_type level)
{
switch (level) {
/* initialize the wlan sub system */
case PLD_BUS_WIDTH_NONE:
return "NONE";
case PLD_BUS_WIDTH_IDLE:
return "IDLE";
case PLD_BUS_WIDTH_LOW:
return "LOW";
case PLD_BUS_WIDTH_MEDIUM:
return "MEDIUM";
case PLD_BUS_WIDTH_HIGH:
return "HIGH";
case PLD_BUS_WIDTH_VERY_HIGH:
return "VERY_HIGH";
case PLD_BUS_WIDTH_LOW_LATENCY:
return "LOW_LAT";
default:
if (level > PLD_BUS_WIDTH_ULTRA_HIGH)
return "ULTRA_HIGH+";
else
return "INVAL";
}
}
int pld_get_thermal_state(struct device *dev, unsigned long *thermal_state,
int mon_id)
{