Merge "msm: ipa3: Fix to restart tasklet for pending packets"

This commit is contained in:
qctecmdr 2020-05-13 11:32:54 -07:00 committed by Gerrit - the friendly Code Review server
commit d6d5c4eb4a
2 changed files with 32 additions and 2 deletions

View file

@ -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);

View file

@ -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 */
};