mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-09 05:39:54 -04:00
msm: ipa: page pool recycling enhancements
Added the following enhancements to page pool recycling logic. 1) Common page pool for coalescing/default pipe. 2) Common page pool will hold 5 times the rx_pool_sz (224) for page recycling pool and 3 times for temp pool. This is done to sustain 50 stream scenarios. Change-Id: I55adfffa101df33c46e95b0214fb7338644e8d7c Signed-off-by: Ashok Vuyyuru <quic_avuyyuru@quicinc.com>
This commit is contained in:
parent
f46595d8a5
commit
d851d46728
4 changed files with 88 additions and 56 deletions
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
|
|||
Loading…
Reference in a new issue