mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-09 21:59:12 -04:00
qcacmn: Add lock protection for prevent_suspend_list
Need to protect prevent_suspend_list by runtime_lock. Issue happens when 1 printing lock0 of prevent_suspend_list in thread0 2 thread0 scheduled out and lock0 is released. 3 return back to thread0, it will using lock0 pointer to check next lock, then issue happens. Fix is adding runtime_lock to protect. Change-Id: I7182651e445cf5008dba73e15b2c261cc125577f CRs-Fixed: 2883052
This commit is contained in:
parent
1eb33580f7
commit
bc5baf5ca6
1 changed files with 27 additions and 15 deletions
|
|
@ -42,6 +42,8 @@
|
|||
#include "hif_exec.h"
|
||||
|
||||
#ifdef FEATURE_RUNTIME_PM
|
||||
#define PREVENT_LIST_STRING_LEN 200
|
||||
|
||||
/**
|
||||
* hif_pci_pm_runtime_enabled() - To check if Runtime PM is enabled
|
||||
* @scn: hif context
|
||||
|
|
@ -733,29 +735,40 @@ void hif_process_runtime_suspend_failure(struct hif_opaque_softc *hif_ctx)
|
|||
hif_runtime_pm_set_state_on(scn);
|
||||
}
|
||||
|
||||
static void hif_pm_runtime_print_prevent_list(struct hif_softc *scn)
|
||||
{
|
||||
struct hif_runtime_pm_ctx *rpm_ctx = hif_bus_get_rpm_ctx(scn);
|
||||
struct hif_pm_runtime_lock *ctx;
|
||||
|
||||
hif_info("prevent_suspend_cnt %u", rpm_ctx->prevent_suspend_cnt);
|
||||
list_for_each_entry(ctx, &rpm_ctx->prevent_suspend_list, list)
|
||||
hif_info("%s", ctx->name);
|
||||
}
|
||||
|
||||
static bool hif_pm_runtime_is_suspend_allowed(struct hif_softc *scn)
|
||||
{
|
||||
struct hif_runtime_pm_ctx *rpm_ctx = hif_bus_get_rpm_ctx(scn);
|
||||
bool ret;
|
||||
struct hif_pm_runtime_lock *ctx;
|
||||
uint32_t prevent_suspend_cnt;
|
||||
char *str_buf;
|
||||
bool is_suspend_allowed;
|
||||
int len = 0;
|
||||
|
||||
if (!scn->hif_config.enable_runtime_pm)
|
||||
return 0;
|
||||
return false;
|
||||
|
||||
str_buf = qdf_mem_malloc(PREVENT_LIST_STRING_LEN);
|
||||
if (!str_buf)
|
||||
return false;
|
||||
|
||||
spin_lock_bh(&rpm_ctx->runtime_lock);
|
||||
ret = (rpm_ctx->prevent_suspend_cnt == 0);
|
||||
prevent_suspend_cnt = rpm_ctx->prevent_suspend_cnt;
|
||||
is_suspend_allowed = (prevent_suspend_cnt == 0);
|
||||
if (!is_suspend_allowed) {
|
||||
list_for_each_entry(ctx, &rpm_ctx->prevent_suspend_list, list)
|
||||
len += qdf_scnprintf(str_buf + len,
|
||||
PREVENT_LIST_STRING_LEN - len,
|
||||
"%s ", ctx->name);
|
||||
}
|
||||
spin_unlock_bh(&rpm_ctx->runtime_lock);
|
||||
|
||||
return ret;
|
||||
if (!is_suspend_allowed)
|
||||
hif_info("prevent_suspend_cnt %u, prevent_list: %s",
|
||||
rpm_ctx->prevent_suspend_cnt, str_buf);
|
||||
|
||||
qdf_mem_free(str_buf);
|
||||
|
||||
return is_suspend_allowed;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -783,7 +796,6 @@ int hif_pre_runtime_suspend(struct hif_opaque_softc *hif_ctx)
|
|||
/* keep this after set suspending */
|
||||
if (!hif_pm_runtime_is_suspend_allowed(scn)) {
|
||||
hif_info("Runtime PM not allowed now");
|
||||
hif_pm_runtime_print_prevent_list(scn);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue