diff options
author | Takashi Iwai <tiwai@suse.de> | 2017-10-18 15:51:59 +0200 |
---|---|---|
committer | Takashi Iwai <tiwai@suse.de> | 2017-10-19 13:58:36 +0200 |
commit | 9780ded39bef5d22a84bdc39112df93f70a58bdd (patch) | |
tree | 312c860555df48fda2450d833a2cb1a7a7cd5b0e /sound/pci | |
parent | 28d1d6d2f314ff395ff67565d1145742614b21c8 (diff) | |
download | linux-9780ded39bef5d22a84bdc39112df93f70a58bdd.tar.gz linux-9780ded39bef5d22a84bdc39112df93f70a58bdd.tar.bz2 linux-9780ded39bef5d22a84bdc39112df93f70a58bdd.zip |
ALSA: hda: Avoid racy recreation of widget kobjects
The refresh of HD-audio widget sysfs kobjects via
snd_hdac_refresh_widget_sysfs() is slightly racy.
The driver recreates the whole tree from scratch after deleting the
whole. When CONFIG_DEBUG_KOBJECT_RELEASE option is used, kobject
release doesn't happen immediately but delayed, while the re-creation
of the same named kobject happens soon after invoking kobject_put().
This may end up with the conflicts of duplicated kobjects, as found in
the bug report below.
In this patch, we take another approach to refresh the tree: instead
of recreating the whole tree, just add the new nodes and delete the
non-existing nodes. Since the refresh happens only once at
initialization, no longer race would happen.
Along with the code change, merge snd_hdac_refresh_widget_sysfs() with
the existing snd_hdac_refresh_widgets() with an additional bool flag
for simplifying the code.
Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=197307
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Diffstat (limited to 'sound/pci')
-rw-r--r-- | sound/pci/hda/hda_codec.c | 2 |
1 files changed, 1 insertions, 1 deletions
diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c index 3db26c451837..bb086665c3e0 100644 --- a/sound/pci/hda/hda_codec.c +++ b/sound/pci/hda/hda_codec.c @@ -977,7 +977,7 @@ int snd_hda_codec_update_widgets(struct hda_codec *codec) hda_nid_t fg; int err; - err = snd_hdac_refresh_widget_sysfs(&codec->core); + err = snd_hdac_refresh_widgets(&codec->core, true); if (err < 0) return err; |