Merge "msm: ipa3: Fix to restart tasklet for pending packets"
This commit is contained in:
commit
d6d5c4eb4a
2 changed files with 32 additions and 2 deletions
|
@ -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 @@ fail_page_recycle_repl:
|
|||
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);
|
||||
|
||||
|
|
|
@ -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 */
|
||||
};
|
||||
|
||||
|
|
Loading…
Reference in a new issue