All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v2 0/5] ALSA: Drop async signal support
@ 2022-07-17  7:05 Takashi Iwai
  2022-07-17  7:05 ` [PATCH v2 1/5] ALSA: timer: " Takashi Iwai
                   ` (5 more replies)
  0 siblings, 6 replies; 8+ messages in thread
From: Takashi Iwai @ 2022-07-17  7:05 UTC (permalink / raw)
  To: alsa-devel

Hi,

this is a revised patch set for dropping fasync support from ALSA
core.

The async signal itself is very difficult to use properly due to
various restrictions (e.g. you cannot perform any I/O in the context),
hence it's a feature that has been never used by real applications.

OTOH, the real problem is that there have been quite a few syzcaller
reports indicating that fasync code path may lead to some potential
deadlocks for long time.  Dropping the feature is the easiest
solution, obviously.

The corresponding update for alsa-lib will follow once when we agree
with this approach.


thanks,

Takashi

===

v1: https://lore.kernel.org/r/20220715102935.4695-1-tiwai@suse.de
v1->v2: Fix unused variable warning in patch 2

===

Takashi Iwai (5):
  ALSA: timer: Drop async signal support
  ALSA: pcm: Drop async signal support
  ALSA: control: Drop async signal support
  ALSA: core: Drop async signal support
  ALSA: doc: Drop stale fasync entry

 .../kernel-api/writing-an-alsa-driver.rst      |  1 -
 include/sound/control.h                        |  1 -
 include/sound/pcm.h                            |  1 -
 sound/core/control.c                           | 11 -----------
 sound/core/init.c                              | 11 +----------
 sound/core/pcm_lib.c                           |  8 +-------
 sound/core/pcm_native.c                        | 18 ------------------
 sound/core/timer.c                             | 13 -------------
 8 files changed, 2 insertions(+), 62 deletions(-)

-- 
2.35.3


^ permalink raw reply	[flat|nested] 8+ messages in thread

* [PATCH v2 1/5] ALSA: timer: Drop async signal support
  2022-07-17  7:05 [PATCH v2 0/5] ALSA: Drop async signal support Takashi Iwai
