[ipoix] Fix two races where ipoib_port_up was called twice.
[mirror/winof/.git] / ulp / ipoib / kernel / ipoib_port.c
index fd82966..7713149 100644 (file)
@@ -5136,14 +5136,24 @@ ipoib_port_up(
 \r
        IPOIB_ENTER( IPOIB_DBG_INIT );\r
 \r
+       cl_obj_lock( &p_port->obj );\r
+       if ((p_port->state == IB_QPS_INIT) ||\r
+               (p_port->state == IB_QPS_RTS)){\r
+               cl_obj_unlock( &p_port->obj );\r
+               status = STATUS_SUCCESS;\r
+               IPOIB_PRINT_EXIT( TRACE_LEVEL_INFORMATION, IPOIB_DBG_INIT,\r
+                       ("p_port->state = %d - Aborting.\n", p_port->state) );        \r
+               goto up_done;\r
+       }\r
+       p_port->state = IB_QPS_INIT;\r
+       cl_obj_unlock( &p_port->obj );  \r
+\r
+\r
        /* Wait for all work requests to get flushed. */\r
        while( p_port->recv_mgr.depth || p_port->send_mgr.depth )\r
                cl_thread_suspend( 0 );\r
 \r
-       cl_obj_lock( &p_port->obj );\r
-       p_port->state = IB_QPS_INIT;\r
        KeResetEvent( &p_port->sa_event );\r
-       cl_obj_unlock( &p_port->obj );\r
 \r
        mad_out = (ib_mad_t*)cl_zalloc(256);\r
        if(! mad_out)\r
@@ -5203,6 +5213,8 @@ up_done:
                        ipoib_set_inactive( p_port->p_adapter );\r
                        __endpt_mgr_reset_all( p_port );\r
                }\r
+               ASSERT(p_port->state == IB_QPS_INIT || p_port->state == IB_QPS_ERROR);\r
+               p_port->state = IB_QPS_ERROR;\r
                KeSetEvent( &p_port->sa_event, EVENT_INCREMENT, FALSE );\r
        }\r
 \r
@@ -5344,14 +5356,20 @@ __bcast_get_cb(
 \r
        cl_obj_lock( &p_port->obj );\r
        p_port->ib_mgr.h_query = NULL;\r
+\r
+       CL_ASSERT(p_port->state == IB_QPS_INIT || p_port->state == IB_QPS_ERROR);\r
        if( p_port->state != IB_QPS_INIT )\r
        {\r
                status = IB_CANCELED;\r
                goto done;\r
        }\r
-\r
+       \r
        status = p_query_rec->status;\r
 \r
+       IPOIB_PRINT( TRACE_LEVEL_INFORMATION, IPOIB_DBG_INIT,\r
+               ("status of request %s\n", \r
+               p_port->p_adapter->p_ifc->get_err_str( status )) );\r
+\r
        switch( status )\r
        {\r
        case IB_SUCCESS:\r
@@ -5380,7 +5398,6 @@ __bcast_get_cb(
                NdisWriteErrorLogEntry( p_port->p_adapter->h_adapter,\r
                        EVENT_IPOIB_BCAST_GET, 1, p_query_rec->status );\r
        }\r
-\r
 done:\r
        cl_obj_unlock( &p_port->obj );\r
 \r
@@ -5391,6 +5408,7 @@ done:
                        ipoib_set_inactive( p_port->p_adapter );\r
                        __endpt_mgr_reset_all( p_port );\r
                }\r
+               p_port->state = IB_QPS_ERROR;\r
                KeSetEvent( &p_port->sa_event, EVENT_INCREMENT, FALSE );\r
        }\r
 \r
@@ -5621,11 +5639,12 @@ __bcast_cb(
        p_port = (ipoib_port_t*)p_mcast_rec->mcast_context;\r
 \r
        cl_obj_lock( &p_port->obj );\r
+\r
+       ASSERT(p_port->state == IB_QPS_INIT || p_port->state == IB_QPS_ERROR);\r
        if( p_port->state != IB_QPS_INIT )\r
        {\r
                cl_obj_unlock( &p_port->obj );\r
                if( p_mcast_rec->status == IB_SUCCESS )\r
-\r
                {\r
                        ipoib_port_ref(p_port, ref_leave_mcast);\r
                        p_port->p_adapter->p_ifc->leave_mcast( p_mcast_rec->h_mcast, __leave_error_mcast_cb );\r
@@ -5636,9 +5655,7 @@ __bcast_cb(
                        ("Invalid state - Aborting.\n") );\r
                return;\r
        }\r
-\r
        status = p_mcast_rec->status;\r
-\r
        if( status != IB_SUCCESS )\r
        {\r
                IPOIB_PRINT( TRACE_LEVEL_ERROR, IPOIB_DBG_ERROR,\r
@@ -5684,6 +5701,8 @@ __bcast_cb(
                {\r
                        ipoib_set_inactive( p_port->p_adapter );\r
                        __endpt_mgr_reset_all( p_port );\r
+                       ASSERT(p_port->state == IB_QPS_INIT || p_port->state == IB_QPS_ERROR);\r
+                       p_port->state = IB_QPS_ERROR;\r
                        KeSetEvent( &p_port->sa_event, EVENT_INCREMENT, FALSE );\r
                }\r
                ipoib_port_deref( p_port, ref_bcast_req_failed );\r
@@ -5729,6 +5748,8 @@ __bcast_cb(
 err:\r
                /* Flag the adapter as hung. */\r
                p_port->p_adapter->hung = TRUE;\r
+               ASSERT(p_port->state == IB_QPS_INIT || p_port->state == IB_QPS_ERROR);\r
+               p_port->state = IB_QPS_ERROR;        \r
                KeSetEvent( &p_port->sa_event, EVENT_INCREMENT, FALSE );\r
                ipoib_port_deref( p_port, ref_bcast_error );\r
                IPOIB_EXIT( IPOIB_DBG_INIT );\r
@@ -5737,8 +5758,10 @@ err:
 \r
        cl_obj_lock( &p_port->obj );\r
        /* Only change the state if we're still in INIT. */\r
-       if( p_port->state == IB_QPS_INIT )\r
+       ASSERT( p_port->state == IB_QPS_INIT || p_port->state == IB_QPS_ERROR);\r
+       if (p_port->state == IB_QPS_INIT) {\r
                p_port->state = IB_QPS_RTS;\r
+       }\r
        cl_obj_unlock( &p_port->obj );\r
 \r
        /* Prepost receives. */\r