<feed xmlns='http://www.w3.org/2005/Atom'>
<title>linux-stable.git/sound/core/seq, branch master</title>
<subtitle>Linux kernel stable tree</subtitle>
<link rel='alternate' type='text/html' href='https://git.tavy.me/linux-stable.git/'/>
<entry>
<title>ALSA: seq: midi: Serialize input teardown with event_input</title>
<updated>2026-08-13T16:21:51+00:00</updated>
<author>
<name>John Keeping</name>
<email>jkeeping@inmusicbrands.com</email>
</author>
<published>2026-08-13T15:08:08+00:00</published>
<link rel='alternate' type='text/html' href='https://git.tavy.me/linux-stable.git/commit/?id=403f7f3ad3808a0096d84cf228fab68dc253fd9d'/>
<id>403f7f3ad3808a0096d84cf228fab68dc253fd9d</id>
<content type='text'>
snd_midi_input_event() must not be running while a rawmidi substream is
closing, since this can lead to the trigger state becoming out-of-step
through this sequence in snd_rawmidi_input_trigger():

	snd_rawmidi_input_trigger(up=0)
					snd_midi_input_event()
					 -&gt; snd_rawmidi_kernel_read()
					     -&gt; snd_rawmidi_input_trigger(up=1)
	  -&gt; cancel_work_sync()

which ends with the underlying device being active unexpectedly.

When this is called from close_substream(), further input can re-trigger
the input event leaving it running after rawmidi_release_priv() has set
rfile-&gt;rmidi to NULL which leads to:

	Unable to handle kernel NULL pointer dereference at virtual address 00000000000000b0
	Call trace:
	 snd_midi_input_event+0x3c/0x134 [snd_seq_midi] (P)
	 snd_rawmidi_input_event_work+0x1c/0x2c
	 process_one_work+0x150/0x3a4
	 worker_thread+0x190/0x318

