msm: ipa3: call napi_schedule() from irq context
The current implementation of IPA driver is to call
napi_schedule() from workqueue context creates a latency issue
which leads to high ping RTT.
This change will call napi_schedule() from irq context directly.
Change-Id: I17e31251b09a49b55437feb8ecd125bba37d33a8
CRs-Fixed: 2079976
Acked-by: Ady Abraham <adya@qti.qualcomm.com>
Signed-off-by: Skylar Chang <chiaweic@codeaurora.org>
diff --git a/drivers/platform/msm/ipa/ipa_v3/ipa_dp.c b/drivers/platform/msm/ipa/ipa_v3/ipa_dp.c
index b2a00de..018467a 100644
--- a/drivers/platform/msm/ipa/ipa_v3/ipa_dp.c
+++ b/drivers/platform/msm/ipa/ipa_v3/ipa_dp.c
@@ -784,8 +784,8 @@
sys = container_of(dwork, struct ipa3_sys_context, switch_to_intr_work);
if (sys->ep->napi_enabled) {
- ipa3_rx_switch_to_intr_mode(sys);
- IPA_ACTIVE_CLIENTS_DEC_SPECIAL("NAPI");
+ /* interrupt mode is done in ipa3_rx_poll context */
+ ipa_assert();
} else
ipa3_handle_rx(sys);
}
@@ -3270,6 +3270,7 @@
{
struct ipa3_sys_context *sys;
struct ipa3_rx_pkt_wrapper *rx_pkt_expected, *rx_pkt_rcvd;
+ int clk_off;
if (!notify) {
IPAERR("gsi notify is NULL.\n");
@@ -3301,7 +3302,20 @@
GSI_CHAN_MODE_POLL);
ipa3_inc_acquire_wakelock();
atomic_set(&sys->curr_polling_state, 1);
- queue_work(sys->wq, &sys->work);
+ if (sys->ep->napi_enabled) {
+ struct ipa_active_client_logging_info log;
+
+ IPA_ACTIVE_CLIENTS_PREP_SPECIAL(log, "NAPI");
+ clk_off = ipa3_inc_client_enable_clks_no_block(
+ &log);
+ if (!clk_off)
+ sys->ep->client_notify(sys->ep->priv,
+ IPA_CLIENT_START_POLL, 0);
+ else
+ queue_work(sys->wq, &sys->work);
+ } else {
+ queue_work(sys->wq, &sys->work);
+ }
}
break;
default:
@@ -3669,6 +3683,9 @@
int cnt = 0;
struct ipa_mem_buffer mem_info = {0};
static int total_cnt;
+ struct ipa_active_client_logging_info log;
+
+ IPA_ACTIVE_CLIENTS_PREP_SPECIAL(log, "NAPI");
if (clnt_hdl >= ipa3_ctx->ipa_num_pipes ||
ipa3_ctx->ep[clnt_hdl].valid == 0) {
@@ -3681,6 +3698,7 @@
while (cnt < weight &&
atomic_read(&ep->sys->curr_polling_state)) {
+ atomic_set(&ipa3_ctx->transport_pm.eot_activity, 1);
ret = ipa_poll_gsi_pkt(ep->sys, &mem_info);
if (ret)
break;
@@ -3698,7 +3716,8 @@
if (cnt < weight) {
ep->client_notify(ep->priv, IPA_CLIENT_COMP_NAPI, 0);
- queue_work(ep->sys->wq, &ep->sys->switch_to_intr_work.work);
+ ipa3_rx_switch_to_intr_mode(ep->sys);
+ ipa3_dec_client_disable_clks_no_block(&log);
}
return cnt;