dm-delay: change locking to avoid contention
authorBenjamin Marzinski <bmarzins@redhat.com>
Tue, 7 May 2024 21:16:24 +0000 (17:16 -0400)
committerMike Snitzer <snitzer@kernel.org>
Thu, 9 May 2024 13:10:58 +0000 (09:10 -0400)
commitc542ee149230c4c3fc086feae608230e7aa97fcf
tree03da18a4a9e5355dda5231f529958ae840b73c69
parent64eb88d6caee2c8eb806a68dab3f184f14f818a4
dm-delay: change locking to avoid contention

The delayed_bios list is protected by one mutex shared by all dm-delay
devices. This mutex must be held whenever a bio is added or expired bios
are removed from the list.  Since a large number of expired bios could
be on the list, flush_delayed_bios() can schedule while holding the
mutex. This means a flush_delayed_bios() call on any dm-delay device can
slow down delay_map() calls on any other dm-delay device.

To keep dm-delay devices from slowing each other down and keep
processing delay bios from slowing adding delayed bios, the global mutex
has been removed, and each dm-delay device now has two locks.
delayed_bios_lock is a spinlock that must be held whenever the
delayed_bios list is accessed. process_bios_lock is a mutex that must be
held whenever a process has temporarily pulled bios off the delayed_bios
list to check which ones should be processed. It must be held until all
the bios that won't be processed are returned to the list. This is what
flush_delayed_bios() now does. The mutex is necessary to guarantee that
delay_presuspend() sees the entire list of delayed bios when it calls
flush_delayed_bios().

Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
Signed-off-by: Mike Snitzer <snitzer@kernel.org>
drivers/md/dm-delay.c