Merge "msm: camera: Deregister sync callbacks at context flush" into dev/msm-4.9-camx

This commit is contained in:
Jeyaprakash Soundrapandian 2018-04-06 10:16:51 -07:00 • committed by Gerrit - the friendly Code Review server
commit 0bb037141d
3 changed files with 57 additions and 8 deletions

View file

@ -70,7 +70,7 @@ struct cam_ctx_request {
uint32_t num_in_map_entries;
struct cam_hw_fence_map_entry out_map_entries[CAM_CTX_CFG_MAX];
uint32_t num_out_map_entries;
uint32_t num_in_acked;
atomic_t num_in_acked;
uint32_t num_out_acked;
int flushed;
struct cam_context *ctx;

View file

@ -189,8 +189,7 @@ static void cam_context_sync_callback(int32_t sync_obj, int status, void *data)
return;
}
req->num_in_acked++;
if (req->num_in_acked == req->num_in_map_entries) {
if (atomic_inc_return(&req->num_in_acked) == req->num_in_map_entries) {
apply.request_id = req->request_id;
/*
* take mutex to ensure that another thread does
@ -342,6 +341,7 @@ int32_t cam_context_prepare_dev_to_hw(struct cam_context *ctx,
req->num_hw_update_entries = cfg.num_hw_update_entries;
req->num_out_map_entries = cfg.num_out_map_entries;
req->num_in_map_entries = cfg.num_in_map_entries;
atomic_set(&req->num_in_acked, 0);
req->request_id = packet->header.request_id;
req->status = 1;
req->req_priv = cfg.priv;
@ -492,6 +492,7 @@ int32_t cam_context_flush_ctx_to_hw(struct cam_context *ctx)
struct cam_ctx_request *req;
uint32_t i;
int rc = 0;
bool free_req;
CAM_DBG(CAM_CTXT, "[%s] E: NRT flush ctx", ctx->dev_name);
@ -528,6 +529,21 @@ int32_t cam_context_flush_ctx_to_hw(struct cam_context *ctx)
flush_args.flush_req_pending[flush_args.num_req_pending++] =
req->req_priv;
free_req = false;
for (i = 0; i < req->num_in_map_entries; i++) {
rc = cam_sync_deregister_callback(
cam_context_sync_callback,
(void *)req,
req->in_map_entries[i].sync_id);
if (!rc) {
cam_context_putref(ctx);
if (atomic_inc_return(&req->num_in_acked) ==
req->num_in_map_entries)
free_req = true;
}
}
for (i = 0; i < req->num_out_map_entries; i++) {
if (req->out_map_entries[i].sync_id != -1) {
rc = cam_sync_signal(
@ -543,6 +559,17 @@ int32_t cam_context_flush_ctx_to_hw(struct cam_context *ctx)
}
}
/*
* If we have deregistered the last sync callback, req will
* not be put on the free list. So put it on the free list here
*/
if (free_req) {
req->ctx = NULL;
spin_lock(&ctx->lock);
list_add_tail(&req->list, &ctx->free_req_list);
spin_unlock(&ctx->lock);
}
if (cam_debug_ctx_req_list & ctx->dev_id)
CAM_INFO(CAM_CTXT,
"[%s][%d] : Deleting req[%llu] from temp_list",
@ -630,6 +657,7 @@ int32_t cam_context_flush_req_to_hw(struct cam_context *ctx,
uint32_t i;
int32_t sync_id = 0;
int rc = 0;
bool free_req = false;
CAM_DBG(CAM_CTXT, "[%s] E: NRT flush req", ctx->dev_name);
@ -682,6 +710,22 @@ int32_t cam_context_flush_req_to_hw(struct cam_context *ctx,
}
if (req) {
if (flush_args.num_req_pending) {
for (i = 0; i < req->num_in_map_entries; i++) {
rc = cam_sync_deregister_callback(
cam_context_sync_callback,
(void *)req,
req->in_map_entries[i].sync_id);
if (rc)
continue;
cam_context_putref(ctx);
if (atomic_inc_return(&req->num_in_acked) ==
req->num_in_map_entries)
free_req = true;
}
}
if (flush_args.num_req_pending || flush_args.num_req_active) {
for (i = 0; i < req->num_out_map_entries; i++) {
sync_id =
@ -697,17 +741,20 @@ int32_t cam_context_flush_req_to_hw(struct cam_context *ctx,
}
}
}
if (flush_args.num_req_active) {
if (flush_args.num_req_active || free_req) {
req->ctx = NULL;
spin_lock(&ctx->lock);
list_add_tail(&req->list, &ctx->free_req_list);
spin_unlock(&ctx->lock);
req->ctx = NULL;
if (cam_debug_ctx_req_list & ctx->dev_id)
CAM_INFO(CAM_CTXT,
"[%s][%d] : Moving req[%llu] from active_list to free_list",
"[%s][%d] : Moving req[%llu] from %s to free_list",
ctx->dev_name, ctx->ctx_id,
req->request_id);
req->request_id,
flush_args.num_req_active ?
"active_list" :
"pending_list");
}
}
}

View file

@ -123,6 +123,7 @@ int cam_sync_deregister_callback(sync_callback cb_func,
{
struct sync_table_row *row = NULL;
struct sync_callback_info *sync_cb, *temp;
bool found = false;
if (sync_obj >= CAM_SYNC_MAX_OBJS || sync_obj <= 0)
return -EINVAL;
@ -145,11 +146,12 @@ int cam_sync_deregister_callback(sync_callback cb_func,
sync_cb->cb_data == userdata) {
list_del_init(&sync_cb->list);
kfree(sync_cb);
found = true;
}
}
spin_unlock_bh(&sync_dev->row_spinlocks[sync_obj]);
return 0;
return found ? 0 : -ENOENT;
}
int cam_sync_signal(int32_t sync_obj, uint32_t status)