• Tejun Heo's avatar
    block, cfq: fix cic lookup locking · f1a4f4d3
    Tejun Heo authored
    * cfq_cic_lookup() may be called without queue_lock and multiple tasks
      can execute it simultaneously for the same shared ioc.  Nothing
      prevents them racing each other and trying to drop the same dead cic
      entry multiple times.
    
    * smp_wmb() in cfq_exit_cic() doesn't really do anything and nothing
      prevents cfq_cic_lookup() seeing stale cic->key.  This usually
      doesn't blow up because by the time cic is exited, all requests have
      been drained and new requests are terminated before going through
      elevator.  However, it can still be triggered by plug merge path
      which doesn't grab queue_lock and thus can't check DEAD state
      reliably.
    
    This patch updates lookup locking such that,
    
    * Lookup is always performed under queue_lock.  This doesn't add any
      more locking.  The only issue is cfq_allow_merge() which can be
      called from plug merge path without holding any lock.  For now, this
      is worked around by using cic of the request to merge into, which is
      guaranteed to have the same ioc.  For longer term, I think it would
      be best to separate out plug merge method from regular one.
    
    * Spurious ioc->lock locking around cic lookup hint assignment
      dropped.
    Signed-off-by: default avatarTejun Heo <tj@kernel.org>
    Signed-off-by: default avatarJens Axboe <axboe@kernel.dk>
    f1a4f4d3
cfq-iosched.c 108 KB