@ 2022-07-17  7:05 ` Takashi Iwai
  2022-07-17  7:05 ` [PATCH v2 2/5] ALSA: pcm: " Takashi Iwai
                   ` (4 subsequent siblings)
  5 siblings, 0 replies; 8+ messages in thread
From: Takashi Iwai @ 2022-07-17  7:05 UTC (permalink / raw)
  To: alsa-devel

The async signal (SIGIO) support for ALSA timer API has been never
used by real applications, but yet it can be a cause of various
potential deadlocks, as spotted by syzkaller.  Let's drop the feature
as the simplest solution.

Reported-by: syzbot+1ee0910eca9c94f71f25@syzkaller.appspotmail.com
Reported-by: syzbot+49b10793b867871ee26f@syzkaller.appspotmail.com
Reported-by: syzbot+8285e973a41b5aa68902@syzkaller.appspotmail.com
Signed-off-by: Takashi Iwai <tiwai@suse.de>
---
 sound/core/timer.c | 13 -------------
 1 file changed, 13 deletions(-)

diff --git a/sound/core/timer.c b/sound/core/timer.c
index b3214baa8919..4ac3ab2cf575 100644
--- a/sound/core/timer.c
+++ b/sound/core/timer.c
@@ -83,7 +83,6 @@ struct snd_timer_user {
 	unsigned int filter;
 	struct timespec64 tstamp;		/* trigger tstamp */
 	wait_queue_head_t qchange_sleep;
-	struct fasync_struct *fasync;
 	struct mutex ioctl_lock;
 };
 
@@ -1345,7 +1344,6 @@ static void snd_timer_user_interrupt(struct snd_timer_instance *timeri,
 	}
       __wake:
 	spin_unlock(&tu->qlock);
-	kill_fasync(&tu->fasync, SIGIO, POLL_IN);
 	wake_up(&tu->qchange_sleep);
 }
 
@@ -1383,7 +1381,6 @@ static void snd_timer_user_ccallback(struct snd_timer_instance *timeri,
 	spin_lock_irqsave(&tu->qlock, flags);
 	snd_timer_user_append_to_tqueue(tu, &r1);
 	spin_unlock_irqrestore(&tu->qlock, flags);
-	kill_fasync(&tu->fasync, SIGIO, POLL_IN);
 	wake_up(&tu->qchange_sleep);
 }
 
@@ -1453,7 +1450,6 @@ static void snd_timer_user_tinterrupt(struct snd_timer_instance *timeri,
 	spin_unlock(&tu->qlock);
 	if (append == 0)
 		return;
-	kill_fasync(&tu->fasync, SIGIO, POLL_IN);
 	wake_up(&tu->qchange_sleep);
 }
 
@@ -2130,14 +2126,6 @@ static long snd_timer_user_ioctl(struct file *file, unsigned int cmd,
 	return ret;
 }
 
-static int snd_timer_user_fasync(int fd, struct file * file, int on)
-{
-	struct snd_timer_user *tu;
-
-	tu = file->private_data;
-	return fasync_helper(fd, file, on, &tu->fasync);
-}
-
 static ssize_t snd_timer_user_read(struct file *file, char __user *buffer,
 				   size_t count, loff_t *offset)
 {
@@ -2280,7 +2268,6 @@ static const struct file_operations snd_timer_f_ops =
 	.poll =		snd_timer_user_poll,
 	.unlocked_ioctl =	snd_timer_user_ioctl,
 	.compat_ioctl =	snd_timer_user_ioctl_compat,
-	.fasync = 	snd_timer_user_fasync,
 };
 
 /* unregister the system timer */
-- 
2.35.3


^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [PATCH v2 2/5] ALSA: pcm: Drop async signal support
  2022-07-17  7:05 [PATCH v2 0/5] ALSA: Drop async signal support Takashi Iwai
  2022-07-17  7:05 ` [PATCH v2 1/5] ALSA: timer: " Takashi Iwai
