diff options
| author | Mahesh A Saptasagar <c_msapta@qti.qualcomm.com> | 2014-04-08 12:48:39 +0530 |
|---|---|---|
| committer | Akash Patel <c_akashp@qca.qualcomm.com> | 2014-04-17 16:45:55 -0700 |
| commit | b76a99192adc00ff78028b342a497dd5aed02b22 (patch) | |
| tree | 6d101093424fc7dd5c3f96d7c2ebf18cac9eda90 /CORE/VOSS | |
| parent | 9738a6e5ec3b63a6ea2114bf2ca8805348a12fee (diff) | |
wlan: Delay SSR during active entry points.
Changes for delaying SSR if any identified entry points are active.
This is required to avoid any access to uninitialized or
deallocated data structure.
Change-Id: I8a80567ae58b642dbd314296b0986616c268fc8b
CRs-fixed: 650401
Diffstat (limited to 'CORE/VOSS')
| -rw-r--r-- | CORE/VOSS/src/vos_sched.c | 71 | ||||
| -rw-r--r-- | CORE/VOSS/src/vos_sched.h | 2 |
2 files changed, 73 insertions, 0 deletions
diff --git a/CORE/VOSS/src/vos_sched.c b/CORE/VOSS/src/vos_sched.c index de52f786843d..32a83cfbb635 100644 --- a/CORE/VOSS/src/vos_sched.c +++ b/CORE/VOSS/src/vos_sched.c @@ -71,6 +71,15 @@ * Preprocessor Definitions and Constants * ------------------------------------------------------------------------*/ #define VOS_SCHED_THREAD_HEART_BEAT INFINITE +/* Milli seconds to delay SSR thread when an Entry point is Active */ +#define SSR_WAIT_SLEEP_TIME 100 +/* MAX iteration count to wait for Entry point to exit before + * we proceed with SSR in WD Thread + */ +#define MAX_SSR_WAIT_ITERATIONS 20 + +static atomic_t ssr_protect_entry_count; + /*--------------------------------------------------------------------------- * Type Declarations * ------------------------------------------------------------------------*/ @@ -814,6 +823,7 @@ VosWDThread pVosWatchdogContext pWdContext = (pVosWatchdogContext)Arg; int retWaitStatus = 0; v_BOOL_t shutdown = VOS_FALSE; + int count = 0; VOS_STATUS vosStatus = VOS_STATUS_SUCCESS; set_user_nice(current, -3); @@ -850,6 +860,33 @@ VosWDThread clear_bit(WD_POST_EVENT_MASK, &pWdContext->wdEventFlag); while(1) { + /* Check for any Active Entry Points + * If active, delay SSR until no entry point is active or + * delay until count is decremented to ZERO + */ + count = MAX_SSR_WAIT_ITERATIONS; + while (count) + { + if (!atomic_read(&ssr_protect_entry_count)) + { + /* no external threads are executing */ + break; + } + /* at least one external thread is executing */ + if (--count) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: Waiting for active entry points to exit", __func__); + msleep(SSR_WAIT_SLEEP_TIME); + } + } + /* at least one external thread is executing */ + if (!count) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: Continuing SSR when %d Entry points are still active", + __func__, atomic_read(&ssr_protect_entry_count)); + } // Check if Watchdog needs to shutdown if(test_bit(WD_SHUTDOWN_EVENT_MASK, &pWdContext->wdEventFlag)) { @@ -2301,3 +2338,37 @@ VOS_STATUS vos_watchdog_wlan_re_init(void) return VOS_STATUS_SUCCESS; } + +/** + @brief vos_ssr_protect() + + This function is called to keep track of active driver entry points + + @param + caller_func - Name of calling function. + @return + void +*/ +void vos_ssr_protect(const char *caller_func) +{ + int count; + count = atomic_inc_return(&ssr_protect_entry_count); + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "%s: ENTRY ACTIVE %d", caller_func, count); +} + +/** + @brief vos_ssr_unprotect() + + @param + caller_func - Name of calling function. + @return + void +*/ +void vos_ssr_unprotect(const char *caller_func) +{ + int count; + count = atomic_dec_return(&ssr_protect_entry_count); + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "%s: ENTRY INACTIVE %d", caller_func, count); +} diff --git a/CORE/VOSS/src/vos_sched.h b/CORE/VOSS/src/vos_sched.h index 257c28ed99a9..0b7059432611 100644 --- a/CORE/VOSS/src/vos_sched.h +++ b/CORE/VOSS/src/vos_sched.h @@ -653,5 +653,7 @@ void vos_timer_module_init( void ); VOS_STATUS vos_watchdog_wlan_shutdown(void); VOS_STATUS vos_watchdog_wlan_re_init(void); v_BOOL_t isWDresetInProgress(void); +void vos_ssr_protect(const char *caller_func); +void vos_ssr_unprotect(const char *caller_func); #endif // #if !defined __VOSS_SCHED_H |
