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 <[email protected]> --- 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

