From e01629963c8aa6cc03d2727043f341ae3a3d1454 Mon Sep 17 00:00:00 2001 From: Skylar Chang Date: Fri, 14 Apr 2017 15:59:50 -0700 Subject: [PATCH] msm: ipa3: allocate memory for DMA task on init On some conditions, such as reboot, the allocation context for DMA task might be a user space processes with SIGKILL. Pre allocate this buffer to avoid DMA allocation failure. Change-Id: Ie0c5ecbb7aebbf03c42c2f8976aad40e9987fd4a CRs-Fixed: 2032907 Acked-by: Ady Abraham Signed-off-by: Skylar Chang --- drivers/platform/msm/ipa/ipa_v3/ipa.c | 10 +++ drivers/platform/msm/ipa/ipa_v3/ipa_i.h | 8 +++ drivers/platform/msm/ipa/ipa_v3/ipa_utils.c | 78 +++++++++++++-------- 3 files changed, 65 insertions(+), 31 deletions(-) diff --git a/drivers/platform/msm/ipa/ipa_v3/ipa.c b/drivers/platform/msm/ipa/ipa_v3/ipa.c index ddff50834f03..7aaddbbdabaf 100644 --- a/drivers/platform/msm/ipa/ipa_v3/ipa.c +++ b/drivers/platform/msm/ipa/ipa_v3/ipa.c @@ -4036,6 +4036,7 @@ fail_register_device: unregister_chrdev_region(ipa3_ctx->dev_num, 1); if (ipa3_ctx->pipe_mem_pool) gen_pool_destroy(ipa3_ctx->pipe_mem_pool); + ipa3_free_dma_task_for_gsi(); ipa3_destroy_flt_tbl_idrs(); idr_destroy(&ipa3_ctx->ipa_idr); kmem_cache_destroy(ipa3_ctx->rx_pkt_wrapper_cache); @@ -4551,6 +4552,13 @@ static int ipa3_pre_init(const struct ipa3_plat_drv_res *resource_p, goto fail_dma_pool; } + /* allocate memory for DMA_TASK workaround */ + result = ipa3_allocate_dma_task_for_gsi(); + if (result) { + IPAERR("failed to allocate dma task\n"); + goto fail_dma_task; + } + /* init the various list heads */ INIT_LIST_HEAD(&ipa3_ctx->hdr_tbl.head_hdr_entry_list); for (i = 0; i < IPA_HDR_BIN_MAX; i++) { @@ -4723,6 +4731,8 @@ fail_cdev_add: fail_device_create: unregister_chrdev_region(ipa3_ctx->dev_num, 1); fail_alloc_chrdev_region: + ipa3_free_dma_task_for_gsi(); +fail_dma_task: if (ipa3_ctx->pipe_mem_pool) gen_pool_destroy(ipa3_ctx->pipe_mem_pool); ipa3_destroy_flt_tbl_idrs(); diff --git a/drivers/platform/msm/ipa/ipa_v3/ipa_i.h b/drivers/platform/msm/ipa/ipa_v3/ipa_i.h index 0cf77bbde496..ac7ef6a21952 100644 --- a/drivers/platform/msm/ipa/ipa_v3/ipa_i.h +++ b/drivers/platform/msm/ipa/ipa_v3/ipa_i.h @@ -1027,6 +1027,11 @@ struct ipa_tz_unlock_reg_info { u32 size; }; +struct ipa_dma_task_info { + struct ipa_mem_buffer mem; + struct ipahal_imm_cmd_pyld *cmd_pyld; +}; + /** * struct ipa3_context - IPA context * @class: pointer to the struct class @@ -1246,6 +1251,7 @@ struct ipa3_context { struct ipa3_smp2p_info smp2p_info; u32 ipa_tz_unlock_reg_num; struct ipa_tz_unlock_reg_info *ipa_tz_unlock_reg; + struct ipa_dma_task_info dma_task_info; }; /** @@ -2053,4 +2059,6 @@ int ipa3_get_ntn_stats(struct Ipa3HwStatsNTNInfoData_t *stats); struct dentry *ipa_debugfs_get_root(void); bool ipa3_is_msm_device(void); struct device *ipa3_get_pdev(void); +int ipa3_allocate_dma_task_for_gsi(void); +void ipa3_free_dma_task_for_gsi(void); #endif /* _IPA3_I_H_ */ diff --git a/drivers/platform/msm/ipa/ipa_v3/ipa_utils.c b/drivers/platform/msm/ipa/ipa_v3/ipa_utils.c index 14735787cb9c..f4a7319ca290 100644 --- a/drivers/platform/msm/ipa/ipa_v3/ipa_utils.c +++ b/drivers/platform/msm/ipa/ipa_v3/ipa_utils.c @@ -3483,6 +3483,51 @@ void ipa3_suspend_apps_pipes(bool suspend) } } +int ipa3_allocate_dma_task_for_gsi(void) +{ + struct ipahal_imm_cmd_dma_task_32b_addr cmd = { 0 }; + + IPADBG("Allocate mem\n"); + ipa3_ctx->dma_task_info.mem.size = IPA_GSI_CHANNEL_STOP_PKT_SIZE; + ipa3_ctx->dma_task_info.mem.base = dma_alloc_coherent(ipa3_ctx->pdev, + ipa3_ctx->dma_task_info.mem.size, + &ipa3_ctx->dma_task_info.mem.phys_base, + GFP_KERNEL); + if (!ipa3_ctx->dma_task_info.mem.base) { + IPAERR("no mem\n"); + return -EFAULT; + } + + cmd.flsh = 1; + cmd.size1 = ipa3_ctx->dma_task_info.mem.size; + cmd.addr1 = ipa3_ctx->dma_task_info.mem.phys_base; + cmd.packet_size = ipa3_ctx->dma_task_info.mem.size; + ipa3_ctx->dma_task_info.cmd_pyld = ipahal_construct_imm_cmd( + IPA_IMM_CMD_DMA_TASK_32B_ADDR, &cmd, false); + if (!ipa3_ctx->dma_task_info.cmd_pyld) { + IPAERR("failed to construct dma_task_32b_addr cmd\n"); + dma_free_coherent(ipa3_ctx->pdev, + ipa3_ctx->dma_task_info.mem.size, + ipa3_ctx->dma_task_info.mem.base, + ipa3_ctx->dma_task_info.mem.phys_base); + memset(&ipa3_ctx->dma_task_info, 0, + sizeof(ipa3_ctx->dma_task_info)); + return -EFAULT; + } + + return 0; +} + +void ipa3_free_dma_task_for_gsi(void) +{ + dma_free_coherent(ipa3_ctx->pdev, + ipa3_ctx->dma_task_info.mem.size, + ipa3_ctx->dma_task_info.mem.base, + ipa3_ctx->dma_task_info.mem.phys_base); + ipahal_destroy_imm_cmd(ipa3_ctx->dma_task_info.cmd_pyld); + memset(&ipa3_ctx->dma_task_info, 0, sizeof(ipa3_ctx->dma_task_info)); +} + /** * ipa3_inject_dma_task_for_gsi()- Send DMA_TASK to IPA for GSI stop channel * @@ -3491,41 +3536,12 @@ void ipa3_suspend_apps_pipes(bool suspend) */ int ipa3_inject_dma_task_for_gsi(void) { - static struct ipa_mem_buffer mem = {0}; - struct ipahal_imm_cmd_dma_task_32b_addr cmd = {0}; - static struct ipahal_imm_cmd_pyld *cmd_pyld; struct ipa3_desc desc = {0}; - /* allocate the memory only for the very first time */ - if (!mem.base) { - IPADBG("Allocate mem\n"); - mem.size = IPA_GSI_CHANNEL_STOP_PKT_SIZE; - mem.base = dma_alloc_coherent(ipa3_ctx->pdev, - mem.size, - &mem.phys_base, - GFP_KERNEL); - if (!mem.base) { - IPAERR("no mem\n"); - return -EFAULT; - } - } - if (!cmd_pyld) { - cmd.flsh = 1; - cmd.size1 = mem.size; - cmd.addr1 = mem.phys_base; - cmd.packet_size = mem.size; - cmd_pyld = ipahal_construct_imm_cmd( - IPA_IMM_CMD_DMA_TASK_32B_ADDR, &cmd, false); - if (!cmd_pyld) { - IPAERR("failed to construct dma_task_32b_addr cmd\n"); - return -EFAULT; - } - } - desc.opcode = ipahal_imm_cmd_get_opcode_param( IPA_IMM_CMD_DMA_TASK_32B_ADDR, 1); - desc.pyld = cmd_pyld->data; - desc.len = cmd_pyld->len; + desc.pyld = ipa3_ctx->dma_task_info.cmd_pyld->data; + desc.len = ipa3_ctx->dma_task_info.cmd_pyld->len; desc.type = IPA_IMM_CMD_DESC; IPADBG("sending 1B packet to IPA\n");