From 24f6cc8d160c5bdbf91a652507ae5ada858d5f58 Mon Sep 17 00:00:00 2001 From: ftillier Date: Thu, 18 Aug 2005 18:38:23 +0000 Subject: [PATCH] Fix synchronization issue where a destroyed CEP could successfully issue a GET_EVENT IOCTL due to the CID being recycled too quicly. git-svn-id: svn://openib.tc.cornell.edu/gen1@53 ad392aa1-c5ef-ae45-8dd8-e69d62a5ef86 --- trunk/core/al/user/ual_cm_cep.c | 33 ++++++++++++++++++++------------- 1 file changed, 20 insertions(+), 13 deletions(-) diff --git a/trunk/core/al/user/ual_cm_cep.c b/trunk/core/al/user/ual_cm_cep.c index 505b3206..5b284206 100644 --- a/trunk/core/al/user/ual_cm_cep.c +++ b/trunk/core/al/user/ual_cm_cep.c @@ -370,20 +370,26 @@ al_destroy_cep( if( p_cep && p_cep->h_al == h_al ) cl_ptr_vector_set( &gp_cep_mgr->cep_vector, cid, NULL ); else - p_cep = NULL; + goto invalid; } else { - p_cep = NULL; - } - cl_spinlock_release( &gp_cep_mgr->obj.lock ); - - if( !p_cep ) - { +invalid: + cl_spinlock_release( &gp_cep_mgr->obj.lock ); AL_EXIT( AL_DBG_CM ); return IB_INVALID_PARAMETER; } + /* + * Destroy the kernel CEP right away. We must synchronize with issuing + * the next GET_EVENT IOCTL. + */ + DeviceIoControl( g_al_device, UAL_DESTROY_CEP, &p_cep->cid, + sizeof(p_cep->cid), NULL, 0, &bytes_ret, NULL ); + p_cep->cid = AL_INVALID_CID; + + cl_spinlock_release( &gp_cep_mgr->obj.lock ); + p_cep->pfn_destroy_cb = pfn_destroy_cb; /* @@ -394,10 +400,6 @@ al_destroy_cep( cl_qlist_remove_item( &h_al->cep_list, &p_cep->al_item ); cl_spinlock_release( &h_al->obj.lock ); - /* Destroy the kernel CEP right away. */ - DeviceIoControl( g_al_device, UAL_DESTROY_CEP, &p_cep->cid, - sizeof(p_cep->cid), NULL, 0, &bytes_ret, NULL ); - if( !cl_atomic_dec( &p_cep->ref_cnt ) ) { /* We have no remaining refrences. */ @@ -1367,6 +1369,7 @@ cm_cb( IN LPOVERLAPPED p_ov ) { ucep_t *p_cep; + BOOL ret; AL_ENTER( AL_DBG_CM ); @@ -1379,9 +1382,13 @@ cm_cb( { p_cep->pfn_cb( p_cep->h_al, p_cep->cid ); - if( !DeviceIoControl( gp_cep_mgr->h_file, UAL_CEP_GET_EVENT, + /* Synchronize with destruction. */ + cl_spinlock_acquire( &gp_cep_mgr->obj.lock ); + ret = DeviceIoControl( gp_cep_mgr->h_file, UAL_CEP_GET_EVENT, &p_cep->cid, sizeof(p_cep->cid), NULL, 0, - NULL, &p_cep->ov ) && GetLastError() == ERROR_IO_PENDING ) + NULL, &p_cep->ov ); + cl_spinlock_release( &gp_cep_mgr->obj.lock ); + if( !ret && GetLastError() == ERROR_IO_PENDING ) { AL_EXIT( AL_DBG_CM ); return; -- 2.41.0