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)

Attachment: ndv2.15.patch
Description: ndv2.15.patch

_______________________________________________
ofw mailing list
[email protected]
http://lists.openfabrics.org/cgi-bin/mailman/listinfo/ofw

Reply via email to