• Tejun Heo's avatar
    async: fix __lowest_in_progress() · f56c3196
    Tejun Heo authored
    Commit 083b804c ("async: use workqueue for worker pool") made it
    possible that async jobs are moved from pending to running out-of-order.
    While pending async jobs will be queued and dispatched for execution in
    the same order, nothing guarantees they'll enter "1) move self to the
    running queue" of async_run_entry_fn() in the same order.
    
    Before the conversion, async implemented its own worker pool.  An async
    worker, upon being woken up, fetches the first item from the pending
    list, which kept the executing lists sorted.  The conversion to
    workqueue was done by adding work_struct to each async_entry and async
    just schedules the work item.  The queueing and dispatching of such work
    items are still in order but now each worker thread is associated with a
    specific async_entry and moves that specific async_entry to the
    executing list.  So, depending on which worker reaches that point
    earlier, which is non-deterministic, we may end up moving an async_entry
    with larger cookie before one with smaller one.
    
    This broke __lowest_in_progress().  running->domain may not be properly
    sorted and is not guaranteed to contain lower cookies than pending list
    when not empty.  Fix it by ensuring sort-inserting to the running list
    and always looking at both pending and running when trying to determine
    the lowest cookie.
    
    Over time, the async synchronization implementation became quite messy.
    We better restructure it such that each async_entry is linked to two
    lists - one global and one per domain - and not move it when execution
    starts.  There's no reason to distinguish pending and running.  They
    behave the same for synchronization purposes.
    Signed-off-by: default avatarTejun Heo <tj@kernel.org>
    Cc: Arjan van de Ven <arjan@linux.intel.com>
    Cc: stable@vger.kernel.org
    Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
    f56c3196
async.c 10.9 KB