diff mbox series

[4/5] media: coda: Remove pic_run_work worker

Message ID 20190425183546.16244-5-ezequiel@collabora.com (mailing list archive)
State New, archived
Headers show
Series Assorted CODA fixes | expand

Commit Message

Ezequiel Garcia April 25, 2019, 6:35 p.m. UTC
There isn't any reason to run the mem2mem job on a separate worker,
because the mem2mem framework guarantees that device_run will never
run in interrupt context.

Therefore, get rid of the extra pic_run_work worker, and instead
run the job in the context of .device_run itself.

Signed-off-by: Ezequiel Garcia <ezequiel@collabora.com>
---
 drivers/media/platform/coda/coda-common.c | 9 ---------
 drivers/media/platform/coda/coda.h        | 1 -
 2 files changed, 10 deletions(-)

Comments

Philipp Zabel April 26, 2019, 8:11 a.m. UTC | #1
On Thu, 2019-04-25 at 15:35 -0300, Ezequiel Garcia wrote:
> There isn't any reason to run the mem2mem job on a separate worker,
> because the mem2mem framework guarantees that device_run will never
> run in interrupt context.

The purpose of the workqueue is to serialize BIT processor commands,
currently the PIC_RUN commands issued by the mem2mem framework (as well
as SEQ_INIT, SET_FRAME_BUF, and ENCODE_HEADER) against the SEQ_END
command issued directly from the STREAMOFF ioctl.
Further, to fully support the stateful decoder API we'll have to move
SEQ_INIT out of the mem2mem device_run as well, since that should be
called on queued OUTPUT buffers before the CAPTURE side is even
streaming.

regards
Philipp
Ezequiel Garcia April 26, 2019, 6:19 p.m. UTC | #2
On Fri, 2019-04-26 at 10:11 +0200, Philipp Zabel wrote:
> On Thu, 2019-04-25 at 15:35 -0300, Ezequiel Garcia wrote:
> > There isn't any reason to run the mem2mem job on a separate worker,
> > because the mem2mem framework guarantees that device_run will never
> > run in interrupt context.
> 
> The purpose of the workqueue is to serialize BIT processor commands,
> currently the PIC_RUN commands issued by the mem2mem framework (as well
> as SEQ_INIT, SET_FRAME_BUF, and ENCODE_HEADER) against the SEQ_END
> command issued directly from the STREAMOFF ioctl.

Right, but that's serialized by the coda_mutex, not by the worker, right?

> Further, to fully support the stateful decoder API we'll have to move
> SEQ_INIT out of the mem2mem device_run as well, since that should be
> called on queued OUTPUT buffers before the CAPTURE side is even
> streaming.
> 

Isn't that already done? I see SEQ_INIT being issued in start_streaming.
In what sense is this driver currently violating the decoder spec?

So, returning to the serialization. I believe commands are still
serialized after this change.

The pic_run_work worker is only queued from .device_run.
Only one job can run on a context at any given time,
but multiple contexts can run in parallel.

Inside the worker, the coda_mutex serializes the commands.
The worker waits until the command has finished execution.

So, with this commit, there is no longer a worker, but commands
are still serialized by the mutex and the fact that the command
is completed in .device_run.

That being said, the worker does makes the serialization
more clear, so I think dropping this patch is better.

Perhaps adding a small comment so the purpose of pic_run_work
is clear.

Thanks,
Eze
Philipp Zabel April 29, 2019, 9:55 a.m. UTC | #3
On Fri, 2019-04-26 at 15:19 -0300, Ezequiel Garcia wrote:
> On Fri, 2019-04-26 at 10:11 +0200, Philipp Zabel wrote:
> > On Thu, 2019-04-25 at 15:35 -0300, Ezequiel Garcia wrote:
> > > There isn't any reason to run the mem2mem job on a separate worker,
> > > because the mem2mem framework guarantees that device_run will never
> > > run in interrupt context.
> > 
> > The purpose of the workqueue is to serialize BIT processor commands,
> > currently the PIC_RUN commands issued by the mem2mem framework (as well
> > as SEQ_INIT, SET_FRAME_BUF, and ENCODE_HEADER) against the SEQ_END
> > command issued directly from the STREAMOFF ioctl.
> 
> Right, but that's serialized by the coda_mutex, not by the worker, right?

Hmm, coda_start_decoding as called from .start_streaming is indeed just
serialized by the device coda_mutex. I would prefer this to be scheduled
as a work item as well though, those are way easier to reason about.

As an aside, while SEQ_INIT on its own is fast, technically
.start_streaming (or .buf_queue, see below) wouldn't even have to wait
until the SEQ_INIT command has finished, in case the BIT processor is
busy decoding for another context.

> > Further, to fully support the stateful decoder API we'll have to move
> > SEQ_INIT out of the mem2mem device_run as well, since that should be
> > called on queued OUTPUT buffers before the CAPTURE side is even
> > streaming.
> 
> Isn't that already done? I see SEQ_INIT being issued in start_streaming.
> In what sense is this driver currently violating the decoder spec?

I suppose it should try SEQ_INIT on every OUTPUT .buf_queue as long as
initialization hasn't succeeded, not only on .start_streaming of the
second queue (whichever is last). Right now, the buffers fed into the
output queue before STREAMON on both OUTPUT and CAPTURE must already
contain headers, or stream start will fail.

> So, returning to the serialization. I believe commands are still
> serialized after this change.

While I'm not sure if any odd corner cases could still arise with this
change, I think you are right. I remember having a few deadlock issues
with the locking before adding the workqueue, but that was before we
could just wait for the device to finish in .device_run.

> The pic_run_work worker is only queued from .device_run.
> Only one job can run on a context at any given time,
> but multiple contexts can run in parallel.
> 
> Inside the worker, the coda_mutex serializes the commands.
> The worker waits until the command has finished execution.
> 
> So, with this commit, there is no longer a worker, but commands
> are still serialized by the mutex and the fact that the command
> is completed in .device_run.
> 
> That being said, the worker does makes the serialization
> more clear, so I think dropping this patch is better.

I agree with both analysis and conclusion.

> Perhaps adding a small comment so the purpose of pic_run_work
> is clear.

Yes, that is a good idea.

regards
Philipp
diff mbox series

Patch

diff --git a/drivers/media/platform/coda/coda-common.c b/drivers/media/platform/coda/coda-common.c
index 617d4547ec82..e0227593a649 100644
--- a/drivers/media/platform/coda/coda-common.c
+++ b/drivers/media/platform/coda/coda-common.c
@@ -1306,14 +1306,6 @@  static void coda_device_run(void *m2m_priv)
 {
 	struct coda_ctx *ctx = m2m_priv;
 	struct coda_dev *dev = ctx->dev;
-
-	queue_work(dev->workqueue, &ctx->pic_run_work);
-}
-
-static void coda_pic_run_work(struct work_struct *work)
-{
-	struct coda_ctx *ctx = container_of(work, struct coda_ctx, pic_run_work);
-	struct coda_dev *dev = ctx->dev;
 	int ret;
 
 	mutex_lock(&ctx->buffer_mutex);
@@ -2233,7 +2225,6 @@  static int coda_open(struct file *file)
 	ctx->ops = ctx->cvd->ops;
 	ctx->use_bit = !ctx->cvd->direct;
 	init_completion(&ctx->completion);
-	INIT_WORK(&ctx->pic_run_work, coda_pic_run_work);
 	if (ctx->ops->seq_end_work)
 		INIT_WORK(&ctx->seq_end_work, ctx->ops->seq_end_work);
 	v4l2_fh_init(&ctx->fh, video_devdata(file));
diff --git a/drivers/media/platform/coda/coda.h b/drivers/media/platform/coda/coda.h
index 31c80bda2c0b..6870edeb6324 100644
--- a/drivers/media/platform/coda/coda.h
+++ b/drivers/media/platform/coda/coda.h
@@ -194,7 +194,6 @@  struct coda_context_ops {
 struct coda_ctx {
 	struct coda_dev			*dev;
 	struct mutex			buffer_mutex;
-	struct work_struct		pic_run_work;
 	struct work_struct		seq_end_work;
 	struct completion		completion;
 	const struct coda_video_device	*cvd;