[IBAL] crash on IBBUS disabling while mad traffic. [mlnx: 4275]
authorleonidk <leonidk@ad392aa1-c5ef-ae45-8dd8-e69d62a5ef86>
Sun, 3 May 2009 12:47:37 +0000 (12:47 +0000)
committerleonidk <leonidk@ad392aa1-c5ef-ae45-8dd8-e69d62a5ef86>
Sun, 3 May 2009 12:47:37 +0000 (12:47 +0000)
__ioc_query_sa takes references on IOC PnP service before sending the node and path_record requests.
But these references get released at the end of __node_rec_cb and __path_rec_cb, while __process_sweep routine, which performs the IOU sweeping, is just scheduled to run in an async thread.
If the test happens to unload the driver after __node_rec_cb and __path_rec_cb and before __process_sweep started to run, IOC PnP service gets released and __process_sweep crashes.

The patch takes a reference on IOC PnP service before scheduling a thread for __process_sweep and releases the reference at the end of __process_sweep.
(Pay attention, that __process_sweep schedules a thread for itself twice while moving through its FSM:
SWEEP_IOU_INFO --> SWEEP_IOC_PROFILE --> SWEEP_SVC_ENTRIES --> SWEEP_COMPLETE)

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

core/al/kernel/al_ioc_pnp.c

index 9366a38..ab8da1e 100644 (file)
@@ -2034,6 +2034,8 @@ __query_ious(
                        if( !cl_atomic_dec( &p_results->p_svc->query_cnt ) &&\r
                                status == IB_SUCCESS )\r
                        {\r
                        if( !cl_atomic_dec( &p_results->p_svc->query_cnt ) &&\r
                                status == IB_SUCCESS )\r
                        {\r
+                               /* Reference the service till the end of processing in the thread */\r
+                               ref_al_obj( &p_results->p_svc->obj );\r
                                cl_async_proc_queue( gp_async_pnp_mgr,\r
                                        &p_results->async_item );\r
                        }\r
                                cl_async_proc_queue( gp_async_pnp_mgr,\r
                                        &p_results->async_item );\r
                        }\r
@@ -2229,8 +2231,11 @@ __ioc_pnp_send_cb(
         * If this is the last MAD, finish processing the IOU queries\r
         * in the PnP thread.\r
         */\r
         * If this is the last MAD, finish processing the IOU queries\r
         * in the PnP thread.\r
         */\r
-       if( !cl_atomic_dec( &p_results->p_svc->query_cnt ) )\r
+       if( !cl_atomic_dec( &p_results->p_svc->query_cnt ) ) {\r
+               /* Reference the service till the end of processing in the thread */\r
+               ref_al_obj( &p_results->p_svc->obj );\r
                cl_async_proc_queue( gp_async_pnp_mgr, &p_results->async_item );\r
                cl_async_proc_queue( gp_async_pnp_mgr, &p_results->async_item );\r
+       }\r
 \r
        AL_EXIT( AL_DBG_PNP );\r
 }\r
 \r
        AL_EXIT( AL_DBG_PNP );\r
 }\r
@@ -2351,6 +2356,8 @@ __process_sweep(
 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
 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
+               /* Release the reference taken for the query. */\r
+               deref_al_obj( &p_results->p_svc->obj );\r
                cl_free( p_results );\r
        }\r
 \r
                cl_free( p_results );\r
        }\r
 \r