RDMA/cma: Fix deadlock destroying listen requests
authorSean Hefty <sean.hefty@intel.com>
Tue, 9 Oct 2007 18:12:34 +0000 (11:12 -0700)
committerRoland Dreier <rolandd@cisco.com>
Tue, 16 Oct 2007 19:25:49 +0000 (12:25 -0700)
commitd02d1f5359e795bac9a4461698521680cddd782b
treef90595e51f9f006155bad6a68b67f5ee52c32589
parentc5483388bb4d771007ef36478db038e07922a020
RDMA/cma: Fix deadlock destroying listen requests

Deadlock condition reported by Kanoj Sarcar <kanoj@netxen.com>.
The deadlock occurs when a connection request arrives at the same
time that a wildcard listen is being destroyed.

A wildcard listen maintains per device listen requests for each
RDMA device in the system.  The per device listens are automatically
added and removed when RDMA devices are inserted or removed from
the system.

When a wildcard listen is destroyed, rdma_destroy_id() acquires
the rdma_cm's device mutex ('lock') to protect against hot-plug
events adding or removing per device listens.  It then tries to
destroy the per device listens by calling ib_destroy_cm_id() or
iw_destroy_cm_id().  It does this while holding the device mutex.

However, if the underlying iw/ib CM reports a connection request
while this is occurring, the rdma_cm callback function will try
to acquire the same device mutex.  Since we're in a callback,
the ib_destroy_cm_id() or iw_destroy_cm_id() calls will block until
their callback thread returns, but the callback is blocked waiting for
the device mutex.

Fix this by re-working how per device listens are destroyed.  Use
rdma_destroy_id(), which avoids the deadlock, in place of
cma_destroy_listen().  Additional synchronization is added to handle
device hot-plug events and ensure that the id is not destroyed twice.

Signed-off-by: Sean Hefty <sean.hefty@intel.com>
Signed-off-by: Roland Dreier <rolandd@cisco.com>
drivers/infiniband/core/cma.c