diff --git a/driver/vidc/inc/msm_vidc_driver.h b/driver/vidc/inc/msm_vidc_driver.h index 7b700e4792..6e3a77f96a 100644 --- a/driver/vidc/inc/msm_vidc_driver.h +++ b/driver/vidc/inc/msm_vidc_driver.h @@ -290,18 +290,6 @@ 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); -struct msm_vidc_timestamp *msm_vidc_get_ts(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_put_ts(struct msm_vidc_inst *inst, struct msm_vidc_timestamp *ts); -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_destroy_ts(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); diff --git a/driver/vidc/inc/msm_vidc_inst.h b/driver/vidc/inc/msm_vidc_inst.h index d8aed7cd21..67551caba9 100644 --- a/driver/vidc/inc/msm_vidc_inst.h +++ b/driver/vidc/inc/msm_vidc_inst.h @@ -7,6 +7,7 @@ #define _MSM_VIDC_INST_H_ #include "msm_vidc_internal.h" +#include "msm_vidc_memory.h" #include "hfi_property.h" struct msm_vidc_inst; @@ -27,13 +28,6 @@ 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_pool timestamps; -}; - struct msm_vidc_allocations_info { struct msm_vidc_allocations bin; struct msm_vidc_allocations arp; @@ -119,7 +113,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_memory_pool pool[MSM_MEM_POOL_MAX]; struct msm_vidc_buffers_info buffers; struct msm_vidc_mappings_info mappings; struct msm_vidc_allocations_info allocations; diff --git a/driver/vidc/inc/msm_vidc_internal.h b/driver/vidc/inc/msm_vidc_internal.h index 36e7addf28..23f56b357f 100644 --- a/driver/vidc/inc/msm_vidc_internal.h +++ b/driver/vidc/inc/msm_vidc_internal.h @@ -828,11 +828,6 @@ struct msm_vidc_timestamps { u64 rank; }; -struct msm_vidc_pool { - struct list_head list; - u32 count; -}; - enum msm_vidc_allow { MSM_VIDC_DISALLOW = 0, MSM_VIDC_ALLOW, diff --git a/driver/vidc/inc/msm_vidc_memory.h b/driver/vidc/inc/msm_vidc_memory.h index cb183ad3f9..04eef96d56 100644 --- a/driver/vidc/inc/msm_vidc_memory.h +++ b/driver/vidc/inc/msm_vidc_memory.h @@ -7,7 +7,30 @@ #define _MSM_VIDC_MEMORY_H_ #include "msm_vidc_internal.h" -#include "msm_vidc_core.h" + +struct msm_vidc_core; +struct msm_vidc_inst; + +enum msm_memory_pool_type { + MSM_MEM_POOL_BUFFER = 0, + MSM_MEM_POOL_MAP, + MSM_MEM_POOL_ALLOC, + MSM_MEM_POOL_TIMESTAMP, + MSM_MEM_POOL_MAX, +}; + +struct msm_memory_alloc_header { + struct list_head list; + void *buf; +}; + +struct msm_memory_pool { + u32 type; + u32 size; + char *name; + struct list_head free_pool; /* list of struct msm_memory_alloc_header */ + struct list_head busy_pool; /* list of struct msm_memory_alloc_header */ +}; int msm_vidc_memory_alloc(struct msm_vidc_core *core, struct msm_vidc_alloc *alloc); @@ -19,5 +42,11 @@ int msm_vidc_memory_unmap(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); +int msm_memory_pools_init(struct msm_vidc_inst *inst); +void msm_memory_pools_deinit(struct msm_vidc_inst *inst); +void *msm_memory_alloc(struct msm_vidc_inst *inst, + enum msm_memory_pool_type type); +void msm_memory_free(struct msm_vidc_inst *inst, + enum msm_memory_pool_type type, void *vidc_buf); #endif // _MSM_VIDC_MEMORY_H_ \ No newline at end of file diff --git a/driver/vidc/src/msm_vdec.c b/driver/vidc/src/msm_vdec.c index 018577440d..e453b2e4be 100644 --- a/driver/vidc/src/msm_vdec.c +++ b/driver/vidc/src/msm_vdec.c @@ -1848,7 +1848,7 @@ int msm_vdec_handle_release_buffer(struct msm_vidc_inst *inst, print_vidc_buffer(VIDC_LOW, "low ", "release done", inst, buf); /* delete the buffer from release list */ list_del(&buf->list); - msm_vidc_put_vidc_buffer(inst, buf); + msm_memory_free(inst, MSM_MEM_POOL_BUFFER, buf); return rc; } diff --git a/driver/vidc/src/msm_vidc.c b/driver/vidc/src/msm_vidc.c index 4b3a35a61d..a5599296df 100644 --- a/driver/vidc/src/msm_vidc.c +++ b/driver/vidc/src/msm_vidc.c @@ -17,6 +17,7 @@ #include "msm_vidc_debug.h" #include "msm_vidc_control.h" #include "msm_vidc_power.h" +#include "msm_vidc_memory.h" #include "venus_hfi_response.h" #define MSM_VIDC_DRV_NAME "msm_vidc_driver" @@ -778,13 +779,15 @@ void *msm_vidc_open(void *vidc_core, u32 session_type) kref_init(&inst->kref); mutex_init(&inst->lock); msm_vidc_update_debug_str(inst); - i_vpr_h(inst, "Opening video instance: %d\n", session_type); + + rc = msm_memory_pools_init(inst); + if (rc) { + i_vpr_e(inst, "%s: failed to init pool buffers\n", __func__); + kfree(inst); + return NULL; + } 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->pool.timestamps.list); INIT_LIST_HEAD(&inst->timestamps.list); INIT_LIST_HEAD(&inst->buffers.input.list); INIT_LIST_HEAD(&inst->buffers.input_meta.list); diff --git a/driver/vidc/src/msm_vidc_driver.c b/driver/vidc/src/msm_vidc_driver.c index 66ee0fb224..8161a2cc8b 100644 --- a/driver/vidc/src/msm_vidc_driver.c +++ b/driver/vidc/src/msm_vidc_driver.c @@ -1980,7 +1980,7 @@ 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); - msm_vidc_put_vidc_buffer(inst, ro_buf); + msm_memory_free(inst, MSM_MEM_POOL_BUFFER, ro_buf); break; } } @@ -2007,7 +2007,7 @@ int msm_vidc_memory_unmap_completely(struct msm_vidc_inst *inst, if (!map->refcount) { msm_vidc_memory_put_dmabuf(map->dmabuf); list_del(&map->list); - msm_vidc_put_map_buffer(inst, map); + msm_memory_free(inst, MSM_MEM_POOL_MAP, map); break; } } @@ -2112,7 +2112,7 @@ int msm_vidc_flush_ts(struct msm_vidc_inst *inst) i_vpr_l(inst, "%s: flushing ts: val %lld, rank %%lld\n", __func__, ts->sort.val, ts->rank); list_del(&ts->sort.list); - msm_vidc_put_ts(inst, ts); + msm_memory_free(inst, MSM_MEM_POOL_TIMESTAMP, ts); } inst->timestamps.count = 0; inst->timestamps.rank = 0; @@ -2130,7 +2130,7 @@ int msm_vidc_update_timestamp(struct msm_vidc_inst *inst, u64 timestamp) return -EINVAL; } - ts = msm_vidc_get_ts(inst); + ts = msm_memory_alloc(inst, MSM_MEM_POOL_TIMESTAMP); if (!ts) { i_vpr_e(inst, "%s: ts alloc failed\n", __func__); return -ENOMEM; @@ -2153,229 +2153,12 @@ int msm_vidc_update_timestamp(struct msm_vidc_inst *inst, u64 timestamp) } inst->timestamps.count--; list_del(&ts->sort.list); - msm_vidc_put_ts(inst, ts); + msm_memory_free(inst, MSM_MEM_POOL_TIMESTAMP, ts); } return 0; } -struct msm_vidc_timestamp *msm_vidc_get_ts(struct msm_vidc_inst *inst) -{ - struct msm_vidc_timestamp *ts = NULL; - - if (!inst) { - d_vpr_e("%s: Invalid params\n", __func__); - return NULL; - } - - if (!list_empty(&inst->pool.timestamps.list)) { - ts = list_first_entry(&inst->pool.timestamps.list, - struct msm_vidc_timestamp, sort.list); - inst->pool.timestamps.count--; - list_del(&ts->sort.list); - memset(ts, 0, sizeof(struct msm_vidc_timestamp)); - return ts; - } - - ts = kzalloc(sizeof(struct msm_vidc_timestamp), GFP_KERNEL); - if (!ts) { - i_vpr_e(inst, "%s: ts failed\n", __func__); - return NULL; - } - - return ts; -} - -int msm_vidc_put_ts(struct msm_vidc_inst *inst, struct msm_vidc_timestamp *ts) -{ - if (!inst || !ts) { - d_vpr_e("%s: Invalid params\n", __func__); - return -EINVAL; - } - - inst->pool.timestamps.count++; - list_add_tail(&ts->sort.list, &inst->pool.timestamps.list); - - return 0; -} - -int msm_vidc_destroy_ts(struct msm_vidc_inst *inst) -{ - struct msm_vidc_timestamp *ts, *temp; - - if (!inst) { - d_vpr_e("%s: Invalid params\n", __func__); - return -EINVAL; - } - - i_vpr_h(inst, "%s: pool: ts count %u\n", __func__, inst->pool.timestamps.count); - - /* free all timestamps from pool */ - list_for_each_entry_safe(ts, temp, &inst->pool.timestamps.list, sort.list) { - list_del(&ts->sort.list); - kfree(ts); - } - - return 0; -} - -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_get_delayed_unmap(struct msm_vidc_inst *inst, struct msm_vidc_map *map) { int rc = 0; @@ -2416,32 +2199,12 @@ int msm_vidc_put_delayed_unmap(struct msm_vidc_inst *inst, struct msm_vidc_map * if (!map->refcount) { msm_vidc_memory_put_dmabuf(map->dmabuf); list_del(&map->list); - msm_vidc_put_map_buffer(inst, map); + msm_memory_free(inst, MSM_MEM_POOL_MAP, map); } return rc; } -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) { @@ -2504,7 +2267,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); - msm_vidc_put_map_buffer(inst, map); + msm_memory_free(inst, MSM_MEM_POOL_MAP, map); } return rc; @@ -2539,7 +2302,7 @@ int msm_vidc_map_driver_buf(struct msm_vidc_inst *inst, } if (!found) { /* new buffer case */ - map = msm_vidc_get_map_buffer(inst); + map = msm_memory_alloc(inst, MSM_MEM_POOL_MAP); if (!map) { i_vpr_e(inst, "%s: alloc failed\n", __func__); return -ENOMEM; @@ -2555,7 +2318,7 @@ int msm_vidc_map_driver_buf(struct msm_vidc_inst *inst, rc = msm_vidc_get_delayed_unmap(inst, map); if (rc) { msm_vidc_memory_put_dmabuf(map->dmabuf); - msm_vidc_put_map_buffer(inst, map); + msm_memory_free(inst, MSM_MEM_POOL_MAP, map); return rc; } } @@ -2586,7 +2349,7 @@ int msm_vidc_put_driver_buf(struct msm_vidc_inst *inst, /* delete the buffer from buffers->list */ list_del(&buf->list); - msm_vidc_put_vidc_buffer(inst, buf); + msm_memory_free(inst, MSM_MEM_POOL_BUFFER, buf); return rc; } @@ -2612,7 +2375,7 @@ struct msm_vidc_buffer *msm_vidc_get_driver_buf(struct msm_vidc_inst *inst, if (!buffers) return NULL; - buf = msm_vidc_get_vidc_buffer(inst); + buf = msm_memory_alloc(inst, MSM_MEM_POOL_BUFFER); if (!buf) { i_vpr_e(inst, "%s: alloc failed\n", __func__); return NULL; @@ -2640,7 +2403,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); - msm_vidc_put_vidc_buffer(inst, buf); + msm_memory_free(inst, MSM_MEM_POOL_BUFFER, buf); return NULL; } @@ -3083,7 +2846,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); - msm_vidc_put_map_buffer(inst, map); + msm_memory_free(inst, MSM_MEM_POOL_MAP, map); break; } } @@ -3092,7 +2855,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); - msm_vidc_put_alloc_buffer(inst, alloc); + msm_memory_free(inst, MSM_MEM_POOL_ALLOC, alloc); break; } } @@ -3100,7 +2863,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); - msm_vidc_put_vidc_buffer(inst, buf); + msm_memory_free(inst, MSM_MEM_POOL_BUFFER, buf); break; } } @@ -3180,7 +2943,7 @@ int msm_vidc_create_internal_buffer(struct msm_vidc_inst *inst, if (!buffers->size) return 0; - buffer = msm_vidc_get_vidc_buffer(inst); + buffer = msm_memory_alloc(inst, MSM_MEM_POOL_BUFFER); if (!buffer) { i_vpr_e(inst, "%s: buf alloc failed\n", __func__); return -ENOMEM; @@ -3191,7 +2954,7 @@ int msm_vidc_create_internal_buffer(struct msm_vidc_inst *inst, buffer->buffer_size = buffers->size; list_add_tail(&buffer->list, &buffers->list); - alloc = msm_vidc_get_alloc_buffer(inst); + alloc = msm_memory_alloc(inst, MSM_MEM_POOL_ALLOC); if (!alloc) { i_vpr_e(inst, "%s: alloc failed\n", __func__); return -ENOMEM; @@ -3207,7 +2970,7 @@ int msm_vidc_create_internal_buffer(struct msm_vidc_inst *inst, return -ENOMEM; list_add_tail(&alloc->list, &allocations->list); - map = msm_vidc_get_map_buffer(inst); + map = msm_memory_alloc(inst, MSM_MEM_POOL_MAP); if (!map) { i_vpr_e(inst, "%s: map alloc failed\n", __func__); return -ENOMEM; @@ -4735,20 +4498,20 @@ 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); - msm_vidc_put_vidc_buffer(inst, buf); + msm_memory_free(inst, MSM_MEM_POOL_BUFFER, buf); } list_for_each_entry_safe(buf, dummy, &inst->buffers.release.list, list) { print_vidc_buffer(VIDC_ERR, "err ", "destroying release buffer", inst, buf); list_del(&buf->list); - msm_vidc_put_vidc_buffer(inst, buf); + msm_memory_free(inst, MSM_MEM_POOL_BUFFER, buf); } list_for_each_entry_safe(ts, dummy_ts, &inst->timestamps.list, sort.list) { i_vpr_e(inst, "%s: removing ts: val %lld, rank %lld\n", __func__, ts->sort.val, ts->rank); list_del(&ts->sort.list); - msm_vidc_put_ts(inst, ts); + msm_memory_free(inst, MSM_MEM_POOL_TIMESTAMP, ts); } list_for_each_entry_safe(work, dummy_work, &inst->response_works, list) { @@ -4758,10 +4521,7 @@ void msm_vidc_destroy_buffers(struct msm_vidc_inst *inst) } /* destroy buffers from pool */ - msm_vidc_destroy_vidc_buffer(inst); - msm_vidc_destroy_alloc_buffer(inst); - msm_vidc_destroy_map_buffer(inst); - msm_vidc_destroy_ts(inst); + msm_memory_pools_deinit(inst); } static void msm_vidc_close_helper(struct kref *kref) diff --git a/driver/vidc/src/msm_vidc_memory.c b/driver/vidc/src/msm_vidc_memory.c index d532b7b263..bf18aba39b 100644 --- a/driver/vidc/src/msm_vidc_memory.c +++ b/driver/vidc/src/msm_vidc_memory.c @@ -314,6 +314,172 @@ int msm_vidc_memory_free(struct msm_vidc_core *core, struct msm_vidc_alloc *mem) return rc; }; + +void *msm_memory_alloc(struct msm_vidc_inst *inst, enum msm_memory_pool_type type) +{ + struct msm_memory_alloc_header *hdr; + struct msm_memory_pool *pool; + + if (!inst || type < 0 || type >= MSM_MEM_POOL_MAX) { + d_vpr_e("%s: Invalid params\n", __func__); + return NULL; + } + pool = &inst->pool[type]; + + if (!list_empty(&pool->free_pool)) { + /* get 1st node from free pool */ + hdr = list_first_entry(&pool->free_pool, + struct msm_memory_alloc_header, list); + list_del_init(&hdr->list); + + /* reset existing data */ + memset((char *)hdr->buf, 0, pool->size); + + /* add to busy pool */ + list_add_tail(&hdr->list, &pool->busy_pool); + + return hdr->buf; + } + + hdr = kzalloc(pool->size + sizeof(struct msm_memory_alloc_header), GFP_KERNEL); + if (!hdr) { + i_vpr_e(inst, "%s: buffer allocation failed\n", __func__); + return NULL; + } + INIT_LIST_HEAD(&hdr->list); + hdr->buf = (void *)(hdr + 1); + list_add_tail(&hdr->list, &pool->busy_pool); + + return hdr->buf; +} + +void msm_memory_free(struct msm_vidc_inst *inst, enum msm_memory_pool_type type, + void *vidc_buf) +{ + struct msm_memory_alloc_header *hdr; + struct msm_memory_pool *pool; + bool found = false; + + if (!inst || !vidc_buf || type < 0 || type >= MSM_MEM_POOL_MAX) { + d_vpr_e("%s: Invalid params\n", __func__); + return; + } + pool = &inst->pool[type]; + + /* sanitize buffer addr */ + list_for_each_entry(hdr, &pool->busy_pool, list) { + if (hdr->buf == vidc_buf) { + found = true; + break; + } + } + if (!found) { + i_vpr_e(inst, "%s: invalid buf addr %#x\n", __func__, vidc_buf); + return; + } + + /* remove from busy pool */ + list_del_init(&hdr->list); + + /* add to free pool */ + list_add_tail(&hdr->list, &pool->free_pool); +} + +static void msm_vidc_destroy_pool_buffers(struct msm_vidc_inst *inst, + enum msm_memory_pool_type type) +{ + struct msm_memory_alloc_header *hdr, *dummy; + struct msm_memory_pool *pool; + u32 fcount = 0, bcount = 0; + + if (!inst || type < 0 || type >= MSM_MEM_POOL_MAX) { + d_vpr_e("%s: Invalid params\n", __func__); + return; + } + pool = &inst->pool[type]; + + /* detect memleak: busy pool is expected to be empty here */ + if (!list_empty(&pool->busy_pool)) + i_vpr_e(inst, "%s: destroy request on active buffer. type %s\n", + __func__, pool->name); + + /* destroy all free buffers */ + list_for_each_entry_safe(hdr, dummy, &pool->free_pool, list) { + list_del(&hdr->list); + kfree(hdr); + fcount++; + } + + /* destroy all busy buffers */ + list_for_each_entry_safe(hdr, dummy, &pool->busy_pool, list) { + list_del(&hdr->list); + kfree(hdr); + bcount++; + } + + i_vpr_h(inst, "%s: type: %23s, count: free %2u, busy %2u\n", + __func__, pool->name, fcount, bcount); +} + +void msm_memory_pools_deinit(struct msm_vidc_inst *inst) +{ + u32 i = 0; + + if (!inst) { + d_vpr_e("%s: Invalid params\n", __func__); + return; + } + + /* destroy all buffers from all pool types */ + for (i = 0; i < MSM_MEM_POOL_MAX; i++) + msm_vidc_destroy_pool_buffers(inst, i); +} + +struct msm_vidc_type_size_name { + enum msm_memory_pool_type type; + u32 size; + char *name; +}; + +static struct msm_vidc_type_size_name buftype_size_name_arr[] = { + {MSM_MEM_POOL_BUFFER, sizeof(struct msm_vidc_buffer), "MSM_MEM_POOL_BUFFER" }, + {MSM_MEM_POOL_MAP, sizeof(struct msm_vidc_map), "MSM_MEM_POOL_MAP" }, + {MSM_MEM_POOL_ALLOC, sizeof(struct msm_vidc_alloc), "MSM_MEM_POOL_ALLOC" }, + {MSM_MEM_POOL_TIMESTAMP, sizeof(struct msm_vidc_timestamp), "MSM_MEM_POOL_TIMESTAMP" }, +}; + +int msm_memory_pools_init(struct msm_vidc_inst *inst) +{ + u32 i; + + if (!inst) { + d_vpr_e("%s: Invalid params\n", __func__); + return -EINVAL; + } + + if (ARRAY_SIZE(buftype_size_name_arr) != MSM_MEM_POOL_MAX) { + i_vpr_e(inst, "%s: num elements mismatch %u %u\n", __func__, + ARRAY_SIZE(buftype_size_name_arr), MSM_MEM_POOL_MAX); + return -EINVAL; + } + + for (i = 0; i < MSM_MEM_POOL_MAX; i++) { + if (i != buftype_size_name_arr[i].type) { + i_vpr_e(inst, "%s: type mismatch %u %u\n", __func__, + i, buftype_size_name_arr[i].type); + return -EINVAL; + } + + inst->pool[i].type = buftype_size_name_arr[i].type; + inst->pool[i].size = buftype_size_name_arr[i].size; + inst->pool[i].name = buftype_size_name_arr[i].name; + INIT_LIST_HEAD(&inst->pool[i].free_pool); + INIT_LIST_HEAD(&inst->pool[i].busy_pool); + } + + return 0; +} + /* int msm_memory_cache_operations(struct msm_vidc_inst *inst, struct dma_buf *dbuf, enum smem_cache_ops cache_op, diff --git a/driver/vidc/src/venus_hfi_response.c b/driver/vidc/src/venus_hfi_response.c index 734214593e..6b4499f17c 100644 --- a/driver/vidc/src/venus_hfi_response.c +++ b/driver/vidc/src/venus_hfi_response.c @@ -12,6 +12,7 @@ #include "msm_vidc_driver.h" #include "msm_vdec.h" #include "msm_vidc_control.h" +#include "msm_vidc_memory.h" #define in_range(range, val) (((range.begin) < (val)) && ((range.end) > (val))) @@ -593,7 +594,7 @@ static int handle_read_only_buffer(struct msm_vidc_inst *inst, * if present, do nothing */ if (!found) { - ro_buf = msm_vidc_get_vidc_buffer(inst); + ro_buf = msm_memory_alloc(inst, MSM_MEM_POOL_BUFFER); if (!ro_buf) { i_vpr_e(inst, "%s: buffer alloc failed\n", __func__); return -ENOMEM; @@ -644,7 +645,7 @@ static int handle_non_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); - msm_vidc_put_vidc_buffer(inst, ro_buf); + msm_memory_free(inst, MSM_MEM_POOL_BUFFER, ro_buf); } return 0;