• Richard Fitzgerald's avatar
    soundwire: stream: Make master_list ordered to prevent deadlocks · a4857d1a
    Richard Fitzgerald authored
    Always add buses to the stream->master_list in a fixed order.
    The unique bus->id is used to order the adding of buses to the
    list.
    
    This prevents lockdep asserts and possible deadlocks on streams
    that have multiple buses.
    
    sdw_acquire_bus_lock() takes bus_lock in the order that buses
    are listed in stream->master_list. do_bank_switch() takes all
    the msg_lock in the same order.
    
    To prevent a lockdep assert, and a possible real deadlock, the
    relative order of taking these mutexes must always be the same.
    
    For example, if a stream takes the mutexes in the order
    (bus0, bus1) lockdep will assert if another stream takes them
    in the order (bus1, bus0).
    
    More complex relative ordering will also assert, for example
    if two streams take (bus0, bus1) and (bus1, bus2), then a third
    stream takes (bus2, bus0).
    
    Previously sdw_stream_add_master() simply added the given bus
    to the end of the list, requiring the caller to guarantee that
    buses are added in a fixed order. This isn't reasonable or
    necessary - it's an internal implementation detail that should
    not be exposed by the API. It doesn't really make sense when
    there could be multiple independent calling drivers, to say
    "you must add your buses in the same order as a different driver,
    that you don't know about, added them".
    Signed-off-by: default avatarRichard Fitzgerald <rf@opensource.cirrus.com>
    Reviewed-by: default avatarPierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
    Link: https://lore.kernel.org/r/20230615141208.679011-2-rf@opensource.cirrus.comSigned-off-by: default avatarVinod Koul <vkoul@kernel.org>
    a4857d1a
stream.c 49.6 KB