Browse Source

cnss2: wait and cancel dms work before dms deinit

During cnss unload or error quit, cnss_dms_deinit() is called to
perform dms client deinit. When dms sever quit, modem also send event
to cnss to schedule dms client restart with dms_del_server(). The two
processes are asynchronous so qmi_handle_release() may be entered
twice and cause qmi->sock to be used after free.

To avoid this race condition, call cnss_cancel_dms_work() before
cnss_dms_deinit() to guarantee the two processes not run concurrently.

Change-Id: I291c1d0bdead190549dcbbb2c4b7aa65a68196d7
CRs-Fixed: 3875961
Nijun Gong 11 tháng trước cách đây
mục cha
commit
bbf4e9cd00
1 tập tin đã thay đổi với 2 bổ sung1 xóa
  1. 2 1
      cnss2/main.c

+ 2 - 1
cnss2/main.c

@@ -5610,6 +5610,7 @@ deinit_misc:
 destroy_debugfs:
 	cnss_debugfs_destroy(plat_priv);
 deinit_dms:
+	cnss_cancel_dms_work();
 	cnss_dms_deinit(plat_priv);
 deinit_event_work:
 	cnss_event_work_deinit(plat_priv);
@@ -5642,10 +5643,10 @@ static int cnss_remove(struct platform_device *plat_dev)
 	cnss_bus_deinit(plat_priv);
 	cnss_misc_deinit(plat_priv);
 	cnss_debugfs_destroy(plat_priv);
+	cnss_cancel_dms_work();
 	cnss_dms_deinit(plat_priv);
 	cnss_qmi_deinit(plat_priv);
 	cnss_event_work_deinit(plat_priv);
-	cnss_cancel_dms_work();
 	cnss_remove_sysfs(plat_priv);
 	cnss_unregister_bus_scale(plat_priv);
 	cnss_unregister_esoc(plat_priv);