From b8429f0813934c3c4351cf4ffb1b87a4b7c107fc Mon Sep 17 00:00:00 2001 From: Tejas Prajapati Date: Wed, 25 Aug 2021 15:14:42 +0530 Subject: [PATCH] msm: camera: memmgr: ref count for init and deinit Shared memory is initialized by CRM and used by ICP; with CRM not active the ICP would fail to access the shared memory if memory manager is deinit. Tracking open and close calls will help ICP driver to access the shared memory if CRM is not active. CRs-Fixed: 3019488 Change-Id: Ifdf198c2e3593050573c66aeba69d50d131435b9 Signed-off-by: Tejas Prajapati --- drivers/cam_icp/cam_icp_subdev.c | 10 +++++ drivers/cam_req_mgr/cam_mem_mgr.c | 65 +++++++++++++++++++------------ drivers/cam_req_mgr/cam_mem_mgr.h | 6 --- 3 files changed, 50 insertions(+), 31 deletions(-) diff --git a/drivers/cam_icp/cam_icp_subdev.c b/drivers/cam_icp/cam_icp_subdev.c index 1a3be9b64ad5..8a69ff7c1e8f 100644 --- a/drivers/cam_icp/cam_icp_subdev.c +++ b/drivers/cam_icp/cam_icp_subdev.c @@ -20,6 +20,7 @@ #include #include #include +#include "cam_mem_mgr.h" #include "cam_req_mgr_dev.h" #include "cam_subdev.h" #include "cam_node.h" @@ -86,10 +87,18 @@ static int cam_icp_subdev_open(struct v4l2_subdev *sd, goto end; } + + rc = cam_mem_mgr_init(); + if (rc) { + CAM_ERR(CAM_CRM, "mem mgr init failed"); + goto end; + } + hw_mgr_intf = &node->hw_mgr_intf; rc = hw_mgr_intf->hw_open(hw_mgr_intf->hw_mgr_priv, NULL); if (rc < 0) { CAM_ERR(CAM_ICP, "FW download failed"); + cam_mem_mgr_deinit(); goto end; } g_icp_dev.open_cnt++; @@ -130,6 +139,7 @@ int cam_icp_subdev_close_internal(struct v4l2_subdev *sd, goto end; } + cam_mem_mgr_deinit(); end: mutex_unlock(&g_icp_dev.icp_lock); return rc; diff --git a/drivers/cam_req_mgr/cam_mem_mgr.c b/drivers/cam_req_mgr/cam_mem_mgr.c index b928c7da46c7..9c8a404dbfe5 100644 --- a/drivers/cam_req_mgr/cam_mem_mgr.c +++ b/drivers/cam_req_mgr/cam_mem_mgr.c @@ -19,8 +19,11 @@ #include "cam_trace.h" #include "cam_common_util.h" -static struct cam_mem_table tbl; -static atomic_t cam_mem_mgr_state = ATOMIC_INIT(CAM_MEM_MGR_UNINITIALIZED); +static struct cam_mem_table tbl = { + .m_lock = __MUTEX_INITIALIZER(tbl.m_lock), +}; + +static atomic_t cam_mem_mgr_refcnt = ATOMIC_INIT(0); static void cam_mem_mgr_print_tbl(void) { @@ -164,6 +167,16 @@ int cam_mem_mgr_init(void) int i; int bitmap_size; + mutex_lock(&tbl.m_lock); + + if (atomic_inc_return(&cam_mem_mgr_refcnt) > 1) { + CAM_DBG(CAM_MEM, + "Mem mgr refcnt: %d", + atomic_read(&cam_mem_mgr_refcnt)); + mutex_unlock(&tbl.m_lock); + return 0; + } + memset(tbl.bufq, 0, sizeof(tbl.bufq)); if (cam_smmu_need_force_alloc_cached(&tbl.force_cache_allocs)) { @@ -173,8 +186,13 @@ int cam_mem_mgr_init(void) bitmap_size = BITS_TO_LONGS(CAM_MEM_BUFQ_MAX) * sizeof(long); tbl.bitmap = kzalloc(bitmap_size, GFP_KERNEL); - if (!tbl.bitmap) + if (!tbl.bitmap) { + atomic_dec(&cam_mem_mgr_refcnt); + CAM_DBG(CAM_MEM, "Mem mgr refcnt: %d", + atomic_read(&cam_mem_mgr_refcnt)); + mutex_unlock(&tbl.m_lock); return -ENOMEM; + } tbl.bits = bitmap_size * BITS_PER_BYTE; bitmap_zero(tbl.bitmap, tbl.bits); @@ -185,9 +203,8 @@ int cam_mem_mgr_init(void) tbl.bufq[i].fd = -1; tbl.bufq[i].buf_handle = -1; } - mutex_init(&tbl.m_lock); - atomic_set(&cam_mem_mgr_state, CAM_MEM_MGR_INITIALIZED); + mutex_unlock(&tbl.m_lock); cam_mem_mgr_create_debug_fs(); @@ -234,7 +251,7 @@ int cam_mem_get_io_buf(int32_t buf_handle, int32_t mmu_handle, *len_ptr = 0; - if (!atomic_read(&cam_mem_mgr_state)) { + if (!atomic_read(&cam_mem_mgr_refcnt)) { CAM_ERR(CAM_MEM, "failed. mem_mgr not initialized"); return -EINVAL; } @@ -285,12 +302,7 @@ int cam_mem_get_cpu_buf(int32_t buf_handle, uintptr_t *vaddr_ptr, size_t *len) { int idx; - if (!atomic_read(&cam_mem_mgr_state)) { - CAM_ERR(CAM_MEM, "failed. mem_mgr not initialized"); - return -EINVAL; - } - - if (!atomic_read(&cam_mem_mgr_state)) { + if (!atomic_read(&cam_mem_mgr_refcnt)) { CAM_ERR(CAM_MEM, "failed. mem_mgr not initialized"); return -EINVAL; } @@ -333,7 +345,7 @@ int cam_mem_mgr_cache_ops(struct cam_mem_cache_ops_cmd *cmd) uint32_t cache_dir; unsigned long dmabuf_flag = 0; - if (!atomic_read(&cam_mem_mgr_state)) { + if (!atomic_read(&cam_mem_mgr_refcnt)) { CAM_ERR(CAM_MEM, "failed. mem_mgr not initialized"); return -EINVAL; } @@ -659,7 +671,7 @@ int cam_mem_mgr_alloc_and_map(struct cam_mem_mgr_alloc_cmd *cmd) uintptr_t kvaddr = 0; size_t klen; - if (!atomic_read(&cam_mem_mgr_state)) { + if (!atomic_read(&cam_mem_mgr_refcnt)) { CAM_ERR(CAM_MEM, "failed. mem_mgr not initialized"); return -EINVAL; } @@ -811,7 +823,7 @@ int cam_mem_mgr_map(struct cam_mem_mgr_map_cmd *cmd) size_t len = 0; bool is_internal = false; - if (!atomic_read(&cam_mem_mgr_state)) { + if (!atomic_read(&cam_mem_mgr_refcnt)) { CAM_ERR(CAM_MEM, "failed. mem_mgr not initialized"); return -EINVAL; } @@ -998,7 +1010,6 @@ static int cam_mem_mgr_cleanup_table(void) { int i; - mutex_lock(&tbl.m_lock); for (i = 1; i < CAM_MEM_BUFQ_MAX; i++) { if (!tbl.bufq[i].active) { CAM_DBG(CAM_MEM, @@ -1034,23 +1045,27 @@ static int cam_mem_mgr_cleanup_table(void) bitmap_zero(tbl.bitmap, tbl.bits); /* We need to reserve slot 0 because 0 is invalid */ set_bit(0, tbl.bitmap); - mutex_unlock(&tbl.m_lock); return 0; } void cam_mem_mgr_deinit(void) { - atomic_set(&cam_mem_mgr_state, CAM_MEM_MGR_UNINITIALIZED); + mutex_lock(&tbl.m_lock); + if (!atomic_dec_and_test(&cam_mem_mgr_refcnt)) { + CAM_DBG(CAM_MEM, "Mem mgr refcnt: %d", + atomic_read(&cam_mem_mgr_refcnt)); + mutex_unlock(&tbl.m_lock); + return; + } + cam_mem_mgr_cleanup_table(); debugfs_remove_recursive(tbl.dentry); - mutex_lock(&tbl.m_lock); bitmap_zero(tbl.bitmap, tbl.bits); kfree(tbl.bitmap); tbl.bitmap = NULL; tbl.dbg_buf_idx = -1; mutex_unlock(&tbl.m_lock); - mutex_destroy(&tbl.m_lock); } static int cam_mem_util_unmap(int32_t idx, @@ -1148,7 +1163,7 @@ int cam_mem_mgr_release(struct cam_mem_mgr_release_cmd *cmd) int idx; int rc; - if (!atomic_read(&cam_mem_mgr_state)) { + if (!atomic_read(&cam_mem_mgr_refcnt)) { CAM_ERR(CAM_MEM, "failed. mem_mgr not initialized"); return -EINVAL; } @@ -1201,7 +1216,7 @@ int cam_mem_mgr_request_mem(struct cam_mem_mgr_request_desc *inp, enum cam_smmu_region_id region = CAM_SMMU_REGION_SHARED; - if (!atomic_read(&cam_mem_mgr_state)) { + if (!atomic_read(&cam_mem_mgr_refcnt)) { CAM_ERR(CAM_MEM, "failed. mem_mgr not initialized"); return -EINVAL; } @@ -1327,7 +1342,7 @@ int cam_mem_mgr_release_mem(struct cam_mem_mgr_memory_desc *inp) int32_t idx; int rc; - if (!atomic_read(&cam_mem_mgr_state)) { + if (!atomic_read(&cam_mem_mgr_refcnt)) { CAM_ERR(CAM_MEM, "failed. mem_mgr not initialized"); return -EINVAL; } @@ -1380,7 +1395,7 @@ int cam_mem_mgr_reserve_memory_region(struct cam_mem_mgr_request_desc *inp, int32_t smmu_hdl = 0; int32_t num_hdl = 0; - if (!atomic_read(&cam_mem_mgr_state)) { + if (!atomic_read(&cam_mem_mgr_refcnt)) { CAM_ERR(CAM_MEM, "failed. mem_mgr not initialized"); return -EINVAL; } @@ -1475,7 +1490,7 @@ int cam_mem_mgr_free_memory_region(struct cam_mem_mgr_memory_desc *inp) int rc; int32_t smmu_hdl; - if (!atomic_read(&cam_mem_mgr_state)) { + if (!atomic_read(&cam_mem_mgr_refcnt)) { CAM_ERR(CAM_MEM, "failed. mem_mgr not initialized"); return -EINVAL; } diff --git a/drivers/cam_req_mgr/cam_mem_mgr.h b/drivers/cam_req_mgr/cam_mem_mgr.h index 26ab9cb75319..9cf7a74b07cf 100644 --- a/drivers/cam_req_mgr/cam_mem_mgr.h +++ b/drivers/cam_req_mgr/cam_mem_mgr.h @@ -11,12 +11,6 @@ #include #include "cam_mem_mgr_api.h" -/* Enum for possible mem mgr states */ -enum cam_mem_mgr_state { - CAM_MEM_MGR_UNINITIALIZED, - CAM_MEM_MGR_INITIALIZED, -}; - /*Enum for possible SMMU operations */ enum cam_smmu_mapping_client { CAM_SMMU_MAPPING_USER,