diff --git a/msm/vidc/hfi_common.c b/msm/vidc/hfi_common.c index b2a964296e14..88dd892ded14 100644 --- a/msm/vidc/hfi_common.c +++ b/msm/vidc/hfi_common.c @@ -3397,6 +3397,7 @@ static int __protect_cp_mem(struct venus_hfi_device *device) memprot.cp_nonpixel_start = 0x0; memprot.cp_nonpixel_size = 0x0; + mutex_lock(&device->res->cb_lock); list_for_each_entry(cb, &device->res->context_banks, list) { if (!strcmp(cb->name, "venus_ns")) { memprot.cp_size = cb->addr_range.start; @@ -3414,6 +3415,7 @@ static int __protect_cp_mem(struct venus_hfi_device *device) memprot.cp_nonpixel_size); } } + mutex_unlock(&device->res->cb_lock); rc = qcom_scm_mem_protect_video(memprot.cp_start, memprot.cp_size, memprot.cp_nonpixel_start, memprot.cp_nonpixel_size); diff --git a/msm/vidc/msm_smem.c b/msm/vidc/msm_smem.c index 4d326ab0bea5..4688aa9717a3 100644 --- a/msm/vidc/msm_smem.c +++ b/msm/vidc/msm_smem.c @@ -583,6 +583,7 @@ struct context_bank_info *msm_smem_get_context_bank(u32 session_type, buffer_type = HAL_BUFFER_INTERNAL_PERSIST_1; } + mutex_lock(&res->cb_lock); list_for_each_entry(cb, &res->context_banks, list) { if (cb->is_secure == is_secure && cb->buffer_type & buffer_type) { @@ -590,6 +591,7 @@ struct context_bank_info *msm_smem_get_context_bank(u32 session_type, break; } } + mutex_unlock(&res->cb_lock); if (!match) s_vpr_e(sid, "%s: cb not found for buffer_type %x, is_secure %d\n", diff --git a/msm/vidc/msm_v4l2_vidc.c b/msm/vidc/msm_v4l2_vidc.c index 1bf40ea95347..fb4aca41fcbd 100644 --- a/msm/vidc/msm_v4l2_vidc.c +++ b/msm/vidc/msm_v4l2_vidc.c @@ -289,6 +289,7 @@ static int msm_vidc_initialize_core(struct platform_device *pdev, INIT_LIST_HEAD(&core->instances); mutex_init(&core->lock); + mutex_init(&core->resources.cb_lock); core->state = VIDC_CORE_UNINIT; for (i = SYS_MSG_INDEX(SYS_MSG_START); @@ -644,6 +645,7 @@ static int msm_vidc_remove(struct platform_device *pdev) msm_vidc_free_platform_resources(&core->resources); sysfs_remove_group(&pdev->dev.kobj, &msm_vidc_core_attr_group); dev_set_drvdata(&pdev->dev, NULL); + mutex_destroy(&core->resources.cb_lock); mutex_destroy(&core->lock); kfree(core); return rc; diff --git a/msm/vidc/msm_vidc_common.c b/msm/vidc/msm_vidc_common.c index f34957431023..0edf1ad8913f 100644 --- a/msm/vidc/msm_vidc_common.c +++ b/msm/vidc/msm_vidc_common.c @@ -5717,26 +5717,29 @@ int msm_comm_check_memory_supported(struct msm_vidc_inst *vidc_inst) struct msm_vidc_format *fmt; struct v4l2_format *f; struct hal_buffer_requirements *req; + struct context_bank_info *cb = NULL; u32 i, dpb_cnt = 0, dpb_size = 0, rc = 0; - u64 mem_size = 0; + u32 inst_mem_size, non_sec_cb_size = 0; + u64 total_mem_size = 0, non_sec_mem_size = 0; u32 memory_limit_mbytes; core = vidc_inst->core; mutex_lock(&core->lock); list_for_each_entry(inst, &core->instances, list) { + inst_mem_size = 0; /* input port buffers memory size */ fmt = &inst->fmts[INPUT_PORT]; f = &fmt->v4l2_fmt; for (i = 0; i < f->fmt.pix_mp.num_planes; i++) - mem_size += f->fmt.pix_mp.plane_fmt[i].sizeimage * + inst_mem_size += f->fmt.pix_mp.plane_fmt[i].sizeimage * fmt->count_min_host; /* output port buffers memory size */ fmt = &inst->fmts[OUTPUT_PORT]; f = &fmt->v4l2_fmt; for (i = 0; i < f->fmt.pix_mp.num_planes; i++) - mem_size += f->fmt.pix_mp.plane_fmt[i].sizeimage * + inst_mem_size += f->fmt.pix_mp.plane_fmt[i].sizeimage * fmt->count_min_host; /* dpb buffers memory size */ @@ -5753,29 +5756,49 @@ int msm_comm_check_memory_supported(struct msm_vidc_inst *vidc_inst) } dpb_cnt = dpb.buffer_count_actual; dpb_size = dpb.buffer_size; - mem_size += dpb_cnt * dpb_size; + inst_mem_size += dpb_cnt * dpb_size; } /* internal buffers memory size */ for (i = 0; i < HAL_BUFFER_MAX; i++) { req = &inst->buff_req.buffer[i]; if (is_internal_buffer(req->buffer_type)) - mem_size += req->buffer_size * + inst_mem_size += req->buffer_size * req->buffer_count_actual; } + + if (!is_secure_session(inst)) + non_sec_mem_size += inst_mem_size; + total_mem_size += inst_mem_size; } mutex_unlock(&core->lock); memory_limit_mbytes = msm_comm_get_memory_limit(core); - if ((mem_size >> 20) > memory_limit_mbytes) { + if ((total_mem_size >> 20) > memory_limit_mbytes) { s_vpr_e(vidc_inst->sid, "%s: video mem overshoot - reached %llu MB, max_limit %llu MB\n", - __func__, mem_size >> 20, memory_limit_mbytes); - msm_comm_print_mem_usage(core); + __func__, total_mem_size >> 20, memory_limit_mbytes); + msm_comm_print_insts_info(core); return -EBUSY; } + if (!is_secure_session(vidc_inst)) { + mutex_lock(&core->resources.cb_lock); + list_for_each_entry(cb, &core->resources.context_banks, list) + if (!cb->is_secure) + non_sec_cb_size = cb->addr_range.size; + mutex_unlock(&core->resources.cb_lock); + + if (non_sec_mem_size > non_sec_cb_size) { + s_vpr_e(vidc_inst->sid, + "%s: insufficient device addr space, required %llu, available %llu\n", + __func__, non_sec_mem_size, non_sec_cb_size); + msm_comm_print_insts_info(core); + return -EINVAL; + } + } + return 0; } @@ -6284,6 +6307,23 @@ void msm_comm_print_inst_info(struct msm_vidc_inst *inst) mutex_unlock(&inst->outputbufs.lock); } +void msm_comm_print_insts_info(struct msm_vidc_core *core) +{ + struct msm_vidc_inst *inst = NULL; + + if (!core) { + d_vpr_e("%s: invalid params\n", __func__); + return; + } + + msm_comm_print_mem_usage(core); + + mutex_lock(&core->lock); + list_for_each_entry(inst, &core->instances, list) + msm_comm_print_inst_info(inst); + mutex_unlock(&core->lock); +} + int msm_comm_session_continue(void *instance) { struct msm_vidc_inst *inst = instance; diff --git a/msm/vidc/msm_vidc_common.h b/msm/vidc/msm_vidc_common.h index 2e95871b9dd9..124edf58c036 100644 --- a/msm/vidc/msm_vidc_common.h +++ b/msm/vidc/msm_vidc_common.h @@ -273,6 +273,7 @@ int msm_comm_ctrl_deinit(struct msm_vidc_inst *inst); void msm_comm_cleanup_internal_buffers(struct msm_vidc_inst *inst); bool msm_comm_turbo_session(struct msm_vidc_inst *inst); void msm_comm_print_inst_info(struct msm_vidc_inst *inst); +void msm_comm_print_insts_info(struct msm_vidc_core *core); int msm_comm_v4l2_to_hfi(int id, int value, u32 sid); int msm_comm_hfi_to_v4l2(int id, int value, u32 sid); int msm_comm_get_v4l2_profile(int fourcc, int profile, u32 sid); diff --git a/msm/vidc/msm_vidc_res_parse.c b/msm/vidc/msm_vidc_res_parse.c index a8d6edf0ce57..82343b0ae837 100644 --- a/msm/vidc/msm_vidc_res_parse.c +++ b/msm/vidc/msm_vidc_res_parse.c @@ -850,7 +850,6 @@ int read_platform_resources_from_dt( if (rc) return rc; - INIT_LIST_HEAD(&res->context_banks); res->firmware_base = (phys_addr_t)firmware_base; @@ -989,7 +988,6 @@ int msm_vidc_smmu_fault_handler(struct iommu_domain *domain, struct device *dev, unsigned long iova, int flags, void *token) { struct msm_vidc_core *core = token; - struct msm_vidc_inst *inst; if (!domain || !core) { d_vpr_e("%s: invalid params %pK %pK\n", @@ -1008,12 +1006,8 @@ int msm_vidc_smmu_fault_handler(struct iommu_domain *domain, d_vpr_e("%s: faulting address: %lx\n", __func__, iova); - mutex_lock(&core->lock); - list_for_each_entry(inst, &core->instances, list) { - msm_comm_print_inst_info(inst); - } core->smmu_fault_handled = true; - mutex_unlock(&core->lock); + msm_comm_print_insts_info(core); /* * Return -EINVAL to elicit the default behaviour of smmu driver. * If we return -EINVAL, then smmu driver assumes page fault handler @@ -1043,7 +1037,10 @@ static int msm_vidc_populate_context_bank(struct device *dev, } INIT_LIST_HEAD(&cb->list); + + mutex_lock(&core->resources.cb_lock); list_add_tail(&cb->list, &core->resources.context_banks); + mutex_unlock(&core->resources.cb_lock); rc = of_property_read_string(np, "label", &cb->name); if (rc) { @@ -1123,7 +1120,10 @@ static int msm_vidc_populate_legacy_context_bank( return -ENOMEM; } INIT_LIST_HEAD(&cb->list); + + mutex_lock(&res->cb_lock); list_add_tail(&cb->list, &res->context_banks); + mutex_unlock(&res->cb_lock); ctx_node = of_parse_phandle(domains_child_node, "qcom,vidc-domain-phandle", 0); diff --git a/msm/vidc/msm_vidc_resources.h b/msm/vidc/msm_vidc_resources.h index 5cea98cad011..a192430bbabe 100644 --- a/msm/vidc/msm_vidc_resources.h +++ b/msm/vidc/msm_vidc_resources.h @@ -167,6 +167,7 @@ struct msm_vidc_platform_resources { bool sw_power_collapsible; bool slave_side_cp; struct list_head context_banks; + struct mutex cb_lock; bool thermal_mitigable; const char *fw_name; const char *hfi_version;