The race is as follows :

A process : cma_process_remove() calls cma_remove_id_dev(),
            which sets id state to CMA_DEVICE_REMOVAL and
            calls wait_event(dev_remove).

B process : cma_req_handler() had incremented dev_remove,
            and calls cma_acquire_ib_dev() and on failure
            calls cma_release_remove(), which does a
            wake_up of cma_process_remove(). Then
            cma_req_handler() calls rdma_destroy_id();

A Process : cma_remove_id_dev() gets woken and checks the
            state of id, and since it is still (wrongly)
            CMA_DEVICE_REMOVAL, it calls notify_user(id)
            and if that fails, the caller - cma_process_remove()
            calls rdma_destroy_id(id). Two processes can
            call rdma_destroy_id(), resulting in one
            de-referencing kfreed id_priv.

Fix is for process B to set CMA_DESTROYING in cma_req_handler()
so that process A will return instead of doing a rdma_destroy_id().

Signed-off-by: Krishna Kumar <[EMAIL PROTECTED]>

diff -ruNp org/core/cma.c new/core/cma.c
--- org/core/cma.c      2006-09-14 15:41:01.000000000 +0530
+++ new/core/cma.c      2006-09-18 11:52:52.000000000 +0530
@@ -1023,6 +1023,7 @@ static int cma_req_handler(struct ib_cm_
        mutex_unlock(&lock);
        if (ret) {
                ret = -ENODEV;
+               cma_exch(conn_id, CMA_DESTROYING);
                cma_release_remove(conn_id);
                rdma_destroy_id(&conn_id->id);
                goto out;


_______________________________________________
openib-general mailing list
[email protected]
http://openib.org/mailman/listinfo/openib-general

To unsubscribe, please visit http://openib.org/mailman/listinfo/openib-general

Reply via email to