aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTakashi Iwai <tiwai@suse.de>2018-07-30 14:48:29 +0200
committerTakashi Iwai <tiwai@suse.de>2018-07-30 14:52:30 +0200
commit89b4ab213feb11a5bece544cfa12374f66c2c47c (patch)
tree9a1725a0138dc002d2c65481cf96e5f8eb0e2e57
parentALSA: seq: virmidi: Offload the output event processing (diff)
downloadlinux-dev-89b4ab213feb11a5bece544cfa12374f66c2c47c.tar.xz
linux-dev-89b4ab213feb11a5bece544cfa12374f66c2c47c.zip
ALSA: seq: virmidi: Use READ_ONCE/WRITE_ONCE() macros
The trigger flag in vmidi object can be referred in different contexts concurrently, hence it's better to be put with READ_ONCE() and WRITE_ONCE() macros to assure the accesses. Signed-off-by: Takashi Iwai <tiwai@suse.de>
-rw-r--r--include/sound/seq_virmidi.h2
-rw-r--r--sound/core/seq/seq_virmidi.c14
2 files changed, 6 insertions, 10 deletions
diff --git a/include/sound/seq_virmidi.h b/include/sound/seq_virmidi.h
index d488dcfa3a4e..796ce7772213 100644
--- a/include/sound/seq_virmidi.h
+++ b/include/sound/seq_virmidi.h
@@ -36,7 +36,7 @@ struct snd_virmidi {
int seq_mode;
int client;
int port;
- unsigned int trigger: 1;
+ bool trigger;
struct snd_midi_event *parser;
struct snd_seq_event event;
struct snd_virmidi_dev *rdev;
diff --git a/sound/core/seq/seq_virmidi.c b/sound/core/seq/seq_virmidi.c
index 67ea5d62cebc..03ac5e72dbe6 100644
--- a/sound/core/seq/seq_virmidi.c
+++ b/sound/core/seq/seq_virmidi.c
@@ -89,7 +89,7 @@ static int snd_virmidi_dev_receive_event(struct snd_virmidi_dev *rdev,
else
down_read(&rdev->filelist_sem);
list_for_each_entry(vmidi, &rdev->filelist, list) {
- if (!vmidi->trigger)
+ if (!READ_ONCE(vmidi->trigger))
continue;
if (ev->type == SNDRV_SEQ_EVENT_SYSEX) {
if ((ev->flags & SNDRV_SEQ_EVENT_LENGTH_MASK) != SNDRV_SEQ_EVENT_LENGTH_VARIABLE)
@@ -147,11 +147,7 @@ static void snd_virmidi_input_trigger(struct snd_rawmidi_substream *substream, i
{
struct snd_virmidi *vmidi = substream->runtime->private_data;
- if (up) {
- vmidi->trigger = 1;
- } else {
- vmidi->trigger = 0;
- }
+ WRITE_ONCE(vmidi->trigger, !!up);
}
/* process rawmidi bytes and send events;
@@ -175,7 +171,7 @@ static void snd_vmidi_output_work(struct work_struct *work)
return;
}
- while (vmidi->trigger) {
+ while (READ_ONCE(vmidi->trigger)) {
if (snd_rawmidi_transmit(substream, &input, 1) != 1)
break;
if (snd_midi_event_encode_byte(vmidi->parser, input,
@@ -201,7 +197,7 @@ static void snd_virmidi_output_trigger(struct snd_rawmidi_substream *substream,
{
struct snd_virmidi *vmidi = substream->runtime->private_data;
- vmidi->trigger = !!up;
+ WRITE_ONCE(vmidi->trigger, !!up);
if (up)
queue_work(system_highpri_wq, &vmidi->output_work);
}
@@ -289,7 +285,7 @@ static int snd_virmidi_output_close(struct snd_rawmidi_substream *substream)
{
struct snd_virmidi *vmidi = substream->runtime->private_data;
- vmidi->trigger = 0; /* to be sure */
+ WRITE_ONCE(vmidi->trigger, false); /* to be sure */
cancel_work_sync(&vmidi->output_work);
snd_midi_event_free(vmidi->parser);
substream->runtime->private_data = NULL;