Loading drivers/cam_req_mgr/cam_mem_mgr.c +56 −8 Original line number Original line Diff line number Diff line // SPDX-License-Identifier: GPL-2.0-only // SPDX-License-Identifier: GPL-2.0-only /* /* * Copyright (c) 2016-2019, The Linux Foundation. All rights reserved. * Copyright (c) 2016-2020, The Linux Foundation. All rights reserved. */ */ #include <linux/module.h> #include <linux/module.h> Loading @@ -22,6 +22,39 @@ static struct cam_mem_table tbl; static struct cam_mem_table tbl; static atomic_t cam_mem_mgr_state = ATOMIC_INIT(CAM_MEM_MGR_UNINITIALIZED); static atomic_t cam_mem_mgr_state = ATOMIC_INIT(CAM_MEM_MGR_UNINITIALIZED); static void cam_mem_mgr_print_tbl(void) { int i; uint64_t ms, tmp, hrs, min, sec; struct timespec64 *ts = NULL; struct timespec64 current_ts; ktime_get_real_ts64(&(current_ts)); tmp = current_ts.tv_sec; ms = (current_ts.tv_nsec) / 1000000; sec = do_div(tmp, 60); min = do_div(tmp, 60); hrs = do_div(tmp, 24); CAM_INFO(CAM_MEM, "***%llu:%llu:%llu:%llu Mem mgr table dump***", hrs, min, sec, ms); for (i = 1; i < CAM_MEM_BUFQ_MAX; i++) { if (tbl.bufq[i].active) { ts = &tbl.bufq[i].timestamp; tmp = ts->tv_sec; ms = (ts->tv_nsec) / 1000000; sec = do_div(tmp, 60); min = do_div(tmp, 60); hrs = do_div(tmp, 24); CAM_INFO(CAM_MEM, "%llu:%llu:%llu:%llu idx %d fd %d size %llu", hrs, min, sec, ms, i, tbl.bufq[i].fd, tbl.bufq[i].len); } } } static int cam_mem_util_get_dma_dir(uint32_t flags) static int cam_mem_util_get_dma_dir(uint32_t flags) { { int rc = -EINVAL; int rc = -EINVAL; Loading Loading @@ -185,6 +218,7 @@ static int32_t cam_mem_get_slot(void) set_bit(idx, tbl.bitmap); set_bit(idx, tbl.bitmap); tbl.bufq[idx].active = true; tbl.bufq[idx].active = true; ktime_get_real_ts64(&(tbl.bufq[idx].timestamp)); mutex_init(&tbl.bufq[idx].q_lock); mutex_init(&tbl.bufq[idx].q_lock); mutex_unlock(&tbl.m_lock); mutex_unlock(&tbl.m_lock); Loading @@ -196,6 +230,7 @@ static void cam_mem_put_slot(int32_t idx) mutex_lock(&tbl.m_lock); mutex_lock(&tbl.m_lock); mutex_lock(&tbl.bufq[idx].q_lock); mutex_lock(&tbl.bufq[idx].q_lock); tbl.bufq[idx].active = false; tbl.bufq[idx].active = false; memset(&tbl.bufq[idx].timestamp, 0, sizeof(struct timespec64)); mutex_unlock(&tbl.bufq[idx].q_lock); mutex_unlock(&tbl.bufq[idx].q_lock); mutex_destroy(&tbl.bufq[idx].q_lock); mutex_destroy(&tbl.bufq[idx].q_lock); clear_bit(idx, tbl.bitmap); clear_bit(idx, tbl.bitmap); Loading Loading @@ -643,6 +678,7 @@ int cam_mem_mgr_alloc_and_map(struct cam_mem_mgr_alloc_cmd *cmd) CAM_ERR(CAM_MEM, CAM_ERR(CAM_MEM, "Ion Alloc failed, len=%llu, align=%llu, flags=0x%x, num_hdl=%d", "Ion Alloc failed, len=%llu, align=%llu, flags=0x%x, num_hdl=%d", cmd->len, cmd->align, cmd->flags, cmd->num_hdl); cmd->len, cmd->align, cmd->flags, cmd->num_hdl); cam_mem_mgr_print_tbl(); return rc; return rc; } } Loading Loading @@ -679,9 +715,14 @@ int cam_mem_mgr_alloc_and_map(struct cam_mem_mgr_alloc_cmd *cmd) if (rc) { if (rc) { CAM_ERR(CAM_MEM, CAM_ERR(CAM_MEM, "Failed in map_hw_va, len=%llu, flags=0x%x, fd=%d, region=%d, num_hdl=%d, rc=%d", "Failed in map_hw_va, [Size cmdlen=%llu dma %llu smmu %llu], flags=0x%x, fd=%d, region=%d, num_hdl=%d, rc=%d", cmd->len, cmd->flags, fd, region, cmd->len, dmabuf->size, len, cmd->flags, cmd->num_hdl, rc); fd, region, cmd->num_hdl, rc); if (rc == -EALREADY) { if ((size_t)dmabuf->size != len) rc = -EBADR; cam_mem_mgr_print_tbl(); } goto map_hw_fail; goto map_hw_fail; } } } } Loading Loading @@ -780,9 +821,15 @@ int cam_mem_mgr_map(struct cam_mem_mgr_map_cmd *cmd) CAM_SMMU_REGION_IO); CAM_SMMU_REGION_IO); if (rc) { if (rc) { CAM_ERR(CAM_MEM, CAM_ERR(CAM_MEM, "Failed in map_hw_va, flags=0x%x, fd=%d, region=%d, num_hdl=%d, rc=%d", "Failed in map_hw_va, flags=0x%x, fd=%d, [Size smmu %llu dma %llu], region=%d, num_hdl=%d, rc=%d", cmd->flags, cmd->fd, CAM_SMMU_REGION_IO, cmd->flags, cmd->fd, len, dmabuf->size, cmd->num_hdl, rc); CAM_SMMU_REGION_IO, cmd->num_hdl, rc); if (rc == -EALREADY) { if ((size_t)dmabuf->size != len) { rc = -EBADR; cam_mem_mgr_print_tbl(); } } goto map_fail; goto map_fail; } } } } Loading Loading @@ -817,7 +864,7 @@ int cam_mem_mgr_map(struct cam_mem_mgr_map_cmd *cmd) cmd->out.buf_handle = tbl.bufq[idx].buf_handle; cmd->out.buf_handle = tbl.bufq[idx].buf_handle; cmd->out.vaddr = 0; cmd->out.vaddr = 0; cmd->out.size = (uint32_t)len; CAM_DBG(CAM_MEM, CAM_DBG(CAM_MEM, "fd=%d, flags=0x%x, num_hdl=%d, idx=%d, buf handle=%x, len=%zu", "fd=%d, flags=0x%x, num_hdl=%d, idx=%d, buf handle=%x, len=%zu", cmd->fd, cmd->flags, cmd->num_hdl, idx, cmd->out.buf_handle, cmd->fd, cmd->flags, cmd->num_hdl, idx, cmd->out.buf_handle, Loading Loading @@ -1037,6 +1084,7 @@ static int cam_mem_util_unmap(int32_t idx, tbl.bufq[idx].len = 0; tbl.bufq[idx].len = 0; tbl.bufq[idx].num_hdl = 0; tbl.bufq[idx].num_hdl = 0; tbl.bufq[idx].active = false; tbl.bufq[idx].active = false; memset(&tbl.bufq[idx].timestamp, 0, sizeof(struct timespec64)); mutex_unlock(&tbl.bufq[idx].q_lock); mutex_unlock(&tbl.bufq[idx].q_lock); mutex_destroy(&tbl.bufq[idx].q_lock); mutex_destroy(&tbl.bufq[idx].q_lock); clear_bit(idx, tbl.bitmap); clear_bit(idx, tbl.bitmap); Loading drivers/cam_req_mgr/cam_mem_mgr.h +3 −1 Original line number Original line Diff line number Diff line /* SPDX-License-Identifier: GPL-2.0-only */ /* SPDX-License-Identifier: GPL-2.0-only */ /* /* * Copyright (c) 2016-2019, The Linux Foundation. All rights reserved. * Copyright (c) 2016-2020, The Linux Foundation. All rights reserved. */ */ #ifndef _CAM_MEM_MGR_H_ #ifndef _CAM_MEM_MGR_H_ Loading Loading @@ -41,6 +41,7 @@ enum cam_smmu_mapping_client { * @kmdvaddr: Kernel virtual address * @kmdvaddr: Kernel virtual address * @active: state of the buffer * @active: state of the buffer * @is_imported: Flag indicating if buffer is imported from an FD in user space * @is_imported: Flag indicating if buffer is imported from an FD in user space * @timestamp: Timestamp at which this entry in tbl was made */ */ struct cam_mem_buf_queue { struct cam_mem_buf_queue { struct dma_buf *dma_buf; struct dma_buf *dma_buf; Loading @@ -56,6 +57,7 @@ struct cam_mem_buf_queue { uintptr_t kmdvaddr; uintptr_t kmdvaddr; bool active; bool active; bool is_imported; bool is_imported; struct timespec64 timestamp; }; }; /** /** Loading drivers/cam_smmu/cam_smmu_api.c +50 −12 Original line number Original line Diff line number Diff line Loading @@ -196,6 +196,7 @@ struct cam_dma_buff_info { int ion_fd; int ion_fd; size_t len; size_t len; size_t phys_len; size_t phys_len; struct timespec64 ts; }; }; struct cam_sec_buff_info { struct cam_sec_buff_info { Loading Loading @@ -401,6 +402,9 @@ static void cam_smmu_dump_cb_info(int idx) size_t shared_reg_len = 0, io_reg_len = 0; size_t shared_reg_len = 0, io_reg_len = 0; size_t shared_free_len = 0, io_free_len = 0; size_t shared_free_len = 0, io_free_len = 0; uint32_t i = 0; uint32_t i = 0; uint64_t ms, tmp, hrs, min, sec; struct timespec64 *ts = NULL; struct timespec64 current_ts; struct cam_context_bank_info *cb_info = struct cam_context_bank_info *cb_info = &iommu_cb_set.cb_info[idx]; &iommu_cb_set.cb_info[idx]; Loading @@ -414,9 +418,15 @@ static void cam_smmu_dump_cb_info(int idx) io_free_len = io_reg_len - cb_info->io_mapping_size; io_free_len = io_reg_len - cb_info->io_mapping_size; } } ktime_get_real_ts64(&(current_ts)); tmp = current_ts.tv_sec; ms = (current_ts.tv_nsec) / 1000000; sec = do_div(tmp, 60); min = do_div(tmp, 60); hrs = do_div(tmp, 24); CAM_ERR(CAM_SMMU, CAM_ERR(CAM_SMMU, "********** Context bank dump for %s **********", "********** %llu:%llu:%llu:%llu Context bank dump for %s **********", cb_info->name); hrs, min, sec, ms, cb_info->name); CAM_ERR(CAM_SMMU, CAM_ERR(CAM_SMMU, "Usage: shared_usage=%u io_usage=%u shared_free=%u io_free=%u", "Usage: shared_usage=%u io_usage=%u shared_free=%u io_free=%u", (unsigned int)cb_info->shared_mapping_size, (unsigned int)cb_info->shared_mapping_size, Loading @@ -428,9 +438,16 @@ static void cam_smmu_dump_cb_info(int idx) list_for_each_entry_safe(mapping, mapping_temp, list_for_each_entry_safe(mapping, mapping_temp, &iommu_cb_set.cb_info[idx].smmu_buf_list, list) { &iommu_cb_set.cb_info[idx].smmu_buf_list, list) { i++; i++; ts = &mapping->ts; tmp = ts->tv_sec; ms = (ts->tv_nsec) / 1000000; sec = do_div(tmp, 60); min = do_div(tmp, 60); hrs = do_div(tmp, 24); CAM_ERR(CAM_SMMU, CAM_ERR(CAM_SMMU, "%u. ion_fd=%d start=0x%x end=0x%x len=%u region=%d", "%llu:%llu:%llu:%llu: %u ion_fd=%d start=0x%x end=0x%x len=%u region=%d", i, mapping->ion_fd, (void *)mapping->paddr, hrs, min, sec, ms, i, mapping->ion_fd, (void *)mapping->paddr, ((uint64_t)mapping->paddr + ((uint64_t)mapping->paddr + (uint64_t)mapping->len), (uint64_t)mapping->len), (unsigned int)mapping->len, (unsigned int)mapping->len, Loading Loading @@ -1999,6 +2016,7 @@ static int cam_smmu_map_buffer_and_add_to_list(int idx, int ion_fd, } } mapping_info->ion_fd = ion_fd; mapping_info->ion_fd = ion_fd; ktime_get_real_ts64(&mapping_info->ts); /* add to the list */ /* add to the list */ list_add(&mapping_info->list, list_add(&mapping_info->list, &iommu_cb_set.cb_info[idx].smmu_buf_list); &iommu_cb_set.cb_info[idx].smmu_buf_list); Loading Loading @@ -2026,7 +2044,7 @@ static int cam_smmu_map_kernel_buffer_and_add_to_list(int idx, } } mapping_info->ion_fd = -1; mapping_info->ion_fd = -1; ktime_get_real_ts64(&mapping_info->ts); /* add to the list */ /* add to the list */ list_add(&mapping_info->list, list_add(&mapping_info->list, &iommu_cb_set.cb_info[idx].smmu_buf_kernel_list); &iommu_cb_set.cb_info[idx].smmu_buf_kernel_list); Loading Loading @@ -2124,15 +2142,28 @@ static int cam_smmu_unmap_buf_and_remove_from_list( } } static enum cam_smmu_buf_state cam_smmu_check_fd_in_list(int idx, static enum cam_smmu_buf_state cam_smmu_check_fd_in_list(int idx, int ion_fd, dma_addr_t *paddr_ptr, size_t *len_ptr) int ion_fd, dma_addr_t *paddr_ptr, size_t *len_ptr, size_t *dma_buf_len) { { struct cam_dma_buff_info *mapping; struct cam_dma_buff_info *mapping; struct timespec64 *ts = NULL; uint64_t ms, tmp, hrs, min, sec; list_for_each_entry(mapping, list_for_each_entry(mapping, &iommu_cb_set.cb_info[idx].smmu_buf_list, list) { &iommu_cb_set.cb_info[idx].smmu_buf_list, list) { if (mapping->ion_fd == ion_fd) { if (mapping->ion_fd == ion_fd) { *paddr_ptr = mapping->paddr; *paddr_ptr = mapping->paddr; *len_ptr = mapping->len; *len_ptr = mapping->len; *dma_buf_len = mapping->buf->size; ts = &mapping->ts; tmp = ts->tv_sec; ms = (ts->tv_nsec) / 1000000; sec = do_div(tmp, 60); min = do_div(tmp, 60); hrs = do_div(tmp, 24); CAM_WARN(CAM_SMMU, "Mapping found ts %llu:%llu:%llu:%llu paddr 0x%p len %llu dma_len %llu", hrs, min, sec, ms, (void *)mapping->paddr, mapping->len, *dma_buf_len); return CAM_SMMU_BUFF_EXIST; return CAM_SMMU_BUFF_EXIST; } } } } Loading Loading @@ -2863,6 +2894,7 @@ int cam_smmu_map_user_iova(int handle, int ion_fd, bool dis_delayed_unmap, size_t *len_ptr, enum cam_smmu_region_id region_id) size_t *len_ptr, enum cam_smmu_region_id region_id) { { int idx, rc = 0; int idx, rc = 0; size_t dma_len = 0; enum cam_smmu_buf_state buf_state; enum cam_smmu_buf_state buf_state; enum dma_data_direction dma_dir; enum dma_data_direction dma_dir; Loading Loading @@ -2900,11 +2932,14 @@ int cam_smmu_map_user_iova(int handle, int ion_fd, bool dis_delayed_unmap, goto get_addr_end; goto get_addr_end; } } buf_state = cam_smmu_check_fd_in_list(idx, ion_fd, paddr_ptr, len_ptr); buf_state = cam_smmu_check_fd_in_list(idx, ion_fd, paddr_ptr, len_ptr, &dma_len); if (buf_state == CAM_SMMU_BUFF_EXIST) { if (buf_state == CAM_SMMU_BUFF_EXIST) { CAM_ERR(CAM_SMMU, CAM_ERR(CAM_SMMU, "fd:%d already in list idx:%d, handle=%d, give same addr back", "fd:%d already in list cb:%s idx:%d handle=%d len=%llu dma_len=%llu, give same addr back", ion_fd, idx, handle); ion_fd, iommu_cb_set.cb_info[idx].name, idx, handle, *len_ptr, dma_len); *len_ptr = dma_len; rc = -EALREADY; rc = -EALREADY; goto get_addr_end; goto get_addr_end; } } Loading @@ -2913,8 +2948,9 @@ int cam_smmu_map_user_iova(int handle, int ion_fd, bool dis_delayed_unmap, dis_delayed_unmap, dma_dir, paddr_ptr, len_ptr, region_id); dis_delayed_unmap, dma_dir, paddr_ptr, len_ptr, region_id); if (rc < 0) { if (rc < 0) { CAM_ERR(CAM_SMMU, CAM_ERR(CAM_SMMU, "mapping or add list fail, idx=%d, fd=%d, region=%d, rc=%d", "mapping or add list fail cb:%s idx=%d, fd=%d, region=%d, rc=%d", idx, ion_fd, region_id, rc); iommu_cb_set.cb_info[idx].name, idx, ion_fd, region_id, rc); cam_smmu_dump_cb_info(idx); cam_smmu_dump_cb_info(idx); } } Loading Loading @@ -2988,6 +3024,7 @@ int cam_smmu_get_iova(int handle, int ion_fd, dma_addr_t *paddr_ptr, size_t *len_ptr) dma_addr_t *paddr_ptr, size_t *len_ptr) { { int idx, rc = 0; int idx, rc = 0; size_t dma_buf_size = 0; enum cam_smmu_buf_state buf_state; enum cam_smmu_buf_state buf_state; if (!paddr_ptr || !len_ptr) { if (!paddr_ptr || !len_ptr) { Loading Loading @@ -3027,7 +3064,8 @@ int cam_smmu_get_iova(int handle, int ion_fd, goto get_addr_end; goto get_addr_end; } } buf_state = cam_smmu_check_fd_in_list(idx, ion_fd, paddr_ptr, len_ptr); buf_state = cam_smmu_check_fd_in_list(idx, ion_fd, paddr_ptr, len_ptr, &dma_buf_size); if (buf_state == CAM_SMMU_BUFF_NOT_EXIST) { if (buf_state == CAM_SMMU_BUFF_NOT_EXIST) { CAM_ERR(CAM_SMMU, "ion_fd:%d not in the mapped list", ion_fd); CAM_ERR(CAM_SMMU, "ion_fd:%d not in the mapped list", ion_fd); rc = -EINVAL; rc = -EINVAL; Loading include/uapi/media/cam_req_mgr.h +2 −2 Original line number Original line Diff line number Diff line Loading @@ -341,12 +341,12 @@ struct cam_mem_alloc_out_params { /** /** * struct cam_mem_map_out_params * struct cam_mem_map_out_params * @buf_handle: buffer handle * @buf_handle: buffer handle * @reserved: reserved for future * @size: size of the buffer being mapped * @vaddr: virtual address pointer * @vaddr: virtual address pointer */ */ struct cam_mem_map_out_params { struct cam_mem_map_out_params { uint32_t buf_handle; uint32_t buf_handle; uint32_t reserved; uint32_t size; uint64_t vaddr; uint64_t vaddr; }; }; Loading Loading
drivers/cam_req_mgr/cam_mem_mgr.c +56 −8 Original line number Original line Diff line number Diff line // SPDX-License-Identifier: GPL-2.0-only // SPDX-License-Identifier: GPL-2.0-only /* /* * Copyright (c) 2016-2019, The Linux Foundation. All rights reserved. * Copyright (c) 2016-2020, The Linux Foundation. All rights reserved. */ */ #include <linux/module.h> #include <linux/module.h> Loading @@ -22,6 +22,39 @@ static struct cam_mem_table tbl; static struct cam_mem_table tbl; static atomic_t cam_mem_mgr_state = ATOMIC_INIT(CAM_MEM_MGR_UNINITIALIZED); static atomic_t cam_mem_mgr_state = ATOMIC_INIT(CAM_MEM_MGR_UNINITIALIZED); static void cam_mem_mgr_print_tbl(void) { int i; uint64_t ms, tmp, hrs, min, sec; struct timespec64 *ts = NULL; struct timespec64 current_ts; ktime_get_real_ts64(&(current_ts)); tmp = current_ts.tv_sec; ms = (current_ts.tv_nsec) / 1000000; sec = do_div(tmp, 60); min = do_div(tmp, 60); hrs = do_div(tmp, 24); CAM_INFO(CAM_MEM, "***%llu:%llu:%llu:%llu Mem mgr table dump***", hrs, min, sec, ms); for (i = 1; i < CAM_MEM_BUFQ_MAX; i++) { if (tbl.bufq[i].active) { ts = &tbl.bufq[i].timestamp; tmp = ts->tv_sec; ms = (ts->tv_nsec) / 1000000; sec = do_div(tmp, 60); min = do_div(tmp, 60); hrs = do_div(tmp, 24); CAM_INFO(CAM_MEM, "%llu:%llu:%llu:%llu idx %d fd %d size %llu", hrs, min, sec, ms, i, tbl.bufq[i].fd, tbl.bufq[i].len); } } } static int cam_mem_util_get_dma_dir(uint32_t flags) static int cam_mem_util_get_dma_dir(uint32_t flags) { { int rc = -EINVAL; int rc = -EINVAL; Loading Loading @@ -185,6 +218,7 @@ static int32_t cam_mem_get_slot(void) set_bit(idx, tbl.bitmap); set_bit(idx, tbl.bitmap); tbl.bufq[idx].active = true; tbl.bufq[idx].active = true; ktime_get_real_ts64(&(tbl.bufq[idx].timestamp)); mutex_init(&tbl.bufq[idx].q_lock); mutex_init(&tbl.bufq[idx].q_lock); mutex_unlock(&tbl.m_lock); mutex_unlock(&tbl.m_lock); Loading @@ -196,6 +230,7 @@ static void cam_mem_put_slot(int32_t idx) mutex_lock(&tbl.m_lock); mutex_lock(&tbl.m_lock); mutex_lock(&tbl.bufq[idx].q_lock); mutex_lock(&tbl.bufq[idx].q_lock); tbl.bufq[idx].active = false; tbl.bufq[idx].active = false; memset(&tbl.bufq[idx].timestamp, 0, sizeof(struct timespec64)); mutex_unlock(&tbl.bufq[idx].q_lock); mutex_unlock(&tbl.bufq[idx].q_lock); mutex_destroy(&tbl.bufq[idx].q_lock); mutex_destroy(&tbl.bufq[idx].q_lock); clear_bit(idx, tbl.bitmap); clear_bit(idx, tbl.bitmap); Loading Loading @@ -643,6 +678,7 @@ int cam_mem_mgr_alloc_and_map(struct cam_mem_mgr_alloc_cmd *cmd) CAM_ERR(CAM_MEM, CAM_ERR(CAM_MEM, "Ion Alloc failed, len=%llu, align=%llu, flags=0x%x, num_hdl=%d", "Ion Alloc failed, len=%llu, align=%llu, flags=0x%x, num_hdl=%d", cmd->len, cmd->align, cmd->flags, cmd->num_hdl); cmd->len, cmd->align, cmd->flags, cmd->num_hdl); cam_mem_mgr_print_tbl(); return rc; return rc; } } Loading Loading @@ -679,9 +715,14 @@ int cam_mem_mgr_alloc_and_map(struct cam_mem_mgr_alloc_cmd *cmd) if (rc) { if (rc) { CAM_ERR(CAM_MEM, CAM_ERR(CAM_MEM, "Failed in map_hw_va, len=%llu, flags=0x%x, fd=%d, region=%d, num_hdl=%d, rc=%d", "Failed in map_hw_va, [Size cmdlen=%llu dma %llu smmu %llu], flags=0x%x, fd=%d, region=%d, num_hdl=%d, rc=%d", cmd->len, cmd->flags, fd, region, cmd->len, dmabuf->size, len, cmd->flags, cmd->num_hdl, rc); fd, region, cmd->num_hdl, rc); if (rc == -EALREADY) { if ((size_t)dmabuf->size != len) rc = -EBADR; cam_mem_mgr_print_tbl(); } goto map_hw_fail; goto map_hw_fail; } } } } Loading Loading @@ -780,9 +821,15 @@ int cam_mem_mgr_map(struct cam_mem_mgr_map_cmd *cmd) CAM_SMMU_REGION_IO); CAM_SMMU_REGION_IO); if (rc) { if (rc) { CAM_ERR(CAM_MEM, CAM_ERR(CAM_MEM, "Failed in map_hw_va, flags=0x%x, fd=%d, region=%d, num_hdl=%d, rc=%d", "Failed in map_hw_va, flags=0x%x, fd=%d, [Size smmu %llu dma %llu], region=%d, num_hdl=%d, rc=%d", cmd->flags, cmd->fd, CAM_SMMU_REGION_IO, cmd->flags, cmd->fd, len, dmabuf->size, cmd->num_hdl, rc); CAM_SMMU_REGION_IO, cmd->num_hdl, rc); if (rc == -EALREADY) { if ((size_t)dmabuf->size != len) { rc = -EBADR; cam_mem_mgr_print_tbl(); } } goto map_fail; goto map_fail; } } } } Loading Loading @@ -817,7 +864,7 @@ int cam_mem_mgr_map(struct cam_mem_mgr_map_cmd *cmd) cmd->out.buf_handle = tbl.bufq[idx].buf_handle; cmd->out.buf_handle = tbl.bufq[idx].buf_handle; cmd->out.vaddr = 0; cmd->out.vaddr = 0; cmd->out.size = (uint32_t)len; CAM_DBG(CAM_MEM, CAM_DBG(CAM_MEM, "fd=%d, flags=0x%x, num_hdl=%d, idx=%d, buf handle=%x, len=%zu", "fd=%d, flags=0x%x, num_hdl=%d, idx=%d, buf handle=%x, len=%zu", cmd->fd, cmd->flags, cmd->num_hdl, idx, cmd->out.buf_handle, cmd->fd, cmd->flags, cmd->num_hdl, idx, cmd->out.buf_handle, Loading Loading @@ -1037,6 +1084,7 @@ static int cam_mem_util_unmap(int32_t idx, tbl.bufq[idx].len = 0; tbl.bufq[idx].len = 0; tbl.bufq[idx].num_hdl = 0; tbl.bufq[idx].num_hdl = 0; tbl.bufq[idx].active = false; tbl.bufq[idx].active = false; memset(&tbl.bufq[idx].timestamp, 0, sizeof(struct timespec64)); mutex_unlock(&tbl.bufq[idx].q_lock); mutex_unlock(&tbl.bufq[idx].q_lock); mutex_destroy(&tbl.bufq[idx].q_lock); mutex_destroy(&tbl.bufq[idx].q_lock); clear_bit(idx, tbl.bitmap); clear_bit(idx, tbl.bitmap); Loading
drivers/cam_req_mgr/cam_mem_mgr.h +3 −1 Original line number Original line Diff line number Diff line /* SPDX-License-Identifier: GPL-2.0-only */ /* SPDX-License-Identifier: GPL-2.0-only */ /* /* * Copyright (c) 2016-2019, The Linux Foundation. All rights reserved. * Copyright (c) 2016-2020, The Linux Foundation. All rights reserved. */ */ #ifndef _CAM_MEM_MGR_H_ #ifndef _CAM_MEM_MGR_H_ Loading Loading @@ -41,6 +41,7 @@ enum cam_smmu_mapping_client { * @kmdvaddr: Kernel virtual address * @kmdvaddr: Kernel virtual address * @active: state of the buffer * @active: state of the buffer * @is_imported: Flag indicating if buffer is imported from an FD in user space * @is_imported: Flag indicating if buffer is imported from an FD in user space * @timestamp: Timestamp at which this entry in tbl was made */ */ struct cam_mem_buf_queue { struct cam_mem_buf_queue { struct dma_buf *dma_buf; struct dma_buf *dma_buf; Loading @@ -56,6 +57,7 @@ struct cam_mem_buf_queue { uintptr_t kmdvaddr; uintptr_t kmdvaddr; bool active; bool active; bool is_imported; bool is_imported; struct timespec64 timestamp; }; }; /** /** Loading
drivers/cam_smmu/cam_smmu_api.c +50 −12 Original line number Original line Diff line number Diff line Loading @@ -196,6 +196,7 @@ struct cam_dma_buff_info { int ion_fd; int ion_fd; size_t len; size_t len; size_t phys_len; size_t phys_len; struct timespec64 ts; }; }; struct cam_sec_buff_info { struct cam_sec_buff_info { Loading Loading @@ -401,6 +402,9 @@ static void cam_smmu_dump_cb_info(int idx) size_t shared_reg_len = 0, io_reg_len = 0; size_t shared_reg_len = 0, io_reg_len = 0; size_t shared_free_len = 0, io_free_len = 0; size_t shared_free_len = 0, io_free_len = 0; uint32_t i = 0; uint32_t i = 0; uint64_t ms, tmp, hrs, min, sec; struct timespec64 *ts = NULL; struct timespec64 current_ts; struct cam_context_bank_info *cb_info = struct cam_context_bank_info *cb_info = &iommu_cb_set.cb_info[idx]; &iommu_cb_set.cb_info[idx]; Loading @@ -414,9 +418,15 @@ static void cam_smmu_dump_cb_info(int idx) io_free_len = io_reg_len - cb_info->io_mapping_size; io_free_len = io_reg_len - cb_info->io_mapping_size; } } ktime_get_real_ts64(&(current_ts)); tmp = current_ts.tv_sec; ms = (current_ts.tv_nsec) / 1000000; sec = do_div(tmp, 60); min = do_div(tmp, 60); hrs = do_div(tmp, 24); CAM_ERR(CAM_SMMU, CAM_ERR(CAM_SMMU, "********** Context bank dump for %s **********", "********** %llu:%llu:%llu:%llu Context bank dump for %s **********", cb_info->name); hrs, min, sec, ms, cb_info->name); CAM_ERR(CAM_SMMU, CAM_ERR(CAM_SMMU, "Usage: shared_usage=%u io_usage=%u shared_free=%u io_free=%u", "Usage: shared_usage=%u io_usage=%u shared_free=%u io_free=%u", (unsigned int)cb_info->shared_mapping_size, (unsigned int)cb_info->shared_mapping_size, Loading @@ -428,9 +438,16 @@ static void cam_smmu_dump_cb_info(int idx) list_for_each_entry_safe(mapping, mapping_temp, list_for_each_entry_safe(mapping, mapping_temp, &iommu_cb_set.cb_info[idx].smmu_buf_list, list) { &iommu_cb_set.cb_info[idx].smmu_buf_list, list) { i++; i++; ts = &mapping->ts; tmp = ts->tv_sec; ms = (ts->tv_nsec) / 1000000; sec = do_div(tmp, 60); min = do_div(tmp, 60); hrs = do_div(tmp, 24); CAM_ERR(CAM_SMMU, CAM_ERR(CAM_SMMU, "%u. ion_fd=%d start=0x%x end=0x%x len=%u region=%d", "%llu:%llu:%llu:%llu: %u ion_fd=%d start=0x%x end=0x%x len=%u region=%d", i, mapping->ion_fd, (void *)mapping->paddr, hrs, min, sec, ms, i, mapping->ion_fd, (void *)mapping->paddr, ((uint64_t)mapping->paddr + ((uint64_t)mapping->paddr + (uint64_t)mapping->len), (uint64_t)mapping->len), (unsigned int)mapping->len, (unsigned int)mapping->len, Loading Loading @@ -1999,6 +2016,7 @@ static int cam_smmu_map_buffer_and_add_to_list(int idx, int ion_fd, } } mapping_info->ion_fd = ion_fd; mapping_info->ion_fd = ion_fd; ktime_get_real_ts64(&mapping_info->ts); /* add to the list */ /* add to the list */ list_add(&mapping_info->list, list_add(&mapping_info->list, &iommu_cb_set.cb_info[idx].smmu_buf_list); &iommu_cb_set.cb_info[idx].smmu_buf_list); Loading Loading @@ -2026,7 +2044,7 @@ static int cam_smmu_map_kernel_buffer_and_add_to_list(int idx, } } mapping_info->ion_fd = -1; mapping_info->ion_fd = -1; ktime_get_real_ts64(&mapping_info->ts); /* add to the list */ /* add to the list */ list_add(&mapping_info->list, list_add(&mapping_info->list, &iommu_cb_set.cb_info[idx].smmu_buf_kernel_list); &iommu_cb_set.cb_info[idx].smmu_buf_kernel_list); Loading Loading @@ -2124,15 +2142,28 @@ static int cam_smmu_unmap_buf_and_remove_from_list( } } static enum cam_smmu_buf_state cam_smmu_check_fd_in_list(int idx, static enum cam_smmu_buf_state cam_smmu_check_fd_in_list(int idx, int ion_fd, dma_addr_t *paddr_ptr, size_t *len_ptr) int ion_fd, dma_addr_t *paddr_ptr, size_t *len_ptr, size_t *dma_buf_len) { { struct cam_dma_buff_info *mapping; struct cam_dma_buff_info *mapping; struct timespec64 *ts = NULL; uint64_t ms, tmp, hrs, min, sec; list_for_each_entry(mapping, list_for_each_entry(mapping, &iommu_cb_set.cb_info[idx].smmu_buf_list, list) { &iommu_cb_set.cb_info[idx].smmu_buf_list, list) { if (mapping->ion_fd == ion_fd) { if (mapping->ion_fd == ion_fd) { *paddr_ptr = mapping->paddr; *paddr_ptr = mapping->paddr; *len_ptr = mapping->len; *len_ptr = mapping->len; *dma_buf_len = mapping->buf->size; ts = &mapping->ts; tmp = ts->tv_sec; ms = (ts->tv_nsec) / 1000000; sec = do_div(tmp, 60); min = do_div(tmp, 60); hrs = do_div(tmp, 24); CAM_WARN(CAM_SMMU, "Mapping found ts %llu:%llu:%llu:%llu paddr 0x%p len %llu dma_len %llu", hrs, min, sec, ms, (void *)mapping->paddr, mapping->len, *dma_buf_len); return CAM_SMMU_BUFF_EXIST; return CAM_SMMU_BUFF_EXIST; } } } } Loading Loading @@ -2863,6 +2894,7 @@ int cam_smmu_map_user_iova(int handle, int ion_fd, bool dis_delayed_unmap, size_t *len_ptr, enum cam_smmu_region_id region_id) size_t *len_ptr, enum cam_smmu_region_id region_id) { { int idx, rc = 0; int idx, rc = 0; size_t dma_len = 0; enum cam_smmu_buf_state buf_state; enum cam_smmu_buf_state buf_state; enum dma_data_direction dma_dir; enum dma_data_direction dma_dir; Loading Loading @@ -2900,11 +2932,14 @@ int cam_smmu_map_user_iova(int handle, int ion_fd, bool dis_delayed_unmap, goto get_addr_end; goto get_addr_end; } } buf_state = cam_smmu_check_fd_in_list(idx, ion_fd, paddr_ptr, len_ptr); buf_state = cam_smmu_check_fd_in_list(idx, ion_fd, paddr_ptr, len_ptr, &dma_len); if (buf_state == CAM_SMMU_BUFF_EXIST) { if (buf_state == CAM_SMMU_BUFF_EXIST) { CAM_ERR(CAM_SMMU, CAM_ERR(CAM_SMMU, "fd:%d already in list idx:%d, handle=%d, give same addr back", "fd:%d already in list cb:%s idx:%d handle=%d len=%llu dma_len=%llu, give same addr back", ion_fd, idx, handle); ion_fd, iommu_cb_set.cb_info[idx].name, idx, handle, *len_ptr, dma_len); *len_ptr = dma_len; rc = -EALREADY; rc = -EALREADY; goto get_addr_end; goto get_addr_end; } } Loading @@ -2913,8 +2948,9 @@ int cam_smmu_map_user_iova(int handle, int ion_fd, bool dis_delayed_unmap, dis_delayed_unmap, dma_dir, paddr_ptr, len_ptr, region_id); dis_delayed_unmap, dma_dir, paddr_ptr, len_ptr, region_id); if (rc < 0) { if (rc < 0) { CAM_ERR(CAM_SMMU, CAM_ERR(CAM_SMMU, "mapping or add list fail, idx=%d, fd=%d, region=%d, rc=%d", "mapping or add list fail cb:%s idx=%d, fd=%d, region=%d, rc=%d", idx, ion_fd, region_id, rc); iommu_cb_set.cb_info[idx].name, idx, ion_fd, region_id, rc); cam_smmu_dump_cb_info(idx); cam_smmu_dump_cb_info(idx); } } Loading Loading @@ -2988,6 +3024,7 @@ int cam_smmu_get_iova(int handle, int ion_fd, dma_addr_t *paddr_ptr, size_t *len_ptr) dma_addr_t *paddr_ptr, size_t *len_ptr) { { int idx, rc = 0; int idx, rc = 0; size_t dma_buf_size = 0; enum cam_smmu_buf_state buf_state; enum cam_smmu_buf_state buf_state; if (!paddr_ptr || !len_ptr) { if (!paddr_ptr || !len_ptr) { Loading Loading @@ -3027,7 +3064,8 @@ int cam_smmu_get_iova(int handle, int ion_fd, goto get_addr_end; goto get_addr_end; } } buf_state = cam_smmu_check_fd_in_list(idx, ion_fd, paddr_ptr, len_ptr); buf_state = cam_smmu_check_fd_in_list(idx, ion_fd, paddr_ptr, len_ptr, &dma_buf_size); if (buf_state == CAM_SMMU_BUFF_NOT_EXIST) { if (buf_state == CAM_SMMU_BUFF_NOT_EXIST) { CAM_ERR(CAM_SMMU, "ion_fd:%d not in the mapped list", ion_fd); CAM_ERR(CAM_SMMU, "ion_fd:%d not in the mapped list", ion_fd); rc = -EINVAL; rc = -EINVAL; Loading
include/uapi/media/cam_req_mgr.h +2 −2 Original line number Original line Diff line number Diff line Loading @@ -341,12 +341,12 @@ struct cam_mem_alloc_out_params { /** /** * struct cam_mem_map_out_params * struct cam_mem_map_out_params * @buf_handle: buffer handle * @buf_handle: buffer handle * @reserved: reserved for future * @size: size of the buffer being mapped * @vaddr: virtual address pointer * @vaddr: virtual address pointer */ */ struct cam_mem_map_out_params { struct cam_mem_map_out_params { uint32_t buf_handle; uint32_t buf_handle; uint32_t reserved; uint32_t size; uint64_t vaddr; uint64_t vaddr; }; }; Loading