소스 검색

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
Sarada Prasanna Garnayak 8 년 전
부모
커밋
ed8018ded1
1개의 변경된 파일30개의 추가작업 그리고 32개의 파일을 삭제
  1. 30 32
      hif/src/pcie/if_pci.c

+ 30 - 32
hif/src/pcie/if_pci.c

@@ -977,7 +977,7 @@ static const char *hif_pm_runtime_state_to_string(uint32_t state)
  *
  * Return: void
  */
-void hif_pci_runtime_pm_warn(struct hif_pci_softc *sc, const char *msg)
+static void hif_pci_runtime_pm_warn(struct hif_pci_softc *sc, const char *msg)
 {
 	struct hif_pm_runtime_lock *ctx;
 
@@ -1038,7 +1038,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",
@@ -1078,9 +1078,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;
 	}
 
@@ -1092,7 +1092,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;
 }
@@ -1253,7 +1253,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)
@@ -1261,13 +1260,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_runtime_lock_deinit(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
@@ -1293,14 +1292,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);
 }
 
 /**
@@ -4058,7 +4056,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) {
@@ -4079,9 +4076,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;
 	}
 
@@ -4210,11 +4205,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;
 
@@ -4242,7 +4236,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,
@@ -4251,7 +4245,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;
@@ -4259,10 +4252,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;
 }
@@ -4274,15 +4270,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);
 
@@ -4298,7 +4295,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;
 }
@@ -4327,7 +4324,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)) {
@@ -4347,6 +4343,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.
@@ -4360,7 +4359,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);
@@ -4374,7 +4373,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(
@@ -4417,7 +4416,6 @@ struct hif_pm_runtime_lock *hif_runtime_lock_init(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);
 
@@ -4431,9 +4429,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);
 }