[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-Id: <20190307101229.7856-2-srinivas.kandagatla@linaro.org>
Date: Thu, 7 Mar 2019 10:12:22 +0000
From: Srinivas Kandagatla <srinivas.kandagatla@...aro.org>
To: gregkh@...uxfoundation.org, arnd@...db.de
Cc: linux-kernel@...r.kernel.org, bjorn.andersson@...aro.org,
bkumar@....qualcomm.com, linux-arm-msm@...r.kernel.org,
ktadakam@....qualcomm.com,
Thierry Escande <thierry.escande@...aro.org>,
Srinivas Kandagatla <srinivas.kandagatla@...aro.org>
Subject: [PATCH 1/8] misc: fastrpc: Avoid free of DMA buffer in interrupt context
From: Thierry Escande <thierry.escande@...aro.org>
When the remote DSP invocation is interrupted by the user, the
associated DMA buffer can be freed in interrupt context causing a kernel
BUG.
This patch adds a worker thread associated to the fastrpc context. It
is scheduled in the rpmsg callback to decrease its refcount out of the
interrupt context.
Fixes: c68cfb718c8f ("misc: fastrpc: Add support for context Invoke method")
Signed-off-by: Thierry Escande <thierry.escande@...aro.org>
Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@...aro.org>
---
drivers/misc/fastrpc.c | 18 +++++++++++++++++-
1 file changed, 17 insertions(+), 1 deletion(-)
diff --git a/drivers/misc/fastrpc.c b/drivers/misc/fastrpc.c
index 89aec17738ef..82e7217ae87a 100644
--- a/drivers/misc/fastrpc.c
+++ b/drivers/misc/fastrpc.c
@@ -149,6 +149,7 @@ struct fastrpc_invoke_ctx {
struct kref refcount;
struct list_head node; /* list of ctxs */
struct completion work;
+ struct work_struct put_work;
struct fastrpc_msg msg;
struct fastrpc_user *fl;
struct fastrpc_remote_arg *rpra;
@@ -311,6 +312,14 @@ static void fastrpc_context_put(struct fastrpc_invoke_ctx *ctx)
kref_put(&ctx->refcount, fastrpc_context_free);
}
+static void fastrpc_context_put_wq(struct work_struct *work)
+{
+ struct fastrpc_invoke_ctx *ctx =
+ container_of(work, struct fastrpc_invoke_ctx, put_work);
+
+ fastrpc_context_put(ctx);
+}
+
static struct fastrpc_invoke_ctx *fastrpc_context_alloc(
struct fastrpc_user *user, u32 kernel, u32 sc,
struct fastrpc_invoke_args *args)
@@ -345,6 +354,7 @@ static struct fastrpc_invoke_ctx *fastrpc_context_alloc(
ctx->tgid = user->tgid;
ctx->cctx = cctx;
init_completion(&ctx->work);
+ INIT_WORK(&ctx->put_work, fastrpc_context_put_wq);
spin_lock(&user->lock);
list_add_tail(&ctx->node, &user->pending);
@@ -1349,7 +1359,13 @@ static int fastrpc_rpmsg_callback(struct rpmsg_device *rpdev, void *data,
ctx->retval = rsp->retval;
complete(&ctx->work);
- fastrpc_context_put(ctx);
+
+ /*
+ * The DMA buffer associated with the context cannot be freed in
+ * interrupt context so schedule it through a worker thread to
+ * avoid a kernel BUG.
+ */
+ schedule_work(&ctx->put_work);
return 0;
}
--
2.21.0
Powered by blists - more mailing lists