@ 2022-07-17  7:05 ` Takashi Iwai
  2022-07-17  7:05 ` [PATCH v2 3/5] ALSA: control: " Takashi Iwai
                   ` (3 subsequent siblings)
  5 siblings, 0 replies; 8+ messages in thread
From: Takashi Iwai @ 2022-07-17  7:05 UTC (permalink / raw)
  To: alsa-devel

The async signal (SIGIO) support for ALSA PCM API has been never used
by real applications, but yet it can be a cause of various potential
deadlocks, as spotted by syzkaller.  Let's drop the feature as the
simplest solution.

Reported-by: syzbot+8285e973a41b5aa68902@syzkaller.appspotmail.com
Reported-by: syzbot+669c9abf11a6a011dd09@syzkaller.appspotmail.com
Signed-off-by: Takashi Iwai <tiwai@suse.de>
---
 include/sound/pcm.h     |  1 -
 sound/core/pcm_lib.c    |  8 +-------
 sound/core/pcm_native.c | 18 ------------------
 3 files changed, 1 insertion(+), 26 deletions(-)

diff --git a/include/sound/pcm.h b/include/sound/pcm.h
index 08cf4a5801f3..9bbd3742ef59 100644
--- a/include/sound/pcm.h
+++ b/include/sound/pcm.h
@@ -399,7 +399,6 @@ struct snd_pcm_runtime {
 	snd_pcm_uframes_t twake; 	/* do transfer (!poll) wakeup if non-zero */
 	wait_queue_head_t sleep;	/* poll sleep */
 	wait_queue_head_t tsleep;	/* transfer sleep */
-	struct fasync_struct *fasync;
 	bool stop_operating;		/* sync_stop will be called */
 	struct mutex buffer_mutex;	/* protect for buffer changes */
 	atomic_t buffer_accessing;	/* >0: in r/w operation, <0: blocked */
diff --git a/sound/core/pcm_lib.c b/sound/core/pcm_lib.c
index 1fc7c50ffa62..e490a575aa03 100644
--- a/sound/core/pcm_lib.c
+++ b/sound/core/pcm_lib.c
@@ -1807,22 +1807,16 @@ EXPORT_SYMBOL(snd_pcm_lib_ioctl);
  */
 void snd_pcm_period_elapsed_under_stream_lock(struct snd_pcm_substream *substream)
 {
-	struct snd_pcm_runtime *runtime;
-
 	if (PCM_RUNTIME_CHECK(substream))
 		return;
-	runtime = substream->runtime;
-
 	if (!snd_pcm_running(substream) ||
 	    snd_pcm_update_hw_ptr0(substream, 1) < 0)
-		goto _end;
+		return;
 
 #ifdef CONFIG_SND_PCM_TIMER
 	if (substream->timer_running)
 		snd_timer_interrupt(substream->timer, 1);
 #endif
- _end:
-	kill_fasync(&runtime->fasync, SIGIO, POLL_IN);
 }
 EXPORT_SYMBOL(snd_pcm_period_elapsed_under_stream_lock);
 
diff --git a/sound/core/pcm_native.c b/sound/core/pcm_native.c
index aa0453e51595..c8e340b97277 100644
--- a/sound/core/pcm_native.c
+++ b/sound/core/pcm_native.c
@@ -3938,22 +3938,6 @@ static int snd_pcm_mmap(struct file *file, struct vm_area_struct *area)
 	return 0;
 }
 
-static int snd_pcm_fasync(int fd, struct file * file, int on)
-{
-	struct snd_pcm_file * pcm_file;
-	struct snd_pcm_substream *substream;
-	struct snd_pcm_runtime *runtime;
-
-	pcm_file = file->private_data;
-	substream = pcm_file->substream;
-	if (PCM_RUNTIME_CHECK(substream))
-		return -ENXIO;
-	runtime = substream->runtime;
-	if (runtime->status->state == SNDRV_PCM_STATE_DISCONNECTED)
-		return -EBADFD;
-	return fasync_helper(fd, file, on, &runtime->fasync);
-}
-
 /*
  * ioctl32 compat
  */
@@ -4118,7 +4102,6 @@ const struct file_operations snd_pcm_f_ops[2] = {
 		.unlocked_ioctl =	snd_pcm_ioctl,
 		.compat_ioctl = 	snd_pcm_ioctl_compat,
 		.mmap =			snd_pcm_mmap,
-		.fasync =		snd_pcm_fasync,
 		.get_unmapped_area =	snd_pcm_get_unmapped_area,
 	},
 	{
@@ -4132,7 +4115,6 @@ const struct file_operations snd_pcm_f_ops[2] = {
 		.unlocked_ioctl =	snd_pcm_ioctl,
 		.compat_ioctl = 	snd_pcm_ioctl_compat,
 		.mmap =			snd_pcm_mmap,
-		.fasync =		snd_pcm_fasync,
 		.get_unmapped_area =	snd_pcm_get_unmapped_area,
 	}
 };
-- 
2.35.3


^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [PATCH v2 3/5] ALSA: control: Drop async signal support
  2022-07-17  7:05 [PATCH v2 0/5] ALSA: Drop async signal support Takashi Iwai
  2022-07-17  7:05 ` [PATCH v2 1/5] ALSA: timer: " Takashi Iwai
  2022-07-17  7:05 ` [PATCH v2 2/5] ALSA: pcm: " Takashi Iwai
@ 2022-07-17  7:05 ` Takashi Iwai
  2022-07-17  7:05 ` [PATCH v2 4/5] ALSA: core: " Takashi Iwai
                   ` (2 subsequent siblings)
  5 siblings, 0 replies; 8+ messages in thread
From: Takashi Iwai @ 2022-07-17  7:05 UTC (permalink / raw)
  To: alsa-devel

