浏览代码

video: driver: amend delayed unmap feature

Due to delayed unmap feature on decoder output buffers,
refcount will become one when no one uses the buffer
in driver. In release done functonality, remove the
buffer from maps list only if refcount equal to one.
If refcount is more than one indicates the buffer is
being used, so do not remove from maps list. There are
chances that same decoder output buffer might be queued
by the client in which case we are not supposed to
unmap it from maps list in release done.

Change-Id: I69250c3efa89d77055e89770fd441af1fb50b755
Signed-off-by: Maheshwar Ajja <[email protected]>
Maheshwar Ajja 4 年之前
父节点
当前提交
09356ed279

+ 4 - 0
driver/vidc/inc/msm_vidc_driver.h

@@ -314,6 +314,10 @@ int msm_vidc_map_driver_buf(struct msm_vidc_inst *inst,
 	struct msm_vidc_buffer *buf);
 int msm_vidc_put_driver_buf(struct msm_vidc_inst *inst,
 	struct msm_vidc_buffer *buf);
+int msm_vidc_get_delayed_unmap(struct msm_vidc_inst *inst,
+	struct msm_vidc_map *map);
+int msm_vidc_put_delayed_unmap(struct msm_vidc_inst *inst,
+	struct msm_vidc_map *map);
 int msm_vidc_queue_buffer_single(struct msm_vidc_inst *inst, struct vb2_buffer *vb2);
 int msm_vidc_destroy_internal_buffer(struct msm_vidc_inst *inst,
 	struct msm_vidc_buffer *buffer);

+ 1 - 1
driver/vidc/inc/msm_vidc_internal.h

@@ -123,7 +123,7 @@
 /*
  * MAX_MAPPED_OUTPUT_COUNT: maximum mappings which can
  * be present in output map list with refcount 1. These
- * mappings exist due to lazy unmap feature. Current
+ * mappings exist due to delayed unmap feature. Current
  * threshold is kept as 50 to handle vpp usecases
  * which might have many output buffers.
  */

+ 23 - 2
driver/vidc/src/msm_vdec.c

