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

Commit dd9de0d2 authored by Bojun Pan's avatar Bojun Pan Committed by Gerrit - the friendly Code Review server
Browse files

msm: ipa: Fix race condition between timer expiry for wq and pipe teardown



db_timer expires after wq has been flushed in ipa3_teardown_sys_pipe.
This causes the wq to be scheduled after pipe teardown.

Add workqueue_flushed flag which set after the wq is flushed during
teardown. This flag is checked against in the wq function to ensure
it is not executed once the wq has been flushed.

Change-Id: I176a3a6dbf25985a41decf008ad045647081b871
Acked-by: default avatarPriyadarshini Rajagopal <prajagop@qti.qualcomm.com>
Signed-off-by: default avatarBojun Pan <bojunp@codeaurora.org>
parent b8658fe7
Loading
Loading
Loading
Loading
+8 −0
Original line number Diff line number Diff line
@@ -3487,6 +3487,14 @@ int gsi_queue_xfer(unsigned long chan_hdl, uint16_t num_xfers,
		return -GSI_STATUS_INVALID_PARAMS;
	}

	if (unlikely(gsi_ctx->chan[chan_hdl].state
				 == GSI_CHAN_STATE_NOT_ALLOCATED)) {
		GSIERR("bad state %d\n",
			   gsi_ctx->chan[chan_hdl].state);
		return -GSI_STATUS_UNSUPPORTED_OP;
	}


	ctx = &gsi_ctx->chan[chan_hdl];

	if (ctx->props.prot != GSI_CHAN_PROT_GPI &&
+9 −0
Original line number Diff line number Diff line
@@ -236,6 +236,10 @@ static void ipa3_send_nop_desc(struct work_struct *work)
	struct ipa3_tx_pkt_wrapper *tx_pkt;

	IPADBG_LOW("gsi send NOP for ch: %lu\n", sys->ep->gsi_chan_hdl);

	if (atomic_read(&sys->workqueue_flushed))
		return;

	tx_pkt = kmem_cache_zalloc(ipa3_ctx->tx_pkt_wrapper_cache, GFP_KERNEL);
	if (!tx_pkt) {
		queue_work(sys->wq, &sys->work);
@@ -466,6 +470,7 @@ int ipa3_send(struct ipa3_sys_context *sys,

	/* set the timer for sending the NOP descriptor */
	if (send_nop) {

		ktime_t time = ktime_set(0, IPA_TX_SEND_COMPL_NOP_DELAY_NS);

		IPADBG_LOW("scheduling timer for ch %lu\n",
@@ -1268,6 +1273,8 @@ int ipa3_teardown_sys_pipe(u32 clnt_hdl)
	if (IPA_CLIENT_IS_CONS(ep->client))
		cancel_delayed_work_sync(&ep->sys->replenish_rx_work);
	flush_workqueue(ep->sys->wq);
	if (IPA_CLIENT_IS_PROD(ep->client))
		atomic_set(&ep->sys->workqueue_flushed, 1);

	/* tear down the default pipe before we reset the channel*/
	if (ep->client == IPA_CLIENT_APPS_WAN_COAL_CONS) {
@@ -3514,6 +3521,7 @@ static int ipa3_assign_policy(struct ipa_sys_connect_params *in,
		sys->policy = IPA_POLICY_INTR_MODE;
		sys->use_comm_evt_ring = true;
		INIT_WORK(&sys->work, ipa3_send_nop_desc);
		atomic_set(&sys->workqueue_flushed, 0);

		/*
		 * enable source notification status for exception packets
@@ -3543,6 +3551,7 @@ static int ipa3_assign_policy(struct ipa_sys_connect_params *in,
			sys->policy = IPA_POLICY_INTR_MODE;
			sys->use_comm_evt_ring = true;
			INIT_WORK(&sys->work, ipa3_send_nop_desc);
			atomic_set(&sys->workqueue_flushed, 0);
		}
	} else {
		if (in->client == IPA_CLIENT_APPS_LAN_CONS ||
+1 −0
Original line number Diff line number Diff line
@@ -975,6 +975,7 @@ struct ipa3_repl_ctx {
struct ipa3_sys_context {
	u32 len;
	atomic_t curr_polling_state;
	atomic_t workqueue_flushed;
	struct delayed_work switch_to_intr_work;
	enum ipa3_sys_pipe_policy policy;
	bool use_comm_evt_ring;