Răsfoiți Sursa

msm: camera: memmgr: reduce mutex lock duration

Allow concurrent calls to unmap buffer by reducing the
mutex lock duration, and allow same fd for mapping user iova,
use book keeping for user smmu.

CRs-Fixed: 2559879
Change-Id: Ic3c92d4fa0ca7d1c29e621172e0b058420e1501d
Signed-off-by: Haibin Liu <[email protected]>
Haibin Liu 5 ani în urmă
părinte
comite
891c47b17e
2 a modificat fișierele cu 50 adăugiri și 6 ștergeri
  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

@@ -254,8 +254,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) {
@@ -310,8 +313,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;
@@ -353,6 +359,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;
 	}
@@ -1061,6 +1069,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,
@@ -1091,10 +1106,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);
 
@@ -1113,7 +1128,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

@@ -2181,6 +2181,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)
 {
@@ -2944,7 +2964,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;
@@ -2961,7 +2981,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;
 	}
 
@@ -3222,6 +3242,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);