Jelajahi Sumber

qcacmn: register va based minidump entry with module name

Current code registers va-md entry with static name
'qdf_va_md' when loading wlan driver, with no unregister
upon failure or driver unloading, this has a problem when
multiple wlan drivers are present, in which case it will
try to load all one by one during system bootup, but only
one driver will be loaded successfully at last. The
notifier_block for the unexpected wlan drivers will be left
in the notifier chain, which will result in kernel panic
when collecting minidump.

We can improve this by registering va-md entry with module
name, and unregistering the entry during de-init with the
newly added API qcom_va_md_unregister(), then different
wlan driver will register va-md entry with different module
name, and the entry will be unregistered on loading failure
or unloading, then there will be no stale notifier_block.

Change-Id: Ic08136f3f2ce1c202cab1ee68d8d376f2bd2fa57
CRs-Fixed: 3265807
Yu Wang 2 tahun lalu
induk
melakukan
aec06bc9b7
1 mengubah file dengan 13 tambahan dan 2 penghapusan
  1. 13 2
      qdf/linux/src/qdf_trace.c

+ 13 - 2
qdf/linux/src/qdf_trace.c

@@ -4639,10 +4639,16 @@ static struct notifier_block qdf_va_md_notif_blk = {
 
 void __qdf_minidump_init(void)
 {
+	int ret;
+
+	if (qdf_va_md_initialized)
+		return;
+
 	qdf_spinlock_create(&qdf_va_md_list_lock);
 	qdf_list_create(&qdf_va_md_list, QDF_MINIDUMP_LIST_SIZE);
-	qcom_va_md_register("qdf_va_md", &qdf_va_md_notif_blk);
-	qdf_va_md_initialized = true;
+	ret = qcom_va_md_register(qdf_trace_wlan_modname(),
+				  &qdf_va_md_notif_blk);
+	qdf_va_md_initialized = !ret;
 }
 
 qdf_export_symbol(__qdf_minidump_init);
@@ -4652,7 +4658,12 @@ void __qdf_minidump_deinit(void)
 	struct qdf_va_md_entry *entry;
 	struct qdf_va_md_entry *next;
 
+	if (!qdf_va_md_initialized)
+		return;
+
 	qdf_va_md_initialized = false;
+	qcom_va_md_unregister(qdf_trace_wlan_modname(),
+			      &qdf_va_md_notif_blk);
 	qdf_spin_lock_irqsave(&qdf_va_md_list_lock);
 	qdf_list_for_each_del(&qdf_va_md_list, entry, next, node) {
 		qdf_list_remove_node(&qdf_va_md_list, &entry->node);