فهرست منبع

video: driver: enable buffer pool for mostly used structures

Enabled recycling for below structure types.

- struct msm_vidc_buffer
- struct msm_vidc_alloc
- struct msm_vidc_map.

Change-Id: I062abef85db24385745119b821f87e5b72a4e835
Signed-off-by: Govindaraj Rajagopal <[email protected]>
Govindaraj Rajagopal 4 سال پیش
والد
کامیت
a13f0e1416

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

@@ -255,6 +255,15 @@ int msm_vidc_release_internal_buffers(struct msm_vidc_inst *inst,
 		enum msm_vidc_buffer_type buffer_type);
 int msm_vidc_vb2_buffer_done(struct msm_vidc_inst *inst,
 	struct msm_vidc_buffer *buf);
+struct msm_vidc_buffer *msm_vidc_get_vidc_buffer(struct msm_vidc_inst *inst);
+struct msm_vidc_alloc *msm_vidc_get_alloc_buffer(struct msm_vidc_inst *inst);
+struct msm_vidc_map *msm_vidc_get_map_buffer(struct msm_vidc_inst *inst);
+int msm_vidc_put_vidc_buffer(struct msm_vidc_inst *inst, struct msm_vidc_buffer *buf);
+int msm_vidc_put_alloc_buffer(struct msm_vidc_inst *inst, struct msm_vidc_alloc *alloc);
+int msm_vidc_put_map_buffer(struct msm_vidc_inst *inst, struct msm_vidc_map *map);
+int msm_vidc_destroy_vidc_buffer(struct msm_vidc_inst *inst);
+int msm_vidc_destroy_alloc_buffer(struct msm_vidc_inst *inst);
+int msm_vidc_destroy_map_buffer(struct msm_vidc_inst *inst);
 int msm_vidc_remove_session(struct msm_vidc_inst *inst);
 int msm_vidc_add_session(struct msm_vidc_inst *inst);
 int msm_vidc_session_open(struct msm_vidc_inst *inst);

+ 7 - 0
driver/vidc/inc/msm_vidc_inst.h

@@ -27,6 +27,12 @@ struct msm_vidc_session_ops {
 	int (*extra_count)(struct msm_vidc_inst *inst, enum msm_vidc_buffer_type type);
 };
 
