Linux Sound subsystem development
 help / color / mirror / Atom feed
* [PATCH] ALSA: seq: Use flexible array for MIDI channels
@ 2026-05-11  7:54 Rosen Penev
  0 siblings, 0 replies; only message in thread
From: Rosen Penev @ 2026-05-11  7:54 UTC (permalink / raw)
  To: linux-sound
  Cc: Jaroslav Kysela, Takashi Iwai, Kees Cook, Gustavo A. R. Silva,
	open list,
	open list:KERNEL HARDENING (not covered by other areas):Keyword:b__counted_by(_le|_be)?b

Store MIDI channel entries in the MIDI channel set allocation instead
of allocating them separately.

This ties the channel array lifetime directly to the channel set, removes
a separate allocation failure path, and lets __counted_by() describe the
array bounds. Move the embedded emux channel set to the end of its
containing structure so it can carry the flexible array.

Assisted-by: Codex:GPT-5.5
Signed-off-by: Rosen Penev <rosenp@gmail.com>
---
 include/sound/emux_synth.h     |  2 +-
 include/sound/seq_midi_emul.h  |  6 +++---
 sound/core/seq/seq_midi_emul.c | 38 ++++++++++------------------------
 sound/synth/emux/emux_seq.c    | 11 +++-------
 4 files changed, 18 insertions(+), 39 deletions(-)

diff --git a/include/sound/emux_synth.h b/include/sound/emux_synth.h
index 3f7f365ed248..2c0a976e00ab 100644
--- a/include/sound/emux_synth.h
+++ b/include/sound/emux_synth.h
@@ -125,7 +125,6 @@ struct snd_emux {
  */
 struct snd_emux_port {
 
-	struct snd_midi_channel_set chset;
 	struct snd_emux *emu;
 
 	char port_mode;			/* operation mode */
@@ -138,6 +137,7 @@ struct snd_emux_port {
 #if IS_ENABLED(CONFIG_SND_SEQUENCER_OSS)
 	struct snd_seq_oss_arg *oss_arg;
 #endif
+	struct snd_midi_channel_set chset;
 };
 
 /* port_mode */
diff --git a/include/sound/seq_midi_emul.h b/include/sound/seq_midi_emul.h
index 88799d1e1f53..afc765437870 100644
--- a/include/sound/seq_midi_emul.h
+++ b/include/sound/seq_midi_emul.h
@@ -55,14 +55,14 @@ struct snd_midi_channel_set {
 	int  client;			/* Client for this port */
 	int  port;			/* The port number */
 
-	int  max_channels;		/* Size of the channels array */
-	struct snd_midi_channel *channels;
-
 	unsigned char midi_mode;	/* MIDI operating mode */
 	unsigned char gs_master_volume;	/* SYSEX master volume: 0-127 */
 	unsigned char gs_chorus_mode;
 	unsigned char gs_reverb_mode;
 
+	int  max_channels;		/* Size of the channels array */
+	struct snd_midi_channel channels[] __counted_by(max_channels);
+
 };
 
 struct snd_midi_op {
diff --git a/sound/core/seq/seq_midi_emul.c b/sound/core/seq/seq_midi_emul.c
index fd067c85c524..a90ebc7b3811 100644
--- a/sound/core/seq/seq_midi_emul.c
+++ b/sound/core/seq/seq_midi_emul.c
@@ -81,9 +81,6 @@ snd_midi_process_event(const struct snd_midi_op *ops,
 		pr_debug("ALSA: seq_midi_emul: ev or chanbase NULL (snd_midi_process_event)\n");
 		return;
 	}
-	if (chanset->channels == NULL)
-		return;
-
 	if (snd_seq_ev_is_channel_type(ev)) {
 		dest_channel = ev->data.note.channel;
 		if (dest_channel >= chanset->max_channels) {
@@ -642,23 +639,6 @@ static void snd_midi_channel_init(struct snd_midi_channel *p, int n)
 		p->drum_channel = 1;	/* Default ch 10 as drums */
 }
 
-/*
- * Allocate and initialise a set of midi channel control blocks.
- */
-static struct snd_midi_channel *snd_midi_channel_init_set(int n)
-{
-	struct snd_midi_channel *chan;
-	int  i;
-
-	chan = kmalloc_objs(struct snd_midi_channel, n);
-	if (chan) {
-		for (i = 0; i < n; i++)
-			snd_midi_channel_init(chan+i, i);
-	}
-
-	return chan;
-}
-
 /*
  * reset all midi channels
  */
@@ -687,13 +667,18 @@ reset_all_channels(struct snd_midi_channel_set *chset)
 struct snd_midi_channel_set *snd_midi_channel_alloc_set(int n)
 {
 	struct snd_midi_channel_set *chset;
+	int i;
+
+	chset = kmalloc_flex(*chset, channels, n);
+	if (!chset)
+		return NULL;
+
+	chset->max_channels = n;
+	chset->private_data = NULL;
+
+	for (i = 0; i < n; i++)
+		snd_midi_channel_init(&chset->channels[i], i);
 
-	chset = kmalloc_obj(*chset);
-	if (chset) {
-		chset->channels = snd_midi_channel_init_set(n);
-		chset->private_data = NULL;
-		chset->max_channels = n;
-	}
 	return chset;
 }
 EXPORT_SYMBOL(snd_midi_channel_alloc_set);
@@ -717,7 +702,6 @@ void snd_midi_channel_free_set(struct snd_midi_channel_set *chset)
 {
 	if (chset == NULL)
 		return;
-	kfree(chset->channels);
 	kfree(chset);
 }
 EXPORT_SYMBOL(snd_midi_channel_free_set);
diff --git a/sound/synth/emux/emux_seq.c b/sound/synth/emux/emux_seq.c
index 2ed01e9d79bb..01ad5b12b680 100644
--- a/sound/synth/emux/emux_seq.c
+++ b/sound/synth/emux/emux_seq.c
@@ -132,19 +132,15 @@ snd_emux_create_port(struct snd_emux *emu, char *name,
 	int i, type, cap;
 
 	/* Allocate structures for this channel */
-	p = kzalloc_obj(*p);
+	p = kzalloc_flex(*p, chset.channels, max_channels);
 	if (!p)
 		return NULL;
 
-	p->chset.channels = kzalloc_objs(*p->chset.channels, max_channels);
-	if (!p->chset.channels) {
-		kfree(p);
-		return NULL;
-	}
+	p->chset.max_channels = max_channels;
+
 	for (i = 0; i < max_channels; i++)
 		p->chset.channels[i].number = i;
 	p->chset.private_data = p;
-	p->chset.max_channels = max_channels;
 	p->emu = emu;
 	p->chset.client = emu->client;
 #ifdef SNDRV_EMUX_USE_RAW_EFFECT
@@ -182,7 +178,6 @@ free_port(void *private_data)
 #ifdef SNDRV_EMUX_USE_RAW_EFFECT
 		snd_emux_delete_effect(p);
 #endif
-		kfree(p->chset.channels);
 		kfree(p);
 	}
 }
-- 
2.54.0


^ permalink raw reply related	[flat|nested] only message in thread

only message in thread, other threads:[~2026-05-11  7:55 UTC | newest]

Thread overview: (only message) (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-05-11  7:54 [PATCH] ALSA: seq: Use flexible array for MIDI channels Rosen Penev

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