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:
Jingxiang Ge 2021-02-23 11:50:37 +08:00 • committed by snandini
commit bc5baf5ca6

View file

@ -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;
}