From 2dfd041679cc8b89fcd40a7ecf03ef01d1620451 Mon Sep 17 00:00:00 2001 From: Karthikeyan Ramasubramanian Date: Mon, 22 Aug 2016 16:31:53 -0600 Subject: [PATCH] soc: qcom: ipc_router_glink_xprt: Add larger size receive intents Currently IPC Router does not queue larger size intents by default. It also does not re-use larger size intents once queued. This causes some performance impact for larger size message exchange. Add limited number of larger size receive intents on demand and re-use them. CRs-Fixed: 1066173 Change-Id: I8b1ff2af7db2ca13671e31a9bce05329346bda10 Signed-off-by: Karthikeyan Ramasubramanian --- drivers/soc/qcom/ipc_router_glink_xprt.c | 49 ++++++++++++++++++++---- 1 file changed, 41 insertions(+), 8 deletions(-) diff --git a/drivers/soc/qcom/ipc_router_glink_xprt.c b/drivers/soc/qcom/ipc_router_glink_xprt.c index 791221971e1c..1f36dd0ba07e 100644 --- a/drivers/soc/qcom/ipc_router_glink_xprt.c +++ b/drivers/soc/qcom/ipc_router_glink_xprt.c @@ -43,8 +43,14 @@ if (ipc_router_glink_xprt_debug_mask) \ #define MIN_FRAG_SZ (IPC_ROUTER_HDR_SIZE + sizeof(union rr_control_msg)) #define IPC_RTR_XPRT_NAME_LEN (2 * GLINK_NAME_SIZE) #define PIL_SUBSYSTEM_NAME_LEN 32 -#define DEFAULT_NUM_INTENTS 5 -#define DEFAULT_RX_INTENT_SIZE 2048 + +#define MAX_NUM_LO_INTENTS 5 +#define MAX_NUM_MD_INTENTS 3 +#define MAX_NUM_HI_INTENTS 2 +#define LO_RX_INTENT_SIZE 2048 +#define MD_RX_INTENT_SIZE 8192 +#define HI_RX_INTENT_SIZE (17 * 1024) + /** * ipc_router_glink_xprt - IPC Router's GLINK XPRT structure * @list: IPC router's GLINK XPRT list. @@ -82,6 +88,9 @@ struct ipc_router_glink_xprt { unsigned xprt_version; unsigned xprt_option; bool disable_pil_loading; + uint32_t cur_lo_intents_cnt; + uint32_t cur_md_intents_cnt; + uint32_t cur_hi_intents_cnt; }; struct ipc_router_glink_xprt_work { @@ -340,7 +349,7 @@ static void glink_xprt_read_data(struct work_struct *work) } D("%s %zu bytes @ %p\n", __func__, rx_work->iovec_size, rx_work->iovec); - if (rx_work->iovec_size <= DEFAULT_RX_INTENT_SIZE) + if (rx_work->iovec_size <= HI_RX_INTENT_SIZE) reuse_intent = true; pkt = glink_xprt_copy_data(rx_work); @@ -369,9 +378,14 @@ static void glink_xprt_open_event(struct work_struct *work) IPC_ROUTER_XPRT_EVENT_OPEN, NULL); D("%s: Notified IPC Router of %s OPEN\n", __func__, glink_xprtp->xprt.name); - for (i = 0; i < DEFAULT_NUM_INTENTS; i++) + glink_xprtp->cur_lo_intents_cnt = 0; + glink_xprtp->cur_md_intents_cnt = 0; + glink_xprtp->cur_hi_intents_cnt = 0; + for (i = 0; i < MAX_NUM_LO_INTENTS; i++) { glink_queue_rx_intent(glink_xprtp->ch_hndl, (void *)glink_xprtp, - DEFAULT_RX_INTENT_SIZE); + LO_RX_INTENT_SIZE); + glink_xprtp->cur_lo_intents_cnt++; + } kfree(xprt_work); } @@ -392,13 +406,32 @@ static void glink_xprt_close_event(struct work_struct *work) static void glink_xprt_qrx_intent_worker(struct work_struct *work) { + size_t sz; struct queue_rx_intent_work *qrx_intent_work = container_of(work, struct queue_rx_intent_work, work); struct ipc_router_glink_xprt *glink_xprtp = qrx_intent_work->glink_xprtp; + uint32_t *cnt = NULL; + int ret; - glink_queue_rx_intent(glink_xprtp->ch_hndl, (void *)glink_xprtp, - qrx_intent_work->intent_size); + sz = qrx_intent_work->intent_size; + if (sz <= MD_RX_INTENT_SIZE) { + if (glink_xprtp->cur_md_intents_cnt >= MAX_NUM_MD_INTENTS) + goto qrx_intent_worker_out; + sz = MD_RX_INTENT_SIZE; + cnt = &glink_xprtp->cur_md_intents_cnt; + } else if (sz <= HI_RX_INTENT_SIZE) { + if (glink_xprtp->cur_hi_intents_cnt >= MAX_NUM_HI_INTENTS) + goto qrx_intent_worker_out; + sz = HI_RX_INTENT_SIZE; + cnt = &glink_xprtp->cur_hi_intents_cnt; + } + + ret = glink_queue_rx_intent(glink_xprtp->ch_hndl, (void *)glink_xprtp, + sz); + if (!ret && cnt) + (*cnt)++; +qrx_intent_worker_out: kfree(qrx_intent_work); } @@ -468,7 +501,7 @@ static bool glink_xprt_notify_rx_intent_req(void *handle, const void *priv, struct ipc_router_glink_xprt *glink_xprtp = (struct ipc_router_glink_xprt *)priv; - if (sz <= DEFAULT_RX_INTENT_SIZE) + if (sz <= LO_RX_INTENT_SIZE) return true; qrx_intent_work = kmalloc(sizeof(struct queue_rx_intent_work),