Skip to content

Commit

Permalink
ALSA: control: Use deferred fasync helper
Browse files Browse the repository at this point in the history
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/20220728125945.29533-5-tiwai@suse.de
Signed-off-by: Takashi Iwai <tiwai@suse.de>
  • Loading branch information
tiwai committed Jul 29, 2022
1 parent 96b0970 commit 4a971e8
Show file tree
Hide file tree
Showing 2 changed files with 5 additions and 4 deletions.
2 changes: 1 addition & 1 deletion include/sound/control.h
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@ struct snd_ctl_file {
int preferred_subdevice[SND_CTL_SUBDEV_ITEMS];
wait_queue_head_t change_sleep;
spinlock_t read_lock;
struct fasync_struct *fasync;
struct snd_fasync *fasync;
int subscribed; /* read interface is activated */
struct list_head events; /* waiting events for read */
};
Expand Down
7 changes: 4 additions & 3 deletions sound/core/control.c
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,7 @@ static int snd_ctl_release(struct inode *inode, struct file *file)
if (control->vd[idx].owner == ctl)
control->vd[idx].owner = NULL;
up_write(&card->controls_rwsem);
snd_fasync_free(ctl->fasync);
snd_ctl_empty_read_queue(ctl);
put_pid(ctl->pid);
kfree(ctl);
Expand Down Expand Up @@ -181,7 +182,7 @@ void snd_ctl_notify(struct snd_card *card, unsigned int mask,
_found:
wake_up(&ctl->change_sleep);
spin_unlock(&ctl->read_lock);
kill_fasync(&ctl->fasync, SIGIO, POLL_IN);
snd_kill_fasync(ctl->fasync, SIGIO, POLL_IN);
}
read_unlock_irqrestore(&card->ctl_files_rwlock, flags);
}
Expand Down Expand Up @@ -2134,7 +2135,7 @@ static int snd_ctl_fasync(int fd, struct file * file, int on)
struct snd_ctl_file *ctl;

ctl = file->private_data;
return fasync_helper(fd, file, on, &ctl->fasync);
return snd_fasync_helper(fd, file, on, &ctl->fasync);
}

/* return the preferred subdevice number if already assigned;
Expand Down Expand Up @@ -2302,7 +2303,7 @@ static int snd_ctl_dev_disconnect(struct snd_device *device)
read_lock_irqsave(&card->ctl_files_rwlock, flags);
list_for_each_entry(ctl, &card->ctl_files, list) {
wake_up(&ctl->change_sleep);
kill_fasync(&ctl->fasync, SIGIO, POLL_ERR);
snd_kill_fasync(ctl->fasync, SIGIO, POLL_ERR);
}
read_unlock_irqrestore(&card->ctl_files_rwlock, flags);

Expand Down

0 comments on commit 4a971e8

Please sign in to comment.