msm: camera: core: Fix context release timing issue

When sync object is invalid and num_in_map > 1,
it will lead to context ref leak. Check sync
object first, then register sync call back.

CRs-Fixed: 2594185
Change-Id: I2d39ce3ea43bbe7bc05420b86b37fdfba4aa795a
Signed-off-by: Ayush Kumar <ayushkr@codeaurora.org>
This commit is contained in:
Ayush Kumar
2020-02-04 11:33:11 +05:30
committed by Karthik Anantha Ram
szülő 5619d4e93e
commit 320ae57bb9
3 fájl változott, egészen pontosan 58 új sor hozzáadva és 6 régi sor törölve

Fájl megtekintése

@@ -1,6 +1,6 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
* Copyright (c) 2017-2019, The Linux Foundation. All rights reserved.
* Copyright (c) 2017-2020, The Linux Foundation. All rights reserved.
*/
#include <linux/debugfs.h>
@@ -451,6 +451,17 @@ int32_t cam_context_prepare_dev_to_hw(struct cam_context *ctx,
"[%s][%d] : Moving req[%llu] from free_list to pending_list",
ctx->dev_name, ctx->ctx_id, req->request_id);
for (j = 0; j < req->num_in_map_entries; j++) {
rc = cam_sync_check_valid(
req->in_map_entries[j].sync_id);
if (rc) {
CAM_ERR(CAM_CTXT,
"invalid in map sync object %d",
req->in_map_entries[j].sync_id);
goto put_ref;
}
}
for (j = 0; j < req->num_in_map_entries; j++) {
cam_context_getref(ctx);
rc = cam_sync_register_callback(
@@ -472,7 +483,8 @@ int32_t cam_context_prepare_dev_to_hw(struct cam_context *ctx,
ctx->dev_name, ctx->ctx_id,
req->request_id);
goto put_ctx_ref;
cam_context_putref(ctx);
goto put_ref;
}
CAM_DBG(CAM_CTXT, "register in fence cb: %d ret = %d",
req->in_map_entries[j].sync_id, rc);
@@ -480,9 +492,6 @@ int32_t cam_context_prepare_dev_to_hw(struct cam_context *ctx,
}
return rc;
put_ctx_ref:
for (; j >= 0; j--)
cam_context_putref(ctx);
put_ref:
for (--i; i >= 0; i--) {
if (cam_sync_put_obj_ref(req->out_map_entries[i].sync_id))

Fájl megtekintése

@@ -287,6 +287,7 @@ int cam_sync_merge(int32_t *sync_obj, uint32_t num_objs, int32_t *merged_obj)
int rc;
long idx = 0;
bool bit;
int i = 0;
if (!sync_obj || !merged_obj) {
CAM_ERR(CAM_SYNC, "Invalid pointer(s)");
@@ -304,6 +305,14 @@ int cam_sync_merge(int32_t *sync_obj, uint32_t num_objs, int32_t *merged_obj)
return -EINVAL;
}
for (i = 0; i < num_objs; i++) {
rc = cam_sync_check_valid(sync_obj[i]);
if (rc) {
CAM_ERR(CAM_SYNC, "Sync_obj[%d] %d valid check fail",
i, sync_obj[i]);
return rc;
}
}
do {
idx = find_first_zero_bit(sync_dev->bitmap, CAM_SYNC_MAX_OBJS);
if (idx >= CAM_SYNC_MAX_OBJS)
@@ -375,6 +384,30 @@ int cam_sync_destroy(int32_t sync_obj)
return cam_sync_deinit_object(sync_dev->sync_table, sync_obj);
}
int cam_sync_check_valid(int32_t sync_obj)
{
struct sync_table_row *row = NULL;
if (sync_obj >= CAM_SYNC_MAX_OBJS || sync_obj <= 0)
return -EINVAL;
row = sync_dev->sync_table + sync_obj;
if (!test_bit(sync_obj, sync_dev->bitmap)) {
CAM_ERR(CAM_SYNC, "Error: Released sync obj received %d",
sync_obj);
return -EINVAL;
}
if (row->state == CAM_SYNC_STATE_INVALID) {
CAM_ERR(CAM_SYNC,
"Error: accessing an uninitialized sync obj = %d",
sync_obj);
return -EINVAL;
}
return 0;
}
int cam_sync_wait(int32_t sync_obj, uint64_t timeout_ms)
{
unsigned long timeleft;

Fájl megtekintése

@@ -1,6 +1,6 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Copyright (c) 2017-2019, The Linux Foundation. All rights reserved.
* Copyright (c) 2017-2020, The Linux Foundation. All rights reserved.
*/
#ifndef __CAM_SYNC_API_H__
@@ -140,6 +140,16 @@ int cam_sync_destroy(int32_t sync_obj);
*/
int cam_sync_wait(int32_t sync_obj, uint64_t timeout_ms);
/**
* @brief: Check if sync object is valid
*
* @param sync_obj: int referencing the sync object to be checked
*
* @return 0 upon success, -EINVAL if sync object is in bad state or arguments
* are invalid
*/
int cam_sync_check_valid(int32_t sync_obj);
/**
* @brief : API to register SYNC to platform framework.
* @return struct platform_device pointer on on success, or ERR_PTR() on error.