Skip to content

Module loading/Unloading fixes for SOF and legacy drivers - #765

Closed
ranj063 wants to merge 9 commits into
thesofproject:topic/sof-devfrom
ranj063:fix/module_loading
Closed

ranj063 wants to merge 9 commits into
thesofproject:topic/sof-devfrom
ranj063:fix/module_loading

Conversation

@ranj063

@ranj063 ranj063 commented Apr 1, 2019 •

Copy link
Copy Markdown
Collaborator

This pull request contains a series of fixes needed for fixing issues with module unloading/loading.

  1. Fix null pointer dereferencing in remove_widget in soc-topology to
  2. Move topology unloading to component driver remove()
  3. Fix clean_up_card_resources() to remove dai links before freeing snd_card
  4. Make component dev resource managed in SOF
  5. Add remove() callback for component drv in the SKL legacy driver
  6. Finally address the issue with the pci device being allowed to be removed while a pcm stream is open.

Tests performed:

  1. This passed the sof_bootloop test on Up2 with SOF
  2. With the legacy driver, the snd_soc_skl device can now be unloaded without any null pointer dereferences. Tested on GLK chromebook.

@ranj063
ranj063 requested review from bardliao, lgirdwood and plbossart and removed request for bardliao April 1, 2019 16:13
@ranj063
ranj063 force-pushed the fix/module_loading branch from c836329 to c2d341b Compare April 1, 2019 16:22
@ranj063
ranj063 requested a review from bardliao April 1, 2019 16:22

@plbossart plbossart left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

@ranj063 nice patch set with a number of style issues to be fixed. The main concern I have is the dailink removal in soc-core.c, it looks very invasive and will impact all SOC implementations. Wondering if we can avoid and decouple this from topology removal.

Comment thread sound/soc/soc-core.c Outdated

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

how do you deal with pending operations if they are handled in snd_card_free()?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

@plbossart I'm not sure how to handle this at all. The problem is we need to unload topology before the snd_card is freed. Let me think about it a bit more.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

@plbossart the only way I can think of avoiding this is by calling snd_soc_tplg_component_remove(component, SND_SOC_TPLG_INDEX_ALL);

in snd_sof_device_remove() for SOF and in skl_remove() for the legacy driver to make sure that the topoogy is unloaded before the card is freed (this would be instead of calling it in the component driver remove()). What do you think about that?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

or the other option is before cleaning up the card resources in snd_soc_unbind_card(), I could call soc_remove_link_components() to remove the link components which would remove the topology.
snd_soc_bind_card() calls soc_probe_link_components(), so it would be symmetric

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

@plbossart i've change PR to call remove component in unbind_card instead. Let me know what you think

Comment thread sound/soc/sof/core.c Outdated
Comment thread sound/soc/soc-pcm.c Outdated
Comment thread sound/soc/soc-pcm.c Outdated
Comment thread sound/soc/soc-pcm.c Outdated

ghost Apr 1, 2019

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

if (component)

ghost Apr 1, 2019

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

maybe we should rename ignore_module_refcount as check_module_refcount_on_open or something more meaningful than 'ignore' and then use it.

ghost Apr 1, 2019

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

@plbossart sorry about the style fixes. I'll fix them.
I agree it makes sense to rename this field. I havent been able to come up with a nice name that indicates what we're really trying to do here. Let me think about it and rename it today.

ghost Apr 1, 2019

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

done, I've rename it to module_get_upon_open. hopefully thats a bit more indicative of what we want to achieve.

@ranj063
ranj063 force-pushed the fix/module_loading branch 7 times, most recently from 0ff6da0 to 413dffe Compare April 1, 2019 21:31

ghost left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

@ranj063 I am still struggling with the part on the _unbind, mostly since I am not 100% familiar with the code and your comments did not provide the pointer I was looking for. Can you try and made it more self-explanatory, it'll help even with more expert reviewers explain how this works.
Also a couple of commit messages, style, squash and bad refcounts to fix.
Thanks!

Comment thread sound/soc/soc-topology.c Outdated

ghost Apr 1, 2019

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

help me understand something here: the existing code pattern is repeated a number of times, e.g. it's also used for enums:
kfree(dobj->control.dvalues);
for (i = 0; i < se->items; i++)
kfree(dobj->control.dtexts[i]);
kfree(dobj->control.dtexts);

so either we fix this everywhere or we don't. I feel uncomfortable with a specific change that breaks a mostly regular pattern so far.

ghost Apr 1, 2019 •

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

@plbossart it cant be changed everywhere. In the remove_enum() method, the dobj is actually the control's dobj. whereas in remove_widget, the input argument dobj is the widget's dobj and what we're trying to delete is the control's dobj's texts and values.
It was a genuine null pointer dereference I saw with the legacy driver that led to me discovering this error while trying to unload the snd_soc_skl module. We dont have enum controls in SOF. So we never encountered this problem before.

ghost Apr 2, 2019

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

@ranj063 then you'd really want a comment telling reviewers/users of that code that this is very specific and intentional with explanations

ghost Apr 2, 2019

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

@plbossart updated this now. I know the change isnt quite obvious but it is a serious error and hopefully the comment clarifies it.

Comment thread sound/soc/soc-core.c Outdated

ghost Apr 1, 2019

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

"snd_soc_bind_card() probes the link components after the snd_card
is registered". Looking at the code, this is far from obvious, and the code to remove link components does not seem to have a matching equivalent in snd_soc_bind_card(). Either the commit message is wrong or it omits a precision needed for your esteemed (?) reviewer to see the beauty of this PR.

Comment thread sound/soc/sof/core.c Outdated

