Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 8f1d4f1e authored by Tharun Kumar Merugu's avatar Tharun Kumar Merugu
Browse files

msm: adsprpc: wait at least once before checking work done flag



- After sending message to remote subsystem, try waiting for
response at least once, before checking the "work done" flag that
is updated in the interrupt callback on a response from remote
processor.
- Add context complete ftrace event in the SSR and PDR callbacks
also.
- Remove context from the table first, before cleaning up its
buffers and mappings.
- In the interrupt callback, vote with PM before updating response
type, "work done" flag and completing the work.

Change-Id: I5c9c8ddcfb36036fd6d34fd051d2ffb4d7d700ea
Acked-by: default avatarThyagarajan Venkatanarayanan <venkatan@qti.qualcomm.com>
Acked-by: default avatarAmol Maheshwari <amahesh@qti.qualcomm.com>
Signed-off-by: default avatarTharun Kumar Merugu <mtharu@codeaurora.org>
parent 0af2ccf0
Loading
Loading
Loading
Loading
+38 −13
Original line number Diff line number Diff line
@@ -1351,7 +1351,7 @@ static int context_alloc(struct fastrpc_file *fl, uint32_t kernel,
		if (err)
			goto bail;
	}
	ctx->retval = -1;
	ctx->retval = 0xDECAF;
	ctx->pid = current->pid;
	ctx->tgid = fl->tgid;
	init_completion(&ctx->work);
@@ -1405,26 +1405,30 @@ static void context_free(struct smq_invoke_ctx *ctx)
	struct fastrpc_apps *me = &gfa;
	int nbufs = REMOTE_SCALARS_INBUFS(ctx->sc) +
		    REMOTE_SCALARS_OUTBUFS(ctx->sc);

	spin_lock(&me->ctxlock);
	for (i = 0; i < FASTRPC_CTX_MAX; i++) {
		if (me->ctxtable[i] == ctx) {
			me->ctxtable[i] = NULL;
			break;
		}
	}
	spin_unlock(&me->ctxlock);

	spin_lock(&ctx->fl->hlock);
	hlist_del_init(&ctx->hn);
	spin_unlock(&ctx->fl->hlock);

	mutex_lock(&ctx->fl->map_mutex);
	for (i = 0; i < nbufs; ++i)
		fastrpc_mmap_free(ctx->maps[i], 0);
	mutex_unlock(&ctx->fl->map_mutex);

	fastrpc_buf_free(ctx->buf, 1);
	fastrpc_buf_free(ctx->lbuf, 1);
	ctx->magic = 0;
	ctx->ctxid = 0;

	spin_lock(&me->ctxlock);
	for (i = 0; i < FASTRPC_CTX_MAX; i++) {
		if (me->ctxtable[i] == ctx) {
			me->ctxtable[i] = NULL;
			break;
		}
	}
	spin_unlock(&me->ctxlock);
	trace_fastrpc_context_free((uint64_t)ctx,
		ctx->msg.invoke.header.ctx, ctx->handle, ctx->sc);
	kfree(ctx);
@@ -1433,6 +1437,7 @@ static void context_free(struct smq_invoke_ctx *ctx)
static void context_notify_user(struct smq_invoke_ctx *ctx,
		int retval, uint32_t rspFlags, uint32_t earlyWakeTime)
{
	fastrpc_pm_awake(ctx->fl->wake_enable, &ctx->pm_awake_voted);
	ctx->retval = retval;
	switch (rspFlags) {
	case NORMAL_RESPONSE:
@@ -1456,7 +1461,6 @@ static void context_notify_user(struct smq_invoke_ctx *ctx,
		break;
	}
	ctx->rspFlags = (enum fastrpc_response_flags)rspFlags;
	fastrpc_pm_awake(ctx->fl->wake_enable, &ctx->pm_awake_voted);
	trace_fastrpc_context_complete(ctx->fl->cid, (uint64_t)ctx, retval,
		ctx->msg.invoke.header.ctx, ctx->handle, ctx->sc);
	complete(&ctx->work);
@@ -1470,10 +1474,16 @@ static void fastrpc_notify_users(struct fastrpc_file *me)
	spin_lock(&me->hlock);
	hlist_for_each_entry_safe(ictx, n, &me->clst.pending, hn) {
		ictx->isWorkDone = true;
		trace_fastrpc_context_complete(me->cid, (uint64_t)ictx,
			ictx->retval, ictx->msg.invoke.header.ctx,
			ictx->handle, ictx->sc);
		complete(&ictx->work);
	}
	hlist_for_each_entry_safe(ictx, n, &me->clst.interrupted, hn) {
		ictx->isWorkDone = true;
		trace_fastrpc_context_complete(me->cid, (uint64_t)ictx,
			ictx->retval, ictx->msg.invoke.header.ctx,
			ictx->handle, ictx->sc);
		complete(&ictx->work);
	}
	spin_unlock(&me->hlock);
@@ -1489,12 +1499,18 @@ static void fastrpc_notify_users_staticpd_pdr(struct fastrpc_file *me)
	hlist_for_each_entry_safe(ictx, n, &me->clst.pending, hn) {
		if (ictx->msg.pid) {
			ictx->isWorkDone = true;
			trace_fastrpc_context_complete(me->cid, (uint64_t)ictx,
				ictx->retval, ictx->msg.invoke.header.ctx,
				ictx->handle, ictx->sc);
			complete(&ictx->work);
		}
	}
	hlist_for_each_entry_safe(ictx, n, &me->clst.interrupted, hn) {
		if (ictx->msg.pid) {
			ictx->isWorkDone = true;
			trace_fastrpc_context_complete(me->cid, (uint64_t)ictx,
				ictx->retval, ictx->msg.invoke.header.ctx,
				ictx->handle, ictx->sc);
			complete(&ictx->work);
		}
	}
@@ -2099,9 +2115,18 @@ static void fastrpc_wait_for_completion(struct smq_invoke_ctx *ctx,
	int jj;
	bool wait_resp;
	uint32_t wTimeout = FASTRPC_USER_EARLY_HINT_TIMEOUT;
	uint32_t wakeTime = ctx->earlyWakeTime;
	uint32_t wakeTime = 0;

	if (!ctx) {
		/* This failure is not expected */
		err = *pInterrupted = EFAULT;
		pr_err("Error %d: adsprpc: %s: %s: ctx is NULL, cannot wait for response\n",
					err, current->comm, __func__);
		return;
	}
	wakeTime = ctx->earlyWakeTime;

	while (ctx && !ctx->isWorkDone) {
	do {
		switch (ctx->rspFlags) {
		/* try polling on completion with timeout */
		case USER_EARLY_SIGNAL:
@@ -2159,7 +2184,7 @@ static void fastrpc_wait_for_completion(struct smq_invoke_ctx *ctx,
			current->comm, ctx->rspFlags, ctx->handle, ctx->sc);
			return;
		} /* end of switch */
	} /* end of while loop */
	} while (!ctx->isWorkDone);
}

static void fastrpc_update_invoke_count(uint32_t handle, int64_t *perf_counter,