瀏覽代碼

Merge "msm: camera: memmgr: reduce mutex lock duration" into camera-kernel.lnx.4.0

Camera Software Integration 4 年之前
父節點
當前提交
e475f14229
共有 2 個文件被更改,包括 50 次插入6 次删除
  1. 18 4
      drivers/cam_req_mgr/cam_mem_mgr.c
  2. 32 2
      drivers/cam_smmu/cam_smmu_api.c

+ 18 - 4
drivers/cam_req_mgr/cam_mem_mgr.c

@@ -238,8 +238,11 @@ int cam_mem_get_io_buf(int32_t buf_handle, int32_t mmu_handle,
 	if (idx >= CAM_MEM_BUFQ_MAX || idx <= 0)
 		return -ENOENT;
 
-	if (!tbl.bufq[idx].active)
+	if (!tbl.bufq[idx].active) {
+		CAM_ERR(CAM_MEM, "Buffer at idx=%d is already unmapped,",
+			idx);
 		return -EAGAIN;
+	}
 
 	mutex_lock(&tbl.bufq[idx].q_lock);
 	if (buf_handle != tbl.bufq[idx].buf_handle) {
@@ -294,8 +297,11 @@ int cam_mem_get_cpu_buf(int32_t buf_handle, uintptr_t *vaddr_ptr, size_t *len)
 	if (idx >= CAM_MEM_BUFQ_MAX || idx <= 0)
 		return -EINVAL;
 
-	if (!tbl.bufq[idx].active)
+	if (!tbl.bufq[idx].active) {
+		CAM_ERR(CAM_MEM, "Buffer at idx=%d is already unmapped,",
+			idx);
 		return -EPERM;
+	}
 
 	if (buf_handle != tbl.bufq[idx].buf_handle)
 		return -EINVAL;
@@ -337,6 +343,8 @@ int cam_mem_mgr_cache_ops(struct cam_mem_cache_ops_cmd *cmd)
 	mutex_lock(&tbl.bufq[idx].q_lock);
 
 	if (!tbl.bufq[idx].active) {
+		CAM_ERR(CAM_MEM, "Buffer at idx=%d is already unmapped,",
+			idx);
 		rc = -EINVAL;
 		goto end;
 	}
@@ -1053,6 +1061,13 @@ static int cam_mem_util_unmap(int32_t idx,
 		return 0;
 	}
 
+	/* Deactivate the buffer queue to prevent multiple unmap */
+	mutex_lock(&tbl.bufq[idx].q_lock);
+	tbl.bufq[idx].active = false;
+	tbl.bufq[idx].vaddr = 0;
+	mutex_unlock(&tbl.bufq[idx].q_lock);
+	mutex_unlock(&tbl.m_lock);
+
 	if (tbl.bufq[idx].flags & CAM_MEM_FLAG_KMD_ACCESS) {
 		if (tbl.bufq[idx].dma_buf && tbl.bufq[idx].kmdvaddr) {
 			rc = cam_mem_util_unmap_cpu_va(tbl.bufq[idx].dma_buf,
@@ -1083,10 +1098,10 @@ static int cam_mem_util_unmap(int32_t idx,
 			tbl.bufq[idx].dma_buf = NULL;
 	}
 
+	mutex_lock(&tbl.m_lock);
 	mutex_lock(&tbl.bufq[idx].q_lock);
 	tbl.bufq[idx].flags = 0;
 	tbl.bufq[idx].buf_handle = -1;
-	tbl.bufq[idx].vaddr = 0;
 	memset(tbl.bufq[idx].hdls, 0,
 		sizeof(int32_t) * CAM_MEM_MMU_MAX_HANDLE);
 
@@ -1105,7 +1120,6 @@ static int cam_mem_util_unmap(int32_t idx,
 	tbl.bufq[idx].is_internal = false;
 	tbl.bufq[idx].len = 0;
 	tbl.bufq[idx].num_hdl = 0;
-	tbl.bufq[idx].active = false;
 	memset(&tbl.bufq[idx].timestamp, 0, sizeof(struct timespec64));
 	mutex_unlock(&tbl.bufq[idx].q_lock);
 	mutex_destroy(&tbl.bufq[idx].q_lock);

+ 32 - 2
drivers/cam_smmu/cam_smmu_api.c

@@ -2210,6 +2210,26 @@ static enum cam_smmu_buf_state cam_smmu_check_fd_in_list(int idx,
 	return CAM_SMMU_BUFF_NOT_EXIST;
 }
 
+static enum cam_smmu_buf_state cam_smmu_user_reuse_fd_in_list(int idx,
+	int ion_fd, dma_addr_t *paddr_ptr, size_t *len_ptr,
+	struct timespec64 **ts_mapping)
+{
+	struct cam_dma_buff_info *mapping;
+
+	list_for_each_entry(mapping,
+		&iommu_cb_set.cb_info[idx].smmu_buf_list, list) {
+		if (mapping->ion_fd == ion_fd) {
+			*paddr_ptr = mapping->paddr;
+			*len_ptr = mapping->len;
+			*ts_mapping = &mapping->ts;
+			mapping->ref_count++;
+			return CAM_SMMU_BUFF_EXIST;
+		}
+	}
+
+	return CAM_SMMU_BUFF_NOT_EXIST;
+}
+
 static enum cam_smmu_buf_state cam_smmu_check_dma_buf_in_list(int idx,
 	struct dma_buf *buf, dma_addr_t *paddr_ptr, size_t *len_ptr)
 {
@@ -2973,7 +2993,7 @@ int cam_smmu_map_user_iova(int handle, int ion_fd, bool dis_delayed_unmap,
 		goto get_addr_end;
 	}
 
-	buf_state = cam_smmu_check_fd_in_list(idx, ion_fd, paddr_ptr,
+	buf_state = cam_smmu_user_reuse_fd_in_list(idx, ion_fd, paddr_ptr,
 		len_ptr, &ts);
 	if (buf_state == CAM_SMMU_BUFF_EXIST) {
 		uint64_t ms = 0, tmp = 0, hrs = 0, min = 0, sec = 0;
@@ -2990,7 +3010,7 @@ int cam_smmu_map_user_iova(int handle, int ion_fd, bool dis_delayed_unmap,
 			ion_fd, hrs, min, sec, ms,
 			iommu_cb_set.cb_info[idx].name[0],
 			idx, handle, *len_ptr);
-		rc = -EALREADY;
+		rc = 0;
 		goto get_addr_end;
 	}
 
@@ -3251,6 +3271,16 @@ int cam_smmu_unmap_user_iova(int handle,
 		goto unmap_end;
 	}
 
+	mapping_info->ref_count--;
+	if (mapping_info->ref_count > 0) {
+		CAM_DBG(CAM_SMMU,
+			"idx: %d fd = %d ref_count: %d",
+			idx, ion_fd, mapping_info->ref_count);
+		rc = 0;
+		goto unmap_end;
+	}
+	mapping_info->ref_count = 0;
+
 	/* Unmapping one buffer from device */
 	CAM_DBG(CAM_SMMU, "SMMU: removing buffer idx = %d", idx);
 	rc = cam_smmu_unmap_buf_and_remove_from_list(mapping_info, idx);