Applied on 3099 Thanks Tzachi
> -----Original Message----- > From: Irena Gannon > Sent: Sunday, February 27, 2011 10:03 PM > To: Tzachi Dar; Tzachi Dar; Hefty, Sean; [email protected] > Subject: RE: [ofw] patch: [ibbus] Add A new function to IBAL that allows one > to create a multicast group without attaching a QP to it. > > Hello, > > The attached patch is the following fix: > > [core][al] Return ib_mcast_handle_t* from al_join_mcast_common only upon > success > > Index: B:/users/irena/proj1/trunk/core/al/al_mcast.c > =================================================================== > --- B:/users/irena/proj1/trunk/core/al/al_mcast.c (revision 7431) > +++ B:/users/irena/proj1/trunk/core/al/al_mcast.c (revision 7432) > @@ -113,6 +113,11 @@ > > AL_ENTER( AL_DBG_MCAST ); > > + if (p_h_mcast) > + { > + *p_h_mcast = NULL; > + } > + > /* Allocate a new multicast request. */ > h_mcast = cl_zalloc( sizeof( ib_mcast_t ) ); > if( !h_mcast ) > @@ -195,6 +200,12 @@ > } while( cl_status == CL_NOT_DONE ); > CL_ASSERT( cl_status == CL_SUCCESS ); > } > + > + if (p_h_mcast) > + { > + ref_al_obj(&h_mcast->obj); > + *p_h_mcast = h_mcast; > + } > } > else > { > @@ -203,12 +214,6 @@ > h_mcast->obj.pfn_destroy( &h_mcast->obj, NULL ); > } > > - if (p_h_mcast) > - { > - ref_al_obj(&h_mcast->obj); > - *p_h_mcast = h_mcast; > - } > - > /* > * Note: Don't release the reference taken in init_al_obj while we > * have the SA req outstanding. > > > -----Original Message----- > From: [email protected] [mailto:ofw- > [email protected]] On Behalf Of Tzachi Dar > Sent: Sunday, February 20, 2011 10:57 AM > To: Tzachi Dar; Hefty, Sean; [email protected] > Subject: Re: [ofw] patch: [ibbus] Add A new function to IBAL that allows one > to create a multicast group without attaching a QP to it. > > Applied on 3096. > > Thanks > Tzachi > > > -----Original Message----- > > From: Tzachi Dar > > Sent: Thursday, February 17, 2011 11:01 AM > > To: Tzachi Dar; Hefty, Sean; [email protected] > > Subject: RE: [ofw] patch: [ibbus] Add A new function to IBAL that > > allows one to create a multicast group without attaching a QP to it. > > > > Attached is the latest version of the patch. > > > > The mcast object is now also an out parameter (optional). One can > > attach it to a different object or track it by some other mechanism. > > Please note that since the ib_mcast_handle_t is a user object there is > > no need for the kernel to keep tracking it. > > > > Thanks > > Tzachi & Irena > > > > > > Index: core/al/al_mcast.c > > =================================================================== > > --- core/al/al_mcast.c (revision 3095) > > +++ core/al/al_mcast.c (working copy) > > @@ -100,11 +100,11 @@ > > #endif > > > > > > - > > ib_api_status_t > > -al_join_mcast( > > - IN const ib_qp_handle_t h_qp, > > - IN const ib_mcast_req_t* const p_mcast_req ) > > +al_join_mcast_common( > > + IN const ib_qp_handle_t h_qp > > OPTIONAL, > > + IN const ib_mcast_req_t* const p_mcast_req, > > + OUT ib_mcast_handle_t* > > p_h_mcast > > ) > > { > > ib_mcast_handle_t h_mcast; > > ib_api_status_t status; > > @@ -113,20 +113,6 @@ > > > > AL_ENTER( AL_DBG_MCAST ); > > > > - /* > > - * Validate the port GUID. There is no need to validate the pkey index > > as > > - * the user could change it later to make it invalid. There is also no > > - * need to perform any QP transitions as ib_init_dgrm_svc resets the QP > > and > > - * starts from scratch. > > - */ > > - status = get_port_num( h_qp->obj.p_ci_ca, p_mcast_req->port_guid, NULL > > ); > > - if( status != IB_SUCCESS ) > > - { > > - AL_PRINT( TRACE_LEVEL_ERROR, AL_DBG_ERROR, > > - ("get_port_num failed, status: %s\n", > > ib_get_err_str(status)) ); > > - return status; > > - } > > - > > /* Allocate a new multicast request. */ > > h_mcast = cl_zalloc( sizeof( ib_mcast_t ) ); > > if( !h_mcast ) > > @@ -183,13 +169,16 @@ > > h_mcast->port_guid = p_mcast_req->port_guid; > > > > /* Track the multicast with the QP instance. */ > > - status = attach_al_obj( &h_qp->obj, &h_mcast->obj ); > > - if( status != IB_SUCCESS ) > > - { > > - h_mcast->obj.pfn_destroy( &h_mcast->obj, NULL ); > > - AL_PRINT_EXIT( TRACE_LEVEL_ERROR, AL_DBG_ERROR, > > - ("attach_al_obj returned %s.\n", ib_get_err_str(status)) > > ); > > - return status; > > + > > + if (h_qp) { > > + status = attach_al_obj( &h_qp->obj, &h_mcast->obj ); > > + if( status != IB_SUCCESS ) > > + { > > + h_mcast->obj.pfn_destroy( &h_mcast->obj, NULL ); > > + AL_PRINT_EXIT( TRACE_LEVEL_ERROR, AL_DBG_ERROR, > > + ("attach_al_obj returned %s.\n", > > ib_get_err_str(status)) ); > > + return status; > > + } > > } > > > > /* Issue the MAD to the SA. */ > > @@ -214,6 +203,12 @@ > > h_mcast->obj.pfn_destroy( &h_mcast->obj, NULL ); > > } > > > > + if (p_h_mcast) > > + { > > + ref_al_obj(&h_mcast->obj); > > + *p_h_mcast = h_mcast; > > + } > > + > > /* > > * Note: Don't release the reference taken in init_al_obj while we > > * have the SA req outstanding. > > @@ -224,6 +219,40 @@ > > } > > > > > > +ib_api_status_t > > +al_join_mcast_no_qp( > > + IN const ib_mcast_req_t* const p_mcast_req, > > + OUT ib_mcast_handle_t* > > p_h_mcast > > ) > > +{ > > + return al_join_mcast_common(NULL, p_mcast_req, p_h_mcast ); > > + > > +} > > + > > +ib_api_status_t > > +al_join_mcast( > > + IN const ib_qp_handle_t h_qp, > > + IN const ib_mcast_req_t* const p_mcast_req, > > + OUT ib_mcast_handle_t* > > p_h_mcast > > ) > > +{ > > + ib_api_status_t status; > > + /* > > + * Validate the port GUID. There is no need to validate the pkey > > +index > > as > > + * the user could change it later to make it invalid. There is also no > > + * need to perform any QP transitions as ib_init_dgrm_svc resets the > > +QP > > and > > + * starts from scratch. > > + */ > > + > > + status = get_port_num( h_qp->obj.p_ci_ca, p_mcast_req->port_guid, > > +NULL > > ); > > + if( status != IB_SUCCESS ) > > + { > > + AL_PRINT( TRACE_LEVEL_ERROR, AL_DBG_ERROR, > > + ("get_port_num failed, status: %s\n", > > ib_get_err_str(status)) ); > > + return status; > > + } > > + > > + return al_join_mcast_common(h_qp, p_mcast_req, p_h_mcast); } > > + > > static void > > __destroying_mcast( > > IN al_obj_t > > *p_obj ) > > @@ -504,7 +533,8 @@ > > */ > > h_mcast->state = SA_REG_ACTIVE; > > /* Attach the QP to the multicast group. */ > > - if(ib_member_get_state(mcast_rec.p_member_rec- > > >scope_state) == IB_MC_REC_STATE_FULL_MEMBER) > > + if(ib_member_get_state(mcast_rec.p_member_rec- > > >scope_state) == IB_MC_REC_STATE_FULL_MEMBER && > > + (((ib_qp_handle_t)h_mcast->obj.p_parent_obj) != > > NULL)) > > { > > status = verbs_attach_mcast(h_mcast); > > if( status != IB_SUCCESS ) > > Index: core/al/al_mcast.h > > =================================================================== > > --- core/al/al_mcast.h (revision 3095) > > +++ core/al/al_mcast.h (working copy) > > @@ -94,9 +94,15 @@ > > ib_api_status_t > > al_join_mcast( > > IN const ib_qp_handle_t h_qp, > > - IN const ib_mcast_req_t* const p_mcast_req ); > > + IN const ib_mcast_req_t* const p_mcast_req, > > + OUT ib_mcast_handle_t* > > p_h_mcast > > ); > > > > +ib_api_status_t > > +al_join_mcast_no_qp( > > + IN const ib_mcast_req_t* const p_mcast_req, > > + OUT ib_mcast_handle_t* > > p_h_mcast > > ); > > > > + > > #if defined( CL_KERNEL ) > > /* > > * Called by proxy to attach a QP to a multicast group. > > @@ -109,6 +115,7 @@ > > OUT al_attach_handle_t > > *ph_attach, > > IN OUT ci_umv_buf_t > > *p_umv_buf > > OPTIONAL ); > > > > + > > #endif /* CL_KERNEL */ > > > > > > Index: core/al/al_qp.c > > =================================================================== > > --- core/al/al_qp.c (revision 3095) > > +++ core/al/al_qp.c (working copy) > > @@ -597,10 +597,12 @@ > > static ib_api_status_t > > al_bad_join_mcast( > > IN const ib_qp_handle_t h_qp, > > - IN const ib_mcast_req_t* const p_mcast_req ) > > + IN const ib_mcast_req_t* const p_mcast_req, > > + OUT ib_mcast_handle_t* > > p_h_mcast > > ) > > { > > UNUSED_PARAM( h_qp ); > > UNUSED_PARAM( p_mcast_req ); > > + UNUSED_PARAM( p_h_mcast ); > > return IB_INVALID_PARAMETER; > > } > > > > @@ -1571,7 +1573,8 @@ > > ib_api_status_t > > ib_join_mcast( > > IN const ib_qp_handle_t h_qp, > > - IN const ib_mcast_req_t* const p_mcast_req ) > > + IN const ib_mcast_req_t* const p_mcast_req, > > + OUT ib_mcast_handle_t* > > p_h_mcast > > ) > > { > > ib_api_status_t status; > > > > @@ -1588,14 +1591,36 @@ > > return IB_INVALID_PARAMETER; > > } > > > > - status = h_qp->pfn_join_mcast( h_qp, p_mcast_req ); > > + status = h_qp->pfn_join_mcast( h_qp, p_mcast_req, p_h_mcast ); > > > > AL_EXIT( AL_DBG_MCAST ); > > return status; > > } > > > > > > +ib_api_status_t > > +ib_join_mcast_no_qp( > > + IN const ib_mcast_req_t* const p_mcast_req, > > + OUT ib_mcast_handle_t* > > p_h_mcast > > ) > > +{ > > + ib_api_status_t status; > > > > + AL_ENTER( AL_DBG_MCAST ); > > + > > + if( !p_mcast_req ) > > + { > > + AL_PRINT_EXIT( TRACE_LEVEL_ERROR, AL_DBG_ERROR, > > ("IB_INVALID_PARAMETER\n") ); > > + return IB_INVALID_PARAMETER; > > + } > > + > > + status = al_join_mcast_no_qp( p_mcast_req, p_h_mcast); > > + > > + AL_EXIT( AL_DBG_MCAST ); > > + return status; > > +} > > + > > + > > + > > /* > > * Post a work request to the send queue of the QP. > > */ > > Index: core/al/al_qp.h > > =================================================================== > > --- core/al/al_qp.h (revision 3095) > > +++ core/al/al_qp.h (working copy) > > @@ -133,7 +133,8 @@ > > ib_api_status_t > > (*pfn_join_mcast)( > > IN const ib_qp_handle_t > > h_qp, > > - IN const ib_mcast_req_t* const > > p_mcast_req > > ); > > + IN const ib_mcast_req_t* const > > p_mcast_req, > > + OUT ib_mcast_handle_t* > > p_h_mcast ); > > > > } ib_qp_t; > > > > Index: core/bus/kernel/bus_pnp.c > > =================================================================== > > --- core/bus/kernel/bus_pnp.c (revision 3095) > > +++ core/bus/kernel/bus_pnp.c (working copy) > > @@ -53,6 +53,10 @@ > > #include "iba/ib_al_ifc.h" > > #include "iba/ib_ci_ifc.h" > > #include "iba/ib_cm_ifc.h" > > +#include "al_cm_cep.h" > > +#include "al_mgr.h" > > +#include "bus_ev_log.h" > > +#include "al_proxy.h" > > > > > > /* Interface names are generated by IoRegisterDeviceInterface. */ @@ > > -1012,6 > > +1016,7 @@ > > p_ifc->poll_cq = ib_poll_cq; > > p_ifc->rearm_cq = ib_rearm_cq; > > p_ifc->join_mcast = ib_join_mcast; > > + p_ifc->join_mcast_no_qp = al_join_mcast_no_qp; > > p_ifc->leave_mcast = ib_leave_mcast; > > p_ifc->local_mad = ib_local_mad; > > p_ifc->cm_listen = ib_cm_listen; > > Index: inc/iba/ib_al.h > > =================================================================== > > --- inc/iba/ib_al.h (revision 3095) > > +++ inc/iba/ib_al.h (working copy) > > @@ -3797,14 +3797,15 @@ > > * ib_join_mcast > > * > > * DESCRIPTION > > -* Attaches a queue pair to a multicast group. > > +* Creates a multicast group and Attaches a queue pair to it. > > * > > * SYNOPSIS > > */ > > AL_EXPORT ib_api_status_t AL_API > > ib_join_mcast( > > IN const ib_qp_handle_t h_qp, > > - IN const ib_mcast_req_t* const p_mcast_req ); > > + IN const ib_mcast_req_t* const p_mcast_req, > > + OUT ib_mcast_handle_t* > > p_h_mcast > > ); > > /* > > * PARAMETERS > > * h_qp > > @@ -3872,7 +3873,85 @@ > > * ib_leave_mcast, ib_mcast_req_t, ib_create_qp, ib_init_dgrm_svc > > *****/ > > > > +/****f* Access Layer/ib_join_mcast > > +* NAME > > +* ib_join_mcast_no_qp > > +* > > +* DESCRIPTION > > +* Creates a multicast group. > > +* > > +* SYNOPSIS > > +*/ > > +AL_EXPORT ib_api_status_t AL_API > > +ib_join_mcast_no_qp( > > + IN const ib_mcast_req_t* const p_mcast_req, > > + OUT ib_mcast_handle_t* > > p_h_mcast > > ); > > +/* > > +* PARAMETERS > > +* > > +* p_mcast_req > > +* [in] Specifies the multicast group to join. > > +* > > +* RETURN VALUES > > +* IB_SUCCESS > > +* The join multicast group request has been initiated. > > +* > > +* IB_INVALID_QP_HANDLE > > +* The queue pair handle was invalid. > > +* > > +* IB_INVALID_PARAMETER > > +* A reference to the multicast group request information was not > > +* provided. > > +* > > +* IB_INVALID_SERVICE_TYPE > > +* The queue pair configuration does not support this type of > > service. > > +* > > +* IB_INSUFFICIENT_MEMORY > > +* There was insufficient memory to join the multicast group. > > +* > > +* IB_INVALID_GUID > > +* No port was found for the port_guid specified in the request. > > +* > > +* IB_INSUFFICIENT_RESOURCES > > +* There were insufficient resources currently available on the > > channel > > +* adapter to perform the operation. > > +* > > +* IB_INVALID_PKEY > > +* The pkey specified in the multicast join request does not match > > the > > +* pkey of the queue pair. > > +* > > +* IB_INVALID_PORT > > +* The port GUID specified in the multicast join request does not > > match > > +* the port of the queue pair. > > +* > > +* IB_ERROR > > +* An error occurred while performing the multicast group join > > operation. > > +* > > +* IB_INSUFFICIENT_RESOURCES > > +* There were insufficient resources currently available to > > complete > > +* the request. > > +* > > +* IB_INSUFFICIENT_MEMORY > > +* There was insufficient memory to complete the request. > > +* > > +* NOTES > > +* This routine results in the specified queue pair joining a multicast > > +* group. If the multicast group does not already exist, it will be > > created > > +* at the user's option. Information about the multicast group is returned > > +* to the user through a callback specified through the p_mcast_req > > +* parameter. > > +* > > +* If the specified queue pair is already a member of a multicast group > > when > > +* this call is invoked, an error will occur if there are conflicting > > +* membership requirements. The QP is restricted to being bound to a > > single > > +* port_guid and using a single pkey. > > +* > > +* SEE ALSO > > +* ib_leave_mcast, ib_mcast_req_t, ib_create_qp, ib_init_dgrm_svc > > +*****/ > > > > + > > + > > /****f* Access Layer/ib_leave_mcast > > * NAME > > * ib_leave_mcast > > Index: inc/kernel/iba/ib_al_ifc.h > > =================================================================== > > --- inc/kernel/iba/ib_al_ifc.h (revision 3095) > > +++ inc/kernel/iba/ib_al_ifc.h (working copy) > > @@ -48,7 +48,7 @@ > > * IB resources provided by HCAs. > > *********/ > > > > -#define AL_INTERFACE_VERSION (13) > > +#define AL_INTERFACE_VERSION (15) > > > > > > > > @@ -401,9 +401,15 @@ > > typedef ib_api_status_t > > (*ib_pfn_join_mcast_t)( > > IN const ib_qp_handle_t h_qp, > > - IN const ib_mcast_req_t* const p_mcast_req ); > > + IN const ib_mcast_req_t* const p_mcast_req, > > + OUT ib_mcast_handle_t* > > p_h_mcast > > ); > > > > typedef ib_api_status_t > > +(*ib_pfn_join_mcast_no_qp_t)( > > + IN const ib_mcast_req_t* const p_mcast_req, > > + OUT ib_mcast_handle_t* > > p_h_mcast > > ); > > + > > +typedef ib_api_status_t > > (*ib_pfn_leave_mcast_t)( > > IN const ib_mcast_handle_t h_mcast, > > IN const ib_pfn_destroy_cb_t > > destroy_cb ); > > @@ -702,6 +708,7 @@ > > ib_pfn_poll_cq_t poll_cq; > > ib_pfn_rearm_cq_t rearm_cq; > > ib_pfn_join_mcast_t join_mcast; > > + ib_pfn_join_mcast_no_qp_t join_mcast_no_qp; > > ib_pfn_leave_mcast_t leave_mcast; > > ib_pfn_local_mad_t local_mad; > > ib_pfn_cm_listen_t cm_listen; > > Index: ulp/ipoib/kernel/ipoib_port.c > > =================================================================== > > --- ulp/ipoib/kernel/ipoib_port.c (revision 3095) > > +++ ulp/ipoib/kernel/ipoib_port.c (working copy) > > @@ -5634,7 +5634,7 @@ > > ipoib_port_ref( p_port, ref_join_bcast ); > > > > status = p_port->p_adapter->p_ifc->join_mcast( > > - p_port->ib_mgr.h_qp, &mcast_req ); > > + p_port->ib_mgr.h_qp, &mcast_req, NULL ); > > if( status != IB_SUCCESS ) > > { > > ipoib_port_deref( p_port, ref_bcast_join_failed ); @@ -5695,7 > > +5695,7 @@ > > /* reference the object for the multicast join request. */ > > ipoib_port_ref( p_port, ref_join_bcast ); > > > > - status = p_port->p_adapter->p_ifc->join_mcast( p_port->ib_mgr.h_qp, > > &mcast_req ); > > + status = p_port->p_adapter->p_ifc->join_mcast( p_port->ib_mgr.h_qp, > > +&mcast_req, NULL ); > > if( status != IB_SUCCESS ) > > { > > ipoib_port_deref( p_port, ref_bcast_create_failed ); @@ -6155,7 > > +6155,7 @@ > > /* reference the object for the multicast join request. */ > > ipoib_port_ref( p_port, ref_join_mcast ); > > > > - status = p_port->p_adapter->p_ifc->join_mcast( p_port->ib_mgr.h_qp, > > &mcast_req ); > > + status = p_port->p_adapter->p_ifc->join_mcast( p_port->ib_mgr.h_qp, > > +&mcast_req, NULL ); > > if( status != IB_SUCCESS ) > > { > > ipoib_port_deref( p_port, ref_mcast_join_failed ); > > Index: ulp/ipoib_NDIS6_CM/kernel/ipoib_port.cpp > > =================================================================== > > --- ulp/ipoib_NDIS6_CM/kernel/ipoib_port.cpp (revision 3095) > > +++ ulp/ipoib_NDIS6_CM/kernel/ipoib_port.cpp (working copy) > > @@ -8327,7 +8327,7 @@ > > /* reference the object for the multicast join request. */ > > ipoib_port_ref( p_port, ref_join_bcast ); > > > > - status = p_port->p_adapter->p_ifc->join_mcast( p_port->ib_mgr.h_qp, > > &mcast_req ); > > + status = p_port->p_adapter->p_ifc->join_mcast( p_port->ib_mgr.h_qp, > > +&mcast_req, NULL ); > > if( status != IB_SUCCESS ) > > { > > ipoib_port_deref( p_port, ref_bcast_join_failed ); @@ -8388,7 > > +8388,7 @@ > > /* reference the object for the multicast join request. */ > > ipoib_port_ref( p_port, ref_join_bcast ); > > > > - status = p_port->p_adapter->p_ifc->join_mcast( p_port->ib_mgr.h_qp, > > &mcast_req ); > > + status = p_port->p_adapter->p_ifc->join_mcast( p_port->ib_mgr.h_qp, > > +&mcast_req, NULL ); > > if( status != IB_SUCCESS ) > > { > > ipoib_port_deref( p_port, ref_bcast_create_failed ); @@ -8908,7 > > +8908,7 @@ > > /* reference the object for the multicast join request. */ > > ipoib_port_ref( p_port, ref_join_mcast ); > > > > - status = p_port->p_adapter->p_ifc->join_mcast( p_port->ib_mgr.h_qp, > > &mcast_req ); > > + status = p_port->p_adapter->p_ifc->join_mcast( p_port->ib_mgr.h_qp, > > +&mcast_req, NULL ); > > if( status != IB_SUCCESS ) > > { > > ipoib_port_deref( p_port, ref_mcast_join_failed ); > > > > > -----Original Message----- > > > From: [email protected] [mailto:ofw- > > > [email protected]] On Behalf Of Tzachi Dar > > > Sent: Tuesday, February 15, 2011 11:45 PM > > > To: Hefty, Sean; [email protected] > > > Subject: Re: [ofw] patch: [ibbus] Add A new function to IBAL that > > > allows one to create a multicast group without attaching a QP to it. > > > > > > Hi Sean, > > > > > > I now see why you need the h_mcast as an output parameter. We will > > > add this to the function, but I don't think we will add the cancel > > > multicast on the first stage. > > > > > > We will also see how we can track the user objects from the kernel. > > > > > > Thanks > > > Tzachi > > > > > > ________________________________________ > > > From: Hefty, Sean [[email protected]] > > > Sent: Tuesday, February 15, 2011 8:07 PM > > > To: Tzachi Dar; [email protected] > > > Subject: RE: [ofw] patch: [ibbus] Add A new function to IBAL that > > > allows one to create a multicast group without attaching a QP to it. > > > > > > > 1) On ib_join_mcast( ..., ib_mcast_handle_t *h_mcast); the > > > > h_mcast gets back to the user from the call back. > > > > I guess that there is no problem to return the h_mcast in the call > > > > itself but are we sure this has a good reason? > > > > > > This allows the user to cancel the join operation without destroying > > > everything by closing their al instance. For example, after issuing > > > a join, they can immediately respond to an SM change, reregister, or > > > other event by freeing the join and issuing a new one. Without > > > this, handling those events becomes more difficult. > > > > > > Hmm... on the Linux side, the multicast module reports those types > > > of events against the join request. The user can receive multiple > > > (serialized) callbacks for a single join call. How does ibal handle > > > errors on a multicast group after a successful join? > > > > > > > > > > 2) " Personally, I'm fine requiring the caller to handle the > > > > cleanup (provided the kernel cleans up after user space)." > > > > Doesn't this has an influence on the API which would actually > > > > force us to have something else in the API (for example h_al) or > > > > something > > similar. > > > > > > Not necessarily. The user to kernel proxy code needs to associate > > > the h_mcast with another object, such as the file, but that doesn't > > > have to be in the kernel API. The proxy code must free the > > > multicast object when the file is closed. You can look at the > > > winverbs kernel cleanup > > code as an example. > > > > > > - Sean > > > _______________________________________________ > > > ofw mailing list > > > [email protected] > > > http://lists.openfabrics.org/cgi-bin/mailman/listinfo/ofw > _______________________________________________ > ofw mailing list > [email protected] > http://lists.openfabrics.org/cgi-bin/mailman/listinfo/ofw _______________________________________________ ofw mailing list [email protected] http://lists.openfabrics.org/cgi-bin/mailman/listinfo/ofw
