Linux-Rockchip Archive on lore.kernel.org
 help / color / mirror / Atom feed
From: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
To: Tomasz Figa <tfiga@chromium.org>
Cc: kernel@collabora.com,
	Dafna Hirschfeld <dafna.hirschfeld@collabora.com>,
	Ezequiel Garcia <ezequiel@collabora.com>,
	Dafna Hirschfeld <dafna3@gmail.com>,
	Hans Verkuil <hverkuil@xs4all.nl>,
	"open list:ARM/Rockchip SoC..."
	<linux-rockchip@lists.infradead.org>,
	Helen Koike <helen.koike@collabora.com>,
	Sakari Ailus <sakari.ailus@linux.intel.com>,
	Mauro Carvalho Chehab <mchehab@kernel.org>,
	Robin Murphy <robin.murphy@arm.com>,
	Linux Media Mailing List <linux-media@vger.kernel.org>
Subject: Re: [PATCH 3/3] media: staging: rkisp1: params: in 'stop_streaming' don't release the lock while returning buffers
Date: Thu, 13 Aug 2020 16:09:50 +0300	[thread overview]
Message-ID: <20200813130950.GI6057@pendragon.ideasonboard.com> (raw)
In-Reply-To: <CAAFQd5BQWMnpaM4DtACTVyNuSLS4c5-zvy4UQmmoyGHRpw7n8g@mail.gmail.com>

Hi Tomasz,