@@ -1866,6 +1866,8 @@ int msm_vdec_handle_release_buffer(struct msm_vidc_inst *inst,
 	struct msm_vidc_buffer *buf)
 {
 	int rc = 0;
+	struct msm_vidc_map *map;
+	bool found;
 
 	if (!inst || !buf) {
 		d_vpr_e("%s: invalid params\n", __func__);
@@ -1873,7 +1875,26 @@ int msm_vdec_handle_release_buffer(struct msm_vidc_inst *inst,
 	}
 
 	print_vidc_buffer(VIDC_HIGH, "high", "release done", inst, buf);
-	msm_vidc_unmap_driver_buf(inst, buf);
+
+	found = false;
+	list_for_each_entry(map, &inst->mappings.output.list, list) {
+		if (map->device_addr == buf->device_addr) {
+			found = true;
+			break;
+		}
+	}
+	if (found) {
+		/*
+		 * finally remove mappings if no one using it.
+		 * refcount will be more than 1 if anyone using it.
+		 */
+		if (map->refcount == 1) {
+			rc = msm_vidc_put_delayed_unmap(inst, map);
+			if (rc)
+				print_vidc_buffer(VIDC_ERR, "err ",
+					"delayed unmap failed", inst, buf);
+		}
+	}
 
 	/* delete the buffer from release list */
 	list_del(&buf->list);
@@ -1895,7 +1916,7 @@ static int msm_vidc_unmap_excessive_mappings(struct msm_vidc_inst *inst)
 
 	/*
 	 * count entries from map list whose refcount is 1
-	 * these are excess mappings present due to lazy
+	 * these are excess mappings present due to delayed
 	 * unmap feature.
 	 */
 	list_for_each_entry(map, &inst->mappings.output.list, list) {

+ 49 - 4
driver/vidc/src/msm_vidc_driver.c

@@ -2067,6 +2067,52 @@ int msm_vidc_put_map_buffer(struct msm_vidc_inst *inst, struct msm_vidc_map *map
 	return 0;
 }
 
+int msm_vidc_get_delayed_unmap(struct msm_vidc_inst *inst, struct msm_vidc_map *map)
+{
+	int rc = 0;
+
+	if (!inst || !map) {
+		d_vpr_e("%s: invalid params\n", __func__);
+		return -EINVAL;
+	}
+
+	map->skip_delayed_unmap = 1;
+	rc = msm_vidc_memory_map(inst->core, map);
+	if (rc)
+		return rc;
+
+	return 0;
+}
+
+int msm_vidc_put_delayed_unmap(struct msm_vidc_inst *inst, struct msm_vidc_map *map)
+{
+	int rc = 0;
+
+	if (!inst || !map) {
+		d_vpr_e("%s: invalid params\n", __func__);
+		return -EINVAL;
+	}
+
+	if (!map->skip_delayed_unmap) {
+		i_vpr_e(inst, "%s: no delayed unmap, addr %#x\n",
+			__func__, map->device_addr);
+		return -EINVAL;
+	}
+
+	map->skip_delayed_unmap = 0;
+	rc = msm_vidc_memory_unmap(inst->core, map);
+	if (rc)
+		i_vpr_e(inst, "%s: unmap failed\n", __func__);
+
+	if (!map->refcount) {
+		msm_vidc_memory_put_dmabuf(map->dmabuf);
+		list_del(&map->list);
+		msm_vidc_put_map_buffer(inst, map);
+	}
+
+	return rc;
+}
+
 int msm_vidc_destroy_map_buffer(struct msm_vidc_inst *inst)
 {
 	struct msm_vidc_map *map, *dummy;
@@ -2173,7 +2219,7 @@ int msm_vidc_map_driver_buf(struct msm_vidc_inst *inst,
 		return -EINVAL;
 
 	/*
-	 * new buffer: map twice for lazy unmap feature sake
+	 * new buffer: map twice for delayed unmap feature sake
 	 * existing buffer: map once
 	 */
 	list_for_each_entry(map, &mappings->list, list) {
@@ -2195,10 +2241,9 @@ int msm_vidc_map_driver_buf(struct msm_vidc_inst *inst,
 		if (!map->dmabuf)
 			return -EINVAL;
 		map->region = msm_vidc_get_buffer_region(inst, buf->type, __func__);
-		/* lazy unmap feature not needed for decoder output buffers */
+		/* delayed unmap feature needed for decoder output buffers */
 		if (is_decode_session(inst) && is_output_buffer(buf->type)) {
-			map->skip_delayed_unmap = 1;
-			rc = msm_vidc_memory_map(inst->core, map);
+			rc = msm_vidc_get_delayed_unmap(inst, map);
 			if (rc) {
 				msm_vidc_memory_put_dmabuf(map->dmabuf);
 				msm_vidc_put_map_buffer(inst, map);

+ 5 - 4
driver/vidc/src/msm_vidc_memory.c

@@ -98,7 +98,7 @@ int msm_vidc_memory_map(struct msm_vidc_core *core, struct msm_vidc_map *map)
 
 	if (map->refcount) {
 		map->refcount++;
-		return 0;
+		goto exit;
 	}
 
 	cb = get_context_bank(core, map->region);
@@ -153,6 +153,7 @@ int msm_vidc_memory_map(struct msm_vidc_core *core, struct msm_vidc_map *map)
 	map->attach = attach;
 	map->refcount++;
 
+exit:
 	d_vpr_l(
 		"%s: type %11s, device_addr %#x, refcount %d, region %d\n",
 		__func__, buf_name(map->type), map->device_addr, map->refcount, map->region);
@@ -185,13 +186,13 @@ int msm_vidc_memory_unmap(struct msm_vidc_core *core,
 		return -EINVAL;
 	}
 
-	if (map->refcount)
-		goto exit;
-
 	d_vpr_l(
 		"%s: type %11s, device_addr %#x, refcount %d, region %d\n",
 		__func__, buf_name(map->type), map->device_addr, map->refcount, map->region);
 
+	if (map->refcount)
+		goto exit;
+
 	dma_buf_unmap_attachment(map->attach, map->table, DMA_BIDIRECTIONAL);
 	dma_buf_detach(map->dmabuf, map->attach);
 

+ 1 - 1
driver/vidc/src/venus_hfi_response.c

@@ -1356,7 +1356,7 @@ static int handle_session_property(struct msm_vidc_inst *inst,
 		} else {
 			i_vpr_e(inst,
 				"%s: invalid property %#x for %s port %d dpb cap value %d\n",
-				__func__, is_decode_session(inst) ? "decode" : "encode",
+				__func__, pkt->type, is_decode_session(inst) ? "decode" : "encode",
 				port, inst->capabilities->cap[DPB_LIST].value);
 		}
 		break;