summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVignesh Viswanathan <viswanat@codeaurora.org>2018-03-07 17:43:31 +0530
committernshrivas <nshrivas@codeaurora.org>2018-03-08 09:25:55 -0800
commita30f9b07605014e60e1b979fb64f7c79dddab12e (patch)
treebb1c11fd61441f45ff8af773da9b62728464534e
parenta326499fcacd0a18e998f7374eb7ef1e0c31f3bb (diff)
qcacld-3.0: Remove timer from sys msg queue when timer is stopped
In a scenario where timer has expired and the timer msg is posted to the mc thread sys_msgq and from a different context the timer has been stopped and freed, access of freed memory would occur when mc thread resumes and processes the timer msg from sys_msgq. Flush the timer msg pending in the sys_msgq when the timer is stopped based on the unique timer_cookie in the timer msg. Change-Id: I63af19d8782cde97af293d1b6143075f6c53cb31 CRs-Fixed: 2202177
-rw-r--r--core/cds/inc/cds_sched.h12
-rw-r--r--core/cds/src/cds_mc_timer.c4
-rw-r--r--core/cds/src/cds_sched.c43
3 files changed, 57 insertions, 2 deletions
diff --git a/core/cds/inc/cds_sched.h b/core/cds/inc/cds_sched.h
index 1d3347f3eac5..a5eaeb07a18e 100644
--- a/core/cds/inc/cds_sched.h
+++ b/core/cds/inc/cds_sched.h
@@ -641,4 +641,16 @@ void cds_shutdown_notifier_purge(void);
* shutdown.
*/
void cds_shutdown_notifier_call(void);
+
+/**
+ * cds_remove_timer_from_sys_msg() - Flush timer message from sys msg queue
+ * @timer_cookie: Unique cookie of the timer message to be flushed
+ *
+ * Find the timer message in the sys msg queue for the unique cookie
+ * and flush the message from the queue.
+ *
+ * Return: None
+ */
+void cds_remove_timer_from_sys_msg(uint32_t timer_cookie);
+
#endif /* #if !defined __CDS_SCHED_H */
diff --git a/core/cds/src/cds_mc_timer.c b/core/cds/src/cds_mc_timer.c
index c684471da955..4ff88a61eb38 100644
--- a/core/cds/src/cds_mc_timer.c
+++ b/core/cds/src/cds_mc_timer.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2014-2017 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2014-2018 The Linux Foundation. All rights reserved.
*
* Previously licensed under the ISC license by Qualcomm Atheros, Inc.
*
@@ -124,7 +124,7 @@ void cds_linux_timer_callback(unsigned long data)
sys_build_message_header(SYS_MSG_ID_MC_TIMER, &msg);
msg.callback = callback;
msg.bodyptr = user_data;
- msg.bodyval = 0;
+ msg.bodyval = timer->cookie;
if (cds_mq_post_message(QDF_MODULE_ID_SYS, &msg) == QDF_STATUS_SUCCESS)
return;
diff --git a/core/cds/src/cds_sched.c b/core/cds/src/cds_sched.c
index 228dde2c3082..56931a241896 100644
--- a/core/cds/src/cds_sched.c
+++ b/core/cds/src/cds_sched.c
@@ -1238,6 +1238,49 @@ static int cds_ol_rx_thread(void *arg)
}
#endif
+void cds_remove_timer_from_sys_msg(uint32_t timer_cookie)
+{
+ p_cds_msg_wrapper msg_wrapper = NULL;
+ struct list_head *pos, *q;
+ unsigned long flags;
+ p_cds_mq_type sys_msgq;
+
+ if (!gp_cds_sched_context) {
+ cds_err("gp_cds_sched_context is null");
+ return;
+ }
+
+ if (!gp_cds_sched_context->McThread) {
+ cds_err("Cannot post message because MC thread is stopped");
+ return;
+ }
+
+ sys_msgq = &gp_cds_sched_context->sysMcMq;
+ /* No msg present in sys queue */
+ if (cds_is_mq_empty(sys_msgq))
+ return;
+
+ spin_lock_irqsave(&sys_msgq->mqLock, flags);
+ list_for_each_safe(pos, q, &sys_msgq->mqList) {
+ msg_wrapper = list_entry(pos, cds_msg_wrapper, msgNode);
+
+ if ((msg_wrapper->pVosMsg->type == SYS_MSG_ID_MC_TIMER) &&
+ (msg_wrapper->pVosMsg->bodyval == timer_cookie)) {
+ /* return message to the Core */
+ list_del(pos);
+ spin_unlock_irqrestore(&sys_msgq->mqLock, flags);
+ QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_DEBUG,
+ "%s: removing timer message with cookie %d",
+ __func__, timer_cookie);
+ cds_core_return_msg(gp_cds_sched_context->pVContext,
+ msg_wrapper);
+ return;
+ }
+
+ }
+ spin_unlock_irqrestore(&sys_msgq->mqLock, flags);
+}
+
/**
* cds_sched_close() - close the cds scheduler
* @p_cds_context: Pointer to the global CDS Context