From: Sowjanya Komatineni <skomatineni@nvidia.com>
To: Dmitry Osipenko <digetx@gmail.com>, <thierry.reding@gmail.com>,
<jonathanh@nvidia.com>, <frankc@nvidia.com>, <hverkuil@xs4all.nl>,
<sakari.ailus@iki.fi>, <helen.koike@collabora.com>
Cc: <sboyd@kernel.org>, <linux-media@vger.kernel.org>,
<devicetree@vger.kernel.org>, <linux-clk@vger.kernel.org>,
<linux-tegra@vger.kernel.org>, <linux-kernel@vger.kernel.org>
Subject: Re: [RFC PATCH v11 6/9] media: tegra: Add Tegra210 Video input driver
Date: Sat, 2 May 2020 10:04:01 -0700 [thread overview]
Message-ID: <605fc688-7712-cdfd-9d12-5741b984bb68@nvidia.com> (raw)
In-Reply-To: <5d847770-dad9-8f18-67b5-c1ba79084957@nvidia.com>
On 5/2/20 9:55 AM, Sowjanya Komatineni wrote:
>
> On 5/2/20 9:14 AM, Sowjanya Komatineni wrote:
>>
>> On 5/2/20 9:03 AM, Sowjanya Komatineni wrote:
>>>
>>> On 5/2/20 8:38 AM, Sowjanya Komatineni wrote:
>>>>
>>>> On 5/2/20 8:16 AM, Dmitry Osipenko wrote:
>>>>> 02.05.2020 06:55, Sowjanya Komatineni пишет:
>>>>>> On 5/1/20 8:39 PM, Sowjanya Komatineni wrote:
>>>>>>>
>>>>>>> On 5/1/20 2:05 PM, Sowjanya Komatineni wrote:
>>>>>>>>
>>>>>>>> On 5/1/20 1:58 PM, Sowjanya Komatineni wrote:
>>>>>>>>>
>>>>>>>>> On 5/1/20 1:44 PM, Sowjanya Komatineni wrote:
>>>>>>>>>>
>>>>>>>>>> On 5/1/20 11:03 AM, Sowjanya Komatineni wrote:
>>>>>>>>>>>
>>>>>>>>>>> On 4/30/20 4:33 PM, Sowjanya Komatineni wrote:
>>>>>>>>>>>>
>>>>>>>>>>>> On 4/30/20 4:14 PM, Sowjanya Komatineni wrote:
>>>>>>>>>>>>>>>>>>> And in this case synchronization between start/finish
>>>>>>>>>>>>>>>>>>> threads should be
>>>>>>>>>>>>>>>>>>> needed in regards to freezing.
>>>>>>>>>>>>>>>>>> Was thinking to have counter to track outstanding frame
>>>>>>>>>>>>>>>>>> w.r.t single shot issue b/w start and finish and
>>>>>>>>>>>>>>>>>> allow to
>>>>>>>>>>>>>>>>>> freeze only when no outstanding frames in process.
>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>> This will make sure freeze will not happen when any
>>>>>>>>>>>>>>>>>> buffers
>>>>>>>>>>>>>>>>>> are in progress
>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>> Note that this could be a wrong assumption, I'm not
>>>>>>>>>>>>>>>>>>> closely familiar
>>>>>>>>>>>>>>>>>>> with how freezer works.
>>>>>>>>>>>>>>>>> kthread_start can unconditionally allow try_to_freeze
>>>>>>>>>>>>>>>>> before
>>>>>>>>>>>>>>>>> start of frame capture
>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>> We can compute captures inflight w.r.t single shot issued
>>>>>>>>>>>>>>>>> during capture start and finished frames by
>>>>>>>>>>>>>>>>> kthread_finish
>>>>>>>>>>>>>>>>> and allow kthread_finish to freeze only when captures
>>>>>>>>>>>>>>>>> inflight is 0.
>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>> This allows freeze to happen b/w frames but not in
>>>>>>>>>>>>>>>>> middle of
>>>>>>>>>>>>>>>>> frame
>>>>>>>>>>>>>> will have caps inflight check in v12 to allow freeze finish
>>>>>>>>>>>>>> thread only when no captures are in progress
>>>>>>>>>>>>>
>>>>>>>>>>>>> try_to_freeze() returns thread frozen state and looks like we
>>>>>>>>>>>>> can use this in kthread finish to allow finish thread to
>>>>>>>>>>>>> freeze
>>>>>>>>>>>>> only when kthread_start is already frozen and no buffers in
>>>>>>>>>>>>> progress/initiated for capture.
>>>>>>>>>>>>>
>>>>>>>>>>>> chan->capture_frozen holds frozen state returned from
>>>>>>>>>>>> try_to_freeze() in start kthread
>>>>>>>>>>>>
>>>>>>>>>>>> chan->capture_reqs increments after every single shot issued.
>>>>>>>>>>>>
>>>>>>>>>>>>
>>>>>>>>>>>> static int chan_capture_kthread_finish(void *data)
>>>>>>>>>>>>
>>>>>>>>>>>> {
>>>>>>>>>>>> struct tegra_vi_channel *chan = data;
>>>>>>>>>>>> struct tegra_channel_buffer *buf;
>>>>>>>>>>>> int caps_inflight;
>>>>>>>>>>>>
>>>>>>>>>>>> set_freezable();
>>>>>>>>>>>>
>>>>>>>>>>>> while (1) {
>>>>>>>>>>>> wait_event_interruptible(chan->done_wait,
>>>>>>>>>>>> !list_empty(&chan->done) ||
>>>>>>>>>>>> kthread_should_stop());
>>>>>>>>>>>>
>>>>>>>>>>>> /* dequeue buffers and finish capture */
>>>>>>>>>>>> buf = dequeue_buf_done(chan);
>>>>>>>>>>>> while (buf) {
>>>>>>>>>>>> tegra_channel_capture_done(chan, buf);
>>>>>>>>>>>> buf = dequeue_buf_done(chan);
>>>>>>>>>>>> }
>>>>>>>>>>>>
>>>>>>>>>>>> if (kthread_should_stop())
>>>>>>>>>>>> break;
>>>>>>>>>>>>
>>>>>>>>>>>> caps_inflight = chan->capture_reqs - chan->sequence;
>>>>>>>>>>>> if (chan->capture_frozen && !caps_inflight)
>>>>>>>>>>>> try_to_freeze();
>>>>>>>>>>>> }
>>>>>>>>>>>>
>>>>>>>>>>>> return 0;
>>>>>>>>>>>> }
>>>>>>>>>>>
>>>>>>>>>>> Freezing happens prior to suspend() during suspend entry and
>>>>>>>>>>> when
>>>>>>>>>>> we implement suspend/resume during suspend we stop streaming
>>>>>>>>>>> where
>>>>>>>>>>> we stop threads anyway.
>>>>>>>>>>>
>>>>>>>>>>> So, was thinking why we need these threads freezable here?
>>>>>>>>>>>
>>>>>>>>>>>
>>>>>>>>>> Hi Dmitry,
>>>>>>>>>>
>>>>>>>>>> Did some testing and below are latest observation and fix I
>>>>>>>>>> tested.
>>>>>>>>>>
>>>>>>>>>> wait_event_interruptible() uses schedule() which blocks the
>>>>>>>>>> freezer.
>>>>>>>>>> When I do suspend while keeping streaming active in
>>>>>>>>>> background, I
>>>>>>>>>> see freezing of these threads fail and call trace shows
>>>>>>>>>> __schedule
>>>>>>>>>> -> __switch_to from these kthreads.
>>>>>>>>>>
>>>>>>>>>> wait_event_freezable() uses freezable_schedule() which should
>>>>>>>>>> not
>>>>>>>>>> block the freezer but we can't use this here as we need
>>>>>>>>>> conditional
>>>>>>>>>> try_to_freeze().
>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>> So, doing below sequence works where we set PF_FREEZER_SKIP flag
>>>>>>>>>> thru freezer_not_count() before wait_event which calls
>>>>>>>>>> schedule()
>>>>>>>>>> and remove PF_FREEZER_SKIP after schedule allows
>>>>>>>>>> try_to_freeze to
>>>>>>>>>> work and also conditional try_to_freeze below prevents freezing
>>>>>>>>>> thread in middle of capture.
>>>>>>>>>>
>>>>>>>>>> while (1) {
>>>>>>>>>> freezer_not_count()
>>>>>>>>>> wait_event_interruptible()
>>>>>>>>>> freezer_count()
>>>>>>>>>> ...
>>>>>>>>>> ...
>>>>>>>>>> if (chan->capture_frozen && !caps_inflight)
>>>>>>>>>> try_to_freeze()
>>>>>>>>>> }
>>>>>>>>>>
>>>>>>>>>> Please comment if you agree with above sequence. Will include
>>>>>>>>>> this
>>>>>>>>>> in v12.
>>>>>>>>>>
>>>>>>>> sorry, freezer_count() does try_to_freeze after clearing skip
>>>>>>>> flag.
>>>>>>>> So, dont think we can use this as we need conditional
>>>>>>>> try_to_freeze.
>>>>>>>> Please ignore above sequence.
>>>>>>>>> Or probably we can take closer look on this later when we add
>>>>>>>>> suspend/resume support as it need more testing as well.
>>>>>>>>>
>>>>>>>>> As this is initial series which has TPG only I think we shouldn't
>>>>>>>>> get blocked on this now. Series-2 and 3 will be for sensor
>>>>>>>>> support
>>>>>>>>> and on next series when we add suspend/resume will look into
>>>>>>>>> this.
>>>>>>>>>
>>>>>>>>>
>>>>>>> When freeze activity starts and in case if finish thread freezes
>>>>>>> prior
>>>>>>> to start thread issuing capture, its the VI hardware writes data to
>>>>>>> the allocated buffer address.
>>>>>>>
>>>>>>> finish thread just checks for the event from the hardware and we
>>>>>>> don't
>>>>>>> handle/process directly on memory in this driver.
>>>>>>>
>>>>>>> So even we freeze done thread when single shot is issued frame
>>>>>>> buffer
>>>>>>> gets updated.
>>>>>>>
>>>>>>> In case if capture thread is frozen there will not buffers
>>>>>>> queued to
>>>>>>> process by finish thread. So, this will not be an issue.
>>>>>>>
>>>>>>> So, probably we don't need to do conditional try_to_freeze and
>>>>>>> what we
>>>>>>> have should work good in this corner case.
>>>>>>>
>>>>>> I still need to change wait_event_interruptible() to
>>>>>> wait_event_freezable() but no need to synchronize finish thread
>>>>>> freeze
>>>>>> with start thread as even on issuing capture start its vi
>>>>>> hardware that
>>>>>> does frame buffer update and finish thread just checks for mw_ack
>>>>>> event
>>>>>> and returns buffer to application.
>>>>> The problem we are primarily trying to avoid is to have suspending
>>>>> being
>>>>> done in the middle of IO.
>>>>>
>>>>> IIUC, even if system will be suspended in the middle of VI IO, it
>>>>> won't
>>>>> be fatal. In worst case the buffer capture should fail on resume from
>>>>> suspend. Could you please try to simulate this potential issue and
>>>>> see
>>>>> what result will be on suspending in the middle of VI IO?
>>>>>
>>>>> We don't want to suspend system / stop streaming in the middle of
>>>>> IO, so
>>>>> this problem of a proper threads tear-down still exists. It should
>>>>> become easier to resolve the problem in a case of a proper suspending
>>>>> callback because the "start" thread could be turned down at any
>>>>> time, so
>>>>> it should be easier to maintain a proper tear-down order when threads
>>>>> are fully controlled by the driver, i.e. the "start" thread goes down
>>>>> first and the "finish" is second, blocking until the capture is
>>>>> completed.
>>>
>>> I don't see issue of tear-down threads in case of suspend as we do
>>> stop streaming where thread stop happens on both threads and are
>>> stopped only after processing all outstanding buffers.
>>>
>>> Regarding freezing activity during suspend, If done thread freezes
>>> prior to processing buffers for finish, vi hardware is still active
>>> by this time which will update the frame buffer for initiated
>>> capture. Driver is not directly involved in this frame buffer update.
>>>
>>> Finish thread only checks for completion to return buffers back to
>>> the application when done.
>>
>> when done thread freeze happens after start thread initiated capture,
>> vi hardware continues to update frame buffer for ongoing capture till
>> it hits driver suspend callback. Yes worst case this frame data may
>> not be valid data if invoking of this driver suspend happens
>> immediate after this thread freeze during system suspend.
>>
>> But driver will still hold buffers to return which will be returned
>> back on resume when threads are out from frozen state.
>
>
> Also stop stream ioctl request happens during suspend where both
> threads will be stopped properly. done thread stop happens only after
> finishing all outstanding buffers.
>
> Stop stream request happens from streaming applications so even
> without driver suspend/resume implementation currently, streaming will
> be stopped prior to system suspend where both threads will be stopped
> properly (after finishing out standing buffers) and will be resumed by
> application on system resume
>
> Also tested suspending while streaming with this unconditional freeze,
> I don't see any issue as application stops stream where v4l_streamoff
> gets executed during suspend and on resume streaming starts where
> v4l_streamon happens.
>
> So, I don't see any issue with existing implementation of
> unconditional freeze.
To be more clear,
suspend while streaming use case...
- start thread initiating capture
- done thread frozen (with outstanding buffers in process but vi
hardware still continues to update frame buffer)
- start thread frozen
application holding video device will issue stream off ioctl
- stop_streaming does kthread_stop
- threads wake up and start thread breaks and finish thread breaks after
checking outstanding buffers and returning to application
- vi/csi power/clocks off
on resume, application starts streaming again where fresh start stream
happens.
>
>>
>>>
>>>
>>>>> I think yours suggestion about dropping the freezing from the threads
>>>>> for now and returning back to it later on (once a proper
>>>>> suspend/resume
>>>>> support will be added) sounds reasonable.
>>>>>
>>>>> But if you'd want to keep the freezing, then the easy solution
>>>>> could be
>>>>> like that:
>>>>>
>>>>> 1. "start" thread could freeze at any time
>>>>> 2. "finish" thread could freeze only when the "start" thread is
>>>>> frozen
>>>>> and capture isn't in-progress. Use frozen(kthread_start_capture) to
>>>>> check the freezing state.
>>>>>
>>>>> https://elixir.bootlin.com/linux/v5.7-rc3/source/include/linux/freezer.h#L25
>>>>>
>>>>
>>>> That's exactly what I tried, below is the snippet.
>>>>
>>>> But as mentioned I am seeing freezing fail when I
>>>> wait_event_interruptible() in either of the threads.
>>>>
>>>> 60.368709] Call trace:
>>>> [ 60.371216] __switch_to+0xec/0x140
>>>> [ 60.374768] __schedule+0x32c/0x668
>>>> [ 60.378315] schedule+0x78/0x118
>>>> [ 60.381606] chan_capture_kthread_finish+0x244/0x2a0 [tegra_video]
>>>> [ 60.387865] kthread+0x124/0x150
>>>> [ 60.391150] ret_from_fork+0x10/0x1c
>>>>
>>>> wait_event_interruptible() API uses schedule() which blocks freezer
>>>> while wait_event_freezable APIs uses freezable_schedule() which
>>>> allows to skip freezer during schedule and then clears skip and
>>>> calls try_to_freeze()
>>>>
>>>> But we can't use wait_event_freezable() here as we need conditional
>>>> freeze.
>>>>
>>>>
>>>> while (1) {
>>>> caps_inflight = chan->capture_reqs - chan->sequence;
>>>> if (frozen(chan->kthread_start_capture) && !caps_inflight)
>>>> wait_event_freezable(chan->done_wait,
>>>> !list_empty(&chan->done) ||
>>>> kthread_should_stop());
>>>> else
>>>> wait_event_interruptible(chan->done_wait,
>>>> !list_empty(&chan->done) ||
>>>> kthread_should_stop());
>>>>
>>>> /* dequeue buffers and finish capture */
>>>>
>>>> ...
>>>>
>>>> ...
>>>>
>>>>
>>>> if (kthread_should_stop())
>>>> break;
>>>> }
>>>>
>
WARNING: multiple messages have this Message-ID (diff)
From: Sowjanya Komatineni <skomatineni@nvidia.com>
To: Dmitry Osipenko <digetx@gmail.com>,
thierry.reding@gmail.com, jonathanh@nvidia.com,
frankc@nvidia.com, hverkuil@xs4all.nl, sakari.ailus@iki.fi,
helen.koike@collabora.com
Cc: sboyd@kernel.org, linux-media@vger.kernel.org,
devicetree@vger.kernel.org, linux-clk@vger.kernel.org,
linux-tegra@vger.kernel.org, linux-kernel@vger.kernel.org
Subject: Re: [RFC PATCH v11 6/9] media: tegra: Add Tegra210 Video input driver
Date: Sat, 2 May 2020 10:04:01 -0700 [thread overview]
Message-ID: <605fc688-7712-cdfd-9d12-5741b984bb68@nvidia.com> (raw)
In-Reply-To: <5d847770-dad9-8f18-67b5-c1ba79084957@nvidia.com>
On 5/2/20 9:55 AM, Sowjanya Komatineni wrote:
>
> On 5/2/20 9:14 AM, Sowjanya Komatineni wrote:
>>
>> On 5/2/20 9:03 AM, Sowjanya Komatineni wrote:
>>>
>>> On 5/2/20 8:38 AM, Sowjanya Komatineni wrote:
>>>>
>>>> On 5/2/20 8:16 AM, Dmitry Osipenko wrote:
>>>>> 02.05.2020 06:55, Sowjanya Komatineni пишет:
>>>>>> On 5/1/20 8:39 PM, Sowjanya Komatineni wrote:
>>>>>>>
>>>>>>> On 5/1/20 2:05 PM, Sowjanya Komatineni wrote:
>>>>>>>>
>>>>>>>> On 5/1/20 1:58 PM, Sowjanya Komatineni wrote:
>>>>>>>>>
>>>>>>>>> On 5/1/20 1:44 PM, Sowjanya Komatineni wrote:
>>>>>>>>>>
>>>>>>>>>> On 5/1/20 11:03 AM, Sowjanya Komatineni wrote:
>>>>>>>>>>>
>>>>>>>>>>> On 4/30/20 4:33 PM, Sowjanya Komatineni wrote:
>>>>>>>>>>>>
>>>>>>>>>>>> On 4/30/20 4:14 PM, Sowjanya Komatineni wrote:
>>>>>>>>>>>>>>>>>>> And in this case synchronization between start/finish
>>>>>>>>>>>>>>>>>>> threads should be
>>>>>>>>>>>>>>>>>>> needed in regards to freezing.
>>>>>>>>>>>>>>>>>> Was thinking to have counter to track outstanding frame
>>>>>>>>>>>>>>>>>> w.r.t single shot issue b/w start and finish and
>>>>>>>>>>>>>>>>>> allow to
>>>>>>>>>>>>>>>>>> freeze only when no outstanding frames in process.
>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>> This will make sure freeze will not happen when any
>>>>>>>>>>>>>>>>>> buffers
>>>>>>>>>>>>>>>>>> are in progress
>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>> Note that this could be a wrong assumption, I'm not
>>>>>>>>>>>>>>>>>>> closely familiar
>>>>>>>>>>>>>>>>>>> with how freezer works.
>>>>>>>>>>>>>>>>> kthread_start can unconditionally allow try_to_freeze
>>>>>>>>>>>>>>>>> before
>>>>>>>>>>>>>>>>> start of frame capture
>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>> We can compute captures inflight w.r.t single shot issued
>>>>>>>>>>>>>>>>> during capture start and finished frames by
>>>>>>>>>>>>>>>>> kthread_finish
>>>>>>>>>>>>>>>>> and allow kthread_finish to freeze only when captures
>>>>>>>>>>>>>>>>> inflight is 0.
>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>> This allows freeze to happen b/w frames but not in
>>>>>>>>>>>>>>>>> middle of
>>>>>>>>>>>>>>>>> frame
>>>>>>>>>>>>>> will have caps inflight check in v12 to allow freeze finish
>>>>>>>>>>>>>> thread only when no captures are in progress
>>>>>>>>>>>>>
>>>>>>>>>>>>> try_to_freeze() returns thread frozen state and looks like we
>>>>>>>>>>>>> can use this in kthread finish to allow finish thread to
>>>>>>>>>>>>> freeze
>>>>>>>>>>>>> only when kthread_start is already frozen and no buffers in
>>>>>>>>>>>>> progress/initiated for capture.
>>>>>>>>>>>>>
>>>>>>>>>>>> chan->capture_frozen holds frozen state returned from
>>>>>>>>>>>> try_to_freeze() in start kthread
>>>>>>>>>>>>
>>>>>>>>>>>> chan->capture_reqs increments after every single shot issued.
>>>>>>>>>>>>
>>>>>>>>>>>>
>>>>>>>>>>>> static int chan_capture_kthread_finish(void *data)
>>>>>>>>>>>>
>>>>>>>>>>>> {
>>>>>>>>>>>> struct tegra_vi_channel *chan = data;
>>>>>>>>>>>> struct tegra_channel_buffer *buf;
>>>>>>>>>>>> int caps_inflight;
>>>>>>>>>>>>
>>>>>>>>>>>> set_freezable();
>>>>>>>>>>>>
>>>>>>>>>>>> while (1) {
>>>>>>>>>>>> wait_event_interruptible(chan->done_wait,
>>>>>>>>>>>> !list_empty(&chan->done) ||
>>>>>>>>>>>> kthread_should_stop());
>>>>>>>>>>>>
>>>>>>>>>>>> /* dequeue buffers and finish capture */
>>>>>>>>>>>> buf = dequeue_buf_done(chan);
>>>>>>>>>>>> while (buf) {
>>>>>>>>>>>> tegra_channel_capture_done(chan, buf);
>>>>>>>>>>>> buf = dequeue_buf_done(chan);
>>>>>>>>>>>> }
>>>>>>>>>>>>
>>>>>>>>>>>> if (kthread_should_stop())
>>>>>>>>>>>> break;
>>>>>>>>>>>>
>>>>>>>>>>>> caps_inflight = chan->capture_reqs - chan->sequence;
>>>>>>>>>>>> if (chan->capture_frozen && !caps_inflight)
>>>>>>>>>>>> try_to_freeze();
>>>>>>>>>>>> }
>>>>>>>>>>>>
>>>>>>>>>>>> return 0;
>>>>>>>>>>>> }
>>>>>>>>>>>
>>>>>>>>>>> Freezing happens prior to suspend() during suspend entry and
>>>>>>>>>>> when
>>>>>>>>>>> we implement suspend/resume during suspend we stop streaming
>>>>>>>>>>> where
>>>>>>>>>>> we stop threads anyway.
>>>>>>>>>>>
>>>>>>>>>>> So, was thinking why we need these threads freezable here?
>>>>>>>>>>>
>>>>>>>>>>>
>>>>>>>>>> Hi Dmitry,
>>>>>>>>>>
>>>>>>>>>> Did some testing and below are latest observation and fix I
>>>>>>>>>> tested.
>>>>>>>>>>
>>>>>>>>>> wait_event_interruptible() uses schedule() which blocks the
>>>>>>>>>> freezer.
>>>>>>>>>> When I do suspend while keeping streaming active in
>>>>>>>>>> background, I
>>>>>>>>>> see freezing of these threads fail and call trace shows
>>>>>>>>>> __schedule
>>>>>>>>>> -> __switch_to from these kthreads.
>>>>>>>>>>
>>>>>>>>>> wait_event_freezable() uses freezable_schedule() which should
>>>>>>>>>> not
>>>>>>>>>> block the freezer but we can't use this here as we need
>>>>>>>>>> conditional
>>>>>>>>>> try_to_freeze().
>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>> So, doing below sequence works where we set PF_FREEZER_SKIP flag
>>>>>>>>>> thru freezer_not_count() before wait_event which calls
>>>>>>>>>> schedule()
>>>>>>>>>> and remove PF_FREEZER_SKIP after schedule allows
>>>>>>>>>> try_to_freeze to
>>>>>>>>>> work and also conditional try_to_freeze below prevents freezing
>>>>>>>>>> thread in middle of capture.
>>>>>>>>>>
>>>>>>>>>> while (1) {
>>>>>>>>>> freezer_not_count()
>>>>>>>>>> wait_event_interruptible()
>>>>>>>>>> freezer_count()
>>>>>>>>>> ...
>>>>>>>>>> ...
>>>>>>>>>> if (chan->capture_frozen && !caps_inflight)
>>>>>>>>>> try_to_freeze()
>>>>>>>>>> }
>>>>>>>>>>
>>>>>>>>>> Please comment if you agree with above sequence. Will include
>>>>>>>>>> this
>>>>>>>>>> in v12.
>>>>>>>>>>
>>>>>>>> sorry, freezer_count() does try_to_freeze after clearing skip
>>>>>>>> flag.
>>>>>>>> So, dont think we can use this as we need conditional
>>>>>>>> try_to_freeze.
>>>>>>>> Please ignore above sequence.
>>>>>>>>> Or probably we can take closer look on this later when we add
>>>>>>>>> suspend/resume support as it need more testing as well.
>>>>>>>>>
>>>>>>>>> As this is initial series which has TPG only I think we shouldn't
>>>>>>>>> get blocked on this now. Series-2 and 3 will be for sensor
>>>>>>>>> support
>>>>>>>>> and on next series when we add suspend/resume will look into
>>>>>>>>> this.
>>>>>>>>>
>>>>>>>>>
>>>>>>> When freeze activity starts and in case if finish thread freezes
>>>>>>> prior
>>>>>>> to start thread issuing capture, its the VI hardware writes data to
>>>>>>> the allocated buffer address.
>>>>>>>
>>>>>>> finish thread just checks for the event from the hardware and we
>>>>>>> don't
>>>>>>> handle/process directly on memory in this driver.
>>>>>>>
>>>>>>> So even we freeze done thread when single shot is issued frame
>>>>>>> buffer
>>>>>>> gets updated.
>>>>>>>
>>>>>>> In case if capture thread is frozen there will not buffers
>>>>>>> queued to
>>>>>>> process by finish thread. So, this will not be an issue.
>>>>>>>
>>>>>>> So, probably we don't need to do conditional try_to_freeze and
>>>>>>> what we
>>>>>>> have should work good in this corner case.
>>>>>>>
>>>>>> I still need to change wait_event_interruptible() to
>>>>>> wait_event_freezable() but no need to synchronize finish thread
>>>>>> freeze
>>>>>> with start thread as even on issuing capture start its vi
>>>>>> hardware that
>>>>>> does frame buffer update and finish thread just checks for mw_ack
>>>>>> event
>>>>>> and returns buffer to application.
>>>>> The problem we are primarily trying to avoid is to have suspending
>>>>> being
>>>>> done in the middle of IO.
>>>>>
>>>>> IIUC, even if system will be suspended in the middle of VI IO, it
>>>>> won't
>>>>> be fatal. In worst case the buffer capture should fail on resume from
>>>>> suspend. Could you please try to simulate this potential issue and
>>>>> see
>>>>> what result will be on suspending in the middle of VI IO?
>>>>>
>>>>> We don't want to suspend system / stop streaming in the middle of
>>>>> IO, so
>>>>> this problem of a proper threads tear-down still exists. It should
>>>>> become easier to resolve the problem in a case of a proper suspending
>>>>> callback because the "start" thread could be turned down at any
>>>>> time, so
>>>>> it should be easier to maintain a proper tear-down order when threads
>>>>> are fully controlled by the driver, i.e. the "start" thread goes down
>>>>> first and the "finish" is second, blocking until the capture is
>>>>> completed.
>>>
>>> I don't see issue of tear-down threads in case of suspend as we do
>>> stop streaming where thread stop happens on both threads and are
>>> stopped only after processing all outstanding buffers.
>>>
>>> Regarding freezing activity during suspend, If done thread freezes
>>> prior to processing buffers for finish, vi hardware is still active
>>> by this time which will update the frame buffer for initiated
>>> capture. Driver is not directly involved in this frame buffer update.
>>>
>>> Finish thread only checks for completion to return buffers back to
>>> the application when done.
>>
>> when done thread freeze happens after start thread initiated capture,
>> vi hardware continues to update frame buffer for ongoing capture till
>> it hits driver suspend callback. Yes worst case this frame data may
>> not be valid data if invoking of this driver suspend happens
>> immediate after this thread freeze during system suspend.
>>
>> But driver will still hold buffers to return which will be returned
>> back on resume when threads are out from frozen state.
>
>
> Also stop stream ioctl request happens during suspend where both
> threads will be stopped properly. done thread stop happens only after
> finishing all outstanding buffers.
>
> Stop stream request happens from streaming applications so even
> without driver suspend/resume implementation currently, streaming will
> be stopped prior to system suspend where both threads will be stopped
> properly (after finishing out standing buffers) and will be resumed by
> application on system resume
>
> Also tested suspending while streaming with this unconditional freeze,
> I don't see any issue as application stops stream where v4l_streamoff
> gets executed during suspend and on resume streaming starts where
> v4l_streamon happens.
>
> So, I don't see any issue with existing implementation of
> unconditional freeze.
To be more clear,
suspend while streaming use case...
- start thread initiating capture
- done thread frozen (with outstanding buffers in process but vi
hardware still continues to update frame buffer)
- start thread frozen
application holding video device will issue stream off ioctl
- stop_streaming does kthread_stop
- threads wake up and start thread breaks and finish thread breaks after
checking outstanding buffers and returning to application
- vi/csi power/clocks off
on resume, application starts streaming again where fresh start stream
happens.
>
>>
>>>
>>>
>>>>> I think yours suggestion about dropping the freezing from the threads
>>>>> for now and returning back to it later on (once a proper
>>>>> suspend/resume
>>>>> support will be added) sounds reasonable.
>>>>>
>>>>> But if you'd want to keep the freezing, then the easy solution
>>>>> could be
>>>>> like that:
>>>>>
>>>>> 1. "start" thread could freeze at any time
>>>>> 2. "finish" thread could freeze only when the "start" thread is
>>>>> frozen
>>>>> and capture isn't in-progress. Use frozen(kthread_start_capture) to
>>>>> check the freezing state.
>>>>>
>>>>> https://elixir.bootlin.com/linux/v5.7-rc3/source/include/linux/freezer.h#L25
>>>>>
>>>>
>>>> That's exactly what I tried, below is the snippet.
>>>>
>>>> But as mentioned I am seeing freezing fail when I
>>>> wait_event_interruptible() in either of the threads.
>>>>
>>>> 60.368709] Call trace:
>>>> [ 60.371216] __switch_to+0xec/0x140
>>>> [ 60.374768] __schedule+0x32c/0x668
>>>> [ 60.378315] schedule+0x78/0x118
>>>> [ 60.381606] chan_capture_kthread_finish+0x244/0x2a0 [tegra_video]
>>>> [ 60.387865] kthread+0x124/0x150
>>>> [ 60.391150] ret_from_fork+0x10/0x1c
>>>>
>>>> wait_event_interruptible() API uses schedule() which blocks freezer
>>>> while wait_event_freezable APIs uses freezable_schedule() which
>>>> allows to skip freezer during schedule and then clears skip and
>>>> calls try_to_freeze()
>>>>
>>>> But we can't use wait_event_freezable() here as we need conditional
>>>> freeze.
>>>>
>>>>
>>>> while (1) {
>>>> caps_inflight = chan->capture_reqs - chan->sequence;
>>>> if (frozen(chan->kthread_start_capture) && !caps_inflight)
>>>> wait_event_freezable(chan->done_wait,
>>>> !list_empty(&chan->done) ||
>>>> kthread_should_stop());
>>>> else
>>>> wait_event_interruptible(chan->done_wait,
>>>> !list_empty(&chan->done) ||
>>>> kthread_should_stop());
>>>>
>>>> /* dequeue buffers and finish capture */
>>>>
>>>> ...
>>>>
>>>> ...
>>>>
>>>>
>>>> if (kthread_should_stop())
>>>> break;
>>>> }
>>>>
>
next prev parent reply other threads:[~2020-05-02 17:04 UTC|newest]
Thread overview: 117+ messages / expand[flat|nested] mbox.gz Atom feed top
2020-04-29 21:59 [RFC PATCH v11 0/9] Add Tegra driver for video capture Sowjanya Komatineni
2020-04-29 21:59 ` Sowjanya Komatineni
2020-04-29 21:59 ` [RFC PATCH v11 1/9] arm64: tegra: Fix sor powergate clocks and reset Sowjanya Komatineni
2020-04-29 21:59 ` Sowjanya Komatineni
2020-04-29 21:59 ` [RFC PATCH v11 2/9] arm64: tegra: Add reset-cells to mc Sowjanya Komatineni
2020-04-29 21:59 ` Sowjanya Komatineni
2020-04-29 22:00 ` [RFC PATCH v11 3/9] dt-bindings: clock: tegra: Add clk id for CSI TPG clock Sowjanya Komatineni
2020-04-29 22:00 ` Sowjanya Komatineni
2020-04-29 22:00 ` [RFC PATCH v11 4/9] clk: tegra: Add Tegra210 CSI TPG clock gate Sowjanya Komatineni
2020-04-29 22:00 ` Sowjanya Komatineni
2020-04-29 22:00 ` [RFC PATCH v11 5/9] dt-binding: tegra: Add VI and CSI bindings Sowjanya Komatineni
2020-04-29 22:00 ` Sowjanya Komatineni
2020-04-29 22:00 ` [RFC PATCH v11 6/9] media: tegra: Add Tegra210 Video input driver Sowjanya Komatineni
2020-04-29 22:00 ` Sowjanya Komatineni
2020-04-30 13:34 ` Dmitry Osipenko
2020-04-30 19:27 ` Sowjanya Komatineni
2020-04-30 19:27 ` Sowjanya Komatineni
2020-04-30 13:38 ` Dmitry Osipenko
2020-04-30 13:38 ` Dmitry Osipenko
2020-04-30 19:32 ` Sowjanya Komatineni
2020-04-30 19:32 ` Sowjanya Komatineni
2020-04-30 19:47 ` Dmitry Osipenko
2020-04-30 19:51 ` Sowjanya Komatineni
2020-04-30 19:51 ` Sowjanya Komatineni
2020-04-30 13:43 ` Dmitry Osipenko
2020-04-30 13:46 ` Dmitry Osipenko
2020-04-30 13:46 ` Dmitry Osipenko
2020-04-30 13:56 ` Dmitry Osipenko
2020-04-30 13:56 ` Dmitry Osipenko
2020-04-30 14:02 ` Dmitry Osipenko
2020-04-30 14:02 ` Dmitry Osipenko
2020-04-30 14:13 ` Dmitry Osipenko
2020-04-30 14:13 ` Dmitry Osipenko
2020-04-30 16:04 ` Sowjanya Komatineni
2020-04-30 16:04 ` Sowjanya Komatineni
2020-04-30 16:29 ` Sowjanya Komatineni
2020-04-30 16:29 ` Sowjanya Komatineni
2020-04-30 17:06 ` Sowjanya Komatineni
2020-04-30 17:06 ` Sowjanya Komatineni
2020-04-30 18:18 ` Sowjanya Komatineni
2020-04-30 18:18 ` Sowjanya Komatineni
2020-04-30 19:09 ` Sowjanya Komatineni
2020-04-30 19:09 ` Sowjanya Komatineni
2020-04-30 19:33 ` Dmitry Osipenko
2020-04-30 19:33 ` Dmitry Osipenko
2020-04-30 19:46 ` Sowjanya Komatineni
2020-04-30 19:46 ` Sowjanya Komatineni
2020-04-30 19:53 ` Sowjanya Komatineni
2020-04-30 19:53 ` Sowjanya Komatineni
2020-04-30 20:02 ` Sowjanya Komatineni
2020-04-30 20:02 ` Sowjanya Komatineni
2020-04-30 21:17 ` Dmitry Osipenko
2020-04-30 21:17 ` Dmitry Osipenko
2020-04-30 21:26 ` Sowjanya Komatineni
2020-04-30 21:26 ` Sowjanya Komatineni
2020-04-30 21:37 ` Sowjanya Komatineni
2020-04-30 21:37 ` Sowjanya Komatineni
2020-04-30 21:53 ` Sowjanya Komatineni
2020-04-30 21:53 ` Sowjanya Komatineni
2020-04-30 22:16 ` Sowjanya Komatineni
2020-04-30 22:16 ` Sowjanya Komatineni
2020-04-30 22:19 ` Sowjanya Komatineni
2020-04-30 22:19 ` Sowjanya Komatineni
2020-04-30 23:14 ` Sowjanya Komatineni
2020-04-30 23:14 ` Sowjanya Komatineni
[not found] ` <fe7ebad6-0368-b1f0-4f58-648baa5e3f79@nvidia.com>
[not found] ` <4f095181-2338-3b71-316c-f8bbfc7865cc@nvidia.com>
[not found] ` <50e872bb-913a-7b47-3264-af6b1cedb0e2@nvidia.com>
[not found] ` <e17a8a49-be53-465d-f64c-3f4c77391d98@nvidia.com>
[not found] ` <da5154b4-85f9-3e56-a440-f75debaec3a8@nvidia.com>
[not found] ` <cbb047ae-97dc-8b9a-a5ba-8e2a5dab3771@nvidia.com>
[not found] ` <6ae2d00d-7955-d12b-5b56-955ef72ece26@nvidia.com>
2020-05-02 15:16 ` Dmitry Osipenko
2020-05-02 15:16 ` Dmitry Osipenko
2020-05-02 15:38 ` Sowjanya Komatineni
2020-05-02 15:38 ` Sowjanya Komatineni
2020-05-02 16:03 ` Sowjanya Komatineni
2020-05-02 16:03 ` Sowjanya Komatineni
2020-05-02 16:14 ` Sowjanya Komatineni
2020-05-02 16:14 ` Sowjanya Komatineni
2020-05-02 16:55 ` Sowjanya Komatineni
2020-05-02 16:55 ` Sowjanya Komatineni
2020-05-02 17:04 ` Sowjanya Komatineni [this message]
2020-05-02 17:04 ` Sowjanya Komatineni
2020-05-02 19:14 ` Sowjanya Komatineni
2020-05-02 19:14 ` Sowjanya Komatineni
2020-05-02 20:48 ` Dmitry Osipenko
2020-05-02 22:46 ` Sowjanya Komatineni
2020-05-02 22:46 ` Sowjanya Komatineni
2020-05-03 0:03 ` Sowjanya Komatineni
2020-05-03 0:03 ` Sowjanya Komatineni
2020-05-04 12:18 ` Hans Verkuil
2020-05-04 12:18 ` Hans Verkuil
2020-05-04 14:50 ` Sowjanya Komatineni
2020-05-04 14:50 ` Sowjanya Komatineni
2020-04-30 21:22 ` Sowjanya Komatineni
2020-04-30 21:22 ` Sowjanya Komatineni
[not found] ` <960d2715-a717-0cc3-df19-ff78dc426535@nvidia.com>
2020-05-04 15:53 ` Dmitry Osipenko
2020-05-04 15:53 ` Dmitry Osipenko
2020-05-04 15:56 ` Sowjanya Komatineni
2020-05-04 15:56 ` Sowjanya Komatineni
2020-04-30 14:25 ` Dmitry Osipenko
2020-04-30 14:25 ` Dmitry Osipenko
2020-04-30 14:26 ` Dmitry Osipenko
2020-04-30 20:06 ` Dmitry Osipenko
2020-04-30 20:08 ` Sowjanya Komatineni
2020-04-30 20:08 ` Sowjanya Komatineni
2020-04-30 20:09 ` Sowjanya Komatineni
2020-04-30 20:09 ` Sowjanya Komatineni
2020-04-30 20:21 ` Dmitry Osipenko
2020-04-30 20:21 ` Sowjanya Komatineni
2020-04-30 20:21 ` Sowjanya Komatineni
2020-05-04 7:44 ` Dmitry Osipenko
2020-05-04 14:36 ` Sowjanya Komatineni
2020-05-04 14:36 ` Sowjanya Komatineni
2020-04-29 22:00 ` [RFC PATCH v11 7/9] MAINTAINERS: Add Tegra Video driver section Sowjanya Komatineni
2020-04-29 22:00 ` Sowjanya Komatineni
2020-04-29 22:00 ` [RFC PATCH v11 8/9] dt-bindings: reset: Add ID for Tegra210 VI reset Sowjanya Komatineni
2020-04-29 22:00 ` Sowjanya Komatineni
2020-04-29 22:00 ` [RFC PATCH v11 9/9] arm64: tegra: Add Tegra VI CSI support in device tree Sowjanya Komatineni
2020-04-29 22:00 ` Sowjanya Komatineni
2020-04-30 9:59 ` [RFC PATCH v11 0/9] Add Tegra driver for video capture Hans Verkuil
2020-04-30 17:02 ` Sowjanya Komatineni
2020-04-30 17:02 ` Sowjanya Komatineni
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=605fc688-7712-cdfd-9d12-5741b984bb68@nvidia.com \
--to=skomatineni@nvidia.com \
--cc=devicetree@vger.kernel.org \
--cc=digetx@gmail.com \
--cc=frankc@nvidia.com \
--cc=helen.koike@collabora.com \
--cc=hverkuil@xs4all.nl \
--cc=jonathanh@nvidia.com \
--cc=linux-clk@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-media@vger.kernel.org \
--cc=linux-tegra@vger.kernel.org \
--cc=sakari.ailus@iki.fi \
--cc=sboyd@kernel.org \
--cc=thierry.reding@gmail.com \
/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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.