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>
Showing
- drivers/infiniband/hw/mthca/mthca_cq.c 21 additions, 20 deletionsdrivers/infiniband/hw/mthca/mthca_cq.c
- drivers/infiniband/hw/mthca/mthca_dev.h 1 addition, 1 deletiondrivers/infiniband/hw/mthca/mthca_dev.h
- drivers/infiniband/hw/mthca/mthca_provider.h 12 additions, 10 deletionsdrivers/infiniband/hw/mthca/mthca_provider.h
- drivers/infiniband/hw/mthca/mthca_qp.c 22 additions, 9 deletionsdrivers/infiniband/hw/mthca/mthca_qp.c
- drivers/infiniband/hw/mthca/mthca_srq.c 18 additions, 5 deletionsdrivers/infiniband/hw/mthca/mthca_srq.c
Please register or sign in to comment