+struct msm_vidc_pool_info {
+	struct msm_vidc_pool            allocations;
+	struct msm_vidc_pool            mappings;
+	struct msm_vidc_pool            buffers;
+};
+
 struct msm_vidc_allocations_info {
 	struct msm_vidc_allocations     bin;
 	struct msm_vidc_allocations     arp;
@@ -111,6 +117,7 @@ struct msm_vidc_inst {
 	struct msm_vidc_rectangle          compose;
 	struct msm_vidc_power              power;
 	struct vidc_bus_vote_data          bus_data;
+	struct msm_vidc_pool_info          pool;
 	struct msm_vidc_buffers_info       buffers;
 	struct msm_vidc_mappings_info      mappings;
 	struct msm_vidc_allocations_info   allocations;

+ 5 - 2
driver/vidc/inc/msm_vidc_internal.h

@@ -750,7 +750,6 @@ struct msm_vidc_allocations {
 
 struct msm_vidc_map {
 	struct list_head            list;
-	bool                        valid;
 	enum msm_vidc_buffer_type   type;
 	enum msm_vidc_buffer_region region;
 	struct dma_buf             *dmabuf;
@@ -767,7 +766,6 @@ struct msm_vidc_mappings {
 
 struct msm_vidc_buffer {
 	struct list_head                   list;
-	bool                               valid;
 	enum msm_vidc_buffer_type          type;
 	u32                                index;
 	int                                fd;
@@ -790,6 +788,11 @@ struct msm_vidc_buffers {
 	bool                   reuse;
 };
 
+struct msm_vidc_pool {
+	struct list_head       list;
+	u32                    count;
+};
+
 enum msm_vidc_allow {
 	MSM_VIDC_DISALLOW = 0,
 	MSM_VIDC_ALLOW,

+ 0 - 2
driver/vidc/inc/msm_vidc_memory.h

@@ -17,8 +17,6 @@ int msm_vidc_memory_map(struct msm_vidc_core *core,
 	struct msm_vidc_map *map);
 int msm_vidc_memory_unmap(struct msm_vidc_core *core,
 	struct msm_vidc_map *map);
-int msm_vidc_memory_unmap_completely(struct msm_vidc_core *core,
-	struct msm_vidc_map *map);
 struct dma_buf *msm_vidc_memory_get_dmabuf(int fd);
 void msm_vidc_memory_put_dmabuf(void *dmabuf);
 

+ 3 - 0
driver/vidc/src/msm_vidc.c

@@ -745,6 +745,9 @@ void *msm_vidc_open(void *vidc_core, u32 session_type)
 			handle_session_response_work_handler);
 
 	INIT_LIST_HEAD(&inst->response_works);
+	INIT_LIST_HEAD(&inst->pool.buffers.list);
+	INIT_LIST_HEAD(&inst->pool.mappings.list);
+	INIT_LIST_HEAD(&inst->pool.allocations.list);
 	INIT_LIST_HEAD(&inst->buffers.input.list);
 	INIT_LIST_HEAD(&inst->buffers.input_meta.list);
 	INIT_LIST_HEAD(&inst->buffers.output.list);

+ 227 - 22
driver/vidc/src/msm_vidc_driver.c

@@ -1735,7 +1735,6 @@ static int vb2_buffer_to_driver(struct vb2_buffer *vb2,
 		return -EINVAL;
 	}
 
-	buf->valid = true;
 	buf->type = v4l2_type_to_driver(vb2->type, __func__);
 	if (!buf->type)
 		return -EINVAL;
@@ -1778,13 +1777,217 @@ int msm_vidc_process_readonly_buffers(struct msm_vidc_inst *inst,
 			buf->attr |= MSM_VIDC_ATTR_READ_ONLY;
 			print_vidc_buffer(VIDC_LOW, "low", "ro buf removed", inst, ro_buf);
 			list_del(&ro_buf->list);
-			kfree(ro_buf);
+			msm_vidc_put_vidc_buffer(inst, ro_buf);
 			break;
 		}
 	}
 	return rc;
 }
 
+int msm_vidc_memory_unmap_completely(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->refcount)
+		return 0;
+
+	while (map->refcount) {
+		rc = msm_vidc_memory_unmap(inst->core, map);
+		if (rc)
+			break;
+		if (!map->refcount) {
+			msm_vidc_memory_put_dmabuf(map->dmabuf);
+			list_del(&map->list);
+			msm_vidc_put_map_buffer(inst, map);
+			break;
+		}
+	}
+	return rc;
+}
+
+struct msm_vidc_buffer *msm_vidc_get_vidc_buffer(struct msm_vidc_inst *inst)
+{
+	struct msm_vidc_buffer *buf = NULL;
+
+	if (!inst) {
+		d_vpr_e("%s: Invalid params\n", __func__);
+		return NULL;
+	}
+
+	if (!list_empty(&inst->pool.buffers.list)) {
+		buf = list_first_entry(&inst->pool.buffers.list, struct msm_vidc_buffer, list);
+		inst->pool.buffers.count--;
+		list_del(&buf->list);
+		memset(buf, 0, sizeof(struct msm_vidc_buffer));
+		return buf;
+	}
+
+	buf = kzalloc(sizeof(struct msm_vidc_buffer), GFP_KERNEL);
+	if (!buf) {
+		i_vpr_e(inst, "%s: buf failed\n", __func__);
+		return NULL;
+	}
+
+	return buf;
+}
+
+int msm_vidc_put_vidc_buffer(struct msm_vidc_inst *inst, struct msm_vidc_buffer *buf)
+{
+	if (!inst || !buf) {
+		d_vpr_e("%s: Invalid params\n", __func__);
+		return -EINVAL;
+	}
+
+	inst->pool.buffers.count++;
+	list_add_tail(&buf->list, &inst->pool.buffers.list);
+
+	return 0;
+}
+
+int msm_vidc_destroy_vidc_buffer(struct msm_vidc_inst *inst)
+{
+	struct msm_vidc_buffer *buf, *dummy;
+
+	if (!inst) {
+		d_vpr_e("%s: Invalid params\n", __func__);
+		return -EINVAL;
+	}
+
+	i_vpr_h(inst, "%s: pool: buffer count %u\n", __func__, inst->pool.buffers.count);
+
+	/* free all buffers from pool */
+	list_for_each_entry_safe(buf, dummy, &inst->pool.buffers.list, list) {
+		list_del(&buf->list);
+		kfree(buf);
+	}
+
+	return 0;
+}
+
+struct msm_vidc_alloc *msm_vidc_get_alloc_buffer(struct msm_vidc_inst *inst)
+{
+	struct msm_vidc_alloc *alloc = NULL;
+
+	if (!inst) {
+		d_vpr_e("%s: Invalid params\n", __func__);
+		return NULL;
+	}
+
+	if (!list_empty(&inst->pool.allocations.list)) {
+		alloc = list_first_entry(&inst->pool.allocations.list, struct msm_vidc_alloc, list);
+		inst->pool.allocations.count--;
+		list_del(&alloc->list);
+		memset(alloc, 0, sizeof(struct msm_vidc_alloc));
+		return alloc;
+	}
+
+	alloc = kzalloc(sizeof(struct msm_vidc_alloc), GFP_KERNEL);
+	if (!alloc) {
+		i_vpr_e(inst, "%s: alloc failed\n", __func__);
+		return NULL;
+	}
+
+	return alloc;
+}
+
+int msm_vidc_put_alloc_buffer(struct msm_vidc_inst *inst, struct msm_vidc_alloc *alloc)
+{
+	if (!inst || !alloc) {
+		d_vpr_e("%s: Invalid params\n", __func__);
+		return -EINVAL;
+	}
+
+	list_add_tail(&alloc->list, &inst->pool.allocations.list);
+	inst->pool.allocations.count++;
+
+	return 0;
+}
+
+int msm_vidc_destroy_alloc_buffer(struct msm_vidc_inst *inst)
+{
+	struct msm_vidc_alloc *alloc, *dummy;
+
+	if (!inst) {
+		d_vpr_e("%s: Invalid params\n", __func__);
+		return -EINVAL;
+	}
+
+	i_vpr_h(inst, "%s: pool: allocations count %u\n", __func__, inst->pool.allocations.count);
+
+	/* free all allocations from pool */
+	list_for_each_entry_safe(alloc, dummy, &inst->pool.allocations.list, list) {
+		list_del(&alloc->list);
+		kfree(alloc);
+	}
+
+	return 0;
+}
+
+struct msm_vidc_map *msm_vidc_get_map_buffer(struct msm_vidc_inst *inst)
+{
+	struct msm_vidc_map *map = NULL;
+
+	if (!inst) {
+		d_vpr_e("%s: Invalid params\n", __func__);
+		return NULL;
+	}
+
+	if (!list_empty(&inst->pool.mappings.list)) {
+		map = list_first_entry(&inst->pool.mappings.list, struct msm_vidc_map, list);
+		inst->pool.mappings.count--;
+		list_del(&map->list);
+		memset(map, 0, sizeof(struct msm_vidc_map));
+		return map;
+	}
+
+	map = kzalloc(sizeof(struct msm_vidc_map), GFP_KERNEL);
+	if (!map) {
+		i_vpr_e(inst, "%s: map failed\n", __func__);
+		return NULL;
+	}
+
+	return map;
+}
+
+int msm_vidc_put_map_buffer(struct msm_vidc_inst *inst, struct msm_vidc_map *map)
+{
+	if (!inst || !map) {
+		d_vpr_e("%s: Invalid params\n", __func__);
+		return -EINVAL;
+	}
+
+	list_add_tail(&map->list, &inst->pool.mappings.list);
+	inst->pool.mappings.count++;
+
+	return 0;
+}
+
+int msm_vidc_destroy_map_buffer(struct msm_vidc_inst *inst)
+{
+	struct msm_vidc_map *map, *dummy;
+
+	if (!inst) {
+		d_vpr_e("%s: Invalid params\n", __func__);
+		return -EINVAL;
+	}
+
+	i_vpr_h(inst, "%s: pool: mappings count %u\n", __func__, inst->pool.mappings.count);
+
+	/* free all mappings from pool */
+	list_for_each_entry_safe(map, dummy, &inst->pool.mappings.list, list) {
+		list_del(&map->list);
+		kfree(map);
+	}
+
+	return 0;
+}
+
 int msm_vidc_unmap_buffers(struct msm_vidc_inst *inst,
 	enum msm_vidc_buffer_type type)
 {
@@ -1802,7 +2005,7 @@ int msm_vidc_unmap_buffers(struct msm_vidc_inst *inst,
 		return -EINVAL;
 
 	list_for_each_entry_safe(map, dummy, &mappings->list, list) {
-		msm_vidc_memory_unmap_completely(inst->core, map);
+		msm_vidc_memory_unmap_completely(inst, map);
 	}
 
 	return rc;
@@ -1847,8 +2050,7 @@ int msm_vidc_unmap_driver_buf(struct msm_vidc_inst *inst,
 	if (!map->refcount) {
 		msm_vidc_memory_put_dmabuf(map->dmabuf);
 		list_del(&map->list);
-		kfree(map);
-		map = NULL;
+		msm_vidc_put_map_buffer(inst, map);
 	}
 
 	return rc;
@@ -1883,7 +2085,7 @@ int msm_vidc_map_driver_buf(struct msm_vidc_inst *inst,
 	}
 	if (!found) {
 		/* new buffer case */
-		map = kzalloc(sizeof(struct msm_vidc_map), GFP_KERNEL);
+		map = msm_vidc_get_map_buffer(inst);
 		if (!map) {
 			i_vpr_e(inst, "%s: alloc failed\n", __func__);
 			return -ENOMEM;
@@ -1900,7 +2102,7 @@ int msm_vidc_map_driver_buf(struct msm_vidc_inst *inst,
 			rc = msm_vidc_memory_map(inst->core, map);
 			if (rc) {
 				msm_vidc_memory_put_dmabuf(map->dmabuf);
-				kfree(map);
+				msm_vidc_put_map_buffer(inst, map);
 				return rc;
 			}
 		}
@@ -1931,7 +2133,7 @@ int msm_vidc_put_driver_buf(struct msm_vidc_inst *inst,
 
 	/* delete the buffer from buffers->list */
 	list_del(&buf->list);
-	kfree(buf);
+	msm_vidc_put_vidc_buffer(inst, buf);
 
 	return rc;
 }
@@ -1957,7 +2159,7 @@ struct msm_vidc_buffer *msm_vidc_get_driver_buf(struct msm_vidc_inst *inst,
 	if (!buffers)
 		return NULL;
 
-	buf = kzalloc(sizeof(struct msm_vidc_buffer), GFP_KERNEL);
+	buf = msm_vidc_get_vidc_buffer(inst);
 	if (!buf) {
 		i_vpr_e(inst, "%s: alloc failed\n", __func__);
 		return NULL;
@@ -1985,7 +2187,7 @@ struct msm_vidc_buffer *msm_vidc_get_driver_buf(struct msm_vidc_inst *inst,
 error:
 	msm_vidc_memory_put_dmabuf(buf->dmabuf);
 	list_del(&buf->list);
-	kfree(buf);
+	msm_vidc_put_vidc_buffer(inst, buf);
 	return NULL;
 }
 
@@ -2011,8 +2213,6 @@ struct msm_vidc_buffer *get_meta_buffer(struct msm_vidc_inst *inst,
 		return NULL;
 	}
 	list_for_each_entry(mbuf, &buffers->list, list) {
-		if (!mbuf->valid)
-			continue;
 		if (mbuf->index == buf->index) {
 			found = true;
 			break;
@@ -2376,7 +2576,7 @@ int msm_vidc_destroy_internal_buffer(struct msm_vidc_inst *inst,
 		if (map->dmabuf == buffer->dmabuf) {
 			msm_vidc_memory_unmap(inst->core, map);
 			list_del(&map->list);
-			kfree(map);
+			msm_vidc_put_map_buffer(inst, map);
 			break;
 		}
 	}
@@ -2385,7 +2585,7 @@ int msm_vidc_destroy_internal_buffer(struct msm_vidc_inst *inst,
 		if (alloc->dmabuf == buffer->dmabuf) {
 			msm_vidc_memory_free(inst->core, alloc);
 			list_del(&alloc->list);
-			kfree(alloc);
+			msm_vidc_put_alloc_buffer(inst, alloc);
 			break;
 		}
 	}
@@ -2393,7 +2593,7 @@ int msm_vidc_destroy_internal_buffer(struct msm_vidc_inst *inst,
 	list_for_each_entry_safe(buf, dummy, &buffers->list, list) {
 		if (buf->dmabuf == buffer->dmabuf) {
 			list_del(&buf->list);
-			kfree(buf);
+			msm_vidc_put_vidc_buffer(inst, buf);
 			break;
 		}
 	}
@@ -2473,19 +2673,18 @@ int msm_vidc_create_internal_buffer(struct msm_vidc_inst *inst,
 	if (!buffers->size)
 		return 0;
 
-	buffer = kzalloc(sizeof(struct msm_vidc_buffer), GFP_KERNEL);
+	buffer = msm_vidc_get_vidc_buffer(inst);
 	if (!buffer) {
 		i_vpr_e(inst, "%s: buf alloc failed\n", __func__);
 		return -ENOMEM;
 	}
 	INIT_LIST_HEAD(&buffer->list);
-	buffer->valid = true;
 	buffer->type = buffer_type;
 	buffer->index = index;
 	buffer->buffer_size = buffers->size;
 	list_add_tail(&buffer->list, &buffers->list);
 
-	alloc = kzalloc(sizeof(struct msm_vidc_alloc), GFP_KERNEL);
+	alloc = msm_vidc_get_alloc_buffer(inst);
 	if (!alloc) {
 		i_vpr_e(inst, "%s: alloc failed\n", __func__);
 		return -ENOMEM;
@@ -2501,7 +2700,7 @@ int msm_vidc_create_internal_buffer(struct msm_vidc_inst *inst,
 		return -ENOMEM;
 	list_add_tail(&alloc->list, &allocations->list);
 
-	map = kzalloc(sizeof(struct msm_vidc_map), GFP_KERNEL);
+	map = msm_vidc_get_map_buffer(inst);
 	if (!map) {
 		i_vpr_e(inst, "%s: map alloc failed\n", __func__);
 		return -ENOMEM;
@@ -3511,7 +3710,7 @@ int msm_vidc_print_inst_info(struct msm_vidc_inst *inst)
 			buffers->extra_count, buffers->actual_count);
 
 		list_for_each_entry(buf, &buffers->list, list) {
-			if (!buf->valid || !buf->dmabuf)
+			if (!buf->dmabuf)
 				continue;
 			dbuf = (struct dma_buf *)buf->dmabuf;
 			i_vpr_e(inst,
@@ -3814,7 +4013,7 @@ int msm_vidc_flush_delayed_unmap_buffers(struct msm_vidc_inst *inst,
 						__func__, map->refcount, map->device_addr);
 					msm_vidc_change_inst_state(inst, MSM_VIDC_ERROR, __func__);
 				}
-				msm_vidc_memory_unmap_completely(inst->core, map);
+				msm_vidc_memory_unmap_completely(inst, map);
 			}
 		}
 	}
@@ -3876,8 +4075,14 @@ void msm_vidc_destroy_buffers(struct msm_vidc_inst *inst)
 	list_for_each_entry_safe(buf, dummy, &inst->buffers.read_only.list, list) {
 		print_vidc_buffer(VIDC_ERR, "err", "destroying ro buffer", inst, buf);
 		list_del(&buf->list);
-		kfree(buf);
+		msm_vidc_put_vidc_buffer(inst, buf);
 	}
+
+	/* destroy buffers from pool */
+	msm_vidc_destroy_vidc_buffer(inst);
+	msm_vidc_destroy_alloc_buffer(inst);
+	msm_vidc_destroy_map_buffer(inst);
+
 }
 
 static void msm_vidc_close_helper(struct kref *kref)

+ 0 - 28
driver/vidc/src/msm_vidc_memory.c

@@ -202,34 +202,6 @@ exit:
 	return rc;
 }
 
-int msm_vidc_memory_unmap_completely(struct msm_vidc_core *core,
-	struct msm_vidc_map *map)
-{
-	int rc = 0;
-
-	if (!core || !map) {
-		d_vpr_e("%s: invalid params\n", __func__);
-		return -EINVAL;
-	}
-
-	if (!map->refcount)
-		return 0;
-
-	while (map->refcount) {
-		rc = msm_vidc_memory_unmap(core, map);
-		if (rc)
-			break;
-		if (!map->refcount) {
-			msm_vidc_memory_put_dmabuf(map->dmabuf);
-			list_del(&map->list);
-			kfree(map);
-			map = NULL;
-			break;
-		}
-	}
-	return rc;
-}
-
 int msm_vidc_memory_alloc(struct msm_vidc_core *core, struct msm_vidc_alloc *mem)
 {
 	int rc = 0;

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

@@ -515,11 +515,12 @@ static int handle_read_only_buffer(struct msm_vidc_inst *inst,
 	 */
 	if (buffer->attr & MSM_VIDC_ATTR_READ_ONLY) {
 		if (!found) {
-			ro_buf = kmemdup(buffer, sizeof(struct msm_vidc_buffer), GFP_KERNEL);
+			ro_buf = msm_vidc_get_vidc_buffer(inst);
 			if (!ro_buf) {
 				i_vpr_e(inst, "%s: buffer alloc failed\n", __func__);
 				return -ENOMEM;
 			}
+			memcpy(ro_buf, buffer, sizeof(struct msm_vidc_buffer));
 			INIT_LIST_HEAD(&ro_buf->list);
 			list_add_tail(&ro_buf->list, &ro_buffers->list);
 			print_vidc_buffer(VIDC_LOW, "low", "ro buf added", inst, ro_buf);
@@ -528,8 +529,7 @@ static int handle_read_only_buffer(struct msm_vidc_inst *inst,
 		if (found) {
 			print_vidc_buffer(VIDC_LOW, "low", "ro buf deleted", inst, ro_buf);
 			list_del(&ro_buf->list);
-			kfree(ro_buf);
-			ro_buf = NULL;
+			msm_vidc_put_vidc_buffer(inst, ro_buf);
 		}
 	}