summaryrefslogtreecommitdiff
path: root/tools/perf/scripts/python/bin
diff options
context:
space:
mode:
authorTakashi Iwai <tiwai@suse.de>2026-08-10 15:37:04 +0200
committerTakashi Iwai <tiwai@suse.de>2026-08-10 17:44:34 +0200
commit7a287e4615d623fade44bec48077263c7564abf6 (patch)
tree682f6bb9e8b912d084d5d4524beb7ebef9ca2674 /tools/perf/scripts/python/bin
parent4c252fbc06d641d631ad55111a1bffc50c07f72c (diff)
ALSA: seq: Use RCU for the client table
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 <tiwai@suse.de> Link: https://patch.msgid.link/20260810133711.42483-4-tiwai@suse.de
Diffstat (limited to 'tools/perf/scripts/python/bin')
0 files changed, 0 insertions, 0 deletions