mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-10 22:40:54 -04:00
Merge "msm: camera: smmu: Add map and unmap monitor" into camera-kernel.lnx.4.0
This commit is contained in:
commit
c056e39f34
1 changed files with 106 additions and 3 deletions
|
|
@ -42,6 +42,11 @@
|
|||
#define GET_SMMU_HDL(x, y) (((x) << COOKIE_SIZE) | ((y) & COOKIE_MASK))
|
||||
#define GET_SMMU_TABLE_IDX(x) (((x) >> COOKIE_SIZE) & COOKIE_MASK)
|
||||
|
||||
#define CAM_SMMU_MONITOR_MAX_ENTRIES 100
|
||||
#define CAM_SMMU_INC_MONITOR_HEAD(head, ret) \
|
||||
div_u64_rem(atomic64_add_return(1, head),\
|
||||
CAM_SMMU_MONITOR_MAX_ENTRIES, (ret))
|
||||
|
||||
static int g_num_pf_handled = 4;
|
||||
module_param(g_num_pf_handled, int, 0644);
|
||||
|
||||
|
|
@ -94,6 +99,17 @@ struct secheap_buf_info {
|
|||
struct sg_table *table;
|
||||
};
|
||||
|
||||
struct cam_smmu_monitor {
|
||||
struct timespec64 timestamp;
|
||||
bool is_map;
|
||||
|
||||
/* map-unmap info */
|
||||
int ion_fd;
|
||||
dma_addr_t paddr;
|
||||
size_t len;
|
||||
enum cam_smmu_region_id region_id;
|
||||
};
|
||||
|
||||
struct cam_context_bank_info {
|
||||
struct device *dev;
|
||||
struct iommu_domain *domain;
|
||||
|
|
@ -143,6 +159,9 @@ struct cam_context_bank_info {
|
|||
/* discard iova - non-zero values are valid */
|
||||
dma_addr_t discard_iova_start;
|
||||
size_t discard_iova_len;
|
||||
|
||||
atomic64_t monitor_head;
|
||||
struct cam_smmu_monitor monitor_entries[CAM_SMMU_MONITOR_MAX_ENTRIES];
|
||||
};
|
||||
|
||||
struct cam_iommu_cb_set {
|
||||
|
|
@ -266,6 +285,76 @@ static int cam_smmu_probe(struct platform_device *pdev);
|
|||
|
||||
static uint32_t cam_smmu_find_closest_mapping(int idx, void *vaddr);
|
||||
|
||||
static void cam_smmu_update_monitor_array(
|
||||
struct cam_context_bank_info *cb_info,
|
||||
bool is_map,
|
||||
struct cam_dma_buff_info *mapping_info)
|
||||
{
|
||||
int iterator;
|
||||
|
||||
CAM_SMMU_INC_MONITOR_HEAD(&cb_info->monitor_head, &iterator);
|
||||
|
||||
ktime_get_real_ts64(&cb_info->monitor_entries[iterator].timestamp);
|
||||
|
||||
cb_info->monitor_entries[iterator].is_map = is_map;
|
||||
cb_info->monitor_entries[iterator].ion_fd = mapping_info->ion_fd;
|
||||
cb_info->monitor_entries[iterator].paddr = mapping_info->paddr;
|
||||
cb_info->monitor_entries[iterator].len = mapping_info->len;
|
||||
cb_info->monitor_entries[iterator].region_id = mapping_info->region_id;
|
||||
}
|
||||
|
||||
static void cam_smmu_dump_monitor_array(
|
||||
struct cam_context_bank_info *cb_info)
|
||||
{
|
||||
int i = 0;
|
||||
int64_t state_head = 0;
|
||||
uint32_t index, num_entries, oldest_entry;
|
||||
uint64_t ms, tmp, hrs, min, sec;
|
||||
struct timespec64 *ts = NULL;
|
||||
|
||||
state_head = atomic64_read(&cb_info->monitor_head);
|
||||
|
||||
if (state_head == -1) {
|
||||
return;
|
||||
} else if (state_head < CAM_SMMU_MONITOR_MAX_ENTRIES) {
|
||||
num_entries = state_head;
|
||||
oldest_entry = 0;
|
||||
} else {
|
||||
num_entries = CAM_SMMU_MONITOR_MAX_ENTRIES;
|
||||
div_u64_rem(state_head + 1,
|
||||
CAM_SMMU_MONITOR_MAX_ENTRIES, &oldest_entry);
|
||||
}
|
||||
|
||||
CAM_INFO(CAM_SMMU,
|
||||
"========Dumping monitor information for cb %s===========",
|
||||
cb_info->name[0]);
|
||||
|
||||
index = oldest_entry;
|
||||
|
||||
for (i = 0; i < num_entries; i++) {
|
||||
ts = &cb_info->monitor_entries[index].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_SMMU,
|
||||
"**** %llu:%llu:%llu.%llu : Index[%d] [%s] : ion_fd=%d start=0x%x end=0x%x len=%u region=%d",
|
||||
hrs, min, sec, ms,
|
||||
index,
|
||||
cb_info->monitor_entries[index].is_map ? "MAP" : "UNMAP",
|
||||
cb_info->monitor_entries[index].ion_fd,
|
||||
(void *)cb_info->monitor_entries[index].paddr,
|
||||
((uint64_t)cb_info->monitor_entries[index].paddr +
|
||||
(uint64_t)cb_info->monitor_entries[index].len),
|
||||
(unsigned int)cb_info->monitor_entries[index].len,
|
||||
cb_info->monitor_entries[index].region_id);
|
||||
|
||||
index = (index + 1) % CAM_SMMU_MONITOR_MAX_ENTRIES;
|
||||
}
|
||||
}
|
||||
|
||||
static void cam_smmu_page_fault_work(struct work_struct *work)
|
||||
{
|
||||
int j;
|
||||
|
|
@ -328,7 +417,7 @@ static void cam_smmu_dump_cb_info(int idx)
|
|||
|
||||
CAM_ERR(CAM_SMMU,
|
||||
"********** Context bank dump for %s **********",
|
||||
cb_info->name);
|
||||
cb_info->name[0]);
|
||||
CAM_ERR(CAM_SMMU,
|
||||
"Usage: shared_usage=%u io_usage=%u shared_free=%u io_free=%u",
|
||||
(unsigned int)cb_info->shared_mapping_size,
|
||||
|
|
@ -348,6 +437,8 @@ static void cam_smmu_dump_cb_info(int idx)
|
|||
(unsigned int)mapping->len,
|
||||
mapping->region_id);
|
||||
}
|
||||
|
||||
cam_smmu_dump_monitor_array(&iommu_cb_set.cb_info[idx]);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1928,6 +2019,9 @@ static int cam_smmu_map_buffer_and_add_to_list(int idx, int ion_fd,
|
|||
list_add(&mapping_info->list,
|
||||
&iommu_cb_set.cb_info[idx].smmu_buf_list);
|
||||
|
||||
cam_smmu_update_monitor_array(&iommu_cb_set.cb_info[idx], true,
|
||||
mapping_info);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -1953,6 +2047,9 @@ static int cam_smmu_map_kernel_buffer_and_add_to_list(int idx,
|
|||
list_add(&mapping_info->list,
|
||||
&iommu_cb_set.cb_info[idx].smmu_buf_kernel_list);
|
||||
|
||||
cam_smmu_update_monitor_array(&iommu_cb_set.cb_info[idx], true,
|
||||
mapping_info);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -1979,6 +2076,9 @@ static int cam_smmu_unmap_buf_and_remove_from_list(
|
|||
return -EINVAL;
|
||||
}
|
||||
|
||||
cam_smmu_update_monitor_array(&iommu_cb_set.cb_info[idx], false,
|
||||
mapping_info);
|
||||
|
||||
CAM_DBG(CAM_SMMU,
|
||||
"region_id=%d, paddr=%pK, len=%d, dma_map_attrs=%d",
|
||||
mapping_info->region_id, mapping_info->paddr, mapping_info->len,
|
||||
|
|
@ -2948,6 +3048,7 @@ int cam_smmu_get_iova(int handle, int ion_fd,
|
|||
if (buf_state == CAM_SMMU_BUFF_NOT_EXIST) {
|
||||
CAM_ERR(CAM_SMMU, "ion_fd:%d not in the mapped list", ion_fd);
|
||||
rc = -EINVAL;
|
||||
cam_smmu_dump_cb_info(idx);
|
||||
goto get_addr_end;
|
||||
}
|
||||
|
||||
|
|
@ -3305,6 +3406,8 @@ static int cam_smmu_setup_cb(struct cam_context_bank_info *cb,
|
|||
cb->is_fw_allocated = false;
|
||||
cb->is_secheap_allocated = false;
|
||||
|
||||
atomic64_set(&cb->monitor_head, -1);
|
||||
|
||||
/* Create a pool with 64K granularity for supporting shared memory */
|
||||
if (cb->shared_support) {
|
||||
cb->shared_mem_pool = gen_pool_create(
|
||||
|
|
@ -3638,7 +3741,7 @@ static int cam_smmu_get_memory_regions_info(struct device_node *of_node,
|
|||
cb->io_info.iova_start + cb->io_info.iova_len)) {
|
||||
CAM_ERR(CAM_SMMU,
|
||||
"[%s] : Incorrect Discard region specified [0x%x 0x%x] in [0x%x 0x%x]",
|
||||
cb->name,
|
||||
cb->name[0],
|
||||
cb->discard_iova_start,
|
||||
cb->discard_iova_start + cb->discard_iova_len,
|
||||
cb->io_info.iova_start,
|
||||
|
|
@ -3649,7 +3752,7 @@ static int cam_smmu_get_memory_regions_info(struct device_node *of_node,
|
|||
|
||||
CAM_INFO(CAM_SMMU,
|
||||
"[%s] : Discard region specified [0x%x 0x%x] in [0x%x 0x%x]",
|
||||
cb->name,
|
||||
cb->name[0],
|
||||
cb->discard_iova_start,
|
||||
cb->discard_iova_start + cb->discard_iova_len,
|
||||
cb->io_info.iova_start,
|
||||
|
|
|
|||
Loading…
Reference in a new issue