The async signal (SIGIO) support for ALSA control API has been never
used by real applications, but yet it can be a cause of various
potential deadlocks (although there hasn't been a bug report in this
code path unlike timer and PCM).  Let's drop the feature as the
simplest solution to align with other APIs.

Signed-off-by: Takashi Iwai <tiwai@suse.de>
---
 include/sound/control.h |  1 -
 sound/core/control.c    | 11 -----------
 2 files changed, 12 deletions(-)

diff --git a/include/sound/control.h b/include/sound/control.h
index fcd3cce673ec..0390d4952dac 100644
--- a/include/sound/control.h
+++ b/include/sound/control.h
@@ -109,7 +109,6 @@ 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;
 	int subscribed;			/* read interface is activated */
 	struct list_head events;	/* waiting events for read */
 };
diff --git a/sound/core/control.c b/sound/core/control.c
index 4dba3a342458..3d3b8bf93f80 100644
--- a/sound/core/control.c
+++ b/sound/core/control.c
@@ -181,7 +181,6 @@ 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);
 	}
 	read_unlock_irqrestore(&card->ctl_files_rwlock, flags);
 }
@@ -2129,14 +2128,6 @@ int snd_ctl_unregister_ioctl_compat(snd_kctl_ioctl_func_t fcn)
 EXPORT_SYMBOL(snd_ctl_unregister_ioctl_compat);
 #endif
 
-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 the preferred subdevice number if already assigned;
  * otherwise return -1
  */
@@ -2264,7 +2255,6 @@ static const struct file_operations snd_ctl_f_ops =
 	.poll =		snd_ctl_poll,
 	.unlocked_ioctl =	snd_ctl_ioctl,
 	.compat_ioctl =	snd_ctl_ioctl_compat,
