IB/mthca: Fix race in reference counting
authorRoland Dreier <rolandd@cisco.com>
Tue, 9 May 2006 17:50:29 +0000 (10:50 -0700)
committerRoland Dreier <rolandd@cisco.com>
Tue, 9 May 2006 17:50:29 +0000 (10:50 -0700)
commita3285aa4eecd722508dab01c4932b11b4ba80134
tree1d12d6bbba7f42939536ccdba14f7738f2a26793
parentd945e1df28ca07642b3e1a9b9d07074ba5f76be0
IB/mthca: Fix race in reference counting

Fix races in in destroying various objects.  If a destroy routine
waits for an object to become free by doing

wait_event(&obj->wait, !atomic_read(&obj->refcount));
/* now clean up and destroy the object */

and another place drops a reference to the object by doing

if (atomic_dec_and_test(&obj->refcount))
wake_up(&obj->wait);

then this is susceptible to a race where the wait_event() and final
freeing of the object occur between the atomic_dec_and_test() and the
wake_up().  And this is a use-after-free, since wake_up() will be
called on part of the already-freed object.

Fix this in mthca by replacing the atomic_t refcounts with plain old
integers protected by a spinlock.  This makes it possible to do the
decrement of the reference count and the wake_up() so that it appears
as a single atomic operation to the code waiting on the wait queue.

While touching this code, also simplify mthca_cq_clean(): the CQ being
cleaned cannot go away, because it still has a QP attached to it.  So
there's no reason to be paranoid and look up the CQ by number; it's
perfectly safe to use the pointer that the callers already have.

Signed-off-by: Roland Dreier <rolandd@cisco.com>
drivers/infiniband/hw/mthca/mthca_cq.c
drivers/infiniband/hw/mthca/mthca_dev.h
drivers/infiniband/hw/mthca/mthca_provider.h
drivers/infiniband/hw/mthca/mthca_qp.c
drivers/infiniband/hw/mthca/mthca_srq.c