Browse Source

msm: adsprpc: Fix race in async context response

Currently async job is first added to pending context list and later
job is send to remote sub system. After the job is added to pending
context list, if any SSR happens, all the async pending job contexts are
responded and freed in async response thread. Original thread that added
job to pending context list might not have sent the job, as there is SSR and can
free the context again in same thread. Queue response in SSR only when
the job is sent to remote sub system.

Signed-off-by: Himateja Reddy <[email protected]>
Change-Id: I1f880316f327a8345433d5d22b619ef0a50d7240
Himateja Reddy 2 năm trước cách đây
mục cha
commit
5f713c22a4
2 tập tin đã thay đổi với 9 bổ sung2 xóa
  1. 8 2
      dsp/adsprpc.c
  2. 1 0
      dsp/adsprpc_shared.h

+ 8 - 2
dsp/adsprpc.c

@@ -1828,6 +1828,7 @@ static int context_alloc(struct fastrpc_file *fl, uint32_t kernel,
 	ctx->is_work_done = false;
 	ctx->copybuf = NULL;
 	ctx->is_early_wakeup = false;
+	ctx->is_job_sent_to_remote_ss = false;
 
 	if (ctx->fl->profile) {
 		ctx->perf = kzalloc(sizeof(*(ctx->perf)), GFP_KERNEL);
@@ -2084,7 +2085,7 @@ static void fastrpc_notify_users(struct fastrpc_file *me)
 		trace_fastrpc_context_complete(me->cid, (uint64_t)ictx,
 			ictx->retval, ictx->msg.invoke.header.ctx,
 			ictx->handle, ictx->sc);
-		if (ictx->asyncjob.isasyncjob)
+		if (ictx->asyncjob.isasyncjob && ictx->is_job_sent_to_remote_ss)
 			fastrpc_queue_completed_async_job(ictx);
 		else
 			complete(&ictx->work);
@@ -2114,7 +2115,7 @@ static void fastrpc_notify_users_staticpd_pdr(struct fastrpc_file *me)
 			trace_fastrpc_context_complete(me->cid, (uint64_t)ictx,
 				ictx->retval, ictx->msg.invoke.header.ctx,
 				ictx->handle, ictx->sc);
-			if (ictx->asyncjob.isasyncjob)
+			if (ictx->asyncjob.isasyncjob && ictx->is_job_sent_to_remote_ss)
 				fastrpc_queue_completed_async_job(ictx);
 			else
 				complete(&ictx->work);
@@ -2868,6 +2869,11 @@ static int fastrpc_invoke_send(struct smq_invoke_ctx *ctx,
 		msg = &msg_temp;
 	}
 	err = fastrpc_transport_send(cid, (void *)msg, sizeof(*msg), fl->tvm_remote_domain);
+	if (isasync && !err) {
+		spin_lock(&fl->hlock);
+		ctx->is_job_sent_to_remote_ss = true;
+		spin_unlock(&fl->hlock);
+	}
 	trace_fastrpc_transport_send(cid, (uint64_t)ctx, msg->invoke.header.ctx,
 		handle, sc, msg->invoke.page.addr, msg->invoke.page.size);
 	ns = get_timestamp_in_ns();

+ 1 - 0
dsp/adsprpc_shared.h

@@ -836,6 +836,7 @@ struct smq_invoke_ctx {
 	uint64_t xo_time_in_us_interrupted; /* XO Timestamp (in us) of interrupted ctx */
 	uint64_t xo_time_in_us_restored; /* XO Timestamp (in us) of restored ctx */
 	int tx_index; /* index of current ctx in channel gmsg_log array */
+	bool is_job_sent_to_remote_ss; /* Flag to check if job is sent to remote sub system */
 };
 
 struct fastrpc_ctx_lst {