| From b9bca25afcf178d1e5fb49b86bfb9bd7b63c5eb6 Mon Sep 17 00:00:00 2001 |
| From: Steve Longerbeam <slongerbeam@gmail.com> |
| Date: Wed, 19 Sep 2018 16:07:18 -0700 |
| Subject: gpu: ipu-v3: image-convert: Prevent race between run and unprepare |
| |
| [ Upstream commit 819bec35c8c9706185498c9222bd244e0781ad35 ] |
| |
| Prevent possible race by parallel threads between ipu_image_convert_run() |
| and ipu_image_convert_unprepare(). This involves setting ctx->aborting |
| to true unconditionally so that no new job runs can be queued during |
| unprepare, and holding the ctx->aborting flag until the context is freed. |
| |
| Note that the "normal" ipu_image_convert_abort() case (e.g. not during |
| context unprepare) should clear the ctx->aborting flag after aborting |
| any active run and clearing the context's pending queue. This is because |
| it should be possible to continue to use the conversion context and queue |
| more runs after an abort. |
| |
| Signed-off-by: Steve Longerbeam <slongerbeam@gmail.com> |
| Tested-by: Philipp Zabel <p.zabel@pengutronix.de> |
| Signed-off-by: Philipp Zabel <p.zabel@pengutronix.de> |
| Signed-off-by: Sasha Levin <sashal@kernel.org> |
| --- |
| drivers/gpu/ipu-v3/ipu-image-convert.c | 10 +++++++--- |
| 1 file changed, 7 insertions(+), 3 deletions(-) |
| |
| diff --git a/drivers/gpu/ipu-v3/ipu-image-convert.c b/drivers/gpu/ipu-v3/ipu-image-convert.c |
| index 524a717ab28e..a5e33d58e02f 100644 |
| --- a/drivers/gpu/ipu-v3/ipu-image-convert.c |
| +++ b/drivers/gpu/ipu-v3/ipu-image-convert.c |
| @@ -1518,7 +1518,7 @@ unlock: |
| EXPORT_SYMBOL_GPL(ipu_image_convert_queue); |
| |
| /* Abort any active or pending conversions for this context */ |
| -void ipu_image_convert_abort(struct ipu_image_convert_ctx *ctx) |
| +static void __ipu_image_convert_abort(struct ipu_image_convert_ctx *ctx) |
| { |
| struct ipu_image_convert_chan *chan = ctx->chan; |
| struct ipu_image_convert_priv *priv = chan->priv; |
| @@ -1545,7 +1545,7 @@ void ipu_image_convert_abort(struct ipu_image_convert_ctx *ctx) |
| |
| need_abort = (run_count || active_run); |
| |
| - ctx->aborting = need_abort; |
| + ctx->aborting = true; |
| |
| spin_unlock_irqrestore(&chan->irqlock, flags); |
| |
| @@ -1566,7 +1566,11 @@ void ipu_image_convert_abort(struct ipu_image_convert_ctx *ctx) |
| dev_warn(priv->ipu->dev, "%s: timeout\n", __func__); |
| force_abort(ctx); |
| } |
| +} |
| |
| +void ipu_image_convert_abort(struct ipu_image_convert_ctx *ctx) |
| +{ |
| + __ipu_image_convert_abort(ctx); |
| ctx->aborting = false; |
| } |
| EXPORT_SYMBOL_GPL(ipu_image_convert_abort); |
| @@ -1580,7 +1584,7 @@ void ipu_image_convert_unprepare(struct ipu_image_convert_ctx *ctx) |
| bool put_res; |
| |
| /* make sure no runs are hanging around */ |
| - ipu_image_convert_abort(ctx); |
| + __ipu_image_convert_abort(ctx); |
| |
| dev_dbg(priv->ipu->dev, "%s: task %u: removing ctx %p\n", __func__, |
| chan->ic_task, ctx); |
| -- |
| 2.19.1 |
| |