-	.fasync =	snd_ctl_fasync,
 };
 
 /*
@@ -2302,7 +2292,6 @@ 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);
 	}
 	read_unlock_irqrestore(&card->ctl_files_rwlock, flags);
 
-- 
2.35.3


^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [PATCH v2 4/5] ALSA: core: Drop async signal support
  2022-07-17  7:05 [PATCH v2 0/5] ALSA: Drop async signal support Takashi Iwai
                   ` (2 preceding siblings ...)
  2022-07-17  7:05 ` [PATCH v2 3/5] ALSA: control: " Takashi Iwai
@ 2022-07-17  7:05 ` Takashi Iwai
  2022-07-17  7:05 ` [PATCH v2 5/5] ALSA: doc: Drop stale fasync entry Takashi Iwai
  2022-07-17 10:16 ` [PATCH v2 0/5] ALSA: Drop async signal support Jaroslav Kysela
  5 siblings, 0 replies; 8+ messages in thread
From: Takashi Iwai @ 2022-07-17  7:05 UTC (permalink / raw)
  To: alsa-devel

Now fasync support is dropped from all ALSA interfaces, and we can
drop the fasync workaround at the card disconnection code, too.

Signed-off-by: Takashi Iwai <tiwai@suse.de>
---
 sound/core/init.c | 11 +----------
 1 file changed, 1 insertion(+), 10 deletions(-)

diff --git a/sound/core/init.c b/sound/core/init.c
index 3ac95c66a4b5..899bfe838a91 100644
--- a/sound/core/init.c
+++ b/sound/core/init.c
@@ -432,11 +432,8 @@ static int snd_disconnect_release(struct inode *inode, struct file *file)
 	}
 	spin_unlock(&shutdown_lock);
 
-	if (likely(df)) {
-		if ((file->f_flags & FASYNC) && df->disconnected_f_op->fasync)
-			df->disconnected_f_op->fasync(-1, file, 0);
+	if (likely(df))
 		return df->disconnected_f_op->release(inode, file);
-	}
 
 	panic("%s(%p, %p) failed!", __func__, inode, file);
 }
@@ -457,11 +454,6 @@ static int snd_disconnect_mmap(struct file *file, struct vm_area_struct *vma)
 	return -ENODEV;
 }
 
-static int snd_disconnect_fasync(int fd, struct file *file, int on)
-{
-	return -ENODEV;
-}
-
 static const struct file_operations snd_shutdown_f_ops =
 {
 	.owner = 	THIS_MODULE,
@@ -475,7 +467,6 @@ static const struct file_operations snd_shutdown_f_ops =
 	.compat_ioctl = snd_disconnect_ioctl,
 #endif
 	.mmap =		snd_disconnect_mmap,
-	.fasync =	snd_disconnect_fasync
 };
 
 /**
-- 
2.35.3


^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [PATCH v2 5/5] ALSA: doc: Drop stale fasync entry
  2022-07-17  7:05 [PATCH v2 0/5] ALSA: Drop async signal support Takashi Iwai
                   ` (3 preceding siblings ...)
  2022-07-17  7:05 ` [PATCH v2 4/5] ALSA: core: " Takashi Iwai
@ 2022-07-17  7:05 ` Takashi Iwai
  2022-07-17 10:16 ` [PATCH v2 0/5] ALSA: Drop async signal support Jaroslav Kysela
  5 siblings, 0 replies; 8+ messages in thread
From: Takashi Iwai @ 2022-07-17  7:05 UTC (permalink / raw)
  To: alsa-devel

The fasync entry has been dropped recently.  Update the documentation
as well.

Signed-off-by: Takashi Iwai <tiwai@suse.de>
---
 Documentation/sound/kernel-api/writing-an-alsa-driver.rst | 1 -
 1 file changed, 1 deletion(-)

diff --git a/Documentation/sound/kernel-api/writing-an-alsa-driver.rst b/Documentation/sound/kernel-api/writing-an-alsa-driver.rst
index 176b73583b7a..84b4ecae1485 100644
--- a/Documentation/sound/kernel-api/writing-an-alsa-driver.rst
+++ b/Documentation/sound/kernel-api/writing-an-alsa-driver.rst
@@ -1597,7 +1597,6 @@ are the contents of this file:
           spinlock_t lock;
           wait_queue_head_t sleep;
           struct timer_list tick_timer;
-          struct fasync_struct *fasync;
 
           /* -- private section -- */
           void *private_data;
-- 
2.35.3


^ permalink raw reply related	[flat|nested] 8+ messages in thread

* Re: [PATCH v2 0/5] ALSA: Drop async signal support
  2022-07-17  7:05 [PATCH v2 0/5] ALSA: Drop async signal support Takashi Iwai
                   ` (4 preceding siblings ...)
  2022-07-17  7:05 ` [PATCH v2 5/5] ALSA: doc: Drop stale fasync entry Takashi Iwai
@ 2022-07-17 10:16 ` Jaroslav Kysela
  2022-07-25 14:52   ` Takashi Iwai
  5 siblings, 1 reply; 8+ messages in thread
From: Jaroslav Kysela @ 2022-07-17 10:16 UTC (permalink / raw)
  To: alsa-devel; +Cc: Takashi Iwai

Dne 17. 07. 22 v 9:05 Takashi Iwai napsal(a):
> Hi,
> 
> this is a revised patch set for dropping fasync support from ALSA
> core.
> 
> The async signal itself is very difficult to use properly due to
> various restrictions (e.g. you cannot perform any I/O in the context),
> hence it's a feature that has been never used by real applications.
> 
> OTOH, the real problem is that there have been quite a few syzcaller
> reports indicating that fasync code path may lead to some potential
> deadlocks for long time.  Dropping the feature is the easiest
> solution, obviously.

I would probably prefer to fix the problem (deferred async kill or so). The
SIGIO is just another way to wakeup the applications and there may be some
corner cases, where this wakeup is usable (threaded apps). Note that we had
some users (or testers) of SIGIO in past (at least there were questions about
this support).

					Jaroslav

