瀏覽代碼

qcacmn: Fix irq imbalance issue

irq imbalance issue happens when some irq is disabled or enabled multiple
times. For group interrupts enabling one interrut can cause irq to come.
By this time other interrupts in the group are not enabled. But the irq
will disable all group interrupts in qir context. Later those interrupts
will be enabled. This can cause race condition and in turn irq imbalance
issue. Fix this issue by protecting request_irq and free_irq of group
interrupts to avoid race condition.

Change-Id: Ic99e80600ef63c0d7aff45231d0dae6767cd084c
CRs-Fixed: 2262333
Venkateswara Swamy Bandaru 6 年之前
父節點
當前提交
f290a54316
共有 1 個文件被更改,包括 4 次插入0 次删除
  1. 4 0
      hif/src/snoc/if_ahb.c

+ 4 - 0
hif/src/snoc/if_ahb.c

@@ -293,6 +293,7 @@ int hif_ahb_configure_grp_irq(struct hif_softc *scn,
 	hif_ext_group->irq_disable = &hif_ahb_exec_grp_irq_disable;
 	hif_ext_group->work_complete = &hif_dummy_grp_done;
 
+	qdf_spin_lock_irqsave(&hif_ext_group->irq_lock);
 	hif_ext_group->irq_requested = true;
 
 	for (j = 0; j < hif_ext_group->numirq; j++) {
@@ -315,6 +316,7 @@ int hif_ahb_configure_grp_irq(struct hif_softc *scn,
 	}
 
 end:
+	qdf_spin_unlock_irqrestore(&hif_ext_group->irq_lock);
 	return ret;
 }
 
@@ -329,6 +331,7 @@ void hif_ahb_deconfigure_grp_irq(struct hif_softc *scn)
 	for (i = 0; i < hif_state->hif_num_extgroup; i++) {
 		hif_ext_group = hif_state->hif_ext_group[i];
 		if (hif_ext_group->irq_requested == true) {
+			qdf_spin_lock_irqsave(&hif_ext_group->irq_lock);
 			hif_ext_group->irq_requested = false;
 			for (j = 0; j < hif_ext_group->numirq; j++) {
 				irq = hif_ext_group->os_irq[j];
@@ -336,6 +339,7 @@ void hif_ahb_deconfigure_grp_irq(struct hif_softc *scn)
 						       IRQ_DISABLE_UNLAZY);
 				free_irq(irq, hif_ext_group);
 			}
+			qdf_spin_unlock_irqrestore(&hif_ext_group->irq_lock);
 		}
 	}
 }