block, cfq: fix cic lookup locking
authorTejun Heo <tj@kernel.org>
Tue, 13 Dec 2011 23:33:39 +0000 (00:33 +0100)
committerJens Axboe <axboe@kernel.dk>
Tue, 13 Dec 2011 23:33:39 +0000 (00:33 +0100)
commitf1a4f4d35ff30a328d5ea28f6cc826b2083111d2
treec0ad51e3136286a9c1e1728fb1cfd7a322e8cf83
parent216284c352a0061f5b20acff2c4e50fb43fea183
block, cfq: fix cic lookup locking

* 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: Tejun Heo <tj@kernel.org>
Signed-off-by: Jens Axboe <axboe@kernel.dk>
block/cfq-iosched.c