Skip to content

Conversation

@marcinszkudlinski
Copy link
Contributor

@marcinszkudlinski marcinszkudlinski commented Mar 26, 2025

For DP there's a crucial part to properly estimate period that the module will be called. Period value is used in several places in DP scheduling

There were 3 defects:

  1. period should always be a multiplication of LL cycle, currently 1000us. If estimated period is i.e. 1300us, it should be aligned down to 1000

  2. periods lower that 1LL cycle is not allowed, DP scheduler is triggered from LL

  3. for some enormous high bitrates, like 192KHz/8 channels, there was an 32bit overflow in period calculations

Copy link
Member

@lgirdwood lgirdwood left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@marcinszkudlinski fwiw, @jsarha is working on adding a test DP topology that can be used in PR testing CI. Hopefully this will land soon to help test more DP use cases.

unsigned int sink_period =
(uint64_t)1000000 * (uint64_t)sink_get_min_free_space(mod->sinks[i]) /
((uint64_t)sink_get_frame_bytes(mod->sinks[i]) *
(uint64_t)sink_get_rate(mod->sinks[i]));
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: In multiplication it's enough to type cast the first operand to int64_t to calculate the product as 64 bit. It would give a bit more compact code.

* use 64bit integers to avoid overflows
*/
unsigned int sink_period =
(uint64_t)1000000 * (uint64_t)sink_get_min_free_space(mod->sinks[i]) /
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think you can use 1000000ULL

*/
dev->period = 1000000 * sink_get_min_free_space(sink) /
(sink_get_frame_bytes(sink) * sink_get_rate(sink));
dev->period = (uint64_t)1000000 * (uint64_t)sink_get_min_free_space(sink) /
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ditto

Copy link
Collaborator

@kv2019i kv2019i left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No blockers, but some question/notes, please see inline.

module_adapter_calculate_dp_period(dev);

if (dev->period < LL_TIMER_PERIOD_US) {
comp_err(dev, "DP Module period too short (%u uS), must be at least 1LL cycle (%llu uS)",
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Btw, why "uS" micro siemens? https://en.wikipedia.org/wiki/Siemens_(unit)


comp_info(dev, "SRC DP period calculated as: %u", dev->period);
comp_info(dev, "SRC DP period calculated as: %u", dev->period);
}
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could this be a helper or otherwise shared code? Looks wrong to have DP constraints in multiple places in code. I.e. if the period needs to be aligned because of SRC specific reasons, it's good to have here, but if it's a limitation of DP infra, then it should be a common function used by all DP modules.

Copy link
Contributor Author

@marcinszkudlinski marcinszkudlinski Mar 28, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

unfortunately SRC module needs a calculated period for internal purposes at "set params". It happens a bit earlier than "prepare", when module adapter do a "general" period calculation

So, in case of current SRC implementation, it cannot be unified.

in general, if a module wants to enforce its own period instead of a calculated one, it can do it just by setting dev->period to desired value. SRC does it - but for different reasons

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Lets make the automatic DP config calculation the default state, but allow the modules to override with some API calls as needed. This should all be visible in the logs for debug.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@singalsu fyi - some SRC updates may be needed for DP.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe calculating some things in SRC can be moved to prepare() if need. SRC needs a target period duration and it tries to match than with polyphase filter bank(s) constraints. In some cases with 44.1 family <--> 48 family rates those can't be met exactly.

As DP EDF scheduler runs in LL cycles, DP period should be always
calculated at granularity of LL cycle

Fail preparation if a module calculated period shorter than 1LL cycle

Signed-off-by: Marcin Szkudlinski <marcin.szkudlinski@intel.com>
for some huge bitrates there was an overflow in 32bit
numbers in period calculations, i.e:

dev->period = 1000000 * sink_get_min_free_space(sink)

for 192000-32-7 format it was 5824000000, more than maxint32bit

Signed-off-by: Marcin Szkudlinski <marcin.szkudlinski@intel.com>
Copy link
Collaborator

@singalsu singalsu left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good to me, good catch with that dev->period calculate overflow!


comp_info(dev, "SRC DP period calculated as: %u", dev->period);
comp_info(dev, "SRC DP period calculated as: %u", dev->period);
}
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe calculating some things in SRC can be moved to prepare() if need. SRC needs a target period duration and it tries to match than with polyphase filter bank(s) constraints. In some cases with 44.1 family <--> 48 family rates those can't be met exactly.

@kv2019i kv2019i merged commit 25ee30e into thesofproject:main Apr 2, 2025
42 of 49 checks passed
@marcinszkudlinski marcinszkudlinski deleted the dp_period branch April 3, 2025 08:08
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants