From 87a8e4458319c60b618522e263ed900e36aab528 Mon Sep 17 00:00:00 2001 From: Vignesh Viswanathan Date: Fri, 17 Aug 2018 11:39:51 +0530 Subject: [PATCH] qcacmn: Drop beacon/probe frames posted on Scan Queue if queue is full Drop beacon/probe frames before posting on Scan queue if the queue already has too many beacon/probes to process. Also add scheduler API to get the queue size given the module ID. Change-Id: I9153c7e77e74377863774b68e8163839e992358d CRs-Fixed: 2298584 --- scheduler/inc/scheduler_api.h | 10 +++++ scheduler/src/scheduler_api.c | 27 +++++++++++ umac/scan/core/src/wlan_scan_main.h | 12 +++++ .../dispatcher/inc/wlan_scan_public_structs.h | 6 +++ umac/scan/dispatcher/src/wlan_scan_tgt_api.c | 45 ++++++++++++------- 5 files changed, 84 insertions(+), 16 deletions(-) diff --git a/scheduler/inc/scheduler_api.h b/scheduler/inc/scheduler_api.h index 26077145471c..e16979badc98 100644 --- a/scheduler/inc/scheduler_api.h +++ b/scheduler/inc/scheduler_api.h @@ -283,4 +283,14 @@ QDF_STATUS scheduler_deregister_wma_legacy_handler(void); */ void scheduler_mc_timer_callback(unsigned long data); +/** + * scheduler_get_queue_size() - Get the current size of the scheduler queue + * @qid: Queue ID for which the size is requested + * @size: Pointer to size where the size would be returned to the caller + * + * This API finds the size of the scheduler queue for the given Queue ID + * + * Return: QDF Status + */ +QDF_STATUS scheduler_get_queue_size(QDF_MODULE_ID qid, uint32_t *size); #endif diff --git a/scheduler/src/scheduler_api.c b/scheduler/src/scheduler_api.c index 91d03e364703..ed93dfc99760 100644 --- a/scheduler/src/scheduler_api.c +++ b/scheduler/src/scheduler_api.c @@ -619,3 +619,30 @@ void scheduler_mc_timer_callback(unsigned long data) if (QDF_IS_STATUS_ERROR(status)) sched_err("Could not enqueue timer to timer queue"); } + +QDF_STATUS scheduler_get_queue_size(QDF_MODULE_ID qid, uint32_t *size) +{ + uint8_t qidx; + struct scheduler_mq_type *target_mq; + struct scheduler_ctx *sched_ctx; + + sched_ctx = scheduler_get_context(); + if (!sched_ctx) + return QDF_STATUS_E_INVAL; + + /* WMA also uses the target_if queue, so replace the QID */ + if (QDF_MODULE_ID_WMA == qid) + qid = QDF_MODULE_ID_TARGET_IF; + + qidx = sched_ctx->queue_ctx.scheduler_msg_qid_to_qidx[qid]; + if (qidx >= SCHEDULER_NUMBER_OF_MSG_QUEUE) { + sched_err("Scheduler is deinitialized"); + return QDF_STATUS_E_FAILURE; + } + + target_mq = &(sched_ctx->queue_ctx.sch_msg_q[qidx]); + + *size = qdf_list_size(&target_mq->mq_list); + + return QDF_STATUS_SUCCESS; +} diff --git a/umac/scan/core/src/wlan_scan_main.h b/umac/scan/core/src/wlan_scan_main.h index 87a4ae869499..3feb984f1f72 100644 --- a/umac/scan/core/src/wlan_scan_main.h +++ b/umac/scan/core/src/wlan_scan_main.h @@ -44,6 +44,18 @@ #define scm_debug(params...) \ QDF_TRACE_DEBUG(QDF_MODULE_ID_SCAN, params) +/* Rate Limited Logs */ +#define scm_alert_rl(params...) \ + QDF_TRACE_FATAL_RL(QDF_MODULE_ID_SCAN, params) +#define scm_err_rl(params...) \ + QDF_TRACE_ERROR_RL(QDF_MODULE_ID_SCAN, params) +#define scm_warn_rl(params...) \ + QDF_TRACE_WARN_RL(QDF_MODULE_ID_SCAN, params) +#define scm_info_rl(params...) \ + QDF_TRACE_INFO_RL(QDF_MODULE_ID_SCAN, params) +#define scm_debug_rl(params...) \ + QDF_TRACE_DEBUG_RL(QDF_MODULE_ID_SCAN, params) + #define scm_nofl_alert(params...) \ QDF_TRACE_FATAL_NO_FL(QDF_MODULE_ID_SCAN, params) #define scm_nofl_err(params...) \ diff --git a/umac/scan/dispatcher/inc/wlan_scan_public_structs.h b/umac/scan/dispatcher/inc/wlan_scan_public_structs.h index ddd9234602bb..84251fc31773 100644 --- a/umac/scan/dispatcher/inc/wlan_scan_public_structs.h +++ b/umac/scan/dispatcher/inc/wlan_scan_public_structs.h @@ -69,6 +69,12 @@ typedef uint32_t wlan_scan_id; #define MAX_INDEX_SCORE 100 #define MAX_INDEX_PER_INI 4 +#ifdef CONFIG_MCL +#define MAX_BCN_PROBE_IN_SCAN_QUEUE 150 +#else +#define MAX_BCN_PROBE_IN_SCAN_QUEUE 2000 +#endif + #define WLAN_GET_BITS(_val, _index, _num_bits) \ (((_val) >> (_index)) & ((1 << (_num_bits)) - 1)) diff --git a/umac/scan/dispatcher/src/wlan_scan_tgt_api.c b/umac/scan/dispatcher/src/wlan_scan_tgt_api.c index 105e8f7cdc17..9dce20a24ab9 100644 --- a/umac/scan/dispatcher/src/wlan_scan_tgt_api.c +++ b/umac/scan/dispatcher/src/wlan_scan_tgt_api.c @@ -257,29 +257,29 @@ QDF_STATUS tgt_scan_bcn_probe_rx_callback(struct wlan_objmgr_psoc *psoc, enum mgmt_frame_type frm_type) { struct scheduler_msg msg = {0}; - struct scan_bcn_probe_event *bcn; + struct scan_bcn_probe_event *bcn = NULL; QDF_STATUS status; + uint32_t scan_queue_size = 0; if ((frm_type != MGMT_PROBE_RESP) && (frm_type != MGMT_BEACON)) { scm_err("frame is not beacon or probe resp"); - qdf_nbuf_free(buf); - return QDF_STATUS_E_INVAL; + status = QDF_STATUS_E_INVAL; + goto free; } bcn = qdf_mem_malloc_atomic(sizeof(*bcn)); if (!bcn) { scm_err("Failed to allocate memory for bcn"); - qdf_nbuf_free(buf); - return QDF_STATUS_E_NOMEM; + status = QDF_STATUS_E_NOMEM; + goto free; } bcn->rx_data = qdf_mem_malloc_atomic(sizeof(*rx_param)); if (!bcn->rx_data) { scm_err("Failed to allocate memory for rx_data"); - qdf_mem_free(bcn); - qdf_nbuf_free(buf); - return QDF_STATUS_E_NOMEM; + status = QDF_STATUS_E_NOMEM; + goto free; } if (frm_type == MGMT_PROBE_RESP) @@ -287,13 +287,20 @@ QDF_STATUS tgt_scan_bcn_probe_rx_callback(struct wlan_objmgr_psoc *psoc, else bcn->frm_type = MGMT_SUBTYPE_BEACON; + /* Check if the beacon/probe frame can be posted in the scan queue */ + status = scheduler_get_queue_size(QDF_MODULE_ID_SCAN, &scan_queue_size); + if (!QDF_IS_STATUS_SUCCESS(status) || + scan_queue_size > MAX_BCN_PROBE_IN_SCAN_QUEUE) { + scm_debug_rl("Dropping beacon/probe frame, queue size %d", + scan_queue_size); + status = QDF_STATUS_E_FAILURE; + goto free; + } + status = wlan_objmgr_psoc_try_get_ref(psoc, WLAN_SCAN_ID); if (QDF_IS_STATUS_ERROR(status)) { scm_info("unable to get reference"); - qdf_mem_free(bcn->rx_data); - qdf_mem_free(bcn); - qdf_nbuf_free(buf); - return status; + goto free; } bcn->psoc = psoc; @@ -306,13 +313,19 @@ QDF_STATUS tgt_scan_bcn_probe_rx_callback(struct wlan_objmgr_psoc *psoc, status = scheduler_post_msg(QDF_MODULE_ID_SCAN, &msg); - if (!QDF_IS_STATUS_SUCCESS(status)) { - wlan_objmgr_psoc_release_ref(psoc, WLAN_SCAN_ID); - scm_err("failed to post to QDF_MODULE_ID_SCAN"); + if (QDF_IS_STATUS_SUCCESS(status)) + return status; + + wlan_objmgr_psoc_release_ref(psoc, WLAN_SCAN_ID); + scm_err("failed to post to QDF_MODULE_ID_SCAN"); + +free: + if (bcn && bcn->rx_data) qdf_mem_free(bcn->rx_data); + if (bcn) qdf_mem_free(bcn); + if (buf) qdf_nbuf_free(buf); - } return status; }