Browse Source

msm: ipa: stay in NAPI mode when default pipe has low credits

When we have no buffer available in HW and switch to irq, a dead-loop is
observed between sending force close comamnd and replenish workqueue.
The fix is to keep in polling mode, wait for napi-poll and replenish again.

Change-Id: Ied0504564f86f41b8b5f9aa25170768027bf3391
Bojun Pan 4 years ago
parent
commit
c270d92443
1 changed files with 15 additions and 5 deletions
  1. 15 5
      drivers/platform/msm/ipa/ipa_v3/ipa_dp.c

+ 15 - 5
drivers/platform/msm/ipa/ipa_v3/ipa_dp.c

@@ -5248,10 +5248,12 @@ start_poll:
 int ipa3_rx_poll(u32 clnt_hdl, int weight)
 {
 	struct ipa3_ep_context *ep;
+	struct ipa3_sys_context *wan_def_sys;
 	int ret;
 	int cnt = 0;
 	int num = 0;
 	int remain_aggr_weight;
+	int ipa_ep_idx;
 	struct ipa_active_client_logging_info log;
 	struct gsi_chan_xfer_notify notify[IPA_WAN_NAPI_MAX_FRAMES];
 
@@ -5263,8 +5265,16 @@ int ipa3_rx_poll(u32 clnt_hdl, int weight)
 		return cnt;
 	}
 
-	remain_aggr_weight = weight / IPA_WAN_AGGR_PKT_CNT;
+	ipa_ep_idx = ipa3_get_ep_mapping(
+		IPA_CLIENT_APPS_WAN_CONS);
+	if (ipa_ep_idx ==
+		IPA_EP_NOT_ALLOCATED) {
+		IPAERR("Invalid client.\n");
+		return cnt;
+	}
 
+	wan_def_sys = ipa3_ctx->ep[ipa_ep_idx].sys;
+	remain_aggr_weight = weight / IPA_WAN_AGGR_PKT_CNT;
 	if (remain_aggr_weight > IPA_WAN_NAPI_MAX_FRAMES) {
 		IPAERR("NAPI weight is higher than expected\n");
 		IPAERR("expected %d got %d\n",
@@ -5301,11 +5311,11 @@ start_poll:
 	cnt += weight - remain_aggr_weight * IPA_WAN_AGGR_PKT_CNT;
 	/* call repl_hdlr before napi_reschedule / napi_complete */
 	ep->sys->repl_hdlr(ep->sys);
-
-	/* When not able to replenish enough descriptors pipe wait
-	 * until minimum number descripotrs to replish.
+	/* When not able to replenish enough descriptors, keep in polling
+	 * mode, wait for napi-poll and replenish again.
 	 */
-	if (cnt < weight && ep->sys->len > IPA_DEFAULT_SYS_YELLOW_WM) {
+	if (cnt < weight && ep->sys->len > IPA_DEFAULT_SYS_YELLOW_WM &&
+		wan_def_sys->len > IPA_DEFAULT_SYS_YELLOW_WM) {
 		napi_complete(ep->sys->napi_obj);
 		ret = ipa3_rx_switch_to_intr_mode(ep->sys);
 		if (ret == -GSI_STATUS_PENDING_IRQ &&