Linux Sound subsystem development
 help / color / mirror / Atom feed
* [PATCH] ALSA: timer: keep a list of open masters for slave lookup
@ 2026-03-16 13:39 Cássio Gabriel
  2026-03-17  8:17 ` Takashi Iwai
  0 siblings, 1 reply; 2+ messages in thread
From: Cássio Gabriel @ 2026-03-16 13:39 UTC (permalink / raw)
  To: Takashi Iwai, Jaroslav Kysela
  Cc: linux-sound, linux-kernel, Cássio Gabriel

snd_timer_check_slave() still walks all registered timers and all open
timer instances to find a matching master for a newly opened slave.

Maintain a global list of open master instances that can accept slave
links and use it for the slave lookup path instead. This keeps the
existing matching semantics while avoiding the nested walk over
snd_timer_list and each timer open_list_head.

The reverse path in snd_timer_check_master() already scans only the
pending slave list, so this makes both lookup paths closer in shape
without changing the master/slave linking logic.

Signed-off-by: Cássio Gabriel <cassiogabrielcontato@gmail.com>
---
 include/sound/timer.h |  1 +
 sound/core/timer.c    | 29 ++++++++++++++++++++---------
 2 files changed, 21 insertions(+), 9 deletions(-)

diff --git a/include/sound/timer.h b/include/sound/timer.h
index 760e132cc0cd..83bafe70cf33 100644
--- a/include/sound/timer.h
+++ b/include/sound/timer.h
@@ -102,6 +102,7 @@ struct snd_timer_instance {
 	unsigned int slave_id;
 	struct list_head open_list;
 	struct list_head active_list;
+	struct list_head master_list;
 	struct list_head ack_list;
 	struct list_head slave_list_head;
 	struct list_head slave_active_head;
diff --git a/sound/core/timer.c b/sound/core/timer.c
index 6a70df7ae019..820901d503af 100644
--- a/sound/core/timer.c
+++ b/sound/core/timer.c
@@ -129,6 +129,9 @@ static LIST_HEAD(snd_timer_list);
 /* list of slave instances */
 static LIST_HEAD(snd_timer_slave_list);
 
+/* list of open master instances that can accept slave links */
+static LIST_HEAD(snd_timer_master_list);
+
 /* lock for slave active lists */
 static DEFINE_SPINLOCK(slave_active_lock);
 
@@ -161,6 +164,7 @@ struct snd_timer_instance *snd_timer_instance_new(const char *owner)
 	}
 	INIT_LIST_HEAD(&timeri->open_list);
 	INIT_LIST_HEAD(&timeri->active_list);
+	INIT_LIST_HEAD(&timeri->master_list);
 	INIT_LIST_HEAD(&timeri->ack_list);
 	INIT_LIST_HEAD(&timeri->slave_list_head);
 	INIT_LIST_HEAD(&timeri->slave_active_head);
@@ -245,6 +249,12 @@ static int check_matching_master_slave(struct snd_timer_instance *master,
 	return 1;
 }
 
+static bool snd_timer_has_slave_key(const struct snd_timer_instance *timeri)
+{
+	return !(timeri->flags & SNDRV_TIMER_IFLG_SLAVE) &&
+		timeri->slave_class > SNDRV_TIMER_SCLASS_NONE;
+}
+
 /*
  * look for a master instance matching with the slave id of the given slave.
  * when found, relink the open_link of the slave.
@@ -253,19 +263,15 @@ static int check_matching_master_slave(struct snd_timer_instance *master,
  */
 static int snd_timer_check_slave(struct snd_timer_instance *slave)
 {
-	struct snd_timer *timer;
 	struct snd_timer_instance *master;
 	int err = 0;
 
-	/* FIXME: it's really dumb to look up all entries.. */
-	list_for_each_entry(timer, &snd_timer_list, device_list) {
-		list_for_each_entry(master, &timer->open_list_head, open_list) {
-			err = check_matching_master_slave(master, slave);
-			if (err != 0) /* match found or error */
-				goto out;
-		}
+	list_for_each_entry(master, &snd_timer_master_list, master_list) {
+		err = check_matching_master_slave(master, slave);
+		if (err != 0) /* match found or error */
+			goto out;
 	}
- out:
+out:
 	return err < 0 ? err : 0;
 }
 
@@ -377,6 +383,8 @@ int snd_timer_open(struct snd_timer_instance *timeri,
 	timeri->slave_id = slave_id;
 
 	list_add_tail(&timeri->open_list, &timer->open_list_head);
+	if (snd_timer_has_slave_key(timeri))
+		list_add_tail(&timeri->master_list, &snd_timer_master_list);
 	timer->num_instances++;
 	err = snd_timer_check_master(timeri);
 list_added:
@@ -431,6 +439,9 @@ static void snd_timer_close_locked(struct snd_timer_instance *timeri,
 			num_slaves--;
 	}
 
+	if (!list_empty(&timeri->master_list))
+		list_del_init(&timeri->master_list);
+
 	/* force to stop the timer */
 	snd_timer_stop(timeri);
 

---
base-commit: 6447e32cb0a0b05b75d7a591501660ac3cfe5c31
change-id: 20260316-alsa-timer-master-list-f2e4db58596d

Best regards,
-- 
Cássio Gabriel <cassiogabrielcontato@gmail.com>


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

* Re: [PATCH] ALSA: timer: keep a list of open masters for slave lookup
  2026-03-16 13:39 [PATCH] ALSA: timer: keep a list of open masters for slave lookup Cássio Gabriel
@ 2026-03-17  8:17 ` Takashi Iwai
  0 siblings, 0 replies; 2+ messages in thread
From: Takashi Iwai @ 2026-03-17  8:17 UTC (permalink / raw)
  To: Cássio Gabriel
  Cc: Takashi Iwai, Jaroslav Kysela, linux-sound, linux-kernel

On Mon, 16 Mar 2026 14:39:38 +0100,
Cássio Gabriel wrote:
> 
> snd_timer_check_slave() still walks all registered timers and all open
> timer instances to find a matching master for a newly opened slave.
> 
> Maintain a global list of open master instances that can accept slave
> links and use it for the slave lookup path instead. This keeps the
> existing matching semantics while avoiding the nested walk over
> snd_timer_list and each timer open_list_head.
> 
> The reverse path in snd_timer_check_master() already scans only the
> pending slave list, so this makes both lookup paths closer in shape
> without changing the master/slave linking logic.
> 
> Signed-off-by: Cássio Gabriel <cassiogabrielcontato@gmail.com>

Thanks, applied to for-next branch now.


Takashi

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

end of thread, other threads:[~2026-03-17  8:17 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-03-16 13:39 [PATCH] ALSA: timer: keep a list of open masters for slave lookup Cássio Gabriel
2026-03-17  8:17 ` Takashi Iwai

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox