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

Commit 9db64fb7 authored by Ashok Vuyyuru's avatar Ashok Vuyyuru
Browse files

msm: ipa3: Fix to restart tasklet for pending packets



In some conditions tasklet was exiting before processing
the all the packets. Add changes to restart tasklet for
pending packets.

Change-Id: I7246c070a003e27e8ef0b7036cf275a6f072b1b1
Signed-off-by: default avatarAshok Vuyyuru <avuyyuru@codeaurora.org>
parent 94732056
Loading
Loading
Loading
Loading
+30 −2
Original line number Diff line number Diff line
@@ -87,7 +87,7 @@

#define IPA_QMAP_ID_BYTE 0

#define IPA_TX_MAX_DESC (20)
#define IPA_TX_MAX_DESC (50)

static struct sk_buff *ipa3_get_skb_ipa_rx(unsigned int len, gfp_t flags);
static void ipa3_replenish_wlan_rx_cache(struct ipa3_sys_context *sys);
@@ -197,6 +197,15 @@ static void ipa3_wq_write_done_status(int src_pipe,
	ipa3_wq_write_done_common(sys, tx_pkt);
}

static void ipa3_tasklet_schd_work(struct work_struct *work)
{
	struct ipa3_sys_context *sys;

	sys = container_of(work, struct ipa3_sys_context, tasklet_work);
	if (atomic_read(&sys->xmit_eot_cnt))
		tasklet_schedule(&sys->tasklet);
}

/**
 * ipa_write_done() - this function will be (eventually) called when a Tx
 * operation is complete
@@ -235,10 +244,13 @@ static void ipa3_tasklet_write_done(unsigned long data)
		 * to watchdog bark. For avoiding these scenarios exit from
		 * tasklet after reaching max limit.
		 */
		if (max_tx_pkt == IPA_TX_MAX_DESC)
		if (max_tx_pkt >= IPA_TX_MAX_DESC)
			break;
	}
	spin_unlock_bh(&sys->spinlock);

	if (max_tx_pkt >= IPA_TX_MAX_DESC)
		queue_work(sys->tasklet_wq, &sys->tasklet_work);
}


@@ -1040,6 +1052,16 @@ int ipa3_setup_sys_pipe(struct ipa_sys_connect_params *sys_in, u32 *clnt_hdl)
			goto fail_wq2;
		}

		snprintf(buff, IPA_RESOURCE_NAME_MAX, "ipataskletwq%d",
				sys_in->client);
		ep->sys->tasklet_wq = alloc_workqueue(buff,
				WQ_MEM_RECLAIM | WQ_UNBOUND | WQ_SYSFS, 1);
		if (!ep->sys->tasklet_wq) {
			IPAERR("failed to create rep wq for client %d\n",
					sys_in->client);
			result = -EFAULT;
			goto fail_wq3;
		}
		INIT_LIST_HEAD(&ep->sys->head_desc_list);
		INIT_LIST_HEAD(&ep->sys->rcycl_list);
		spin_lock_init(&ep->sys->spinlock);
@@ -1088,6 +1110,8 @@ int ipa3_setup_sys_pipe(struct ipa_sys_connect_params *sys_in, u32 *clnt_hdl)
	atomic_set(&ep->sys->xmit_eot_cnt, 0);
	tasklet_init(&ep->sys->tasklet, ipa3_tasklet_write_done,
			(unsigned long) ep->sys);
	INIT_WORK(&ep->sys->tasklet_work,
		ipa3_tasklet_schd_work);
	ep->skip_ep_cfg = sys_in->skip_ep_cfg;
	if (ipa3_assign_policy(sys_in, ep->sys)) {
		IPAERR("failed to sys ctx for client %d\n", sys_in->client);
@@ -1273,6 +1297,8 @@ int ipa3_setup_sys_pipe(struct ipa_sys_connect_params *sys_in, u32 *clnt_hdl)
fail_gen2:
	ipa_pm_deregister(ep->sys->pm_hdl);
fail_pm:
	destroy_workqueue(ep->sys->tasklet_wq);
fail_wq3:
	destroy_workqueue(ep->sys->repl_wq);
fail_wq2:
	destroy_workqueue(ep->sys->wq);
@@ -1402,6 +1428,8 @@ int ipa3_teardown_sys_pipe(u32 clnt_hdl)
	}
	if (ep->sys->repl_wq)
		flush_workqueue(ep->sys->repl_wq);
	if (ep->sys->tasklet_wq)
		flush_workqueue(ep->sys->tasklet_wq);
	if (IPA_CLIENT_IS_CONS(ep->client))
		ipa3_cleanup_rx(ep->sys);

+2 −0
Original line number Diff line number Diff line
@@ -1031,6 +1031,7 @@ struct ipa3_sys_context {
	struct list_head pending_pkts[GSI_VEID_MAX];
	atomic_t xmit_eot_cnt;
	struct tasklet_struct tasklet;
	struct work_struct tasklet_work;

	/* ordering is important - mutable fields go above */
	struct ipa3_ep_context *ep;
@@ -1044,6 +1045,7 @@ struct ipa3_sys_context {
	u32 pm_hdl;
	unsigned int napi_sch_cnt;
	unsigned int napi_comp_cnt;
	struct workqueue_struct *tasklet_wq;
	/* ordering is important - other immutable fields go below */
};