-- 
Jaroslav Kysela <perex@perex.cz>
Linux Sound Maintainer; ALSA Project; Red Hat, Inc.

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH v2 0/5] ALSA: Drop async signal support
  2022-07-17 10:16 ` [PATCH v2 0/5] ALSA: Drop async signal support Jaroslav Kysela
@ 2022-07-25 14:52   ` Takashi Iwai
  0 siblings, 0 replies; 8+ messages in thread
From: Takashi Iwai @ 2022-07-25 14:52 UTC (permalink / raw)
  To: Jaroslav Kysela; +Cc: alsa-devel

On Sun, 17 Jul 2022 12:16:13 +0200,
Jaroslav Kysela wrote:
> 
> Dne 17. 07. 22 v 9:05 Takashi Iwai napsal(a):
> > Hi,
> > 
> > this is a revised patch set for dropping fasync support from ALSA
> > core.
> > 
> > The async signal itself is very difficult to use properly due to
> > various restrictions (e.g. you cannot perform any I/O in the context),
> > hence it's a feature that has been never used by real applications.
> > 
> > OTOH, the real problem is that there have been quite a few syzcaller
> > reports indicating that fasync code path may lead to some potential
> > deadlocks for long time.  Dropping the feature is the easiest
> > solution, obviously.
> 
> I would probably prefer to fix the problem (deferred async kill or so). The
> SIGIO is just another way to wakeup the applications and there may be some
> corner cases, where this wakeup is usable (threaded apps). Note that we had
> some users (or testers) of SIGIO in past (at least there were questions about
> this support).

Hm, OK, then let's discard it for now.

The deferred kill_async() implementation would be something like below.
A quick test looks OK, so far, with the given syzkaller reproducer.

Ideally speaking, this should be fixed in the fasync sighandler side,
but it appears fragile -- kill_fasync() calls send_sigio(), and
send_sigio() takes read_lock(&tasklist_lock).  And
read_lock(&tasklist_lock) itself is a common pattern taken in the
non/soft-IRQ contexts, which would conflict with the call in an
hard-IRQ context...


thanks,

Takashi

-- 8< --
diff --git a/include/sound/control.h b/include/sound/control.h
index fcd3cce673ec..eae443ba79ba 100644
--- a/include/sound/control.h
+++ b/include/sound/control.h
@@ -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 */
 };
diff --git a/include/sound/core.h b/include/sound/core.h
index dd28de2343b8..4365c35d038b 100644
--- a/include/sound/core.h
+++ b/include/sound/core.h
@@ -507,4 +507,12 @@ snd_pci_quirk_lookup_id(u16 vendor, u16 device,
 }
 #endif
 
+/* async signal helpers */
+struct snd_fasync;
+
+int snd_fasync_helper(int fd, struct file *file, int on,
+		      struct snd_fasync **fasyncp);
+void snd_kill_fasync(struct snd_fasync *fasync, int signal, int poll);
+void snd_fasync_free(struct snd_fasync *fasync);
+
 #endif /* __SOUND_CORE_H */
diff --git a/include/sound/pcm.h b/include/sound/pcm.h
index 2d03c10f6a36..8c48a5bce88c 100644
--- a/include/sound/pcm.h
+++ b/include/sound/pcm.h
@@ -399,7 +399,7 @@ struct snd_pcm_runtime {
 	snd_pcm_uframes_t twake; 	/* do transfer (!poll) wakeup if non-zero */
 	wait_queue_head_t sleep;	/* poll sleep */
 	wait_queue_head_t tsleep;	/* transfer sleep */
-	struct fasync_struct *fasync;
+	struct snd_fasync *fasync;
 	bool stop_operating;		/* sync_stop will be called */
 	struct mutex buffer_mutex;	/* protect for buffer changes */
 	atomic_t buffer_accessing;	/* >0: in r/w operation, <0: blocked */
diff --git a/sound/core/control.c b/sound/core/control.c
index 4dba3a342458..f3e893715369 100644
--- a/sound/core/control.c
+++ b/sound/core/control.c
@@ -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);
@@ -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);
 }
