fastrpc_internal_invoke() skips removing and dropping the invoke context
when userspace wait is interrupted or a kernel invoke times out. The
context remains on the user's pending list even after a later DSP reply
consumes the send reference.

Remove the context from the pending list and drop the caller reference for
all exits. A late DSP reply still holds the send reference until the
callback releases it, but interrupted callers no longer pin completed
contexts for the lifetime of the file.

Signed-off-by: Yousef Alhouseen <[email protected]>
---
 drivers/misc/fastrpc.c | 15 +++++++--------
 1 file changed, 7 insertions(+), 8 deletions(-)

diff --git a/drivers/misc/fastrpc.c b/drivers/misc/fastrpc.c
index 4b258dbcd..90281859a 100644
--- a/drivers/misc/fastrpc.c
+++ b/drivers/misc/fastrpc.c
@@ -1379,14 +1379,6 @@ static int fastrpc_internal_invoke(struct fastrpc_user 
*fl,  u32 kernel,
                goto bail;
 
 bail:
-       if (err != -ERESTARTSYS && err != -ETIMEDOUT) {
-               /* We are done with this compute context */
-               spin_lock(&fl->lock);
-               list_del(&ctx->node);
-               spin_unlock(&fl->lock);
-               fastrpc_context_put(ctx);
-       }
-
        if (err == -ERESTARTSYS) {
                list_for_each_entry_safe(buf, b, &fl->mmaps, node) {
                        list_del(&buf->node);
@@ -1394,6 +1386,13 @@ static int fastrpc_internal_invoke(struct fastrpc_user 
*fl,  u32 kernel,
                }
        }
 
+       /* We are done with this compute context */
+       spin_lock(&fl->lock);
+       if (!list_empty(&ctx->node))
+               list_del_init(&ctx->node);
+       spin_unlock(&fl->lock);
+       fastrpc_context_put(ctx);
+
        if (err)
                dev_dbg(fl->sctx->dev, "Error: Invoke Failed %d\n", err);
 
-- 
2.54.0

Reply via email to