Skip to content

Commit 4a971e8

Browse files
committed
ALSA: control: Use deferred fasync helper
For avoiding the potential deadlock via kill_fasync() call, use the new fasync helpers to defer the invocation from the control API. Note that it's merely a workaround. Another note: although we haven't received reports about the deadlock with the control API, the deadlock is still potentially possible, and it's better to align the behavior with other core APIs (PCM and timer); so let's move altogether. Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Takashi Iwai <[email protected]>
1 parent 96b0970 commit 4a971e8

File tree

2 files changed

+5
-4
lines changed

2 files changed

+5
-4
lines changed

include/sound/control.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -109,7 +109,7 @@ struct snd_ctl_file {
109109
int preferred_subdevice[SND_CTL_SUBDEV_ITEMS];
110110
wait_queue_head_t change_sleep;
111111
spinlock_t read_lock;
112-
struct fasync_struct *fasync;
112+
struct snd_fasync *fasync;
113113
int subscribed; /* read interface is activated */
114114
struct list_head events; /* waiting events for read */
115115
};

sound/core/control.c

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,7 @@ static int snd_ctl_release(struct inode *inode, struct file *file)
127127
if (control->vd[idx].owner == ctl)
128128
control->vd[idx].owner = NULL;
129129
up_write(&card->controls_rwsem);
130+
snd_fasync_free(ctl->fasync);
130131
snd_ctl_empty_read_queue(ctl);
131132
put_pid(ctl->pid);
132133
kfree(ctl);
@@ -181,7 +182,7 @@ void snd_ctl_notify(struct snd_card *card, unsigned int mask,
181182
_found:
182183
wake_up(&ctl->change_sleep);
183184
spin_unlock(&ctl->read_lock);
184-
kill_fasync(&ctl->fasync, SIGIO, POLL_IN);
185+
snd_kill_fasync(ctl->fasync, SIGIO, POLL_IN);
185186
}
186187
read_unlock_irqrestore(&card->ctl_files_rwlock, flags);
187188
}
@@ -2134,7 +2135,7 @@ static int snd_ctl_fasync(int fd, struct file * file, int on)
21342135
struct snd_ctl_file *ctl;
21352136

21362137
ctl = file->private_data;
2137-
return fasync_helper(fd, file, on, &ctl->fasync);
2138+
return snd_fasync_helper(fd, file, on, &ctl->fasync);
21382139
}
21392140

21402141
/* return the preferred subdevice number if already assigned;
@@ -2302,7 +2303,7 @@ static int snd_ctl_dev_disconnect(struct snd_device *device)
23022303
read_lock_irqsave(&card->ctl_files_rwlock, flags);
23032304
list_for_each_entry(ctl, &card->ctl_files, list) {
23042305
wake_up(&ctl->change_sleep);
2305-
kill_fasync(&ctl->fasync, SIGIO, POLL_ERR);
2306+
snd_kill_fasync(ctl->fasync, SIGIO, POLL_ERR);
23062307
}
23072308
read_unlock_irqrestore(&card->ctl_files_rwlock, flags);
23082309

0 commit comments

Comments
 (0)