@@ -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;
@@ -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);
 
diff --git a/sound/core/misc.c b/sound/core/misc.c
index 50e4aaa6270d..f9d100905b98 100644
--- a/sound/core/misc.c
+++ b/sound/core/misc.c
@@ -145,3 +145,53 @@ snd_pci_quirk_lookup(struct pci_dev *pci, const struct snd_pci_quirk *list)
 }
 EXPORT_SYMBOL(snd_pci_quirk_lookup);
 #endif
+
+/* async signal helpers */
+struct snd_fasync {
+	struct fasync_struct *fasync;
+	struct work_struct work;
+	int signal;
+	int poll;
+};
+
+static void snd_fasync_work(struct work_struct *work)
+{
+	struct snd_fasync *fasync = container_of(work, struct snd_fasync, work);
+
+	kill_fasync(&fasync->fasync, fasync->signal, fasync->poll);
+}
+
+int snd_fasync_helper(int fd, struct file *file, int on,
+		      struct snd_fasync **fasyncp)
+{
+	struct snd_fasync *fasync = *fasyncp;
+
+	if (!fasync) {
+		fasync = kzalloc(sizeof(*fasync), GFP_KERNEL);
+		if (!fasync)
+			return -ENOMEM;
+		INIT_WORK(&fasync->work, snd_fasync_work);
+		*fasyncp = fasync;
+	}
+	return fasync_helper(fd, file, on, &fasync->fasync);
+}
+EXPORT_SYMBOL_GPL(snd_fasync_helper);
+
+void snd_kill_fasync(struct snd_fasync *fasync, int signal, int poll)
+{
+	if (!fasync)
+		return;
+	fasync->signal = signal;
+	fasync->poll = poll;
+	schedule_work(&fasync->work);
+}
+EXPORT_SYMBOL_GPL(snd_kill_fasync);
+
+void snd_fasync_free(struct snd_fasync *fasync)
+{
+	if (!fasync)
+		return;
+	cancel_work_sync(&fasync->work);
+	kfree(fasync);
+}
+EXPORT_SYMBOL_GPL(snd_fasync_free);
diff --git a/sound/core/pcm.c b/sound/core/pcm.c
index 03fc5fa5813e..2ac742035310 100644
--- a/sound/core/pcm.c
+++ b/sound/core/pcm.c
@@ -1007,6 +1007,7 @@ void snd_pcm_detach_substream(struct snd_pcm_substream *substream)
 		substream->runtime = NULL;
 	}
 	mutex_destroy(&runtime->buffer_mutex);
+	snd_fasync_free(runtime->fasync);
 	kfree(runtime);
 	put_pid(substream->pid);
 	substream->pid = NULL;
diff --git a/sound/core/pcm_lib.c b/sound/core/pcm_lib.c
index 1fc7c50ffa62..40751e5aff09 100644
--- a/sound/core/pcm_lib.c
+++ b/sound/core/pcm_lib.c
@@ -1822,7 +1822,7 @@ void snd_pcm_period_elapsed_under_stream_lock(struct snd_pcm_substream *substrea
 		snd_timer_interrupt(substream->timer, 1);
 #endif
  _end:
-	kill_fasync(&runtime->fasync, SIGIO, POLL_IN);
+	snd_kill_fasync(runtime->fasync, SIGIO, POLL_IN);
 }
 EXPORT_SYMBOL(snd_pcm_period_elapsed_under_stream_lock);
 
diff --git a/sound/core/pcm_native.c b/sound/core/pcm_native.c
index aa0453e51595..ad0541e9e888 100644
--- a/sound/core/pcm_native.c
+++ b/sound/core/pcm_native.c
@@ -3951,7 +3951,7 @@ static int snd_pcm_fasync(int fd, struct file * file, int on)
 	runtime = substream->runtime;
 	if (runtime->status->state == SNDRV_PCM_STATE_DISCONNECTED)
 		return -EBADFD;
