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

Commit dced4592 authored by Deepak Kumar Singh's avatar Deepak Kumar Singh Committed by Gerrit - the friendly Code Review server
Browse files

soc: qcom: glink: fix race condition while getting rx fifo during ssr



When system goes up driver is trying to allocate rx_fifo from
ssr thread and interrupt handler as well, which can result in
race condition.

Taking spin lock before allocating rx_fifo to avoid race condition.

CRs-Fixed: 2502912
Change-Id: Ibe7b345d4e4edb7e837b84ddd4c03c3873ccf033
Signed-off-by: default avatarDeepak Kumar Singh <deesin@codeaurora.org>
parent 3cf94f42
Loading
Loading
Loading
Loading
+20 −4
Original line number Diff line number Diff line
@@ -948,6 +948,7 @@ static void __rx_worker(struct edge_info *einfo, bool atomic_ctx)
	char trash[FIFO_ALIGNMENT];
	struct deferred_cmd *d_cmd;
	void *cmd_data;
	bool ret = false;

	rcu_id = srcu_read_lock(&einfo->use_ref);

@@ -956,11 +957,18 @@ static void __rx_worker(struct edge_info *einfo, bool atomic_ctx)
		return;
	}

	spin_lock_irqsave(&einfo->rx_lock, flags);
	if (!einfo->rx_fifo) {
		if (!get_rx_fifo(einfo))
		ret = get_rx_fifo(einfo);
		if (!ret) {
			spin_unlock_irqrestore(&einfo->rx_lock, flags);
			srcu_read_unlock(&einfo->use_ref, rcu_id);
			return;
		einfo->xprt_if.glink_core_if_ptr->link_up(&einfo->xprt_if);
		}
	}
	spin_unlock_irqrestore(&einfo->rx_lock, flags);
	if (ret)
		einfo->xprt_if.glink_core_if_ptr->link_up(&einfo->xprt_if);

	if ((atomic_ctx) && ((einfo->tx_resume_needed)
	    || (einfo->tx_blocked_signal_sent)
@@ -1568,15 +1576,23 @@ static void tx_cmd_ch_remote_close_ack(struct glink_transport_if *if_ptr,
static void subsys_up(struct glink_transport_if *if_ptr)
{
	struct edge_info *einfo;
	unsigned long flags;
	bool ret = false;

	einfo = container_of(if_ptr, struct edge_info, xprt_if);
	einfo->in_ssr = false;
	spin_lock_irqsave(&einfo->rx_lock, flags);
	if (!einfo->rx_fifo) {
		if (!get_rx_fifo(einfo))
		ret = get_rx_fifo(einfo);
		if (!ret) {
			spin_unlock_irqrestore(&einfo->rx_lock, flags);
			return;
		einfo->xprt_if.glink_core_if_ptr->link_up(&einfo->xprt_if);
		}
	}
	spin_unlock_irqrestore(&einfo->rx_lock, flags);
	if (ret)
		einfo->xprt_if.glink_core_if_ptr->link_up(&einfo->xprt_if);
}

/**
 * ssr() - process a subsystem restart notification of a transport