On 2021-12-21 3:40 PM, Mark Brown wrote:
On Wed, Dec 08, 2021 at 12:12:41PM +0100, Cezary Rojewski wrote:
+int avs_dsp_get_core(struct avs_dev *adev, u32 core_id)
+{
...
+ if (atomic_add_return(1, ref) == 1) {
+ ret = avs_dsp_enable(adev, mask);
+ if (ret)
+ goto err_enable_dsp;
+ }
+int avs_dsp_put_core(struct avs_dev *adev, u32 core_id)
+{
...
+ ref = &adev->core_refs[core_id];
+ if (atomic_dec_and_test(ref)) {
+ ret = avs_dsp_disable(adev, mask);
This looks wrong - there's nothing that ensures that we don't get
a sequence like:
CPU0 CPU1
decrement
increment
enable DSP
disable DSP
that I can see here? Either there's a lock missing which ensures
that the actual DSP management is in sync with the refcount or
there's no need for the use of atomics since the wider lock will
ensure that only one thing could be updating at once. In general
I'd expect something heavier weight than atomics.
Keen eye, Mark. In fact, you're right in both statements:
- assuming there is no wider lock, existing usage of atomics won't
prevent possible race for enable/disable of DSP carried as a consequence
to ->core_refs manipulation
- there is a wider lock indeed, and that's why we haven't encountered
the problem I guess. It's ->path_mutex, a member of struct avs_dev. Said
mutex is introduced in:
[PATCH 19/37] ASoC: Intel: avs: Path management
along with its usage. By the usage I mean the following:
avs_dsp_put_core() and avs_dsp_get_core() are called only within
avs_dsp_init_module() and avs_dsp_delete_module(). The latter two are
part of 'struct avs_path *' instances creation and deletion procedure:
avs_path_create() and avs_path_free(). Both avs_path_create() and
avs_path_free() lock ->path_mutex before doing anything.
I admit that answer to question: "which approach fits best here?" will
probably need to wait for the Christmas break to be over. While myself
I'm in favour of synchronizing avs_dsp_put_core() and avs_dsp_get_core()
locally as it scales better into the future and we won't get caught
unprepared when avs_path_create() and avs_path_free() stop being the
only places for their usage, such decision need to be made by the team
as a whole.
One more thing came into my mind during this discussion:
avs_dsp_put_core() and avs_dsp_get_core() should probably be 'static' -
as it was said earlier, these are not used outside of the dsp.c file.
Once again, good finding Mark, thank you.
Regards,
Czarek