On Thu, Aug 13, 2020 at 03:05:09PM +0200, Tomasz Figa wrote:
> On Thu, Aug 13, 2020 at 3:02 PM Laurent Pinchart wrote:
> > On Thu, Aug 13, 2020 at 02:50:17PM +0200, Tomasz Figa wrote:
> >> On Thu, Aug 13, 2020 at 12:53 PM Laurent Pinchart wrote:
> >>> On Thu, Aug 13, 2020 at 12:44:35PM +0200, Dafna Hirschfeld wrote:
> >>>> Am 26.06.20 um 18:58 schrieb Robin Murphy:
> >>>>> On 2020-06-26 16:59, Tomasz Figa wrote:
> >>>>>> On Fri, Jun 26, 2020 at 5:48 PM Dafna Hirschfeld wrote:
> >>>>>>> On 26.06.20 16:03, Tomasz Figa wrote:
> >>>>>>>> On Fri, Jun 26, 2020 at 3:32 PM Robin Murphy wrote:
> >>>>>>>>> On 2020-06-25 18:42, Dafna Hirschfeld wrote:
> >>>>>>>>>> In the stop_streaming callback 'rkisp1_params_vb2_stop_streaming'
> >>>>>>>>>> there is no need to release the lock 'config_lock' and then acquire
> >>>>>>>>>> it again at each iteration when returning all buffers.
> >>>>>>>>>> This is because the stream is about to end and there is no need
> >>>>>>>>>> to let the isr access a buffer.
> >>>>>>>>>>
> >>>>>>>>>> Signed-off-by: Dafna Hirschfeld <dafna.hirschfeld@collabora.com>
> >>>>>>>>>> ---
> >>>>>>>>>>     drivers/staging/media/rkisp1/rkisp1-params.c | 7 +------
> >>>>>>>>>>     1 file changed, 1 insertion(+), 6 deletions(-)
> >>>>>>>>>>
> >>>>>>>>>> diff --git a/drivers/staging/media/rkisp1/rkisp1-params.c b/drivers/staging/media/rkisp1/rkisp1-params.c
> >>>>>>>>>> index bf006dbeee2d..5169b02731f1 100644
> >>>>>>>>>> --- a/drivers/staging/media/rkisp1/rkisp1-params.c
> >>>>>>>>>> +++ b/drivers/staging/media/rkisp1/rkisp1-params.c
> >>>>>>>>>> @@ -1488,19 +1488,13 @@ static void rkisp1_params_vb2_stop_streaming(struct vb2_queue *vq)
> >>>>>>>>>>         /* stop params input firstly */
> >>>>>>>>>>         spin_lock_irqsave(&params->config_lock, flags);
> >>>>>>>>>>         params->is_streaming = false;
> >>>>>>>>>> -     spin_unlock_irqrestore(&params->config_lock, flags);
> >>>>>>>>>>
> >>>>>>>>>>         for (i = 0; i < RKISP1_ISP_PARAMS_REQ_BUFS_MAX; i++) {
> >>>>>>>>>> -             spin_lock_irqsave(&params->config_lock, flags);
> >>>>>>>>>>                 if (!list_empty(&params->params)) {
> >>>>>>>>>>                         buf = list_first_entry(&params->params,
> >>>>>>>>>>                                                struct rkisp1_buffer, queue);
> >>>>>>>>>>                         list_del(&buf->queue);
> >>>>>>>>>> -                     spin_unlock_irqrestore(&params->config_lock,
> >>>>>>>>>> -                                            flags);
> >>>>>>>>>>                 } else {
> >>>>>>>>>> -                     spin_unlock_irqrestore(&params->config_lock,
> >>>>>>>>>> -                                            flags);
> >>>>>>>>>>                         break;
> >>>>>>>>>>                 }
> >>>>>>>>>
> >>>>>>>>> Just skimming through out of idle curiosity I was going to comment that
> >>>>>>>>> if you end up with this pattern:
> >>>>>>>>>
> >>>>>>>>>           if (!x) {
> >>>>>>>>>                   //do stuff
> >>>>>>>>>           } else {
> >>>>>>>>>                   break;
> >>>>>>>>>           }
> >>>>>>>>>
> >>>>>>>>> it would be better as:
> >>>>>>>>>
> >>>>>>>>>           if (x)
> >>>>>>>>>                   break;
> >>>>>>>>>           //do stuff
> >>>>>>>>>
> >>>>>>>>> However I then went and looked at the whole function and frankly it's a
> >>>>>>>>> bit of a WTF. As best I could decipher, this whole crazy loop appears to
> >>>>>>>>> be a baroque reinvention of:
> >>>>>>>>>
> >>>>>>>>>           list_for_each_entry_safe(&params->params, ..., buf) {
> >>>>>>>>>                   list_del(&buf->queue);
> >>>>>>>>>                   vb2_buffer_done(&buf->vb.vb2_buf, VB2_BUF_STATE_ERROR);
> >>>>>>>>>           }
> >>>>>>> Hi, indeed this is a much simpler implementation, greping 'return_all_buffers'
> >>>>>>> I see that many drivers implement it this way.
> >>>>>>> thanks!
> >>>>>>>
> >>>>>>>>>
> >>>>>>>>> (assuming from context that the list should never contain more than
> >>>>>>>>> RKISP1_ISP_PARAMS_REQ_BUFS_MAX entries in the first place)
> >>>>>>>>
> >>>>>>>> Or if we want to avoid disabling the interrupts for the whole
> >>>>>>>> iteration, we could use list_splice() to move all the entries of
> >>>>>>>
> >>>>>>> But this code runs when userspace asks to stop the streaming so I don't
> >>>>>>> think it is important at that stage to allow the interrupts.
> >>>>>>
> >>>>>> It's generally a good practice to reduce the time spent with
> >>>>>> interrupts disabled. Disabling the interrupts prevents the system from
> >>>>>> handling external events, including timer interrupts, and scheduling
> >>>>>> higher priority tasks, including real time ones. How much the system
> >>>>>> runs with interrupts disabled is one of the factors determining the
> >>>>>> general system latency.
> >>>>>
> >>>>> Right, with the way we handle interrupt affinity on Arm an IRQ can't
> >>>>> target multiple CPUs in hardware, so any time spent with IRQs
> >>>>> disabled might be preventing other devices' interrupts from being
> >>>>> taken even if they're not explicitly affine to the current CPU.
> >>>>>
> >>>>> Now that I've looked, it appears that vb2_buffer_done() might end up
> >>>>> performing a DMA sync on the buffers, which, if it has to do
> >>>>> order-of-megabytes worth of cache maintenance for large frames, is
> >>>>> the kind of relatively slow operation that really doesn't want to be
> >>>>> done with IRQs disabled (or under a lock at all, ideally) unless it
> >>>>> absolutely *has* to be. If the lock is only needed here to protect
> >>>>> modifications to the params list itself, then moving the whole list
> >>>>> at once to do the cleanup "offline" sounds like a great idea to me.
> >>>
> >>> Ouch.
> >>>
> >>>> ok, that might be a problem in v4l2 in general since vb2_buffer_done
> >>>> is actually often used inside an irq handler
> >>>
> >>> Correct. The DMA sync should be moved to DQBUF time, there shouldn't be
> >>> any reason to do it in the IRQ handler. I thought this had already been
> >>> fixed :-(
> >>
> >> For reference, there was a patch [1] proposed, but it moved the
> >> synchronization to a wrong place in the sequence, already after the
> >> .buf_finish queue callback, ending up breaking the drivers which need
> >> to access the buffer contents there.
> >>
> >> [1] https://patchwork.linuxtv.org/project/linux-media/patch/1494255810-12672-4-git-send-email-sakari.ailus@linux.intel.com/
> >
> > I think we need to fix the drivers. We just can't do cache sync in IRQ
> > context by default because a few drivers need to access the buffer
> > contents. Those drivers should instead deffer access to a work queue,
> > and sync explicitly. We could possibly provide helpers for that, making
> > it transparent if a queue flag is set.
> 
> The drivers don't access the buffers explicitly from the IRQ. The vb2
> queue .buf_finish callback is called at DQBUF time. It was just the
> patch mentioned that moved it to a part of DQBUF executed too late.

Aahhh it's better than I thought :-) Shouldn't be too hard to fix then.
Thanks for refreshing my memory.

-- 
Regards,

Laurent Pinchart

_______________________________________________
Linux-rockchip mailing list
Linux-rockchip@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-rockchip

  reply	other threads:[~2020-08-13 13:10 UTC|newest]

Thread overview: 19+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-06-25 17:42 [PATCH 0/3] media: staging: rkisp1: various bug fixes in params Dafna Hirschfeld
2020-06-25 17:42 ` [PATCH 1/3] media: staging: rkisp1: params: don't reference the vb2 buffer after calling vb2_buffer_done Dafna Hirschfeld
2020-06-26 17:02   ` Helen Koike
2020-06-25 17:42 ` [PATCH 2/3] media: staging: rkisp1: params: don't release lock in isr before buffer is done Dafna Hirschfeld
2020-06-26 17:20   ` Helen Koike
2020-06-25 17:42 ` [PATCH 3/3] media: staging: rkisp1: params: in 'stop_streaming' don't release the lock while returning buffers Dafna Hirschfeld
2020-06-26 13:32   ` Robin Murphy
2020-06-26 14:03     ` Tomasz Figa
2020-06-26 15:48       ` Dafna Hirschfeld
2020-06-26 15:59         ` Tomasz Figa
2020-06-26 16:58           ` Robin Murphy
2020-08-13 10:44             ` Dafna Hirschfeld
2020-08-13 10:53               ` Laurent Pinchart
2020-08-13 12:50                 ` Tomasz Figa
2020-08-13 13:02                   ` Laurent Pinchart
2020-08-13 13:05                     ` Tomasz Figa
2020-08-13 13:09                       ` Laurent Pinchart [this message]
2020-08-14 11:04       ` Dafna Hirschfeld
2020-08-14 11:23         ` Tomasz Figa

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20200813130950.GI6057@pendragon.ideasonboard.com \
    --to=laurent.pinchart@ideasonboard.com \
    --cc=dafna.hirschfeld@collabora.com \
    --cc=dafna3@gmail.com \
    --cc=ezequiel@collabora.com \
    --cc=helen.koike@collabora.com \
    --cc=hverkuil@xs4all.nl \
    --cc=kernel@collabora.com \
    --cc=linux-media@vger.kernel.org \
    --cc=linux-rockchip@lists.infradead.org \
    --cc=mchehab@kernel.org \
    --cc=robin.murphy@arm.com \
    --cc=sakari.ailus@linux.intel.com \
    --cc=tfiga@chromium.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox