Implement proper cancel_listen functionality. The current code will destroy the underlying CEP in cm_cancel_listen, and checks for double-free in kal_cep_destroy. This is a bit risky because the CEP could be reused and the double-free check not trap this case, freeing the CEP from under a different connection.
This patch adds a new function to the CEP manager to cancel a listen (putting the CEP back to the IDLE state). This ensures that the CEP is not freed (or reused) before the current client frees it. Signed-off-by: Fab Tillier <[email protected]> diff -dwup3 -x *svn* -r c:\dev\openib\ofw\gen1\branches\mlx4_30\trunk\core\al\al_cm_cep.h .\core\al\al_cm_cep.h --- c:\dev\openib\ofw\gen1\branches\mlx4_30\trunk\core\al\al_cm_cep.h Thu May 31 11:22:16 2012 +++ .\core\al\al_cm_cep.h Wed Jul 25 19:46:03 2012 @@ -142,6 +142,11 @@ al_cep_listen( #ifdef CL_KERNEL ib_api_status_t +kal_cep_cancel_listen( + IN ib_al_handle_t h_al, + IN net32_t cid ); + +ib_api_status_t kal_cep_pre_req( IN ib_al_handle_t h_al, IN net32_t cid, diff -dwup3 -x *svn* -r c:\dev\openib\ofw\gen1\branches\mlx4_30\trunk\core\al\kernel\al_cm.c .\core\al\kernel\al_cm.c --- c:\dev\openib\ofw\gen1\branches\mlx4_30\trunk\core\al\kernel\al_cm.c Thu Mar 29 00:15:20 2012 +++ .\core\al\kernel\al_cm.c Thu Jul 26 15:31:13 2012 @@ -193,13 +193,10 @@ cm_listen(iba_cm_id *p_id, net64_t servi return ib_to_ntstatus(ib_status); } -static void +static NTSTATUS cm_cancel_listen(iba_cm_id *p_id) { - iba_cm_id_priv *id; - - id = CONTAINING_RECORD(p_id, iba_cm_id_priv, id); - kal_cep_destroy(gh_al, p_id->cid, STATUS_SUCCESS); + return ib_to_ntstatus(kal_cep_cancel_listen(gh_al, p_id->cid)); } static NTSTATUS diff -dwup3 -x *svn* -r c:\dev\openib\ofw\gen1\branches\mlx4_30\trunk\core\al\kernel\al_cm_cep.c .\core\al\kernel\al_cm_cep.c --- c:\dev\openib\ofw\gen1\branches\mlx4_30\trunk\core\al\kernel\al_cm_cep.c Thu May 31 11:22:15 2012 +++ .\core\al\kernel\al_cm_cep.c Mon Jul 30 22:23:51 2012 @@ -4195,11 +4195,7 @@ kal_cep_destroy( KeAcquireInStackQueuedSpinLock( &gp_cep_mgr->lock, &hdl ); p_cep = __lookup_cep( h_al, cid ); - if(p_cep == NULL || p_cep->state == CEP_STATE_DESTROY) - {// kal_cep_destroy was already called - do nothing - KeReleaseInStackQueuedSpinLock( &hdl ); - return; - } + CL_ASSERT( p_cep ); context = p_cep->context; pfn_destroy_cb = p_cep->pfn_destroy_cb; @@ -4221,6 +4217,36 @@ kal_cep_destroy( ib_api_status_t +kal_cep_cancel_listen( + IN ib_al_handle_t h_al, + IN net32_t cid ) +{ + KLOCK_QUEUE_HANDLE hdl; + kcep_t *p_cep; + + KeAcquireInStackQueuedSpinLock( &gp_cep_mgr->lock, &hdl ); + p_cep = __lookup_cep( h_al, cid ); + if( p_cep == NULL ) + { + KeReleaseInStackQueuedSpinLock( &hdl ); + return IB_INVALID_HANDLE; + } + + cl_atomic_inc( &p_cep->ref_cnt ); + /* + * Note that __cleanup_cep will decrement the ref_cnt. + */ + __cleanup_cep( p_cep ); + /* + * __cleanup_cep flipped the state to DESTROY, move it to IDLE. + */ + p_cep->state = CEP_STATE_IDLE; + KeReleaseInStackQueuedSpinLock( &hdl ); + return STATUS_SUCCESS; +} + + +ib_api_status_t al_cep_listen( IN ib_al_handle_t h_al, IN net32_t cid, diff -dwup3 -x *svn* -r c:\dev\openib\ofw\gen1\branches\mlx4_30\trunk\inc\kernel\iba\ib_cm_ifc.h .\inc\kernel\iba\ib_cm_ifc.h --- c:\dev\openib\ofw\gen1\branches\mlx4_30\trunk\inc\kernel\iba\ib_cm_ifc.h Thu Aug 02 12:47:08 2012 +++ .\inc\kernel\iba\ib_cm_ifc.h Thu Jul 26 15:31:14 2012 @@ -285,7 +285,7 @@ typedef struct _iba_cm_interface NTSTATUS (*migrate)(iba_cm_id *p_id); NTSTATUS (*established)(iba_cm_id *p_id); - void (*cancel_listen)(iba_cm_id *p_id); + NTSTATUS (*cancel_listen)(iba_cm_id *p_id); } iba_cm_interface; static inline USHORT IbaCmVersion(UINT8 Major, UINT8 Minor)
ndv2.15.patch
Description: ndv2.15.patch
_______________________________________________ ofw mailing list [email protected] http://lists.openfabrics.org/cgi-bin/mailman/listinfo/ofw
