diff options
| author | Vignesh Viswanathan <viswanat@codeaurora.org> | 2018-03-07 17:43:31 +0530 |
|---|---|---|
| committer | nshrivas <nshrivas@codeaurora.org> | 2018-03-08 09:25:55 -0800 |
| commit | a30f9b07605014e60e1b979fb64f7c79dddab12e (patch) | |
| tree | bb1c11fd61441f45ff8af773da9b62728464534e | |
| parent | a326499fcacd0a18e998f7374eb7ef1e0c31f3bb (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.h | 12 | ||||
| -rw-r--r-- | core/cds/src/cds_mc_timer.c | 4 | ||||
| -rw-r--r-- | core/cds/src/cds_sched.c | 43 |
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 |