-	return fasync_helper(fd, file, on, &runtime->fasync);
+	return snd_fasync_helper(fd, file, on, &runtime->fasync);
 }
 
 /*
diff --git a/sound/core/timer.c b/sound/core/timer.c
index b3214baa8919..e08a37c23add 100644
--- a/sound/core/timer.c
+++ b/sound/core/timer.c
@@ -83,7 +83,7 @@ struct snd_timer_user {
 	unsigned int filter;
 	struct timespec64 tstamp;		/* trigger tstamp */
 	wait_queue_head_t qchange_sleep;
-	struct fasync_struct *fasync;
+	struct snd_fasync *fasync;
 	struct mutex ioctl_lock;
 };
 
@@ -1345,7 +1345,7 @@ static void snd_timer_user_interrupt(struct snd_timer_instance *timeri,
 	}
       __wake:
 	spin_unlock(&tu->qlock);
-	kill_fasync(&tu->fasync, SIGIO, POLL_IN);
+	snd_kill_fasync(tu->fasync, SIGIO, POLL_IN);
 	wake_up(&tu->qchange_sleep);
 }
 
@@ -1383,7 +1383,7 @@ static void snd_timer_user_ccallback(struct snd_timer_instance *timeri,
 	spin_lock_irqsave(&tu->qlock, flags);
 	snd_timer_user_append_to_tqueue(tu, &r1);
 	spin_unlock_irqrestore(&tu->qlock, flags);
-	kill_fasync(&tu->fasync, SIGIO, POLL_IN);
+	snd_kill_fasync(tu->fasync, SIGIO, POLL_IN);
 	wake_up(&tu->qchange_sleep);
 }
 
@@ -1453,7 +1453,7 @@ static void snd_timer_user_tinterrupt(struct snd_timer_instance *timeri,
 	spin_unlock(&tu->qlock);
 	if (append == 0)
 		return;
-	kill_fasync(&tu->fasync, SIGIO, POLL_IN);
+	snd_kill_fasync(tu->fasync, SIGIO, POLL_IN);
 	wake_up(&tu->qchange_sleep);
 }
 
@@ -1521,6 +1521,7 @@ static int snd_timer_user_release(struct inode *inode, struct file *file)
 			snd_timer_instance_free(tu->timeri);
 		}
 		mutex_unlock(&tu->ioctl_lock);
+		snd_fasync_free(tu->fasync);
 		kfree(tu->queue);
 		kfree(tu->tqueue);
 		kfree(tu);
@@ -2135,7 +2136,7 @@ static int snd_timer_user_fasync(int fd, struct file * file, int on)
 	struct snd_timer_user *tu;
 
 	tu = file->private_data;
-	return fasync_helper(fd, file, on, &tu->fasync);
+	return snd_fasync_helper(fd, file, on, &tu->fasync);
 }
 
 static ssize_t snd_timer_user_read(struct file *file, char __user *buffer,

^ permalink raw reply related	[flat|nested] 8+ messages in thread

end of thread, other threads:[~2022-07-25 14:53 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-07-17  7:05 [PATCH v2 0/5] ALSA: Drop async signal support Takashi Iwai
2022-07-17  7:05 ` [PATCH v2 1/5] ALSA: timer: " Takashi Iwai
2022-07-17  7:05 ` [PATCH v2 2/5] ALSA: pcm: " Takashi Iwai
2022-07-17  7:05 ` [PATCH v2 3/5] ALSA: control: " Takashi Iwai
2022-07-17  7:05 ` [PATCH v2 4/5] ALSA: core: " Takashi Iwai
2022-07-17  7:05 ` [PATCH v2 5/5] ALSA: doc: Drop stale fasync entry Takashi Iwai
2022-07-17 10:16 ` [PATCH v2 0/5] ALSA: Drop async signal support Jaroslav Kysela
2022-07-25 14:52   ` Takashi Iwai

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.