[alsa-devel] [PATCH v3 1/2] ASoC: SOF: add flag for position update ipc

Rajwa, Marcin marcin.rajwa at linux.intel.com
Fri Jul 19 12:32:05 CEST 2019


On 7/18/2019 5:24 PM, Pierre-Louis Bossart wrote:
>
>
> On 7/18/19 3:42 AM, Rajwa, Marcin wrote:
>>
>> On 7/18/2019 7:06 AM, Keyon Jie wrote:
>>>
>>>
>>> On 2019/7/18 上午11:35, Pierre-Louis Bossart wrote:
>>>>
>>>>
>>>> On 7/17/19 10:11 PM, Keyon Jie wrote:
>>>>> From: Marcin Rajwa <marcin.rajwa at linux.intel.com>
>>>>>
>>>>> In some cases, FW might need to use the host_period_bytes field to
>>>>> synchronize the DMA copying (with host side) but the driver does not
>>>>
>>>> it's your right to edit my suggested wording, but the notion of 
>>>> 'synchronization' is far from clear. it's my understanding that the 
>>>> host_period_bytes defines the DMA transfer size requested by the 
>>>> firmware, which isn't a value that matters to the host except for 
>>>> rewind usages.
>>>
>>> Hi Pierre, here the host_period_bytes is requested by host, FW has 
>>> its own period size, and DMA will transfer data in FW buffer period 
>>> size. It works like this:
>>>
>>> FW buffer[period 0, period 1, ...] <==> DMA <==> host/alsa 
>>> buffer[host_period 0, host_priod 1, ...]
>>>
>>> We need this host_preiod_bytes information in FW to do fast 
>>> draining(e.g. record 2 seconds data within 10ms) in mmap capture, we 
>>> are slowing down the draining in smaller host_period_bytes cases, 
>>> otherwise, arecord can't read the buffer in time and overrun will 
>>> happen.
>>>
>>> Maybe the wording "synchronize" here is inaccurate, how about 
>>> something like this:
>>>
>>> "FW might need to use the host_period_bytes field to configure and 
>>> control the DMA copying speed but the driver does not..."
>>>
>>
>> Hi,
>>
>> we need *host_period_bytes *in FW to properly drain data - by 
>> properly I mean to no override host buffer but in the same time to 
>> avoid situation when host is waiting for data and doesn't get it. The 
>> former is known as *overrun *while the later *underrun**.
>> *
>>
>> So that's why I originally used the word *"to synchronize" *because 
>> it best reflects the use of this variable in FW.
>>
>> *The problem *- host establishes the *period_size/**host_period_bytes 
>> *and uses it as a "data copy tempo controller" meaning it will copy 
>> data buffered in its own buffer (copied there by FW) in *period_size 
>> *time intervals. Now, in regular copy (real time stream) firmware 
>> doesn't
>>
>> need to care about how fast host copy because the host buffer is big 
>> enough to store even several FW periods (each one or few 
>> milliseconds)  without overriding it. That is why we did not need 
>> this *period_size *variable before. However the draining task is very
>>
>> different ball game - it copies *2,1 seconds* of data as fast as 
>> possible to the host. Therefore we are very prone to *XRUNs*
>>
>> *The solution* - in FW we need to know how often host copies data out 
>> from its own buffer and this information is stored in 
>> *host_period_bytes, *lets send this information down to firmware. 
>> Now, the FW knowing this can fill the host buffer and wait the time 
>> calculated by *host_period_bytes*
>>
>> before next copy. This way we copy as much/fast as we can and in the 
>> same time we are safe that host will handle this and no XRUN will 
>> ever happen.
>
>
> We knew from Day1 that draining faster than real-time could 
> potentially lead to the driver detecting overflows or timeouts. It's 
> been documented left and right, with an assumption that the ring 
> buffer is actually big enough to contain all the data stored in the DSP.

@Pierre, indeed the buffer that kernel allocates is big enough to store 
all the data. However *arecord* introduces its own buffer which is just 
a multiple of *period_sizes *- and it is the buffer which overflows.

>
> Before I provide more feedback, can you clarify if the 
> 'host_period_bytes' is the same value as the ALSA period size (in 
> bytes)? And what would be the value when the no_irq mode is used?

Yes, this is the same value. It is obtained by *params_period_bytes**()* 
in kernel.

*no_irq mode *- it does not affect the value of *host_period_bytes 
*after my patch has been applied. Before my patch however, driver and FW 
used this value to send stream position information from FW to kernel. 
In short, when *(hda && hda->no_ipc_position)*

then *ipc_params->host_period_bytes = 0; *was set in kernel.**Firmware 
then, read this *host_period_bytes = 0 *and treated it as "OK does not 
send any IPC regarding stream position". So once *no_ipc_position *was 
set we lost information about *host_period_bytes *in the FW.

So all my patches in FW and Kernel do is to *relax****host_period_bytes 
*and introduce new parameter dedicated for this stream position IPC. At 
that time we called it *no_period_irq *to resemble old name but now I 
think it would be better if we rename it to something like

*no_stream_position *as it is more informative. What do you think?


>
>>
>>
>> Hope it helped to understand the need of *host_period_bytes *in the 
>> firmware.
>> **
>>
>> Marcin
>>


More information about the Alsa-devel mailing list