Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 1ee91cb9 authored by Subash Abhinov Kasiviswanathan's avatar Subash Abhinov Kasiviswanathan Committed by Gerrit - the friendly Code Review server
Browse files

dfc: Fix dead lock in dfc_svc_init



Handle a dead lock during cleanup due to rtnl_lock between the
unregister notifier and the dfc exit thread.

Change-Id: I3e61b29c305aba269a6370853c3115d0ed06bdff
Acked-by: default avatarNing Cai <ncai@qti.qualcomm.com>
Signed-off-by: default avatarSubash Abhinov Kasiviswanathan <subashab@codeaurora.org>
parent 7ede1bd9
Loading
Loading
Loading
Loading
+8 −1
Original line number Diff line number Diff line
@@ -1092,7 +1092,14 @@ static void dfc_svc_init(struct work_struct *work)
		return;
	}

	rtnl_lock();
	if (data->restart_state == 1)
		return;
	while (!rtnl_trylock()) {
		if (!data->restart_state)
			cond_resched();
		else
			return;
	}
	qmi = (struct qmi_info *)rmnet_get_qmi_pt(data->rmnet_port);
	if (!qmi) {
		rtnl_unlock();
+13 −1
Original line number Diff line number Diff line
@@ -17,6 +17,7 @@ struct wda_qmi_data {
	struct qmi_handle handle;
	struct sockaddr_qrtr ssctl;
	struct svc_info svc;
	int restart_state;
};

static void wda_svc_config(struct work_struct *work);
@@ -313,13 +314,22 @@ static void wda_svc_config(struct work_struct *work)
	struct qmi_info *qmi;
	int rc;

	if (data->restart_state == 1)
		return;
	rc = wda_set_powersave_config_req(&data->handle);
	if (rc < 0) {
		pr_err("%s Failed to init service, err[%d]\n", __func__, rc);
		return;
	}

	rtnl_lock();
	if (data->restart_state == 1)
		return;
	while (!rtnl_trylock()) {
		if (!data->restart_state)
			cond_resched();
		else
			return;
	}
	qmi = (struct qmi_info *)rmnet_get_qmi_pt(data->rmnet_port);
	if (!qmi) {
		rtnl_unlock();
@@ -385,6 +395,7 @@ wda_qmi_client_init(void *port, struct svc_info *psvc, struct qmi_info *qmi)
	}

	data->rmnet_port = port;
	data->restart_state = 0;
	memcpy(&data->svc, psvc, sizeof(data->svc));
	INIT_WORK(&data->svc_arrive, wda_svc_config);

@@ -424,6 +435,7 @@ void wda_qmi_client_exit(void *wda_data)
		return;
	}

	data->restart_state = 1;
	trace_wda_client_state_down(0);
	qmi_handle_release(&data->handle);
	destroy_workqueue(data->wda_wq);