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

Commit 6499aacb authored by Ashok Vuyyuru's avatar Ashok Vuyyuru
Browse files

msm: ipa3: Update the channel mode before start channel



Observing the race condition if channel mode configured after
channel start. To avoid these race conditions configuring the
channel mode and starting the channel.

Change-Id: I8f8ec2d9faed320539e2b18de90ab24059a5616c
Signed-off-by: default avatarAshok Vuyyuru <avuyyuru@codeaurora.org>
parent f2be2c18
Loading
Loading
Loading
Loading
+4 −2
Original line number Diff line number Diff line
@@ -3844,17 +3844,19 @@ int gsi_config_channel_mode(unsigned long chan_hdl, enum gsi_chan_mode mode)
		return -GSI_STATUS_UNSUPPORTED_OP;
	}

	spin_lock_irqsave(&gsi_ctx->slock, flags);

	if (atomic_read(&ctx->poll_mode))
		curr = GSI_CHAN_MODE_POLL;
	else
		curr = GSI_CHAN_MODE_CALLBACK;

	if (mode == curr) {
		GSIDBG("already in requested mode %u chan_hdl=%lu\n",
		GSIERR("already in requested mode %u chan_hdl=%lu\n",
				curr, chan_hdl);
		spin_unlock_irqrestore(&gsi_ctx->slock, flags);
		return -GSI_STATUS_UNSUPPORTED_OP;
	}
	spin_lock_irqsave(&gsi_ctx->slock, flags);
	if (curr == GSI_CHAN_MODE_CALLBACK &&
			mode == GSI_CHAN_MODE_POLL) {
		__gsi_config_ieob_irq(gsi_ctx->per.ee, 1 << ctx->evtr->id, 0);
+3 −0
Original line number Diff line number Diff line
@@ -1795,6 +1795,7 @@ static void ipa3_wq_handle_rx(struct work_struct *work)
		else
			ipa_pm_activate_sync(sys->pm_hdl);
		napi_schedule(sys->napi_obj);
		IPA_STATS_INC_CNT(sys->napi_sch_cnt);
	} else
		ipa3_handle_rx(sys);
}
@@ -4360,6 +4361,7 @@ void __ipa_gsi_irq_rx_scedule_poll(struct ipa3_sys_context *sys)
		clk_off = ipa_pm_activate(sys->pm_hdl);
		if (!clk_off && sys->napi_obj) {
			napi_schedule(sys->napi_obj);
			IPA_STATS_INC_CNT(sys->napi_sch_cnt);
			return;
		}
		queue_work(sys->wq, &sys->work);
@@ -4951,6 +4953,7 @@ int ipa3_rx_poll(u32 clnt_hdl, int weight)
	 */
	if (cnt < weight && ep->sys->len > IPA_DEFAULT_SYS_YELLOW_WM) {
		napi_complete(ep->sys->napi_obj);
		IPA_STATS_INC_CNT(ep->sys->napi_comp_cnt);
		ret = ipa3_rx_switch_to_intr_mode(ep->sys);
		if (ret == -GSI_STATUS_PENDING_IRQ &&
				napi_reschedule(ep->sys->napi_obj))
+2 −0
Original line number Diff line number Diff line
@@ -1059,6 +1059,8 @@ struct ipa3_sys_context {
	struct workqueue_struct *repl_wq;
	struct ipa3_status_stats *status_stat;
	u32 pm_hdl;
	unsigned int napi_sch_cnt;
	unsigned int napi_comp_cnt;
	/* ordering is important - other immutable fields go below */
};

+10 −5
Original line number Diff line number Diff line
@@ -8033,6 +8033,16 @@ static int _ipa_suspend_resume_pipe(enum ipa_client_type client, bool suspend)
			ipa_assert();
		}
	} else {
		if (IPA_CLIENT_IS_APPS_PROD(client) ||
			(client == IPA_CLIENT_APPS_WAN_CONS &&
			coal_ep_idx != IPA_EP_NOT_ALLOCATED))
			goto chan_statrt;
		if (!atomic_read(&ep->sys->curr_polling_state)) {
			IPADBG("switch ch %ld to callback\n", ep->gsi_chan_hdl);
			gsi_config_channel_mode(ep->gsi_chan_hdl,
					GSI_CHAN_MODE_CALLBACK);
		}
chan_statrt:
		res = gsi_start_channel(ep->gsi_chan_hdl);
		if (res) {
			IPAERR("failed to start LAN channel\n");
@@ -8059,12 +8069,7 @@ static int _ipa_suspend_resume_pipe(enum ipa_client_type client, bool suspend)
		gsi_config_channel_mode(ep->gsi_chan_hdl, GSI_CHAN_MODE_POLL);
		if (!ipa3_gsi_channel_is_quite(ep))
			return -EAGAIN;
	} else if (!atomic_read(&ep->sys->curr_polling_state)) {
		IPADBG("switch ch %ld to callback\n", ep->gsi_chan_hdl);
		gsi_config_channel_mode(ep->gsi_chan_hdl,
			GSI_CHAN_MODE_CALLBACK);
	}

	return 0;
}