Browse Source

qcacmn: Free napi context allocated during hif_napi_create

NAPI context allocated during hif_napi_create is freed in
qca_napi_destroy path based on the conditions that NAPI state
is enabled and NAPI context is created for the CE.

There can be cases when the NAPI context is created for the CE
but the current NAPI state not be enable. In such scenarios, NAPI
context is not getting freed in the destroy path.

Add hif_napi_created API to check if NAPI context is created for CE,
and use it in destroy path.

Also, NAPI object allocated is not freed after alloc during cases
when there is a failure in subsequent operations. Free NAPI object
aptly as required.

Change-Id: Ifcc21d70ba52ca309a913ac564406db627e11249
CRs-Fixed: 2256037
Sathish Kumar 6 years ago
parent
commit
2318e0f0e7
2 changed files with 27 additions and 3 deletions
  1. 22 3
      hif/src/hif_napi.c
  2. 5 0
      hif/src/hif_napi.h

+ 22 - 3
hif/src/hif_napi.c

@@ -166,7 +166,7 @@ int hif_napi_create(struct hif_opaque_softc   *hif_ctx,
 		if (!napii) {
 			NAPI_DEBUG("NAPI alloc failure %d", i);
 			rc = -ENOMEM;
-			goto napii_alloc_failure;
+			goto napii_free;
 		}
 	}
 
@@ -218,14 +218,15 @@ int hif_napi_create(struct hif_opaque_softc   *hif_ctx,
 	/* no ces registered with the napi */
 	if (!ce_srng_based(hif) && napid->ce_map == 0) {
 		HIF_WARN("%s: no napis created for copy engines", __func__);
-		return -EFAULT;
+		rc = -EFAULT;
+		goto napii_free;
 	}
 
 	NAPI_DEBUG("napi map = %x", napid->ce_map);
 	NAPI_DEBUG("NAPI ids created for all applicable pipes");
 	return napid->ce_map;
 
-napii_alloc_failure:
+napii_free:
 	for (i = 0; i < hif->ce_count; i++) {
 		napii = napid->napis[i];
 		napid->napis[i] = NULL;
@@ -710,6 +711,24 @@ int hif_napi_enabled(struct hif_opaque_softc *hif_ctx, int ce)
 }
 qdf_export_symbol(hif_napi_enabled);
 
+/**
+ * hif_napi_created() - checks whether NAPI is created for given ce or not
+ * @hif: hif context
+ * @ce : CE instance
+ *
+ * Return: bool
+ */
+bool hif_napi_created(struct hif_opaque_softc *hif_ctx, int ce)
+{
+	int rc;
+	struct hif_softc *hif = HIF_GET_SOFTC(hif_ctx);
+
+	rc = (hif->napi_data.ce_map & (0x01 << ce));
+
+	return !!rc;
+}
+qdf_export_symbol(hif_napi_created);
+
 /**
  * hif_napi_enable_irq() - enables bus interrupts after napi_complete
  *

+ 5 - 0
hif/src/hif_napi.h

@@ -162,6 +162,8 @@ int hif_napi_event(struct hif_opaque_softc     *hif,
 /* called from the ISR within hif, so, ce is known */
 int hif_napi_enabled(struct hif_opaque_softc *hif, int ce);
 
+bool hif_napi_created(struct hif_opaque_softc *hif, int ce);
+
 /* called from hdd (napi_poll), using napi id as a selector */
 void hif_napi_enable_irq(struct hif_opaque_softc *hif, int id);
 
@@ -244,6 +246,9 @@ static inline int hif_napi_event(struct hif_opaque_softc     *hif,
 static inline int hif_napi_enabled(struct hif_opaque_softc *hif, int ce)
 { return 0; }
 
+bool hif_napi_created(struct hif_opaque_softc *hif, int ce)
+{ return false; }
+
 /* called from hdd (napi_poll), using napi id as a selector */
 static inline void hif_napi_enable_irq(struct hif_opaque_softc *hif, int id)
 { return; }