[ofw] RE: IBBUS - keep last HCA reference until IBAL is shutdown.
Sean Hefty
sean.hefty at intel.com
Tue May 19 10:07:54 PDT 2009
To highlight my confusion... see inline comments
static void
fdo_release_resources(
IN DEVICE_OBJECT* const
p_dev_obj )
{
bus_fdo_ext_t *p_ext;
NTSTATUS status;
bus_filter_t *p_bfi;
int ic;
ib_api_status_t ib_status;
BUS_ENTER( BUS_DBG_PNP );
p_ext = p_dev_obj->DeviceExtension;
ic = get_bfi_count();
p_bfi = p_ext->bus_filter;
CL_ASSERT( p_bfi );
//TODO: Fail outstanding I/O operations.
ib_status = ib_deregister_ca( p_ext->hca_ifc.Verbs.guid );
>> This references the hca_ifc.
if( ib_status != IB_SUCCESS ) {
BUS_PRINT( BUS_DBG_ERROR, ("ib_deregister_ca returned %s.\n",
ib_get_err_str(ib_status)) );
}
if ( p_ext->p_port_mgr && p_bfi->p_port_mgr ) {
cl_obj_destroy( &p_ext->p_port_mgr->obj );
p_ext->p_port_mgr = NULL;
}
if ( p_ext->p_iou_mgr && p_bfi->p_iou_mgr ) {
cl_obj_destroy( &p_ext->p_iou_mgr->obj );
p_ext->p_iou_mgr = NULL;
}
if ( ic > 0 && p_ext->hca_ifc_taken ) {
>> This checks to see if we've taken the HCA interface. But we just
>> accessed it above.
p_ext->hca_ifc.InterfaceHeader.InterfaceDereference(
p_ext->hca_ifc.InterfaceHeader.Context);
p_ext->hca_ifc_taken = FALSE;
}
BUS_TRACE( BUS_DBG_PNP, ("Releasing BusFilter %s\n", p_bfi->whoami ));
if (p_bfi) {
p_ext->bus_filter = NULL;
p_bfi->p_bus_ext = NULL;
}
ic = free_bfi( p_bfi );
/* if not last Buf Filter Instance, then exit, otherwise
cleanup/shutdown */
if ( ic > 0 ) {
BUS_TRACE( BUS_DBG_PNP, ("%d remaining BusFilters\n", ic ));
return;
}
IoDeleteSymbolicLink( &g_CDO_dos_name );
/* Disable any exported interfaces. */
status = IoSetDeviceInterfaceState( &al_ifc_name, FALSE );
ASSERT( NT_SUCCESS( status ) );
status = IoSetDeviceInterfaceState( &ci_ifc_name, FALSE );
ASSERT( NT_SUCCESS( status ) );
status = IoSetDeviceInterfaceState( &cm_ifc_name, FALSE );
ASSERT( NT_SUCCESS( status ) );
/* Release the memory allocated for the interface symbolic names. */
RtlFreeUnicodeString( &cm_ifc_name );
RtlFreeUnicodeString( &ci_ifc_name );
RtlFreeUnicodeString( &al_ifc_name );
al_cleanup();
cl_thread_suspend(50); /* allow time for AL's async procs to run
>> Using a sleep is always racy. How do we know that AL is done?
ASSERT( !gp_async_proc_mgr && !gp_async_pnp_mgr && !gp_al_mgr );
/* AL needs the HCA to stick around until AL cleanup has completed.
* Now that it's done, let the HCA fade away.
*/
if ( p_ext->hca_ifc_taken ) {
>> A second location where the interface is dereferenced. This is the
>> only dereference that makes sense to me based on a brief inspection
>> of the code. The if check implies that it's okay to call al_cleanup
>> without holding a reference on the interface.
>> The code would make more sense to me if we removed the dereference
>> above, simply returned if ic > 0, and only release it here.
>> The call above to ib_deregister_ca looks like it needs a check to
>> see if the interface is valid.
p_ext->hca_ifc.InterfaceHeader.InterfaceDereference(
p_ext->hca_ifc.InterfaceHeader.Context);
p_ext->hca_ifc_taken = FALSE;
}
BUS_EXIT( BUS_DBG_PNP );
}
>> Again, I didn't try to understand everything that was happening. The
>> overall handling just looks sketchy and seems like it could be simplified.
- Sean
More information about the ofw
mailing list