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

Commit 6f23053c authored by Skylar Chang's avatar Skylar Chang Committed by Gerrit - the friendly Code Review server
Browse files

msm: ipa: fix race condition when teardown pipe



When pipe is disconnected there might be a delayed work scheduled for
buffer replenish to IPA. This may cause a race condition on replenish
data structures. This change addresses this issue by ensuring that no
work may run during pipe teardown.

Change-Id: I8a138b4bb96e7ff0506781e38bf7741397be92e4
CRs-Fixed: 979113
Acked-by: default avatarAdy Abraham <adya@qti.qualcomm.com>
Signed-off-by: default avatarSkylar Chang <chiaweic@codeaurora.org>
parent bfb07a5c
Loading
Loading
Loading
Loading
+10 −8
Original line number Diff line number Diff line
@@ -1322,14 +1322,6 @@ int ipa2_setup_sys_pipe(struct ipa_sys_connect_params *sys_in, u32 *clnt_hdl)

	*clnt_hdl = ipa_ep_idx;

	if (IPA_CLIENT_IS_CONS(sys_in->client))
		ipa_replenish_rx_cache(ep->sys);

	if (IPA_CLIENT_IS_WLAN_CONS(sys_in->client)) {
		ipa_alloc_wlan_rx_common_cache(IPA_WLAN_COMM_RX_POOL_LOW);
		atomic_inc(&ipa_ctx->wc_memb.active_clnt_cnt);
	}

	if (nr_cpu_ids > 1 &&
		(sys_in->client == IPA_CLIENT_APPS_LAN_CONS ||
		 sys_in->client == IPA_CLIENT_APPS_WAN_CONS)) {
@@ -1347,6 +1339,14 @@ int ipa2_setup_sys_pipe(struct ipa_sys_connect_params *sys_in, u32 *clnt_hdl)
		}
	}

	if (IPA_CLIENT_IS_CONS(sys_in->client))
		ipa_replenish_rx_cache(ep->sys);

	if (IPA_CLIENT_IS_WLAN_CONS(sys_in->client)) {
		ipa_alloc_wlan_rx_common_cache(IPA_WLAN_COMM_RX_POOL_LOW);
		atomic_inc(&ipa_ctx->wc_memb.active_clnt_cnt);
	}

	ipa_ctx->skip_ep_cfg_shadow[ipa_ep_idx] = ep->skip_ep_cfg;
	if (!ep->skip_ep_cfg && IPA_CLIENT_IS_PROD(sys_in->client)) {
		if (ipa_ctx->modem_cfg_emb_pipe_flt &&
@@ -1427,6 +1427,8 @@ int ipa2_teardown_sys_pipe(u32 clnt_hdl)
		} while (1);
	}

	if (IPA_CLIENT_IS_CONS(ep->client))
		cancel_delayed_work_sync(&ep->sys->replenish_rx_work);
	flush_workqueue(ep->sys->wq);
	sps_disconnect(ep->ep_hdl);
	dma_free_coherent(ipa_ctx->pdev, ep->connect.desc.size,
+10 −8
Original line number Diff line number Diff line
@@ -1253,14 +1253,6 @@ int ipa3_setup_sys_pipe(struct ipa_sys_connect_params *sys_in, u32 *clnt_hdl)

	*clnt_hdl = ipa_ep_idx;

	if (IPA_CLIENT_IS_CONS(sys_in->client))
		ipa3_replenish_rx_cache(ep->sys);

	if (IPA_CLIENT_IS_WLAN_CONS(sys_in->client)) {
		ipa3_alloc_wlan_rx_common_cache(IPA_WLAN_COMM_RX_POOL_LOW);
		atomic_inc(&ipa3_ctx->wc_memb.active_clnt_cnt);
	}

	if (ep->sys->repl_hdlr == ipa3_fast_replenish_rx_cache) {
		ep->sys->repl.capacity = ep->sys->rx_pool_sz + 1;
		ep->sys->repl.cache = kzalloc(ep->sys->repl.capacity *
@@ -1276,6 +1268,14 @@ int ipa3_setup_sys_pipe(struct ipa_sys_connect_params *sys_in, u32 *clnt_hdl)
		}
	}

	if (IPA_CLIENT_IS_CONS(sys_in->client))
		ipa3_replenish_rx_cache(ep->sys);

	if (IPA_CLIENT_IS_WLAN_CONS(sys_in->client)) {
		ipa3_alloc_wlan_rx_common_cache(IPA_WLAN_COMM_RX_POOL_LOW);
		atomic_inc(&ipa3_ctx->wc_memb.active_clnt_cnt);
	}

	ipa3_ctx->skip_ep_cfg_shadow[ipa_ep_idx] = ep->skip_ep_cfg;
	if (!ep->skip_ep_cfg && IPA_CLIENT_IS_PROD(sys_in->client)) {
		if (ipa3_ctx->modem_cfg_emb_pipe_flt &&
@@ -1351,6 +1351,8 @@ int ipa3_teardown_sys_pipe(u32 clnt_hdl)
		} while (1);
	}

	if (IPA_CLIENT_IS_CONS(ep->client))
		cancel_delayed_work_sync(&ep->sys->replenish_rx_work);
	flush_workqueue(ep->sys->wq);
	if (ipa3_ctx->transport_prototype == IPA_TRANSPORT_TYPE_GSI) {
		result = ipa3_stop_gsi_channel(clnt_hdl);