diff --git a/drivers/platform/msm/ipa/ipa_v3/ipa.c b/drivers/platform/msm/ipa/ipa_v3/ipa.c index ee60841a1798..c4141001bb30 100644 --- a/drivers/platform/msm/ipa/ipa_v3/ipa.c +++ b/drivers/platform/msm/ipa/ipa_v3/ipa.c @@ -7554,6 +7554,10 @@ static int ipa3_pre_init(const struct ipa3_plat_drv_res *resource_p, /* Initialize Page poll threshold. */ ipa3_ctx->page_poll_threshold = IPA_PAGE_POLL_DEFAULT_THRESHOLD; + /* Use common page pool for Def/Coal pipe. */ + if (ipa3_ctx->ipa_hw_type >= IPA_HW_v4_9) + ipa3_ctx->wan_common_page_pool = true; + /* assume clock is on in virtual/emulation mode */ if (ipa3_ctx->ipa3_hw_mode == IPA_HW_MODE_VIRTUAL || ipa3_ctx->ipa3_hw_mode == IPA_HW_MODE_EMULATION) diff --git a/drivers/platform/msm/ipa/ipa_v3/ipa_debugfs.c b/drivers/platform/msm/ipa/ipa_v3/ipa_debugfs.c index c8cda1cd4ddb..aad988894dbc 100644 --- a/drivers/platform/msm/ipa/ipa_v3/ipa_debugfs.c +++ b/drivers/platform/msm/ipa/ipa_v3/ipa_debugfs.c @@ -1353,6 +1353,7 @@ static ssize_t ipa3_read_stats(struct file *file, char __user *ubuf, "act_clnt=%u\n" "con_clnt_bmap=0x%x\n" "wan_rx_empty=%u\n" + "wan_rx_empty_coal=%u\n" "wan_repl_rx_empty=%u\n" "lan_rx_empty=%u\n" "lan_repl_rx_empty=%u\n" @@ -1372,6 +1373,7 @@ static ssize_t ipa3_read_stats(struct file *file, char __user *ubuf, atomic_read(&ipa3_ctx->ipa3_active_clients.cnt), connect, ipa3_ctx->stats.wan_rx_empty, + ipa3_ctx->stats.wan_rx_empty_coal, ipa3_ctx->stats.wan_repl_rx_empty, ipa3_ctx->stats.lan_rx_empty, ipa3_ctx->stats.lan_repl_rx_empty, diff --git a/drivers/platform/msm/ipa/ipa_v3/ipa_dp.c b/drivers/platform/msm/ipa/ipa_v3/ipa_dp.c index 4484a268a7a6..42eaf09dbed7 100644 --- a/drivers/platform/msm/ipa/ipa_v3/ipa_dp.c +++ b/drivers/platform/msm/ipa/ipa_v3/ipa_dp.c @@ -1280,36 +1280,66 @@ int ipa3_setup_sys_pipe(struct ipa_sys_connect_params *sys_in, u32 *clnt_hdl) } } + /* Use common page pool for Coal and defalt pipe if applicable. */ if (ep->sys->repl_hdlr == ipa3_replenish_rx_page_recycle) { - ep->sys->page_recycle_repl = kzalloc( - sizeof(*ep->sys->page_recycle_repl), GFP_KERNEL); - if (!ep->sys->page_recycle_repl) { - IPAERR("failed to alloc repl for client %d\n", - sys_in->client); - result = -ENOMEM; - goto fail_napi; - } - atomic_set(&ep->sys->page_recycle_repl->pending, 0); - ep->sys->page_recycle_repl->capacity = - (ep->sys->rx_pool_sz + 1) * 2; - INIT_LIST_HEAD(&ep->sys->page_recycle_repl->page_repl_head); - ep->sys->repl = kzalloc(sizeof(*ep->sys->repl), GFP_KERNEL); - if (!ep->sys->repl) { - IPAERR("failed to alloc repl for client %d\n", - sys_in->client); - result = -ENOMEM; - goto fail_page_recycle_repl; - } - ep->sys->repl->capacity = (ep->sys->rx_pool_sz + 1); + if (!(ipa3_ctx->wan_common_page_pool && + sys_in->client == IPA_CLIENT_APPS_WAN_CONS && + coal_ep_id != IPA_EP_NOT_ALLOCATED && + ipa3_ctx->ep[coal_ep_id].valid == 1)) { + ep->sys->page_recycle_repl = kzalloc( + sizeof(*ep->sys->page_recycle_repl), GFP_KERNEL); + if (!ep->sys->page_recycle_repl) { + IPAERR("failed to alloc repl for client %d\n", + sys_in->client); + result = -ENOMEM; + goto fail_napi; + } + atomic_set(&ep->sys->page_recycle_repl->pending, 0); + /* For common page pool double the pool size. */ + if (ipa3_ctx->wan_common_page_pool && + sys_in->client == IPA_CLIENT_APPS_WAN_COAL_CONS) + ep->sys->page_recycle_repl->capacity = + (ep->sys->rx_pool_sz + 1) * + IPA_GENERIC_RX_CMN_PAGE_POOL_SZ_FACTOR; + else + ep->sys->page_recycle_repl->capacity = + (ep->sys->rx_pool_sz + 1) * + IPA_GENERIC_RX_PAGE_POOL_SZ_FACTOR; + IPADBG("Page repl capacity for client:%d, value:%d\n", + sys_in->client, ep->sys->page_recycle_repl->capacity); + INIT_LIST_HEAD(&ep->sys->page_recycle_repl->page_repl_head); + ep->sys->repl = kzalloc(sizeof(*ep->sys->repl), GFP_KERNEL); + if (!ep->sys->repl) { + IPAERR("failed to alloc repl for client %d\n", + sys_in->client); + result = -ENOMEM; + goto fail_page_recycle_repl; + } + /* For common page pool triple the pool size. */ + if (ipa3_ctx->wan_common_page_pool && + sys_in->client == IPA_CLIENT_APPS_WAN_COAL_CONS) + ep->sys->repl->capacity = (ep->sys->rx_pool_sz + 1) * + IPA_GENERIC_RX_CMN_TEMP_POOL_SZ_FACTOR; + else + ep->sys->repl->capacity = (ep->sys->rx_pool_sz + 1); + IPADBG("Repl capacity for client:%d, value:%d\n", + sys_in->client, ep->sys->repl->capacity); + atomic_set(&ep->sys->repl->pending, 0); + ep->sys->repl->cache = kcalloc(ep->sys->repl->capacity, + sizeof(void *), GFP_KERNEL); + atomic_set(&ep->sys->repl->head_idx, 0); + atomic_set(&ep->sys->repl->tail_idx, 0); - atomic_set(&ep->sys->repl->pending, 0); - ep->sys->repl->cache = kcalloc(ep->sys->repl->capacity, - sizeof(void *), GFP_KERNEL); - atomic_set(&ep->sys->repl->head_idx, 0); - atomic_set(&ep->sys->repl->tail_idx, 0); - - ipa3_replenish_rx_page_cache(ep->sys); - ipa3_wq_page_repl(&ep->sys->repl_work); + ipa3_replenish_rx_page_cache(ep->sys); + ipa3_wq_page_repl(&ep->sys->repl_work); + } else { + /* Use pool same as coal pipe when common page pool is used */ + ep->sys->common_buff_pool = true; + ep->sys->common_sys = ipa3_ctx->ep[coal_ep_id].sys; + ep->sys->repl = ipa3_ctx->ep[coal_ep_id].sys->repl; + ep->sys->page_recycle_repl = + ipa3_ctx->ep[coal_ep_id].sys->page_recycle_repl; + } } if (IPA_CLIENT_IS_CONS(sys_in->client)) { @@ -1379,16 +1409,16 @@ int ipa3_setup_sys_pipe(struct ipa_sys_connect_params *sys_in, u32 *clnt_hdl) fail_gen3: ipa3_disable_data_path(ipa_ep_idx); fail_repl: - if (IPA_CLIENT_IS_CONS(ep->client)) + if (IPA_CLIENT_IS_CONS(ep->client) && !ep->sys->common_buff_pool) ipa3_cleanup_rx(ep->sys); - if(ep->sys->repl) { + ep->sys->repl_hdlr = ipa3_replenish_rx_cache; + if (ep->sys->repl && !ep->sys->common_buff_pool) { ep->sys->repl->capacity = 0; kfree(ep->sys->repl); - ep->sys->repl = NULL; } fail_page_recycle_repl: - if (ep->sys->page_recycle_repl) { + if (ep->sys->page_recycle_repl && !ep->sys->common_buff_pool) { ep->sys->page_recycle_repl->capacity = 0; kfree(ep->sys->page_recycle_repl); ep->sys->page_recycle_repl = NULL; @@ -1567,7 +1597,7 @@ int ipa3_teardown_sys_pipe(u32 clnt_hdl) } if (ep->sys->repl_wq) flush_workqueue(ep->sys->repl_wq); - if (IPA_CLIENT_IS_CONS(ep->client)) + if (IPA_CLIENT_IS_CONS(ep->client) && !ep->sys->common_buff_pool) ipa3_cleanup_rx(ep->sys); if (!ep->skip_ep_cfg && IPA_CLIENT_IS_PROD(ep->client)) { @@ -1653,7 +1683,7 @@ static int ipa3_teardown_coal_def_pipe(u32 clnt_hdl) if (ep->sys->repl_wq) flush_workqueue(ep->sys->repl_wq); - if (IPA_CLIENT_IS_CONS(ep->client)) + if (IPA_CLIENT_IS_CONS(ep->client) && !ep->sys->common_buff_pool) ipa3_cleanup_rx(ep->sys); ep->valid = 0; @@ -2187,7 +2217,7 @@ static inline void __trigger_repl_work(struct ipa3_sys_context *sys) head = atomic_read(&sys->repl->head_idx); avail = (tail - head) % sys->repl->capacity; - if (avail < sys->repl->capacity / 4) { + if (avail < sys->repl->capacity / 2) { atomic_set(&sys->repl->pending, 1); queue_work(sys->repl_wq, &sys->repl_work); } @@ -2237,7 +2267,6 @@ static void ipa3_replenish_rx_page_recycle(struct ipa3_sys_context *sys) return; stats_i = (sys->ep->client == IPA_CLIENT_APPS_WAN_COAL_CONS) ? 0 : 1; - spin_lock_bh(&sys->spinlock); rx_len_cached = sys->len; curr_wq = atomic_read(&sys->repl->head_idx); @@ -2258,6 +2287,7 @@ static void ipa3_replenish_rx_page_recycle(struct ipa3_sys_context *sys) curr_wq = (++curr_wq == sys->repl->capacity) ? 0 : curr_wq; } + rx_pkt->sys = sys; dma_sync_single_for_device(ipa3_ctx->pdev, rx_pkt->page_data.dma_addr, @@ -2301,19 +2331,21 @@ static void ipa3_replenish_rx_page_recycle(struct ipa3_sys_context *sys) IPAERR("failed to provide buffer: %d\n", ret); ipa_assert(); } - spin_unlock_bh(&sys->spinlock); - __trigger_repl_work(sys); + + if (sys->common_buff_pool) + __trigger_repl_work(sys->common_sys); + else + __trigger_repl_work(sys); if (rx_len_cached <= IPA_DEFAULT_SYS_YELLOW_WM) { - if (sys->ep->client == IPA_CLIENT_APPS_WAN_CONS || - sys->ep->client == IPA_CLIENT_APPS_WAN_COAL_CONS) + if (sys->ep->client == IPA_CLIENT_APPS_WAN_CONS) IPA_STATS_INC_CNT(ipa3_ctx->stats.wan_rx_empty); + else if (sys->ep->client == IPA_CLIENT_APPS_WAN_COAL_CONS) + IPA_STATS_INC_CNT(ipa3_ctx->stats.wan_rx_empty_coal); else if (sys->ep->client == IPA_CLIENT_APPS_LAN_CONS) IPA_STATS_INC_CNT(ipa3_ctx->stats.lan_rx_empty); else WARN_ON(1); - queue_delayed_work(sys->wq, &sys->replenish_rx_work, - msecs_to_jiffies(1)); } return; @@ -3866,20 +3898,6 @@ static void ipa3_rx_napi_chain(struct ipa3_sys_context *sys, if (prev_skb) { skb_shinfo(prev_skb)->frag_list = NULL; sys->pyld_hdlr(first_skb, sys); - /* - * For coalescing, we have 2 transfer - * rings to replenish - */ - 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; - } - wan_def_sys = - ipa3_ctx->ep[ipa_ep_idx].sys; - wan_def_sys->repl_hdlr(wan_def_sys); } } } @@ -5461,6 +5479,7 @@ start_poll: cnt += weight - remain_aggr_weight * ipa3_ctx->ipa_wan_aggr_pkt_cnt; /* call repl_hdlr before napi_reschedule / napi_complete */ ep->sys->repl_hdlr(ep->sys); + wan_def_sys->repl_hdlr(wan_def_sys); /* When not able to replenish enough descriptors, keep in polling * mode, wait for napi-poll and replenish again. */ diff --git a/drivers/platform/msm/ipa/ipa_v3/ipa_i.h b/drivers/platform/msm/ipa/ipa_v3/ipa_i.h index c2d09a4e91f3..3e5138cc6c80 100644 --- a/drivers/platform/msm/ipa/ipa_v3/ipa_i.h +++ b/drivers/platform/msm/ipa/ipa_v3/ipa_i.h @@ -61,6 +61,9 @@ #define IPA_NUM_DESC_PER_SW_TX (3) #define IPA_GENERIC_RX_POOL_SZ_WAN 224 #define IPA_GENERIC_RX_POOL_SZ 192 +#define IPA_GENERIC_RX_PAGE_POOL_SZ_FACTOR 2 +#define IPA_GENERIC_RX_CMN_PAGE_POOL_SZ_FACTOR 5 +#define IPA_GENERIC_RX_CMN_TEMP_POOL_SZ_FACTOR 3 #define IPA_UC_FINISH_MAX 6 #define IPA_UC_WAIT_MIN_SLEEP 1000 #define IPA_UC_WAII_MAX_SLEEP 1200 @@ -1121,6 +1124,8 @@ struct ipa3_sys_context { u32 eob_drop_cnt; struct napi_struct napi_tx; atomic_t in_napi_context; + bool common_buff_pool; + struct ipa3_sys_context *common_sys; /* ordering is important - mutable fields go above */ struct ipa3_ep_context *ep; @@ -1460,6 +1465,7 @@ struct ipa3_stats { u32 aggr_close; u32 wan_aggr_close; u32 wan_rx_empty; + u32 wan_rx_empty_coal; u32 wan_repl_rx_empty; u32 lan_rx_empty; u32 lan_repl_rx_empty; @@ -2189,6 +2195,7 @@ struct ipa3_context { bool is_device_crashed; int ipa_pil_load; u8 page_poll_threshold; + bool wan_common_page_pool; }; struct ipa3_plat_drv_res {