ghost Apr 1, 2019

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

commit message still riddled with spelling mistakes :-(

ghost Apr 2, 2019

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

@plbossart hmm I knew it wasnt a good idea to just stop wearing glasses. time to make that trip to the optometrist soon. fixed the typos now.

Comment thread sound/soc/sof/core.c Outdated

ghost Apr 1, 2019

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

isn't this comment still relevant, even with the use of devm_ ? does it need to be removed completely or reworded?

Comment thread sound/soc/soc-core.c Outdated

ghost Apr 1, 2019

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

wasn't there a patch for SKL as well that needs to be updated?

Comment thread include/sound/soc.h Outdated

ghost Apr 1, 2019

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

You should add a
Fixes: SHA1 ('title') tag

Comment thread sound/soc/intel/skylake/skl-pcm.c Outdated

ghost Apr 1, 2019

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I wasn't crazy, this needs to be squashed with the previous patch to avoid bisect issues.

Comment thread sound/soc/soc-pcm.c Outdated

ghost Apr 1, 2019

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

this isn't balanced with the module_get(), which is done only when you have a .ops and a .open. You might decrease references that were not previously incremented.

ghost Apr 1, 2019

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

@plbossart good catch. I did infact put it in the wrong place.

@plbossart

ghost commented Apr 1, 2019

Copy link
Copy Markdown
Member

@xiulipan the Intel CI seems to be broken?

@ranj063
ranj063 force-pushed the fix/module_loading branch 4 times, most recently from 386eb34 to 52df475 Compare April 1, 2019 23:46
@ranj063

ghost commented Apr 1, 2019

Copy link
Copy Markdown
Collaborator Author

@plbossart sorry for giving you a hard time with this one. It wasnt a very straight forward PR with fixes everywhere. Hopefully the latest version has no style issue anymore.

@xiulipan

ghost commented Apr 2, 2019

Copy link
Copy Markdown

@plbossart
Not sure. It seems a lot of attempt for this PR. I will check for detail and have a round bug fix for it.

Ranjani Sridharan added 7 commits April 2, 2019 09:46
…texts

"dobj" is the widget dobj. dvalues and dtexts belong to the enum
kcontrol's dobj (se->dobj). So, use this to free the control values
and texts to prevent the NULL pointer dereference while removing
widgets.

Signed-off-by: Ranjani Sridharan <ranjani.sridharan@linux.intel.com>
Topology is loaded when the component driver is probed. So,
it should be removed in the component driver's remove().
This will prevent null pointer dereference while unregistering
the component driver.

Signed-off-by: Ranjani Sridharan <ranjani.sridharan@linux.intel.com>
Topology is not unloaded in the core during unregister_component()
anymore. So, add the remove() callback that will unload the
topology.

Signed-off-by: Ranjani Sridharan <ranjani.sridharan@linux.intel.com>
snd_soc_bind_card() calls snd_soc_instantiate_card()
to first register the snd_card and then probe the link
components by calling soc_probe_link_components().
The snd_card is used by the component driver during
its probe() while loading topology widgets to add the controls
to the snd_card.

The snd_card also needs to be valid while unloading the topology
widgets when the component driver is removed. Therefore,
in snd_soc_unbind_card(), the link components should be removed with
the call to soc_remove_link_components() before the card resources
are cleaned up and the snd_card itself is freed.

Signed-off-by: Ranjani Sridharan <ranjani.sridharan@linux.intel.com>
This is no longer done in the core during unregister_component.
So, it should be done in the component driver's remove
callback().

Signed-off-by: Ranjani Sridharan <ranjani.sridharan@linux.intel.com>
Previously, we couldn't make the component driver
resource-managed because topology unloading was done by the
core when the component driver was unregistered. But this has
been fixed to allow topology removal during the component
driver remove() callback and there aren't any
NULL pointer dereferences anymore.

Signed-off-by: Ranjani Sridharan <ranjani.sridharan@linux.intel.com>
Recently, for Intel platforms the "ignore_module_refcount" field
was introduced for the component driver which prevented the
refcounts being incremented for the device driver module
during component probe. However, this leads to the problem of
allowing the device driver module to be unloaded while a
pcm stream is open.

So rename the field to "module_get_upon_open" which is more
meaningful in terms of allowing the refcount for the module
to be incremented when a pcm is opened.

Also, align with the skylake component driver with the new name.

Fixes: b450b87('ASoC: core: don't increase component module refcount
                 unconditionally'

Signed-off-by: Ranjani Sridharan <ranjani.sridharan@linux.intel.com>
Ranjani Sridharan added 2 commits April 2, 2019 09:46
The "ignore_module_refcount" field in the component driver
has been renamed to "module_get_upon_open". So align with
the new name.

Signed-off-by: Ranjani Sridharan <ranjani.sridharan@linux.intel.com>
Setting the module_get_upon_open field for component driver
prevents the module refcount from being incremented during
component probe(). But this could lead to the module being
allowed to be unloaded when a pcm stream is open. So,
if this field is set, the module's refcount should be
incremented/decremented during pcm open/close to prevent it.

Signed-off-by: Ranjani Sridharan <ranjani.sridharan@linux.intel.com>
@ranj063
ranj063 force-pushed the fix/module_loading branch from 52df475 to 53c42c5 Compare April 2, 2019 16:53
@ranj063

ghost commented Apr 4, 2019

Copy link
Copy Markdown
Collaborator Author

@plbossart I'm going to break this PR into 3 separate ones for easier review. Closing this one for now

@ranj063 ranj063 closed this Apr 4, 2019
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.

3 participants