--- x/sound/core/rawmidi.c +++ y/sound/core/rawmidi.c @@ -607,13 +607,19 @@ int snd_rawmidi_kernel_release(struct sn } EXPORT_SYMBOL(snd_rawmidi_kernel_release); +static DEFINE_MUTEX(rawmidi_poll_mutex); + static int snd_rawmidi_release(struct inode *inode, struct file *file) { struct snd_rawmidi_file *rfile; struct snd_rawmidi *rmidi; struct module *module; + mutex_lock(&rawmidi_poll_mutex); rfile = file->private_data; + file->private_data = NULL; + mutex_unlock(&rawmidi_poll_mutex); + rmidi = rfile->rmidi; rawmidi_release_priv(rfile); kfree(rfile); @@ -1649,7 +1655,11 @@ static __poll_t snd_rawmidi_poll(struct { struct snd_rawmidi_file *rfile; struct snd_rawmidi_runtime *runtime; - __poll_t mask; + __poll_t mask = 0; + + mutex_lock(&rawmidi_poll_mutex); + if (!file->private_data) + goto out; rfile = file->private_data; if (rfile->input != NULL) { @@ -1661,7 +1671,6 @@ static __poll_t snd_rawmidi_poll(struct runtime = rfile->output->runtime; poll_wait(file, &runtime->sleep, wait); } - mask = 0; if (rfile->input != NULL) { if (snd_rawmidi_ready(rfile->input)) mask |= EPOLLIN | EPOLLRDNORM; @@ -1670,6 +1679,8 @@ static __poll_t snd_rawmidi_poll(struct if (snd_rawmidi_ready(rfile->output)) mask |= EPOLLOUT | EPOLLWRNORM; } +out: + mutex_unlock(&rawmidi_poll_mutex); return mask; }