From c944517030bc6aed226c8b614469a5f95ed85c74 Mon Sep 17 00:00:00 2001 From: Himateja Reddy Date: Tue, 7 Apr 2020 23:05:41 -0700 Subject: [PATCH] msm: adsprpc: retrieve table index directly from context ID Currently, a linear search of the entire context table is being done for freeing a particular entry, which is inefficient. Instead retrieve the index already encoded in the context ID and directly free that entry in the table. If the context ID at the retrieved index does not match with the given ID, then fallback to searching the entire table. Change-Id: I22891f2686fd2f181b4d8c7f369fc24c5cfa3322 Acked-by: Thyagarajan Venkatanarayanan Signed-off-by: Himateja Reddy --- drivers/char/adsprpc.c | 39 ++++++++++++++++++++++++--------------- 1 file changed, 24 insertions(+), 15 deletions(-) diff --git a/drivers/char/adsprpc.c b/drivers/char/adsprpc.c index 9d98de9ef675..c527c3197665 100644 --- a/drivers/char/adsprpc.c +++ b/drivers/char/adsprpc.c @@ -107,6 +107,9 @@ ((FASTRPC_CTX_MAX - 1) << FASTRPC_CTX_TABLE_IDX_POS) #define FASTRPC_ASYNC_JOB_MASK (1) +#define GET_TABLE_IDX_FROM_CTXID(ctxid) \ + ((ctxid & FASTRPC_CTX_TABLE_IDX_MASK) >> FASTRPC_CTX_TABLE_IDX_POS) + /* Reserve few entries in context table for critical kernel RPC calls * to avoid user invocations from exhausting all entries. */ @@ -1485,7 +1488,7 @@ static void context_save_interrupted(struct smq_invoke_ctx *ctx) static void context_free(struct smq_invoke_ctx *ctx) { - int i; + uint32_t i = 0; struct fastrpc_apps *me = &gfa; int nbufs = REMOTE_SCALARS_INBUFS(ctx->sc) + REMOTE_SCALARS_OUTBUFS(ctx->sc); @@ -1493,11 +1496,19 @@ static void context_free(struct smq_invoke_ctx *ctx) struct fastrpc_channel_ctx *chan = &me->channel[cid]; unsigned long irq_flags = 0; + i = (uint32_t)GET_TABLE_IDX_FROM_CTXID(ctx->ctxid); + spin_lock_irqsave(&chan->ctxlock, irq_flags); - for (i = 0; i < FASTRPC_CTX_MAX; i++) { - if (chan->ctxtable[i] == ctx) { - chan->ctxtable[i] = NULL; - break; + if (i < FASTRPC_CTX_MAX && chan->ctxtable[i] == ctx) { + chan->ctxtable[i] = NULL; + } else { + pr_warn("adsprpc: %s: %s: encoded table ID %u is invalid (handle 0x%x, sc 0x%x)\n", + current->comm, __func__, i, ctx->handle, ctx->sc); + for (i = 0; i < FASTRPC_CTX_MAX; i++) { + if (chan->ctxtable[i] == ctx) { + chan->ctxtable[i] = NULL; + break; + } } } spin_unlock_irqrestore(&chan->ctxlock, irq_flags); @@ -1512,7 +1523,7 @@ static void context_free(struct smq_invoke_ctx *ctx) mutex_unlock(&ctx->fl->map_mutex); fastrpc_buf_free(ctx->buf, 1); - if (!(ctx->copybuf == ctx->buf)) + if (ctx->copybuf != ctx->buf) fastrpc_buf_free(ctx->copybuf, 1); kfree(ctx->lrpra); ctx->lrpra = NULL; @@ -3810,6 +3821,7 @@ static int fastrpc_rpmsg_callback(struct rpmsg_device *rpdev, void *data, { struct smq_invoke_rsp *rsp = (struct smq_invoke_rsp *)data; struct smq_invoke_rspv2 *rspv2 = NULL; + struct smq_invoke_ctx *ctx = NULL; struct fastrpc_apps *me = &gfa; uint32_t index, rsp_flags = 0, early_wake_time = 0; int err = 0, cid = -1; @@ -3836,21 +3848,19 @@ static int fastrpc_rpmsg_callback(struct rpmsg_device *rpdev, void *data, trace_fastrpc_rpmsg_response(cid, rsp->ctx, rsp->retval, rsp_flags, early_wake_time); - index = (uint32_t)((rsp->ctx & FASTRPC_CTX_TABLE_IDX_MASK) - >> FASTRPC_CTX_TABLE_IDX_POS); + index = (uint32_t)GET_TABLE_IDX_FROM_CTXID(rsp->ctx); VERIFY(err, index < FASTRPC_CTX_MAX); if (err) goto bail; spin_lock_irqsave(&chan->ctxlock, irq_flags); - VERIFY(err, !IS_ERR_OR_NULL(chan->ctxtable[index])); + ctx = chan->ctxtable[index]; + VERIFY(err, !IS_ERR_OR_NULL(ctx)); if (err) goto bail_unlock; - VERIFY(err, ((chan->ctxtable[index]->ctxid == - (rsp->ctx & ~CONTEXT_PD_CHECK)) && - chan->ctxtable[index]->magic == - FASTRPC_CTX_MAGIC)); + VERIFY(err, ((ctx->ctxid == (rsp->ctx & ~CONTEXT_PD_CHECK)) && + ctx->magic == FASTRPC_CTX_MAGIC)); if (err) goto bail_unlock; @@ -3859,8 +3869,7 @@ static int fastrpc_rpmsg_callback(struct rpmsg_device *rpdev, void *data, if (err) goto bail_unlock; } - context_notify_user(chan->ctxtable[index], rsp->retval, - rsp_flags, early_wake_time); + context_notify_user(ctx, rsp->retval, rsp_flags, early_wake_time); bail_unlock: spin_unlock_irqrestore(&chan->ctxlock, irq_flags); bail: