[IBAL] Fix double-free of results in IOC PnP __process_sweep function when
authorftillier <ftillier@ad392aa1-c5ef-ae45-8dd8-e69d62a5ef86>
Fri, 4 Aug 2006 07:31:02 +0000 (07:31 +0000)
committerftillier <ftillier@ad392aa1-c5ef-ae45-8dd8-e69d62a5ef86>
Fri, 4 Aug 2006 07:31:02 +0000 (07:31 +0000)
service is destroying.

git-svn-id: svn://openib.tc.cornell.edu/gen1/trunk@439 ad392aa1-c5ef-ae45-8dd8-e69d62a5ef86

core/al/kernel/al_ioc_pnp.c

index d382cda..7fa9f1e 100644 (file)
@@ -1452,10 +1452,12 @@ __ioc_pnp_timer_cb(
 \r
        p_mgr = (ioc_pnp_mgr_t*)context;\r
 \r
+       cl_spinlock_acquire( &p_mgr->obj.lock );\r
        if( p_mgr->obj.state == CL_DESTROYING )\r
        {\r
                AL_PRINT_EXIT( TRACE_LEVEL_INFORMATION, AL_DBG_PNP,\r
                        ("Destroying - not resetting timer.\n") );\r
+               cl_spinlock_release( &p_mgr->obj.lock );\r
                return;\r
        }\r
 \r
@@ -1463,7 +1465,8 @@ __ioc_pnp_timer_cb(
 \r
        /* Pre-charge the ref count so that we don't toggle between 0 and 1. */\r
        cl_atomic_inc( &p_mgr->query_cnt );\r
-       cl_spinlock_acquire( &p_mgr->obj.lock );\r
+       /* Take a reference on the object for the duration of the sweep process. */\r
+       ref_al_obj( &p_mgr->obj );\r
        for( p_item = cl_qlist_head( &p_mgr->obj.obj_list );\r
                p_item != cl_qlist_end( &p_mgr->obj.obj_list );\r
                p_item = cl_qlist_next( p_item ) )\r
@@ -1475,11 +1478,12 @@ __ioc_pnp_timer_cb(
                if( status != IB_SUCCESS )\r
                        cl_atomic_dec( &p_mgr->query_cnt );\r
        }\r
-       cl_spinlock_release( &p_mgr->obj.lock );\r
        /* Release the reference we took and see if we're done sweeping. */\r
        if( !cl_atomic_dec( &p_mgr->query_cnt ) )\r
                cl_async_proc_queue( gp_async_pnp_mgr, &p_mgr->async_item );\r
 \r
+       cl_spinlock_release( &p_mgr->obj.lock );\r
+\r
        AL_EXIT( AL_DBG_PNP );\r
 }\r
 \r
@@ -1500,10 +1504,10 @@ __ioc_query_sa(
 \r
        AL_ENTER( AL_DBG_PNP );\r
 \r
-       if ( p_svc->h_node_query )\r
-            return IB_NOT_DONE;\r
+       if( p_svc->h_node_query )\r
+               return IB_NOT_DONE;\r
        if( p_svc->h_path_query )\r
-            return IB_NOT_DONE;\r
+               return IB_NOT_DONE;\r
 \r
        if( p_svc->obj.state == CL_DESTROYING )\r
        {\r
@@ -2287,7 +2291,7 @@ __process_sweep(
        if( p_results->p_svc->obj.state == CL_DESTROYING )\r
        {\r
                __put_iou_map( gp_ioc_pnp, &p_results->iou_map );\r
-               cl_free( p_results );\r
+               goto err;\r
        }\r
 \r
        /* Walk the map of IOUs and discard any that didn't respond to IOU info. */\r
@@ -2322,6 +2326,7 @@ __process_sweep(
 \r
        if( p_results->state == SWEEP_COMPLETE || status != IB_SUCCESS )\r
        {\r
+err:\r
                if( !cl_atomic_dec( &gp_ioc_pnp->query_cnt ) )\r
                        cl_async_proc_queue( gp_async_pnp_mgr, &gp_ioc_pnp->async_item );\r
                cl_free( p_results );\r
@@ -2598,6 +2603,9 @@ __ioc_async_cb(
        status = cl_timer_start( &gp_ioc_pnp->sweep_timer, g_ioc_poll_interval );\r
        CL_ASSERT( status == CL_SUCCESS );\r
 \r
+       /* Release the reference we took in the timer callback. */\r
+       deref_al_obj( &gp_ioc_pnp->obj );\r
+\r
        AL_EXIT( AL_DBG_PNP );\r
 }\r
 \r