Browse Source

qcacld-3.0: Schedule work for cds_trigger_recovery() in atomic ctx

Currently wherever cds_trigger_recovery() is called in atomic
context, work is being scheduled.
This change is to modify cds_trigger_recovery() itself detect
that it is being called in atomic context and then
itself schedule work to its own handler.

Change-Id: Id37e97c9b838ad18c355234aa13f2b9c05503029
CRs-Fixed: 2081666
Srinivas Girigowda 7 years ago
parent
commit
161b9f298a
2 changed files with 56 additions and 3 deletions
  1. 2 0
      core/cds/inc/cds_sched.h
  2. 54 3
      core/cds/src/cds_api.c

+ 2 - 0
core/cds/inc/cds_sched.h

@@ -228,6 +228,8 @@ typedef struct _cds_context_type {
 	struct cds_config_info *cds_cfg;
 
 	struct ol_tx_sched_wrr_ac_specs_t ac_specs[TX_WMM_AC_NUM];
+	qdf_work_t cds_recovery_work;
+	qdf_workqueue_t *cds_recovery_wq;
 } cds_context_type, *p_cds_contextType;
 
 /*---------------------------------------------------------------------------

+ 54 - 3
core/cds/src/cds_api.c

@@ -85,6 +85,39 @@ static struct ol_if_ops  dp_ol_if_ops = {
 };
 
 void cds_sys_probe_thread_cback(void *pUserData);
+static void cds_trigger_recovery_work(void *param);
+
+/**
+ * cds_recovery_work_init() - Initialize recovery work queue
+ *
+ * Return: none
+ */
+static QDF_STATUS cds_recovery_work_init(void)
+{
+	qdf_create_work(0, &gp_cds_context->cds_recovery_work,
+			cds_trigger_recovery_work, NULL);
+	gp_cds_context->cds_recovery_wq =
+		qdf_create_workqueue("cds_recovery_workqueue");
+	if (NULL == gp_cds_context->cds_recovery_wq) {
+		cds_err("Failed to create cds_recovery_workqueue");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	return QDF_STATUS_SUCCESS;
+}
+
+/**
+ * cds_recovery_work_deinit() - Initialize recovery work queue
+ *
+ * Return: none
+ */
+static void cds_recovery_work_deinit(void)
+{
+	if (gp_cds_context->cds_recovery_wq) {
+		qdf_flush_workqueue(0, gp_cds_context->cds_recovery_wq);
+		qdf_destroy_workqueue(0, gp_cds_context->cds_recovery_wq);
+	}
+}
 
 /** cds_get_datapath_handles - Initialize pdev, vdev and soc
  * @soc - soc handle
@@ -154,6 +187,8 @@ v_CONTEXT_t cds_init(void)
 
 	cds_ssr_protect_init();
 
+	cds_recovery_work_init();
+
 	return gp_cds_context;
 }
 
@@ -167,6 +202,7 @@ void cds_deinit(void)
 	if (gp_cds_context == NULL)
 		return;
 
+	cds_recovery_work_deinit();
 	qdf_mc_timer_manager_exit();
 	qdf_mem_exit();
 	qdf_lock_stats_deinit();
@@ -1794,11 +1830,11 @@ static QDF_STATUS cds_force_assert_target(qdf_device_t qdf)
 }
 
 /**
- * cds_trigger_recovery() - trigger self recovery
+ * cds_trigger_recovery_work() - trigger self recovery work
  *
  * Return: none
  */
-void cds_trigger_recovery(void)
+static void cds_trigger_recovery_work(void *param)
 {
 	QDF_STATUS status;
 	qdf_runtime_lock_t rtl;
@@ -1823,7 +1859,7 @@ void cds_trigger_recovery(void)
 
 	status = qdf_runtime_lock_init(&rtl);
 	if (QDF_IS_STATUS_ERROR(status)) {
-		cds_err("Failed to initialize runtime pm lock");
+		cds_err("qdf_runtime_lock_init failed, status: %d", status);
 		return;
 	}
 
@@ -1843,6 +1879,21 @@ deinit_rtl:
 	qdf_runtime_lock_deinit(&rtl);
 }
 
+/**
+ * cds_trigger_recovery() - trigger self recovery
+ *
+ * Return: none
+ */
+void cds_trigger_recovery(void)
+{
+	if (in_atomic()) {
+		qdf_queue_work(0, gp_cds_context->cds_recovery_wq,
+				&gp_cds_context->cds_recovery_work);
+		return;
+	}
+	cds_trigger_recovery_work(NULL);
+}
+
 /**
  * cds_get_monotonic_boottime() - Get kernel boot time.
  *