diff options
author | Mark Hills <mark@xwax.org> | 2020-07-08 11:18:45 +0100 |
---|---|---|
committer | Takashi Iwai <tiwai@suse.de> | 2020-07-09 12:58:35 +0200 |
commit | 027c70021b905eb23e2f36c64add062ba218b841 (patch) | |
tree | e31ba3386c152bc8515b16d3022eb674d2d0859b /sound/pci/echoaudio/echoaudio.h | |
parent | db091b0e14239f0ebd5709f3f9b5a1d662483adc (diff) | |
download | linux-next-027c70021b905eb23e2f36c64add062ba218b841.tar.gz |
ALSA: echoaudio: Race conditions around "opencount"
Use of atomics does not make these statements robust:
atomic_inc(&chip->opencount);
if (atomic_read(&chip->opencount) > 1 && chip->rate_set)
chip->can_set_rate=0;
and
if (atomic_read(&chip->opencount)) {
if (chip->opencount) {
changed = -EAGAIN;
} else {
changed = set_digital_mode(chip, dmode);
It would be necessary to atomically increment or decrement the value
and use the returned result. And yet we still need to prevent other
threads making use of "can_set_rate" while we set it.
However in all but one case the atomic is misleading as they are already
running with "mode_mutex" held.
Decisions are made on mode setting are often intrinsically connected
to "opencount" because some operations are not permitted unless
there is sole ownership.
So instead simplify this, and use "mode_mutex" as a lock for all reference
counting and mode setting.
Signed-off-by: Mark Hills <mark@xwax.org>
Link: https://lore.kernel.org/r/20200708101848.3457-2-mark@xwax.org
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Diffstat (limited to 'sound/pci/echoaudio/echoaudio.h')
-rw-r--r-- | sound/pci/echoaudio/echoaudio.h | 6 |
1 files changed, 3 insertions, 3 deletions
diff --git a/sound/pci/echoaudio/echoaudio.h b/sound/pci/echoaudio/echoaudio.h index be4d0489394a..6fd283e4e676 100644 --- a/sound/pci/echoaudio/echoaudio.h +++ b/sound/pci/echoaudio/echoaudio.h @@ -336,7 +336,7 @@ struct echoaudio { struct mutex mode_mutex; u16 num_digital_modes, digital_mode_list[6]; u16 num_clock_sources, clock_source_list[10]; - atomic_t opencount; + unsigned int opencount; /* protected by mode_mutex */ struct snd_kcontrol *clock_src_ctl; struct snd_pcm *analog_pcm, *digital_pcm; struct snd_card *card; @@ -353,8 +353,8 @@ struct echoaudio { struct timer_list timer; char tinuse; /* Timer in use */ char midi_full; /* MIDI output buffer is full */ - char can_set_rate; - char rate_set; + char can_set_rate; /* protected by mode_mutex */ + char rate_set; /* protected by mode_mutex */ /* This stuff is used mainly by the lowlevel code */ struct comm_page *comm_page; /* Virtual address of the memory |