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

Commit 4e24a89a authored by Praveen Kurapati's avatar Praveen Kurapati
Browse files

msm:ipa: Race condition observed during client disconnect



Client ep[i] entries are memset to 0 as part of tearing down
uc offload pipes which results in a race condition, if there are already
some packets which have been sent to IPA, when the client notify callback
is called.

Change-Id: I998e5d1c09d82e72b80ff00d1dd96398a92adc75
Signed-off-by: default avatarPraveen Kurapati <pkurapat@codeaurora.org>
Signed-off-by: default avatarChaitanya Pratapa <cpratapa@codeaurora.org>
parent 1180b8e6
Loading
Loading
Loading
Loading
+1 −3
Original line number Original line Diff line number Diff line
@@ -1792,9 +1792,7 @@ int ipa3_clear_endpoint_delay(u32 clnt_hdl)
	/* Set disconnect in progress flag so further flow control events are
	/* Set disconnect in progress flag so further flow control events are
	 * not honored.
	 * not honored.
	 */
	 */
	spin_lock(&ipa3_ctx->disconnect_lock);
	atomic_set(&ep->disconnect_in_progress, 1);
	ep->disconnect_in_progress = true;
	spin_unlock(&ipa3_ctx->disconnect_lock);


	/* If flow is disabled at this point, restore the ep state.*/
	/* If flow is disabled at this point, restore the ep state.*/
	ep_ctrl.ipa_ep_delay = false;
	ep_ctrl.ipa_ep_delay = false;
+8 −6
Original line number Original line Diff line number Diff line
@@ -3265,11 +3265,8 @@ void ipa3_lan_rx_cb(void *priv, enum ipa_dp_evt_type evt, unsigned long data)
	metadata = status.metadata;
	metadata = status.metadata;
	ucp = status.ucp;
	ucp = status.ucp;
	ep = &ipa3_ctx->ep[src_pipe];
	ep = &ipa3_ctx->ep[src_pipe];
	if (unlikely(src_pipe >= ipa3_ctx->ipa_num_pipes ||
	if (unlikely(src_pipe >= ipa3_ctx->ipa_num_pipes)) {
		!ep->valid ||
		IPAERR_RL("drop pipe=%d\n", src_pipe);
		!ep->client_notify)) {
		IPAERR_RL("drop pipe=%d ep_valid=%d client_notify=%pK\n",
		  src_pipe, ep->valid, ep->client_notify);
		dev_kfree_skb_any(rx_skb);
		dev_kfree_skb_any(rx_skb);
		return;
		return;
	}
	}
@@ -3291,7 +3288,12 @@ void ipa3_lan_rx_cb(void *priv, enum ipa_dp_evt_type evt, unsigned long data)
			metadata, *(u32 *)rx_skb->cb);
			metadata, *(u32 *)rx_skb->cb);
	IPADBG_LOW("ucp: %d\n", *(u8 *)(rx_skb->cb + 4));
	IPADBG_LOW("ucp: %d\n", *(u8 *)(rx_skb->cb + 4));


	ep->client_notify(ep->priv, IPA_RECEIVE, (unsigned long)(rx_skb));
	if (likely((!atomic_read(&ep->disconnect_in_progress)) &&
				ep->valid && ep->client_notify))
		ep->client_notify(ep->priv, IPA_RECEIVE,
				(unsigned long)(rx_skb));
	else
		dev_kfree_skb_any(rx_skb);
}
}


static void ipa3_recycle_rx_wrapper(struct ipa3_rx_pkt_wrapper *rx_pkt)
static void ipa3_recycle_rx_wrapper(struct ipa3_rx_pkt_wrapper *rx_pkt)
+1 −1
Original line number Original line Diff line number Diff line
@@ -935,7 +935,7 @@ struct ipa3_ep_context {
	struct ipa3_wlan_stats wstats;
	struct ipa3_wlan_stats wstats;
	u32 uc_offload_state;
	u32 uc_offload_state;
	u32 gsi_offload_state;
	u32 gsi_offload_state;
	bool disconnect_in_progress;
	atomic_t disconnect_in_progress;
	u32 qmi_request_sent;
	u32 qmi_request_sent;
	u32 eot_in_poll_err;
	u32 eot_in_poll_err;
	bool ep_delay_set;
	bool ep_delay_set;
+4 −1
Original line number Original line Diff line number Diff line
// SPDX-License-Identifier: GPL-2.0-only
// SPDX-License-Identifier: GPL-2.0-only
/*
/*
 * Copyright (c) 2016-2019, The Linux Foundation. All rights reserved.
 * Copyright (c) 2016-2020, The Linux Foundation. All rights reserved.
 */
 */


#include "ipa_i.h"
#include "ipa_i.h"
@@ -550,6 +550,9 @@ int ipa3_tear_down_uc_offload_pipes(int ipa_ep_idx_ul,
		return -EFAULT;
		return -EFAULT;
	}
	}


	atomic_set(&ep_ul->disconnect_in_progress, 1);
	atomic_set(&ep_dl->disconnect_in_progress, 1);

	if (ipa3_ctx->ipa_hw_type >= IPA_HW_v4_0)
	if (ipa3_ctx->ipa_hw_type >= IPA_HW_v4_0)
		cmd.size = sizeof(*cmd_data_v4_0);
		cmd.size = sizeof(*cmd_data_v4_0);
	else
	else