summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSarada Prasanna Garnayak <sgarna@codeaurora.org>2017-02-08 18:59:06 +0530
committerqcabuildsw <qcabuildsw@localhost>2017-02-15 14:15:03 -0800
commit1ed40f4bd7a0c9477b261b92befd519ccede1db5 (patch)
tree8d7b2521f8e32c64819ab023d4fe7626df48e70c
parent91d6a579c881cb20ad8b953c24a0ff0df9fe8063 (diff)
qcacmn: optimize the usage of runtime PM spinlock
Analyze the critical section of the runtime PM feature and replace the spin_lock_irqsave with spin_lock_bh. Disabling the IRQ and usage of spinlock for runtime PM debugging, logging and warning feature Is not required, remove the usage of spinlock from this context. The runtime PM APIs which is used for the prevent/allow runtime PM suspend /resume can be use spin_lock_bh instead of spin_lock_irqsave. For the runtime PM APIs add check point to identify the IRQ context, If the runtime PM APIs calling from IRQ context report WARN_ON for debugging purpose. CRs-Fixed: 1112447 Change-Id: If06970c6ac610a0128344e8c25a9cdd57b2542a3
-rw-r--r--hif/src/pcie/if_pci.c60
1 files changed, 29 insertions, 31 deletions
diff --git a/hif/src/pcie/if_pci.c b/hif/src/pcie/if_pci.c
index 21a6b83edad1..07416f881d13 100644
--- a/hif/src/pcie/if_pci.c
+++ b/hif/src/pcie/if_pci.c
@@ -985,7 +985,7 @@ static int hif_pci_pm_runtime_debugfs_show(struct seq_file *s, void *data)
"SUSPENDED"};
unsigned int msecs_age;
int pm_state = atomic_read(&sc->pm_state);
- unsigned long timer_expires, flags;
+ unsigned long timer_expires;
struct hif_pm_runtime_lock *ctx;
seq_printf(s, "%30s: %s\n", "Runtime PM state",
@@ -1025,9 +1025,9 @@ static int hif_pci_pm_runtime_debugfs_show(struct seq_file *s, void *data)
msecs_age / 1000, msecs_age % 1000);
}
- spin_lock_irqsave(&sc->runtime_lock, flags);
+ spin_lock_bh(&sc->runtime_lock);
if (list_empty(&sc->prevent_suspend_list)) {
- spin_unlock_irqrestore(&sc->runtime_lock, flags);
+ spin_unlock_bh(&sc->runtime_lock);
return 0;
}
@@ -1039,7 +1039,7 @@ static int hif_pci_pm_runtime_debugfs_show(struct seq_file *s, void *data)
seq_puts(s, " ");
}
seq_puts(s, "\n");
- spin_unlock_irqrestore(&sc->runtime_lock, flags);
+ spin_unlock_bh(&sc->runtime_lock);
return 0;
}
@@ -1199,7 +1199,6 @@ static void hif_pm_runtime_open(struct hif_pci_softc *sc)
*/
static void hif_pm_runtime_sanitize_on_exit(struct hif_pci_softc *sc)
{
- unsigned long flags;
struct hif_pm_runtime_lock *ctx, *tmp;
if (atomic_read(&sc->dev->power.usage_count) != 1)
@@ -1207,13 +1206,13 @@ static void hif_pm_runtime_sanitize_on_exit(struct hif_pci_softc *sc)
else
return;
- spin_lock_irqsave(&sc->runtime_lock, flags);
+ spin_lock_bh(&sc->runtime_lock);
list_for_each_entry_safe(ctx, tmp, &sc->prevent_suspend_list, list) {
- spin_unlock_irqrestore(&sc->runtime_lock, flags);
+ spin_unlock_bh(&sc->runtime_lock);
hif_pm_runtime_allow_suspend(GET_HIF_OPAQUE_HDL(sc), ctx);
- spin_lock_irqsave(&sc->runtime_lock, flags);
+ spin_lock_bh(&sc->runtime_lock);
}
- spin_unlock_irqrestore(&sc->runtime_lock, flags);
+ spin_unlock_bh(&sc->runtime_lock);
/* ensure 1 and only 1 usage count so that when the wlan
* driver is re-insmodded runtime pm won't be
@@ -1239,14 +1238,13 @@ static int __hif_pm_runtime_allow_suspend(struct hif_pci_softc *hif_sc,
*/
static void hif_pm_runtime_sanitize_on_ssr_exit(struct hif_pci_softc *sc)
{
- unsigned long flags;
struct hif_pm_runtime_lock *ctx, *tmp;
- spin_lock_irqsave(&sc->runtime_lock, flags);
+ spin_lock_bh(&sc->runtime_lock);
list_for_each_entry_safe(ctx, tmp, &sc->prevent_suspend_list, list) {
__hif_pm_runtime_allow_suspend(sc, ctx);
}
- spin_unlock_irqrestore(&sc->runtime_lock, flags);
+ spin_unlock_bh(&sc->runtime_lock);
}
/**
@@ -3728,7 +3726,6 @@ int hif_pm_runtime_put(struct hif_opaque_softc *hif_ctx)
struct hif_softc *scn = HIF_GET_SOFTC(hif_ctx);
struct hif_pci_softc *sc = HIF_GET_PCI_SOFTC(hif_ctx);
int pm_state, usage_count;
- unsigned long flags;
char *error = NULL;
if (NULL == scn) {
@@ -3749,9 +3746,7 @@ int hif_pm_runtime_put(struct hif_opaque_softc *hif_ctx)
}
if (error) {
- spin_lock_irqsave(&sc->runtime_lock, flags);
hif_pci_runtime_pm_warn(sc, error);
- spin_unlock_irqrestore(&sc->runtime_lock, flags);
return -EINVAL;
}
@@ -3880,11 +3875,10 @@ static int __hif_pm_runtime_allow_suspend(struct hif_pci_softc *hif_sc,
static void hif_pm_runtime_lock_timeout_fn(unsigned long data)
{
struct hif_pci_softc *hif_sc = (struct hif_pci_softc *)data;
- unsigned long flags;
unsigned long timer_expires;
struct hif_pm_runtime_lock *context, *temp;
- spin_lock_irqsave(&hif_sc->runtime_lock, flags);
+ spin_lock_bh(&hif_sc->runtime_lock);
timer_expires = hif_sc->runtime_timer_expires;
@@ -3912,7 +3906,7 @@ static void hif_pm_runtime_lock_timeout_fn(unsigned long data)
}
}
- spin_unlock_irqrestore(&hif_sc->runtime_lock, flags);
+ spin_unlock_bh(&hif_sc->runtime_lock);
}
int hif_pm_runtime_prevent_suspend(struct hif_opaque_softc *ol_sc,
@@ -3921,7 +3915,6 @@ int hif_pm_runtime_prevent_suspend(struct hif_opaque_softc *ol_sc,
struct hif_softc *sc = HIF_GET_SOFTC(ol_sc);
struct hif_pci_softc *hif_sc = HIF_GET_PCI_SOFTC(ol_sc);
struct hif_pm_runtime_lock *context = data;
- unsigned long flags;
if (!sc->hif_config.enable_runtime_pm)
return 0;
@@ -3929,10 +3922,13 @@ int hif_pm_runtime_prevent_suspend(struct hif_opaque_softc *ol_sc,
if (!context)
return -EINVAL;
- spin_lock_irqsave(&hif_sc->runtime_lock, flags);
+ if (in_irq())
+ WARN_ON(1);
+
+ spin_lock_bh(&hif_sc->runtime_lock);
context->timeout = 0;
__hif_pm_runtime_prevent_suspend(hif_sc, context);
- spin_unlock_irqrestore(&hif_sc->runtime_lock, flags);
+ spin_unlock_bh(&hif_sc->runtime_lock);
return 0;
}
@@ -3944,15 +3940,16 @@ int hif_pm_runtime_allow_suspend(struct hif_opaque_softc *ol_sc,
struct hif_pci_softc *hif_sc = HIF_GET_PCI_SOFTC(ol_sc);
struct hif_pm_runtime_lock *context = data;
- unsigned long flags;
-
if (!sc->hif_config.enable_runtime_pm)
return 0;
if (!context)
return -EINVAL;
- spin_lock_irqsave(&hif_sc->runtime_lock, flags);
+ if (in_irq())
+ WARN_ON(1);
+
+ spin_lock_bh(&hif_sc->runtime_lock);
__hif_pm_runtime_allow_suspend(hif_sc, context);
@@ -3968,7 +3965,7 @@ int hif_pm_runtime_allow_suspend(struct hif_opaque_softc *ol_sc,
hif_sc->runtime_timer_expires = 0;
}
- spin_unlock_irqrestore(&hif_sc->runtime_lock, flags);
+ spin_unlock_bh(&hif_sc->runtime_lock);
return 0;
}
@@ -3997,7 +3994,6 @@ int hif_pm_runtime_prevent_suspend_timeout(struct hif_opaque_softc *ol_sc,
int ret = 0;
unsigned long expires;
- unsigned long flags;
struct hif_pm_runtime_lock *context = lock;
if (hif_is_load_or_unload_in_progress(sc)) {
@@ -4017,6 +4013,9 @@ int hif_pm_runtime_prevent_suspend_timeout(struct hif_opaque_softc *ol_sc,
if (!context)
return -EINVAL;
+ if (in_irq())
+ WARN_ON(1);
+
/*
* Don't use internal timer if the timeout is less than auto suspend
* delay.
@@ -4030,7 +4029,7 @@ int hif_pm_runtime_prevent_suspend_timeout(struct hif_opaque_softc *ol_sc,
expires = jiffies + msecs_to_jiffies(delay);
expires += !expires;
- spin_lock_irqsave(&hif_sc->runtime_lock, flags);
+ spin_lock_bh(&hif_sc->runtime_lock);
context->timeout = delay;
ret = __hif_pm_runtime_prevent_suspend(hif_sc, context);
@@ -4044,7 +4043,7 @@ int hif_pm_runtime_prevent_suspend_timeout(struct hif_opaque_softc *ol_sc,
hif_sc->runtime_timer_expires = expires;
}
- spin_unlock_irqrestore(&hif_sc->runtime_lock, flags);
+ spin_unlock_bh(&hif_sc->runtime_lock);
HIF_ERROR("%s: pm_state: %s delay: %dms ret: %d\n", __func__,
hif_pm_runtime_state_to_string(
@@ -4089,7 +4088,6 @@ int hif_runtime_lock_init(qdf_runtime_lock_t *lock, const char *name)
void hif_runtime_lock_deinit(struct hif_opaque_softc *hif_ctx,
struct hif_pm_runtime_lock *data)
{
- unsigned long flags;
struct hif_pm_runtime_lock *context = data;
struct hif_pci_softc *sc = HIF_GET_PCI_SOFTC(hif_ctx);
@@ -4103,9 +4101,9 @@ void hif_runtime_lock_deinit(struct hif_opaque_softc *hif_ctx,
* Ensure to delete the context list entry and reduce the usage count
* before freeing the context if context is active.
*/
- spin_lock_irqsave(&sc->runtime_lock, flags);
+ spin_lock_bh(&sc->runtime_lock);
__hif_pm_runtime_allow_suspend(sc, context);
- spin_unlock_irqrestore(&sc->runtime_lock, flags);
+ spin_unlock_bh(&sc->runtime_lock);
qdf_mem_free(context);
}