Apply a similar approach to commit ef7607ab1c8ad ("ALSA: seq: midi:
Serialize output teardown with event_input") which fixed the same issue
in the output direction, but updated to use RCU following Takashi Iwai's
proposed follow-on patch [1].

With this change in place, midisynth_unsubscribe() clears the input file
so snd_midi_input_event() will not re-trigger the stream and will be
quiesced by the cancel_work_sync() in snd_rawmidi_input_trigger().

[1] https://lore.kernel.org/linux-sound/20260813144224.753399-1-tiwai@suse.de/

Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
Signed-off-by: John Keeping &lt;jkeeping@inmusicbrands.com&gt;
Link: https://patch.msgid.link/20260813150810.795393-1-jkeeping@inmusicbrands.com
Signed-off-by: Takashi Iwai &lt;tiwai@suse.de&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
snd_midi_input_event() must not be running while a rawmidi substream is
closing, since this can lead to the trigger state becoming out-of-step
through this sequence in snd_rawmidi_input_trigger():

	snd_rawmidi_input_trigger(up=0)
					snd_midi_input_event()
					 -&gt; snd_rawmidi_kernel_read()
					     -&gt; snd_rawmidi_input_trigger(up=1)
	  -&gt; cancel_work_sync()

which ends with the underlying device being active unexpectedly.

When this is called from close_substream(), further input can re-trigger
the input event leaving it running after rawmidi_release_priv() has set
rfile-&gt;rmidi to NULL which leads to:

	Unable to handle kernel NULL pointer dereference at virtual address 00000000000000b0
	Call trace:
	 snd_midi_input_event+0x3c/0x134 [snd_seq_midi] (P)
	 snd_rawmidi_input_event_work+0x1c/0x2c
	 process_one_work+0x150/0x3a4
	 worker_thread+0x190/0x318

Apply a similar approach to commit ef7607ab1c8ad ("ALSA: seq: midi:
Serialize output teardown with event_input") which fixed the same issue
in the output direction, but updated to use RCU following Takashi Iwai's
proposed follow-on patch [1].

With this change in place, midisynth_unsubscribe() clears the input file
so snd_midi_input_event() will not re-trigger the stream and will be
quiesced by the cancel_work_sync() in snd_rawmidi_input_trigger().

[1] https://lore.kernel.org/linux-sound/20260813144224.753399-1-tiwai@suse.de/

Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
Signed-off-by: John Keeping &lt;jkeeping@inmusicbrands.com&gt;
Link: https://patch.msgid.link/20260813150810.795393-1-jkeeping@inmusicbrands.com
Signed-off-by: Takashi Iwai &lt;tiwai@suse.de&gt;
</pre>
</div>
</content>
</entry>
<entry>
<title>ALSA: seq: midi: Optimize event_input locking with RCU</title>
<updated>2026-08-13T16:21:17+00:00</updated>
<author>
<name>Takashi Iwai</name>
<email>tiwai@suse.de</email>
</author>
<published>2026-08-13T14:42:16+00:00</published>
<link rel='alternate' type='text/html' href='https://git.tavy.me/linux-stable.git/commit/?id=4cc25cdd3cffa475edb8dec8199b3227038ebcfb'/>
<id>4cc25cdd3cffa475edb8dec8199b3227038ebcfb</id>
<content type='text'>
The recent fix for serializing the output teardown introduced a
spinlock invocation at every MIDI output event via event_process_midi.
Since this is a hot path, let's do performance optimization with RCU.

The new output_substream __rcu pointer is published via
rcu_assign_pointer() in midisynth_use() after output_rfile is set, and
cleared in midisynth_unuse() before the resource teardown.
event_process_midi() reads it under rcu_read_lock() and bumps
output_use_lock inside that section, which is necessary to close the
window between the pointer dereference and the refcount increment.

midisynth_unuse() calls synchronize_rcu() before snd_use_lock_sync():
this guarantees that any reader who obtained a non-NULL pointer has
already called atomic_inc (output_use_lock), so the subsequent
snd_use_lock_sync() sees the correct in-flight count.

Fixes: ef7607ab1c8a ("ALSA: seq: midi: Serialize output teardown with event_input")
Link: https://patch.msgid.link/20260813144224.753399-1-tiwai@suse.de
Signed-off-by: Takashi Iwai &lt;tiwai@suse.de&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
The recent fix for serializing the output teardown introduced a
spinlock invocation at every MIDI output event via event_process_midi.
Since this is a hot path, let's do performance optimization with RCU.

The new output_substream __rcu pointer is published via
rcu_assign_pointer() in midisynth_use() after output_rfile is set, and
cleared in midisynth_unuse() before the resource teardown.
event_process_midi() reads it under rcu_read_lock() and bumps
output_use_lock inside that section, which is necessary to close the
window between the pointer dereference and the refcount increment.

midisynth_unuse() calls synchronize_rcu() before snd_use_lock_sync():
this guarantees that any reader who obtained a non-NULL pointer has
already called atomic_inc (output_use_lock), so the subsequent
snd_use_lock_sync() sees the correct in-flight count.

Fixes: ef7607ab1c8a ("ALSA: seq: midi: Serialize output teardown with event_input")
Link: https://patch.msgid.link/20260813144224.753399-1-tiwai@suse.de
Signed-off-by: Takashi Iwai &lt;tiwai@suse.de&gt;
</pre>
</div>
</content>
</entry>
<entry>
<title>ALSA: seq: Drop the dead struct snd_seq_event_bounce</title>
<updated>2026-08-12T14:39:11+00:00</updated>
<author>
<name>HyeongJun An</name>
<email>sammiee5311@gmail.com</email>
</author>
<published>2026-08-12T14:15:06+00:00</published>
<link rel='alternate' type='text/html' href='https://git.tavy.me/linux-stable.git/commit/?id=0414dd7b6f8b8619c8f1595ba04edb43d405581e'/>
<id>0414dd7b6f8b8619c8f1595ba04edb43d405581e</id>
<content type='text'>
The struct describes a bounce payload of an error code followed by the
original event and its external data.  No kernel has ever sent that.
Before commit efc86691e4d8 ("ALSA: seq: Fix kernel heap address leak in
bounce_error_event()") the kernel emitted no SNDRV_SEQ_EVENT_BOUNCE at
all, and since then it sends the event record alone.

Nothing has ever read it either.  Its only accessor,
snd_seq_event_bounce_ext_data(), has had no caller for the whole git
history, and it did not even compile until commit c7e0b5bf9fff ("[ALSA]
Remove xxx_t typedefs: Sequencer") incidentally repaired the type name
it referred to, three years after the git import.  Drop the accessor
along with the struct.

This removes a definition from a UAPI header.  Since no kernel ever
produced the layout, nothing can have parsed it, but a program that
merely names the type will need to stop.

Suggested-by: Takashi Iwai &lt;tiwai@suse.de&gt;
Assisted-by: Claude:claude-opus-5
Signed-off-by: HyeongJun An &lt;sammiee5311@gmail.com&gt;
Link: https://patch.msgid.link/20260812141506.4016387-1-sammiee5311@gmail.com
Signed-off-by: Takashi Iwai &lt;tiwai@suse.de&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
The struct describes a bounce payload of an error code followed by the
original event and its external data.  No kernel has ever sent that.
Before commit efc86691e4d8 ("ALSA: seq: Fix kernel heap address leak in
bounce_error_event()") the kernel emitted no SNDRV_SEQ_EVENT_BOUNCE at
all, and since then it sends the event record alone.

Nothing has ever read it either.  Its only accessor,
snd_seq_event_bounce_ext_data(), has had no caller for the whole git
history, and it did not even compile until commit c7e0b5bf9fff ("[ALSA]
Remove xxx_t typedefs: Sequencer") incidentally repaired the type name
it referred to, three years after the git import.  Drop the accessor
along with the struct.

This removes a definition from a UAPI header.  Since no kernel ever
produced the layout, nothing can have parsed it, but a program that
merely names the type will need to stop.

Suggested-by: Takashi Iwai &lt;tiwai@suse.de&gt;
Assisted-by: Claude:claude-opus-5
Signed-off-by: HyeongJun An &lt;sammiee5311@gmail.com&gt;
Link: https://patch.msgid.link/20260812141506.4016387-1-sammiee5311@gmail.com
Signed-off-by: Takashi Iwai &lt;tiwai@suse.de&gt;
</pre>
</div>
</content>
</entry>
<entry>
<title>ALSA: seq: Don't leak the extension cell pointer in the bounce payload</title>
<updated>2026-08-11T16:19:06+00:00</updated>
<author>
<name>HyeongJun An</name>
<email>sammiee5311@gmail.com</email>
</author>
<published>2026-08-11T13:18:35+00:00</published>
<link rel='alternate' type='text/html' href='https://git.tavy.me/linux-stable.git/commit/?id=59e1592d3c270ff4642d5d6dc55c545306eb0693'/>
<id>59e1592d3c270ff4642d5d6dc55c545306eb0693</id>
<content type='text'>
The bounce_error_event() embeds the failed event in the bounce payload
by pointing data.ext.ptr at it.  When that event is a queued
variable-length event, its own data.ext.ptr holds the address of its
first extension cell, put there by snd_seq_event_dup().  The payload
goes out verbatim through snd_seq_expand_var_event(), so the address
reaches userspace.

That is the same address commit 705dd6dcbc0e ("ALSA: seq: Clear
variable event pointer on read") removed from the event header.  The
read path still clears it there, just above the call that expands the
payload.

Embed a sanitised copy instead, treated exactly as snd_seq_read()
treats the header.  A stack copy is enough because delivery is
synchronous and snd_seq_event_dup() copies before returning.

An unprivileged client reaches this by setting SNDRV_SEQ_FILTER_BOUNCE,
queueing a variable-length event to a port that does not exist and
reading the bounce back.  Eight bytes on 64-bit, from its own pool.

Fixes: efc86691e4d8 ("ALSA: seq: Fix kernel heap address leak in bounce_error_event()")
Assisted-by: Claude:claude-opus-5
Signed-off-by: HyeongJun An &lt;sammiee5311@gmail.com&gt;
Link: https://patch.msgid.link/20260811131835.3837024-1-sammiee5311@gmail.com
Signed-off-by: Takashi Iwai &lt;tiwai@suse.de&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
The bounce_error_event() embeds the failed event in the bounce payload
by pointing data.ext.ptr at it.  When that event is a queued
variable-length event, its own data.ext.ptr holds the address of its
first extension cell, put there by snd_seq_event_dup().  The payload
goes out verbatim through snd_seq_expand_var_event(), so the address
reaches userspace.

That is the same address commit 705dd6dcbc0e ("ALSA: seq: Clear
variable event pointer on read") removed from the event header.  The
read path still clears it there, just above the call that expands the
payload.

Embed a sanitised copy instead, treated exactly as snd_seq_read()
treats the header.  A stack copy is enough because delivery is
synchronous and snd_seq_event_dup() copies before returning.

An unprivileged client reaches this by setting SNDRV_SEQ_FILTER_BOUNCE,
queueing a variable-length event to a port that does not exist and
reading the bounce back.  Eight bytes on 64-bit, from its own pool.

Fixes: efc86691e4d8 ("ALSA: seq: Fix kernel heap address leak in bounce_error_event()")
Assisted-by: Claude:claude-opus-5
Signed-off-by: HyeongJun An &lt;sammiee5311@gmail.com&gt;
Link: https://patch.msgid.link/20260811131835.3837024-1-sammiee5311@gmail.com
Signed-off-by: Takashi Iwai &lt;tiwai@suse.de&gt;
</pre>
</div>
</content>
</entry>
<entry>
<title>ALSA: seq: Use RCU for the UMP client output substream</title>
<updated>2026-08-10T15:44:34+00:00</updated>
<author>
<name>Takashi Iwai</name>
<email>tiwai@suse.de</email>
</author>
<published>2026-08-10T13:37:06+00:00</published>
<link rel='alternate' type='text/html' href='https://git.tavy.me/linux-stable.git/commit/?id=0252ad169c5eb8d9cfd2ee646a7cd055865e1f12'/>
<id>0252ad169c5eb8d9cfd2ee646a7cd055865e1f12</id>
<content type='text'>
The UMP sequencer client protects its output rawmidi file (out_rfile)
with an rwlock (output_lock).  seq_ump_process_event(), the port's
event_input callback, reads out_rfile.output under read_lock on every
delivered UMP event, while the open/close paths (serialized by
ump-&gt;open_mutex) publish and clear out_rfile under write_lock.

Output is opened/closed only on the subscribe/use lifecycle while
delivery happens per event, so this is another read-mostly hot path.
Convert it to RCU and drop the rwlock.  out_rfile is an embedded struct
rather than a pointer, so instead of restructuring it, add an
RCU-protected shadow of the substream (out_substream) for the reader;
out_rfile itself becomes writer-only state accessed solely under
open_mutex.  The reader now runs lock-free under rcu_read_lock() via
rcu_dereference(), and open publishes the substream with
rcu_assign_pointer().

On close the substream is cleared with rcu_assign_pointer(NULL) and the
rawmidi is released only after synchronize_rcu(), so no reader in the
delivery path can still be writing to the substream when
snd_rawmidi_kernel_release() runs.

Dropping write_lock_irqsave() from the writers is safe: they run in
process context under open_mutex, and the sole atomic reader now uses
RCU, which is IRQ-safe.

Signed-off-by: Takashi Iwai &lt;tiwai@suse.de&gt;
Link: https://patch.msgid.link/20260810133711.42483-6-tiwai@suse.de
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
The UMP sequencer client protects its output rawmidi file (out_rfile)
with an rwlock (output_lock).  seq_ump_process_event(), the port's
event_input callback, reads out_rfile.output under read_lock on every
delivered UMP event, while the open/close paths (serialized by
ump-&gt;open_mutex) publish and clear out_rfile under write_lock.

Output is opened/closed only on the subscribe/use lifecycle while
delivery happens per event, so this is another read-mostly hot path.
Convert it to RCU and drop the rwlock.  out_rfile is an embedded struct
rather than a pointer, so instead of restructuring it, add an
RCU-protected shadow of the substream (out_substream) for the reader;
out_rfile itself becomes writer-only state accessed solely under
open_mutex.  The reader now runs lock-free under rcu_read_lock() via
rcu_dereference(), and open publishes the substream with
rcu_assign_pointer().

On close the substream is cleared with rcu_assign_pointer(NULL) and the
rawmidi is released only after synchronize_rcu(), so no reader in the
delivery path can still be writing to the substream when
snd_rawmidi_kernel_release() runs.

Dropping write_lock_irqsave() from the writers is safe: they run in
process context under open_mutex, and the sole atomic reader now uses
RCU, which is IRQ-safe.

Signed-off-by: Takashi Iwai &lt;tiwai@suse.de&gt;
Link: https://patch.msgid.link/20260810133711.42483-6-tiwai@suse.de
</pre>
</div>
</content>
</entry>
<entry>
<title>ALSA: seq: Use RCU for the virmidi file list</title>
<updated>2026-08-10T15:44:34+00:00</updated>
<author>
<name>Takashi Iwai</name>
<email>tiwai@suse.de</email>
</author>
<published>2026-08-10T13:37:05+00:00</published>
<link rel='alternate' type='text/html' href='https://git.tavy.me/linux-stable.git/commit/?id=7ffa5d2462dcf307746a79e959ceac6cd5828bfe'/>
<id>7ffa5d2462dcf307746a79e959ceac6cd5828bfe</id>
<content type='text'>
Each virmidi device keeps a list of its opened input files (filelist)
protected by both an rwlock (filelist_lock) and a rw_semaphore
(filelist_sem).  snd_virmidi_dev_receive_event() walks the list on the
sequencer event input path -- read_lock() when the event is delivered in
atomic context, down_read() otherwise -- decoding each incoming event
into the file's rawmidi buffer.  The writers (input open/close) take both
locks to add/remove entries.

This is another typical dual-lock read-mostly pattern as the port
subscriber list: files are opened/closed rarely while the receive
callback runs per event.  Let's convert the traversal to RCU and drop
the rwlock; the existing filelist_sem keeps serializing the writers.
The atomic input path now runs lock-free under rcu_read_lock(), and
both readers share a single list_for_each_entry_rcu() (valid under the
rwsem via lockdep_is_held()).  The writers switch to
list_add_tail_rcu() / list_del_rcu().

snd_virmidi_input_close() freed the entry (parser and struct)
immediately after list_del.  A concurrent lockless reader in the atomic
path may still be dereferencing it, so the close path now waits for an
RCU grace period after list_del_rcu() before freeing; synchronize_rcu()
is used rather than kfree_rcu() because the parser must also be released
after the grace period, not just the struct.  Non-atomic readers are
already excluded by the down_write, so only the atomic RCU readers need
the grace period.

Dropping write_lock_irq() from the writers is safe: no writer runs in
atomic/IRQ context, and the sole atomic reader now uses RCU, which is
IRQ-safe.

Signed-off-by: Takashi Iwai &lt;tiwai@suse.de&gt;
Link: https://patch.msgid.link/20260810133711.42483-5-tiwai@suse.de
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
Each virmidi device keeps a list of its opened input files (filelist)
protected by both an rwlock (filelist_lock) and a rw_semaphore
(filelist_sem).  snd_virmidi_dev_receive_event() walks the list on the
sequencer event input path -- read_lock() when the event is delivered in
atomic context, down_read() otherwise -- decoding each incoming event
into the file's rawmidi buffer.  The writers (input open/close) take both
locks to add/remove entries.

This is another typical dual-lock read-mostly pattern as the port
subscriber list: files are opened/closed rarely while the receive
callback runs per event.  Let's convert the traversal to RCU and drop
the rwlock; the existing filelist_sem keeps serializing the writers.
The atomic input path now runs lock-free under rcu_read_lock(), and
both readers share a single list_for_each_entry_rcu() (valid under the
rwsem via lockdep_is_held()).  The writers switch to
list_add_tail_rcu() / list_del_rcu().

snd_virmidi_input_close() freed the entry (parser and struct)
immediately after list_del.  A concurrent lockless reader in the atomic
path may still be dereferencing it, so the close path now waits for an
RCU grace period after list_del_rcu() before freeing; synchronize_rcu()
is used rather than kfree_rcu() because the parser must also be released
after the grace period, not just the struct.  Non-atomic readers are
already excluded by the down_write, so only the atomic RCU readers need
the grace period.

Dropping write_lock_irq() from the writers is safe: no writer runs in
atomic/IRQ context, and the sole atomic reader now uses RCU, which is
IRQ-safe.

Signed-off-by: Takashi Iwai &lt;tiwai@suse.de&gt;
Link: https://patch.msgid.link/20260810133711.42483-5-tiwai@suse.de
</pre>
</div>
</content>
</entry>
<entry>
<title>ALSA: seq: Use RCU for the client table</title>
<updated>2026-08-10T15:44:34+00:00</updated>
<author>
<name>Takashi Iwai</name>
<email>tiwai@suse.de</email>
</author>
<published>2026-08-10T13:37:04+00:00</published>
<link rel='alternate' type='text/html' href='https://git.tavy.me/linux-stable.git/commit/?id=7a287e4615d623fade44bec48077263c7564abf6'/>
<id>7a287e4615d623fade44bec48077263c7564abf6</id>
<content type='text'>
The sequencer keeps a global table of clients (clienttab[]) indexed by
client id, protected by the global clients_lock spinlock.  The lookup
snd_seq_client_use_ptr() reads a slot and takes a use_lock reference on
the client, and this runs on the event delivery hot path: every
dispatched event resolves its destination (and often source) client
through it.  The spinlock's only job on the read side is to make the
"pointer is non-NULL" test and the reference increment indivisible with
respect to the writer that nulls the slot and then drains the refcount.

Clients come and go rarely but delivery happens constantly, so this is
yet another read-mostly case as the port and subscriber lists.
Convert the table to RCU: the read side now runs lock-free under
rcu_read_lock() and takes the use_lock reference via
rcu_dereference(), removing contention on the single global spinlock
from the delivery path.  The writers keep clients_lock (still needed
to serialize slot allocation) and publish / unpublish via
rcu_assign_pointer(); creation and destruction remain serialized at a
higher level by register_mutex.

As with the ports, the client is not freed via kfree_rcu(): its lifetime
is governed by the use_lock refcount drained in seq_free_client1().
list_del under the old spinlock excluded a concurrent lookup from taking
a new reference once the slot was nulled; rcu_assign_pointer(NULL) offers
no such exclusion, so a reader still holding the old pointer can grab a
reference after the unpublish.  seq_free_client1() therefore calls
synchronize_rcu() after nulling the slot and before snd_use_lock_sync():
once the grace period elapses no new reference can appear, and the
existing drain then frees the client safely.

clienttablock[] keeps its slot-reservation role (create/free are
serialized by register_mutex); its read on the lookup path only gates
module autoload, so a lockless read is harmless.  Dropping the spinlock
from the read path is safe: clients_lock is now taken only by the
process-context writers, and the sole atomic reader uses RCU, which is
IRQ-safe.

Signed-off-by: Takashi Iwai &lt;tiwai@suse.de&gt;
Link: https://patch.msgid.link/20260810133711.42483-4-tiwai@suse.de
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
The sequencer keeps a global table of clients (clienttab[]) indexed by
client id, protected by the global clients_lock spinlock.  The lookup
snd_seq_client_use_ptr() reads a slot and takes a use_lock reference on
the client, and this runs on the event delivery hot path: every
dispatched event resolves its destination (and often source) client
through it.  The spinlock's only job on the read side is to make the
"pointer is non-NULL" test and the reference increment indivisible with
respect to the writer that nulls the slot and then drains the refcount.

Clients come and go rarely but delivery happens constantly, so this is
yet another read-mostly case as the port and subscriber lists.
Convert the table to RCU: the read side now runs lock-free under
rcu_read_lock() and takes the use_lock reference via
rcu_dereference(), removing contention on the single global spinlock
from the delivery path.  The writers keep clients_lock (still needed
to serialize slot allocation) and publish / unpublish via
rcu_assign_pointer(); creation and destruction remain serialized at a
higher level by register_mutex.

As with the ports, the client is not freed via kfree_rcu(): its lifetime
is governed by the use_lock refcount drained in seq_free_client1().
list_del under the old spinlock excluded a concurrent lookup from taking
a new reference once the slot was nulled; rcu_assign_pointer(NULL) offers
no such exclusion, so a reader still holding the old pointer can grab a
reference after the unpublish.  seq_free_client1() therefore calls
synchronize_rcu() after nulling the slot and before snd_use_lock_sync():
once the grace period elapses no new reference can appear, and the
existing drain then frees the client safely.

clienttablock[] keeps its slot-reservation role (create/free are
serialized by register_mutex); its read on the lookup path only gates
module autoload, so a lockless read is harmless.  Dropping the spinlock
from the read path is safe: clients_lock is now taken only by the
process-context writers, and the sole atomic reader uses RCU, which is
IRQ-safe.

Signed-off-by: Takashi Iwai &lt;tiwai@suse.de&gt;
Link: https://patch.msgid.link/20260810133711.42483-4-tiwai@suse.de
</pre>
</div>
</content>
</entry>
<entry>
<title>ALSA: seq: Use RCU for the client port list</title>
<updated>2026-08-10T15:44:34+00:00</updated>
<author>
<name>Takashi Iwai</name>
<email>tiwai@suse.de</email>
</author>
<published>2026-08-10T13:37:03+00:00</published>
<link rel='alternate' type='text/html' href='https://git.tavy.me/linux-stable.git/commit/?id=4c252fbc06d641d631ad55111a1bffc50c07f72c'/>
<id>4c252fbc06d641d631ad55111a1bffc50c07f72c</id>
<content type='text'>
Each sequencer client keeps a list of its ports (ports_list_head)
protected by both an rwlock (ports_lock) and a mutex (ports_mutex).
The rwlock is taken read-side on the event delivery hot path:
snd_seq_port_use_ptr() walks the list to resolve a port on every
dispatched event, while the mutex serializes port creation/deletion.

Ports change rarely but delivery happens constantly, so this is the
another read-mostly case as the port subscriber list.  Convert the
port list traversal to RCU and drop the rwlock entirely; the existing
ports_mutex keeps serializing the writers.  The atomic delivery path
(snd_seq_port_use_ptr(), snd_seq_port_query_nearest()) now runs
lock-free under rcu_read_lock() instead of contending on the shared
rwlock.

The writers switch to list_add_tail_rcu()/list_del_rcu().
snd_seq_insert_port() now stores the port number and name before
publishing the node so RCU readers only ever observe a fully
initialized port.  One drawback is that snd_seq_delete_all_ports()
drops the O(1) splice trick and unlinks each port individually,
though: the splice repointed the last port's -&gt;next away from the list
head, which would send a concurrent lockless reader off the end of the
list.

Unlike the subscriber objects, ports are not freed via kfree_rcu():
port_delete() must drain outstanding use_lock references (and run
private_free()) synchronously.  The rwlock previously guaranteed that
no reader could take a new use_lock reference once the port was
unlinked -- list_del under write_lock excluded snd_use_lock_use()
under read_lock.  list_del_rcu() offers no such exclusion, so a reader
still traversing the list can grab a reference after the unlink.
port_delete() therefore calls synchronize_rcu() after the port has
been unlinked and before snd_use_lock_sync(): once the grace period
elapses no new reference can appear, and the existing drain then frees
the port safely.

Dropping write_lock_irq() from the writers is safe: no writer runs in
atomic/IRQ context, and the sole atomic reader now uses RCU, which is
IRQ-safe.

Signed-off-by: Takashi Iwai &lt;tiwai@suse.de&gt;
Link: https://patch.msgid.link/20260810133711.42483-3-tiwai@suse.de
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
Each sequencer client keeps a list of its ports (ports_list_head)
protected by both an rwlock (ports_lock) and a mutex (ports_mutex).
The rwlock is taken read-side on the event delivery hot path:
snd_seq_port_use_ptr() walks the list to resolve a port on every
dispatched event, while the mutex serializes port creation/deletion.

Ports change rarely but delivery happens constantly, so this is the
another read-mostly case as the port subscriber list.  Convert the
port list traversal to RCU and drop the rwlock entirely; the existing
ports_mutex keeps serializing the writers.  The atomic delivery path
(snd_seq_port_use_ptr(), snd_seq_port_query_nearest()) now runs
lock-free under rcu_read_lock() instead of contending on the shared
rwlock.

The writers switch to list_add_tail_rcu()/list_del_rcu().
snd_seq_insert_port() now stores the port number and name before
publishing the node so RCU readers only ever observe a fully
initialized port.  One drawback is that snd_seq_delete_all_ports()
drops the O(1) splice trick and unlinks each port individually,
though: the splice repointed the last port's -&gt;next away from the list
head, which would send a concurrent lockless reader off the end of the
list.

Unlike the subscriber objects, ports are not freed via kfree_rcu():
port_delete() must drain outstanding use_lock references (and run
private_free()) synchronously.  The rwlock previously guaranteed that
no reader could take a new use_lock reference once the port was
unlinked -- list_del under write_lock excluded snd_use_lock_use()
under read_lock.  list_del_rcu() offers no such exclusion, so a reader
still traversing the list can grab a reference after the unlink.
port_delete() therefore calls synchronize_rcu() after the port has
been unlinked and before snd_use_lock_sync(): once the grace period
elapses no new reference can appear, and the existing drain then frees
the port safely.

Dropping write_lock_irq() from the writers is safe: no writer runs in
atomic/IRQ context, and the sole atomic reader now uses RCU, which is
IRQ-safe.

Signed-off-by: Takashi Iwai &lt;tiwai@suse.de&gt;
Link: https://patch.msgid.link/20260810133711.42483-3-tiwai@suse.de
</pre>
</div>
</content>
</entry>
<entry>
<title>ALSA: seq: Use RCU for the port subscriber list</title>
<updated>2026-08-10T15:44:34+00:00</updated>
<author>
<name>Takashi Iwai</name>
<email>tiwai@suse.de</email>
</author>
<published>2026-08-10T13:37:02+00:00</published>
<link rel='alternate' type='text/html' href='https://git.tavy.me/linux-stable.git/commit/?id=a9760db775efb483e6e4cb571f5bda37532a75a8'/>
<id>a9760db775efb483e6e4cb571f5bda37532a75a8</id>
<content type='text'>
Each sequencer port keeps two subscriber groups (c_src and c_dest),
each protected by both an rwlock (list_lock) and a rw_semaphore
(list_mutex).  The rwlock is taken read-side in the event delivery hot
path (__deliver_to_subscribers()) for delivering every event to
subscribers, while the mutex serializes subscribe/unsubscribe and
covers the sleepable delivery and query walks.

Subscriptions change rarely but delivery happens constantly, so this is
a textbook read-mostly case.  Convert the subscriber list traversal to
RCU and drop the rwlock entirely while keeping the existing list_mutex
for serializing the writers.  The atomic delivery path now runs
lock-free under rcu_read_lock() instead of contending on the shared
rwlock.

Along with the conversion to RCU, the subscriber lists are switched
from list_head to hlist so that removal can use hlist_del_init_rcu():
it keeps the -&gt;next pointer intact for concurrent readers while
clearing -&gt;pprev, which lets the double-deletion guard (added in
commit 13d5e5d4725c) keep detecting an already-removed entry via
hlist_unhashed().

Dropping write_lock_irq() from the writers is safe: no writer runs in
atomic/IRQ context, and the sole atomic reader now uses RCU, which is
IRQ-safe.  Port lifetime handling (use_lock/closing drain in
port_delete()) is orthogonal and unchanged.

Note that the conversion to RCU has another merit: it automatically
"fixes" the (rather false) lockdep warnings for the doubly read-locks
of the same subscriber list, too.

Signed-off-by: Takashi Iwai &lt;tiwai@suse.de&gt;
Link: https://patch.msgid.link/20260810133711.42483-2-tiwai@suse.de
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
Each sequencer port keeps two subscriber groups (c_src and c_dest),
each protected by both an rwlock (list_lock) and a rw_semaphore
(list_mutex).  The rwlock is taken read-side in the event delivery hot
path (__deliver_to_subscribers()) for delivering every event to
subscribers, while the mutex serializes subscribe/unsubscribe and
covers the sleepable delivery and query walks.

Subscriptions change rarely but delivery happens constantly, so this is
a textbook read-mostly case.  Convert the subscriber list traversal to
RCU and drop the rwlock entirely while keeping the existing list_mutex
for serializing the writers.  The atomic delivery path now runs
lock-free under rcu_read_lock() instead of contending on the shared
rwlock.

Along with the conversion to RCU, the subscriber lists are switched
from list_head to hlist so that removal can use hlist_del_init_rcu():
it keeps the -&gt;next pointer intact for concurrent readers while
clearing -&gt;pprev, which lets the double-deletion guard (added in
commit 13d5e5d4725c) keep detecting an already-removed entry via
hlist_unhashed().

Dropping write_lock_irq() from the writers is safe: no writer runs in
atomic/IRQ context, and the sole atomic reader now uses RCU, which is
IRQ-safe.  Port lifetime handling (use_lock/closing drain in
port_delete()) is orthogonal and unchanged.

Note that the conversion to RCU has another merit: it automatically
"fixes" the (rather false) lockdep warnings for the doubly read-locks
of the same subscriber list, too.

Signed-off-by: Takashi Iwai &lt;tiwai@suse.de&gt;
Link: https://patch.msgid.link/20260810133711.42483-2-tiwai@suse.de
</pre>
</div>
</content>
</entry>
<entry>
<title>Merge branch 'for-linus' into for-next</title>
<updated>2026-07-30T09:28:26+00:00</updated>
<author>
<name>Takashi Iwai</name>
<email>tiwai@suse.de</email>
</author>
<published>2026-07-30T09:28:26+00:00</published>
<link rel='alternate' type='text/html' href='https://git.tavy.me/linux-stable.git/commit/?id=cbae17630954cb89f2bdf5bbadfd3aa81ea67283'/>
<id>cbae17630954cb89f2bdf5bbadfd3aa81ea67283</id>
<content type='text'>
Pull 7.2 devel branch for applying further patches cleanly.

Signed-off-by: Takashi Iwai &lt;tiwai@suse.de&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
Pull 7.2 devel branch for applying further patches cleanly.

Signed-off-by: Takashi Iwai &lt;tiwai@suse.de&gt;
</pre>
</div>
</content>
</entry>
</feed>
