From 5386d8cace51c4b45d0b4ddb845df0ae03ead76b Mon Sep 17 00:00:00 2001 From: ftillier Date: Tue, 27 Sep 2005 00:13:42 +0000 Subject: [PATCH] [WSD] Fix collision between event handles used in connect/disconnect and listen handle. Eliminated cleanup thread, simplified and improvided socket cleanup. git-svn-id: svn://openib.tc.cornell.edu/gen1@85 ad392aa1-c5ef-ae45-8dd8-e69d62a5ef86 --- trunk/ulp/wsd/user/ib_cm.c | 60 ++++--- trunk/ulp/wsd/user/ibsp_duplicate.c | 10 +- trunk/ulp/wsd/user/ibsp_iblow.c | 243 +++++----------------------- trunk/ulp/wsd/user/ibspdll.c | 51 ++---- trunk/ulp/wsd/user/ibspproto.h | 7 +- trunk/ulp/wsd/user/ibspstruct.h | 68 +++----- trunk/ulp/wsd/user/misc.c | 5 - trunk/ulp/wsd/user/sockinfo.c | 48 +++++- 8 files changed, 159 insertions(+), 333 deletions(-) diff --git a/trunk/ulp/wsd/user/ib_cm.c b/trunk/ulp/wsd/user/ib_cm.c index c53b710c..d3f64353 100644 --- a/trunk/ulp/wsd/user/ib_cm.c +++ b/trunk/ulp/wsd/user/ib_cm.c @@ -137,7 +137,8 @@ cm_req_callback( switch( socket_info->socket_state ) { case IBSP_LISTEN: - if( cl_qlist_count( &socket_info->info.listen.list ) >= socket_info->info.listen.backlog ) + if( cl_qlist_count( &socket_info->listen.list ) >= + socket_info->listen.backlog ) { /* Already too many connection requests are queued */ IBSP_TRACE1( IBSP_DBG_CM, @@ -148,7 +149,7 @@ cm_req_callback( } /* Add to the waiting list */ - cl_qlist_insert_head( &socket_info->info.listen.list, &incoming->item ); + cl_qlist_insert_tail( &socket_info->listen.list, &incoming->item ); /* Send MRA */ mra.mra_length = 0; @@ -168,8 +169,8 @@ cm_req_callback( wait_cq_drain( socket_info ); /* Non-blocking cancel since we're in CM callback context */ - ib_cm_cancel( socket_info->info.listen.handle, NULL ); - socket_info->info.listen.handle = NULL; + ib_cm_cancel( socket_info->listen.handle, NULL ); + socket_info->listen.handle = NULL; #if 0 cl_spinlock_release( &socket_info->mutex ); @@ -239,24 +240,25 @@ cm_rep_callback( cl_spinlock_acquire( &socket_info->mutex ); - if( socket_info->socket_state == IBSP_CONNECT ) + switch( socket_info->socket_state ) { + case IBSP_CONNECT: status = ib_cm_rtu( p_cm_rep_rec->h_cm_rep, &cm_rtu ); if( status != IB_SUCCESS ) { /* Note: a REJ has been automatically sent. */ CL_ERROR( IBSP_DBG_CM, gdbg_lvl, ("ib_cm_rtu failed (0x%d)\n", status) ); IBSP_CHANGE_SOCKET_STATE( socket_info, IBSP_BIND ); - ibsp_post_select_event( socket_info, FD_CONNECT, WSAENOBUFS ); + ibsp_post_select_event( socket_info, FD_CONNECT, WSAETIMEDOUT ); } else { IBSP_CHANGE_SOCKET_STATE( socket_info, IBSP_CONNECTED ); ibsp_post_select_event( socket_info, FD_CONNECT, 0 ); } - } - else if( socket_info->socket_state == IBSP_DUPLICATING_NEW ) - { + break; + + case IBSP_DUPLICATING_NEW: status = ib_cm_rtu( p_cm_rep_rec->h_cm_rep, &cm_rtu ); if( status != IB_SUCCESS ) { @@ -267,10 +269,9 @@ cm_rep_callback( { IBSP_CHANGE_SOCKET_STATE( socket_info, IBSP_CONNECTED ); } - SetEvent( socket_info->info.connect.event ); - } - else - { + SetEvent( socket_info->h_event ); + + default: /* The socket might be closing */ CL_ERROR( IBSP_DBG_CM, gdbg_lvl, ("socket %x not in connecting state (%s)\n", socket_info, IBSP_SOCKET_STATE_STR( socket_info->socket_state )) ); @@ -302,7 +303,7 @@ cm_rtu_callback( if( socket_info->socket_state == IBSP_ACCEPT ) { IBSP_CHANGE_SOCKET_STATE( socket_info, IBSP_CONNECTED ); - SetEvent( socket_info->info.accept.event ); + SetEvent( socket_info->h_event ); } else if( socket_info->socket_state == IBSP_DUPLICATING_REMOTE ) { @@ -353,7 +354,6 @@ cm_rtu_callback( status = ib_post_recv( socket_info->qp, &wr->recv, NULL ); - if( status == IB_SUCCESS ) { /* Update the index and wrap as needed */ @@ -442,7 +442,7 @@ cm_rej_callback( case IBSP_DUPLICATING_NEW: /* Leave in that state. IBSPSocket will eventually return * an error becaus the socket is not connected. */ - SetEvent( socket_info->info.connect.event ); + SetEvent( socket_info->h_event ); break; default: @@ -513,9 +513,9 @@ cm_dreq_callback( socket_info->duplicate.dwProcessId = reason->duplicating.dwProcessId; /* Now, setup our listening callback. */ - socket_info->info.listen.listen_req_param.dwProcessId = + socket_info->listen.listen_req_param.dwProcessId = reason->duplicating.dwProcessId; - socket_info->info.listen.listen_req_param.identifier = + socket_info->listen.listen_req_param.identifier = reason->duplicating.identifier; ret = ib_listen( socket_info, &error ); @@ -533,9 +533,6 @@ cm_dreq_callback( socket_info->qp_error = WSAECONNRESET; } } - else - { - } cl_spinlock_release( &socket_info->mutex ); memset( &cm_drep, 0, sizeof(cm_drep) ); @@ -655,22 +652,22 @@ ib_listen( } param.lid = IB_ALL_LIDS; - param.p_compare_buffer = (uint8_t *) & socket_info->info.listen.listen_req_param; + param.p_compare_buffer = (uint8_t *) & socket_info->listen.listen_req_param; param.compare_length = sizeof(struct listen_req_param); param.compare_offset = offsetof(struct cm_req_params, listen_req_param); fzprint(("%s():%d:0x%x:0x%x: socket=0x%p params: %x %x\n", __FUNCTION__, __LINE__, GetCurrentProcessId(), GetCurrentThreadId(), socket_info, - socket_info->info.listen.listen_req_param.dwProcessId, - socket_info->info.listen.listen_req_param.identifier)); + socket_info->listen.listen_req_param.dwProcessId, + socket_info->listen.listen_req_param.identifier)); param.pfn_cm_req_cb = cm_req_callback; param.qp_type = IB_QPT_RELIABLE_CONN; status = ib_cm_listen( g_ibsp.al_handle, ¶m, listen_err_callback, socket_info, /* context */ - &socket_info->info.listen.handle ); + &socket_info->listen.handle ); if( status != IB_SUCCESS ) { @@ -699,12 +696,12 @@ ib_listen_backlog( cl_list_item_t *item; struct listen_incoming *incoming; - socket_info->info.listen.backlog = backlog; + socket_info->listen.backlog = backlog; while( - cl_qlist_count( &socket_info->info.listen.list ) > (uint32_t)backlog ) + cl_qlist_count( &socket_info->listen.list ) > (uint32_t)backlog ) { - item = cl_qlist_remove_tail( &socket_info->info.listen.list ); + item = cl_qlist_remove_tail( &socket_info->listen.list ); incoming = PARENT_STRUCT(item, struct listen_incoming, item); @@ -724,10 +721,7 @@ ib_listen_cancel( IBSP_ENTER( IBSP_DBG_CM ); - /* We should be in the CLOSING state */ - CL_ASSERT( socket_info->socket_state == IBSP_CLOSING ); - - status = ib_cm_cancel( socket_info->info.listen.handle, ib_sync_destroy ); + status = ib_cm_cancel( socket_info->listen.handle, ib_sync_destroy ); if( status ) { CL_ERROR( IBSP_DBG_CM, gdbg_lvl, @@ -744,7 +738,7 @@ ib_listen_cancel( ib_listen_backlog( socket_info, 0 ); cl_spinlock_release( &socket_info->mutex ); - socket_info->info.listen.handle = NULL; + socket_info->listen.handle = NULL; IBSP_EXIT( IBSP_DBG_CM ); } diff --git a/trunk/ulp/wsd/user/ibsp_duplicate.c b/trunk/ulp/wsd/user/ibsp_duplicate.c index b5e3dbd2..9497ae7a 100644 --- a/trunk/ulp/wsd/user/ibsp_duplicate.c +++ b/trunk/ulp/wsd/user/ibsp_duplicate.c @@ -182,7 +182,7 @@ setup_duplicate_socket( } IBSP_CHANGE_SOCKET_STATE( socket_info, IBSP_DUPLICATING_NEW ); - socket_info->info.connect.event = CreateEvent( NULL, FALSE, FALSE, NULL ); + socket_info->h_event = CreateEvent( NULL, FALSE, FALSE, NULL ); /* Connects the QP. */ ret = ib_connect( socket_info, &path_rec ); @@ -192,7 +192,7 @@ setup_duplicate_socket( goto done; } - if( WaitForSingleObject( socket_info->info.connect.event, INFINITE ) != WAIT_OBJECT_0 ) + if( WaitForSingleObject( socket_info->h_event, INFINITE ) != WAIT_OBJECT_0 ) { CL_ERROR( IBSP_DBG_CM, gdbg_lvl, ("WaitForSingleObject failed\n") ); } @@ -213,10 +213,10 @@ done: if( h ) CloseHandle( h ); - if( socket_info->info.connect.event ) + if( socket_info->h_event ) { - CloseHandle( socket_info->info.connect.event ); - socket_info->info.connect.event = NULL; + CloseHandle( socket_info->h_event ); + socket_info->h_event = NULL; } CL_EXIT( IBSP_DBG_CONN, gdbg_lvl ); diff --git a/trunk/ulp/wsd/user/ibsp_iblow.c b/trunk/ulp/wsd/user/ibsp_iblow.c index 88720811..38103a3b 100644 --- a/trunk/ulp/wsd/user/ibsp_iblow.c +++ b/trunk/ulp/wsd/user/ibsp_iblow.c @@ -37,9 +37,8 @@ static void ib_destroy_cq_tinfo( struct cq_thread_info *cq_tinfo ); typedef struct _io_comp_info { - SOCKET socket; + struct ibsp_socket_info *p_socket; LPWSAOVERLAPPED p_ov; - atomic32_t *p_io_cnt; } io_comp_info_t; @@ -63,7 +62,7 @@ complete_wq( CL_ASSERT( wr ); socket_info = wr->socket_info; - p_io_info->socket = socket_info->switch_socket; + p_io_info->p_socket = socket_info; lpOverlapped = wr->lpOverlapped; @@ -126,7 +125,7 @@ complete_wq( cl_atomic_inc( &socket_info->dup_cnt ); /* ib_cq_comp will decrement the receive count. */ - p_io_info->p_io_cnt = &socket_info->recv_cnt; + cl_atomic_dec( &socket_info->recv_cnt ); cl_spinlock_release( &socket_info->recv_lock ); @@ -280,12 +279,13 @@ complete_wq( lpOverlapped->InternalHigh, lpOverlapped->hEvent) ); p_io_info->p_ov = lpOverlapped; + cl_atomic_inc( &socket_info->ref_cnt ); } if( wc->wc_type == IB_WC_RECV ) - p_io_info->p_io_cnt = &socket_info->recv_cnt; + cl_atomic_dec( &socket_info->recv_cnt ); else - p_io_info->p_io_cnt = &socket_info->send_cnt; + cl_atomic_dec( &socket_info->send_cnt ); IBSP_EXIT( IBSP_DBG_IO ); } @@ -366,25 +366,28 @@ ib_cq_comp( done_wclist = done_wclist->p_next; } - while( cb_idx-- ) + for( i = 0; i < cb_idx; i++ ) { int error; int ret; - if( info[cb_idx].p_ov ) + if( info[i].p_ov ) { + IBSP_TRACE1( IBSP_DBG_IO, + ("Calling WPUCompleteOverlappedRequest for ov=%p\n", + info[i].p_ov) ); + ret = g_ibsp.up_call_table.lpWPUCompleteOverlappedRequest( - info[cb_idx].socket, info[cb_idx].p_ov, - info[cb_idx].p_ov->OffsetHigh, - (DWORD)info[cb_idx].p_ov->InternalHigh, &error ); + info[i].p_socket->switch_socket, info[i].p_ov, + info[i].p_ov->OffsetHigh, + (DWORD)info[i].p_ov->InternalHigh, &error ); if( ret != 0 ) { IBSP_ERROR( ("WPUCompleteOverlappedRequest for ov=%p " - "returned %d err %d\n", info[cb_idx].p_ov, ret, error) ); + "returned %d err %d\n", info[i].p_ov, ret, error) ); } + deref_socket_info( info[i].p_socket ); } - - cl_atomic_dec( info[cb_idx].p_io_cnt ); } #ifdef _DEBUG_ @@ -762,38 +765,6 @@ ib_release(void) unregister_pnp(); - if( g_ibsp.ib_cleanup_thread ) - { - /* Let thread know it's okay to exit after resources are freed */ - g_ibsp.ib_cleanup_thread_exit_wanted = TRUE; - SetEvent( g_ibsp.ib_cleanup_event ); - - fzprint(("%s():%d:0x%x:0x%x: Waiting for ib_cleanup_thread to die.\n", - __FUNCTION__, __LINE__, GetCurrentProcessId(), - GetCurrentThreadId())); - - /* Wait for ib_cleanup_thread to die */ - if( WaitForSingleObject( g_ibsp.ib_cleanup_thread, INFINITE ) != WAIT_OBJECT_0 ) - { - CL_ERROR( IBSP_DBG_CM, gdbg_lvl, ("WaitForSingleObject failed\n") ); - } - else - { - STAT_DEC( thread_num ); - } - - fzprint(("%s():%d:0x%x:0x%x: ib_cleanup_thread exited.\n", __FUNCTION__, - __LINE__, GetCurrentProcessId(), GetCurrentThreadId())); - CloseHandle( g_ibsp.ib_cleanup_thread ); - g_ibsp.ib_cleanup_thread = NULL; - } - - if( g_ibsp.ib_cleanup_event ) - { - CloseHandle( g_ibsp.ib_cleanup_event ); - g_ibsp.ib_cleanup_event = NULL; - } - while( (item = cl_qlist_head( &g_ibsp.hca_list )) != cl_qlist_end( &g_ibsp.hca_list ) ) { struct ibsp_hca *hca = PARENT_STRUCT(item, struct ibsp_hca, item); @@ -841,134 +812,6 @@ ib_release(void) } -/* IP notify thread */ -static DWORD WINAPI -ib_cleanup_thread( - LPVOID lpParameter ) -{ - cl_list_item_t *socket_item = NULL; - - CL_ENTER( IBSP_DBG_HW, gdbg_lvl ); - - UNUSED_PARAM( lpParameter ); - - while( !g_ibsp.ib_cleanup_thread_exit_wanted || - cl_qlist_count( &g_ibsp.socket_info_list ) ) - { - if( g_ibsp.ib_cleanup_thread_exit_wanted == FALSE ) - { - if( WaitForSingleObject( g_ibsp.ib_cleanup_event, INFINITE ) != WAIT_OBJECT_0 ) - { - CL_ERROR( IBSP_DBG_CM, gdbg_lvl, ("WaitForSingleObject failed\n") ); - } - ResetEvent( g_ibsp.ib_cleanup_event ); - } - else - { - fzprint(("%s():%d:0x%x:0x%x: socket_info_list cnt=%d\n", __FUNCTION__, - __LINE__, GetCurrentProcessId(), - GetCurrentThreadId(), - cl_qlist_count( &g_ibsp.socket_info_list) == 0)); - Sleep( 1000 ); - } - - CL_TRACE( IBSP_DBG_WQ, gdbg_lvl, ("%s():%d:0x%x:0x%x: Wakeup\n", - __FUNCTION__, - __LINE__, GetCurrentProcessId(), - GetCurrentThreadId())); - - cl_spinlock_acquire( &g_ibsp.closed_socket_info_mutex ); - while( (socket_item = cl_qlist_remove_head( &g_ibsp.closed_socket_info_list )) != - cl_qlist_end( &g_ibsp.closed_socket_info_list ) ) - { - struct ibsp_socket_info *socket_info = NULL; - - cl_spinlock_release( &g_ibsp.closed_socket_info_mutex ); - - socket_info = PARENT_STRUCT(socket_item, struct ibsp_socket_info, item); - -#ifdef _DEBUG_ - { - uint8_t idx, i; - LPOVERLAPPED lpOverlapped; - - idx = socket_info->send_idx - (uint8_t)socket_info->send_cnt; - if( idx >= QP_ATTRIB_SQ_DEPTH ) - idx += QP_ATTRIB_SQ_DEPTH; - - for( i = 0; i < socket_info->send_cnt; i++ ) - { - lpOverlapped = socket_info->send_wr[idx].lpOverlapped; - fzprint(("%s():%d:0x%x:0x%x: socket=0x%p wr=0x%p overlapped=0x%p Internal=%d InternalHigh=%d hEvent=%d\n", - __FUNCTION__, __LINE__, GetCurrentProcessId(), GetCurrentThreadId(), socket_info, &socket_info->send_wr[idx], lpOverlapped, lpOverlapped->Internal, lpOverlapped->InternalHigh, lpOverlapped->hEvent)); - - if( ++idx == QP_ATTRIB_SQ_DEPTH ) - idx = 0; - } - - idx = socket_info->recv_idx - (uint8_t)socket_info->recv_cnt; - if( idx >= QP_ATTRIB_RQ_DEPTH ) - idx += QP_ATTRIB_RQ_DEPTH; - - for( i = 0; i < socket_info->recv_cnt; i++ ) - { - lpOverlapped = socket_info->recv_wr[idx].wr.lpOverlapped; - fzprint(("%s():%d:0x%x:0x%x: socket=0x%p wr=0x%p overlapped=0x%p Internal=%d InternalHigh=%d hEvent=%d\n", - __FUNCTION__, __LINE__, GetCurrentProcessId(), GetCurrentThreadId(), socket_info, &socket_info->recv_wr[idx], lpOverlapped, lpOverlapped->Internal, lpOverlapped->InternalHigh, lpOverlapped->hEvent)); - - if( ++idx == QP_ATTRIB_RQ_DEPTH ) - idx = 0; - } - } -#endif - fzprint(("%s():%d:0x%x:0x%x: socket=0x%p\n", - __FUNCTION__, - __LINE__, GetCurrentProcessId(), GetCurrentThreadId(), socket_info)); - - wait_cq_drain( socket_info ); - - if( socket_info->dup_cnt ) - ibsp_dup_overlap_abort( socket_info ); - - /* Destroy the switch socket. */ - if( socket_info->switch_socket != INVALID_SOCKET ) - { - int ret; - int error; - - fzprint(("%s():%d:0x%x:0x%x: socket=0x%p calling lpWPUCloseSocketHandle=0x%p\n", __FUNCTION__, __LINE__, GetCurrentProcessId(), GetCurrentThreadId(), socket_info, socket_info->switch_socket)); - - ret = g_ibsp.up_call_table.lpWPUCloseSocketHandle( - socket_info->switch_socket, &error ); - if( ret == SOCKET_ERROR ) - { - CL_ERROR( IBSP_DBG_EP, gdbg_lvl, - ("WPUCloseSocketHandle failed: %d\n", error) ); - } - else - { - STAT_DEC( wpusocket_num ); - } - - socket_info->switch_socket = INVALID_SOCKET; - } - - ib_destroy_socket( socket_info ); - - ib_deregister_all_mr( &socket_info->buf_mem_list ); - free_socket_info( socket_info ); - cl_spinlock_acquire( &g_ibsp.closed_socket_info_mutex ); - } - cl_spinlock_release( &g_ibsp.closed_socket_info_mutex ); - } - - /* No special exit code, even on errors. */ - CL_EXIT( IBSP_DBG_HW, gdbg_lvl ); - ExitThread( 0 ); -} - - - /* Initialize IB ressources. */ int ibsp_initialize(void) @@ -1007,25 +850,6 @@ ibsp_initialize(void) /* Populate IP list. */ update_all_ip_addrs(); - /* Create a cleanup event */ - g_ibsp.ib_cleanup_event = CreateEvent( NULL, TRUE, FALSE, NULL ); - if( g_ibsp.ib_cleanup_event == NULL ) - { - CL_ERROR( IBSP_DBG_HW, gdbg_lvl, ("CreateEvent failed.")); - ret = WSAEPROVIDERFAILEDINIT; - goto done; - } - - /* Create a cleanup thread */ - g_ibsp.ib_cleanup_thread = CreateThread( NULL, 0, ib_cleanup_thread, NULL, 0, NULL ); - - if( g_ibsp.ib_cleanup_thread == NULL ) - { - CL_ERROR( IBSP_DBG_HW, gdbg_lvl, ("CreateThread failed.") ); - ret = WSAEPROVIDERFAILEDINIT; - goto done; - } - STAT_INC( thread_num ); ret = 0; @@ -1271,18 +1095,24 @@ ibsp_dup_overlap_abort( /* Closes a connection and release its ressources. */ void shutdown_and_destroy_socket_info( - IN OUT struct ibsp_socket_info *socket_info, - IN int old_state ) + IN OUT struct ibsp_socket_info *socket_info ) { + enum ibsp_socket_state old_state; + CL_ENTER( IBSP_DBG_EP, gdbg_lvl ); + cl_spinlock_acquire( &socket_info->mutex ); + old_state = socket_info->socket_state; + IBSP_CHANGE_SOCKET_STATE( socket_info, IBSP_CLOSED ); + cl_spinlock_release( &socket_info->mutex ); + if( socket_info->duplicate.mmap_handle ) { CloseHandle( socket_info->duplicate.mmap_handle ); socket_info->duplicate.mmap_handle = NULL; } - if( socket_info->info.listen.handle ) + if( socket_info->listen.handle ) { /* Stop listening and reject queued connections. */ ib_listen_cancel( socket_info ); @@ -1290,13 +1120,6 @@ shutdown_and_destroy_socket_info( switch( old_state ) { - case IBSP_CLOSING: - /* This function has already been called. Should not happen. */ - CL_ERROR( IBSP_DBG_EP, gdbg_lvl, - ("shutdown_and_destroy_socket_info already in closing socket_state\n") ); - return; - break; - case IBSP_CREATE: /* Nothing to do. */ break; @@ -1330,6 +1153,20 @@ shutdown_and_destroy_socket_info( break; } + /* Flush all completions. */ + if( socket_info->dup_cnt ) + ibsp_dup_overlap_abort( socket_info ); + + while( socket_info->send_cnt || socket_info->recv_cnt ) + ib_cq_comp( socket_info->cq_tinfo ); + + ib_deregister_all_mr( &socket_info->buf_mem_list ); + + ib_destroy_socket( socket_info ); + + /* Release the initial reference and clean up. */ + deref_socket_info( socket_info ); + CL_EXIT( IBSP_DBG_EP, gdbg_lvl ); } diff --git a/trunk/ulp/wsd/user/ibspdll.c b/trunk/ulp/wsd/user/ibspdll.c index 1d6c9bdb..8d655284 100644 --- a/trunk/ulp/wsd/user/ibspdll.c +++ b/trunk/ulp/wsd/user/ibspdll.c @@ -277,7 +277,7 @@ IBSPAccept( return INVALID_SOCKET; } - if( cl_qlist_count( &socket_info->info.listen.list ) == 0 ) + if( cl_qlist_count( &socket_info->listen.list ) == 0 ) { cl_spinlock_release( &socket_info->mutex ); @@ -289,7 +289,7 @@ IBSPAccept( CL_TRACE( IBSP_DBG_CONN, gdbg_lvl, ("IBSPAccept: Found pending connection on this socket\n") ); - incoming = PARENT_STRUCT(cl_qlist_head( &socket_info->info.listen.list ), + incoming = PARENT_STRUCT(cl_qlist_head( &socket_info->listen.list ), struct listen_incoming, item); port = socket_info->port; @@ -318,7 +318,7 @@ IBSPAccept( reject: /* The request is invalid. Remove it from the list and reject it. */ - cl_qlist_remove_item( &socket_info->info.listen.list, &incoming->item ); + cl_qlist_remove_item( &socket_info->listen.list, &incoming->item ); cl_spinlock_release( &socket_info->mutex ); ib_reject( incoming->cm_req_received.h_cm_req, IB_REJ_INSUF_QP ); @@ -357,7 +357,7 @@ reject: switch( ret ) { case CF_REJECT: - cl_qlist_remove_item( &socket_info->info.listen.list, &incoming->item ); + cl_qlist_remove_item( &socket_info->listen.list, &incoming->item ); cl_spinlock_release( &socket_info->mutex ); IBSP_TRACE1( IBSP_DBG_CONN, @@ -440,9 +440,9 @@ reject: /* Store the IP address and port number in the socket context */ new_socket_info->local_addr = incoming->params.dest; - cl_qlist_remove_item( &socket_info->info.listen.list, &incoming->item ); + cl_qlist_remove_item( &socket_info->listen.list, &incoming->item ); /* Signal the event again if there are more connection requests. */ - if( cl_qlist_count( &socket_info->info.listen.list ) ) + if( cl_qlist_count( &socket_info->listen.list ) ) ibsp_post_select_event( socket_info, FD_ACCEPT, 0 ); cl_spinlock_release( &socket_info->mutex ); @@ -460,7 +460,7 @@ reject: new_socket_info->peer_addr = incoming->params.source; new_socket_info->switch_socket = new_socket; - new_socket_info->info.accept.event = CreateEvent( NULL, FALSE, FALSE, NULL ); + new_socket_info->h_event = CreateEvent( NULL, FALSE, FALSE, NULL ); cl_spinlock_acquire( &new_socket_info->mutex ); /* Update the state of the socket context */ @@ -486,7 +486,7 @@ reject: STAT_DEC( wpusocket_num ); } - CloseHandle( new_socket_info->info.accept.event ); + CloseHandle( new_socket_info->h_event ); ib_destroy_socket( new_socket_info ); @@ -507,9 +507,10 @@ reject: cl_spinlock_release( &new_socket_info->mutex ); HeapFree( g_ibsp.heap, 0, incoming ); - if( WaitForSingleObject( new_socket_info->info.accept.event, INFINITE ) == WAIT_OBJECT_0 ) + if( WaitForSingleObject( new_socket_info->h_event, INFINITE ) == WAIT_OBJECT_0 ) { - CloseHandle( new_socket_info->info.accept.event ); + CloseHandle( new_socket_info->h_event ); + new_socket_info->h_event = NULL; cl_spinlock_acquire( &new_socket_info->mutex ); @@ -560,7 +561,8 @@ reject: } else { - CloseHandle( new_socket_info->info.accept.event ); + CloseHandle( new_socket_info->h_event ); + new_socket_info->h_event = NULL; CL_EXIT_ERROR( IBSP_DBG_CONN, gdbg_lvl, ("wait for ib_accept failed\n") ); @@ -697,7 +699,6 @@ IBSPCloseSocket( LPINT lpErrno ) { struct ibsp_socket_info *socket_info = (struct ibsp_socket_info *)s; - int old_state; CL_ENTER( IBSP_DBG_CONN, gdbg_lvl ); @@ -714,30 +715,12 @@ IBSPCloseSocket( cl_atomic_inc( &g_ibsp.CloseSocket_count ); #endif - cl_spinlock_acquire( &socket_info->mutex ); - - old_state = socket_info->socket_state; - IBSP_CHANGE_SOCKET_STATE( socket_info, IBSP_CLOSING ); - - cl_spinlock_release( &socket_info->mutex ); - - shutdown_and_destroy_socket_info( socket_info, old_state ); - - cl_spinlock_acquire( &socket_info->mutex ); - IBSP_CHANGE_SOCKET_STATE( socket_info, IBSP_CLOSED ); - cl_spinlock_release( &socket_info->mutex ); - - /* Take off socket_info_list and put on closed_socket_info_list */ cl_spinlock_acquire( &g_ibsp.socket_info_mutex ); cl_qlist_remove_item( &g_ibsp.socket_info_list, &socket_info->item ); cl_spinlock_release( &g_ibsp.socket_info_mutex ); - cl_spinlock_acquire( &g_ibsp.closed_socket_info_mutex ); - cl_qlist_insert_tail( &g_ibsp.closed_socket_info_list, &socket_info->item ); - cl_spinlock_release( &g_ibsp.closed_socket_info_mutex ); + shutdown_and_destroy_socket_info( socket_info ); - /* Notify ib_cleanup_thread() to free this */ - SetEvent( g_ibsp.ib_cleanup_event ); CL_EXIT( IBSP_DBG_CONN, gdbg_lvl ); @@ -1500,11 +1483,11 @@ IBSPListen( case IBSP_BIND: /* Store the backlog value in the context */ - socket_info->info.listen.backlog = backlog; + socket_info->listen.backlog = backlog; IBSP_CHANGE_SOCKET_STATE( socket_info, IBSP_LISTEN ); - socket_info->info.listen.listen_req_param.dwProcessId = 0; - socket_info->info.listen.listen_req_param.identifier = 0; + socket_info->listen.listen_req_param.dwProcessId = 0; + socket_info->listen.listen_req_param.identifier = 0; ret = ib_listen( socket_info, lpErrno ); if( ret ) diff --git a/trunk/ulp/wsd/user/ibspproto.h b/trunk/ulp/wsd/user/ibspproto.h index 67b79992..9a5f867c 100644 --- a/trunk/ulp/wsd/user/ibspproto.h +++ b/trunk/ulp/wsd/user/ibspproto.h @@ -37,6 +37,10 @@ void free_socket_info( struct ibsp_socket_info *socket_info ); +void +deref_socket_info( + IN struct ibsp_socket_info *p_socket ); + /* protos from extension.c */ HANDLE WSPAPI IBSPRegisterMemory( @@ -122,8 +126,7 @@ ib_destroy_socket( void shutdown_and_destroy_socket_info( - IN OUT struct ibsp_socket_info *socket_info, - IN int old_state ); + IN OUT struct ibsp_socket_info *socket_info ); void destroy_qp_and_release_ressources( diff --git a/trunk/ulp/wsd/user/ibspstruct.h b/trunk/ulp/wsd/user/ibspstruct.h index 5cde26f6..4588174a 100644 --- a/trunk/ulp/wsd/user/ibspstruct.h +++ b/trunk/ulp/wsd/user/ibspstruct.h @@ -48,7 +48,6 @@ enum ibsp_socket_state IBSP_DUPLICATING_NEW, /* duplicating socket on the new controlling process */ IBSP_DUPLICATING_REMOTE, /* duplicating socket on the remote side */ IBSP_DISCONNECTED, - IBSP_CLOSING, IBSP_CLOSED, IBSP_NUM_STATES }; @@ -230,36 +229,17 @@ struct ibsp_socket_info enum ibsp_socket_state socket_state; /* represents current socket state */ - union + struct { - struct - { - /* Listening socket */ - unsigned int backlog; /* Maximum number of pending connections */ - cl_qlist_t list; /* list of pending connections */ - ib_listen_handle_t handle; - struct listen_req_param listen_req_param; - } listen; - - struct - { - /* Accepting socket */ - /* TODO: ib_cm_rep will be blocking with some flags. - * Use that instead of this event. */ - HANDLE event; - } accept; - - struct - { - HANDLE event; - } connect; - - struct - { - HANDLE event; - } disconnect; - - } info; + /* Listening socket */ + unsigned int backlog; /* Maximum number of pending connections */ + cl_qlist_t list; /* list of pending connections */ + ib_listen_handle_t handle; + struct listen_req_param listen_req_param; + } listen; + + /* Event for blocking accept, connect, and disconnect */ + HANDLE h_event; /* Variables associated with IBSPSelectEvent */ WSAEVENT event_select; /* Handle to Event Object */ @@ -290,13 +270,19 @@ struct ibsp_socket_info ib_send_opt_t send_opt; struct _wr send_wr[QP_ATTRIB_SQ_DEPTH]; uint8_t send_idx; - atomic32_t send_cnt; + atomic32_t send_cnt; /* Used to limit access to send_wr array. */ /* Receive request processing. */ cl_spinlock_t recv_lock; struct _recv_wr recv_wr[QP_ATTRIB_RQ_DEPTH]; uint8_t recv_idx; - atomic32_t recv_cnt; + atomic32_t recv_cnt; /* Used to limit access to recv_wr array. */ + + /* + * Used to stall destruction of switch socket until all completion + * upcalls have unwound. + */ + atomic32_t ref_cnt; #ifdef _DEBUG_ atomic32_t send_comp; @@ -353,16 +339,6 @@ ibsp_css( return; } - /* - * Once in IBSP_CLOSING state, the only allowed new state - * is IBSP_CLOSING. - */ - if( (old_state == IBSP_CLOSING) && (new_state != IBSP_CLOSED) ) - { - fzprint(("%s():0x%x:0x%x: socket=0x%p cannot change from %s to %s, called by %s():%d\n", __FUNCTION__, GetCurrentProcessId(), GetCurrentThreadId(), s, IBSP_SOCKET_STATE_STR(old_state), IBSP_SOCKET_STATE_STR(new_state), calling_func, line)); - return; - } - fzprint(("%s():0x%x:0x%x: socket=0x%p %s to %s, called by %s():%d\n", __FUNCTION__, GetCurrentProcessId(), GetCurrentThreadId(), s, @@ -434,9 +410,6 @@ struct ibspdll_globals cl_rbmap_t conn_map; /* rb tree of all connections to ensure unique 4-tuple */ cl_spinlock_t socket_info_mutex; - cl_qlist_t closed_socket_info_list; /* List of sockets in IBSP_CLOSED state */ - cl_spinlock_t closed_socket_info_mutex; - WSAPROTOCOL_INFOW protocol_info; /* Infiniband */ @@ -450,11 +423,6 @@ struct ibspdll_globals cl_fmap_t ip_map; /* list of all IP addresses supported by all the ports. */ cl_spinlock_t ip_mutex; - /* IB resource cleanup thread */ - HANDLE ib_cleanup_thread; - HANDLE ib_cleanup_event; - BOOL ib_cleanup_thread_exit_wanted; - #ifdef _DEBUG_ /* Statistics */ atomic32_t qp_num; diff --git a/trunk/ulp/wsd/user/misc.c b/trunk/ulp/wsd/user/misc.c index 2ea7ac1c..0430a9ff 100644 --- a/trunk/ulp/wsd/user/misc.c +++ b/trunk/ulp/wsd/user/misc.c @@ -42,7 +42,6 @@ char *ibsp_socket_state_str[IBSP_NUM_STATES] = { "IBSP_DUPLICATING_NEW", "IBSP_DUPLICATING_REMOTE", "IBSP_DISCONNECTED", - "IBSP_CLOSING", "IBSP_CLOSED" }; @@ -107,9 +106,6 @@ init_globals( void ) cl_rbmap_init( &g_ibsp.conn_map ); cl_spinlock_init( &g_ibsp.socket_info_mutex ); - cl_qlist_init( &g_ibsp.closed_socket_info_list ); - cl_spinlock_init( &g_ibsp.closed_socket_info_mutex ); - return 0; } @@ -122,7 +118,6 @@ release_globals( void ) g_ibsp.heap = NULL; cl_spinlock_destroy( &g_ibsp.socket_info_mutex ); - cl_spinlock_destroy( &g_ibsp.closed_socket_info_mutex ); cl_spinlock_destroy( &g_ibsp.hca_mutex ); cl_spinlock_destroy( &g_ibsp.ip_mutex ); cl_spinlock_destroy( &g_ibsp.mutex ); diff --git a/trunk/ulp/wsd/user/sockinfo.c b/trunk/ulp/wsd/user/sockinfo.c index 2926235a..bdad2f76 100644 --- a/trunk/ulp/wsd/user/sockinfo.c +++ b/trunk/ulp/wsd/user/sockinfo.c @@ -59,7 +59,7 @@ create_socket_info(void) cl_qlist_init( &socket_info->buf_mem_list.list ); cl_spinlock_init( &socket_info->buf_mem_list.mutex ); - cl_qlist_init( &socket_info->info.listen.list ); + cl_qlist_init( &socket_info->listen.list ); cl_spinlock_init( &socket_info->send_lock ); cl_spinlock_init( &socket_info->recv_lock ); @@ -71,6 +71,11 @@ create_socket_info(void) #endif socket_info->switch_socket = INVALID_SOCKET; + /* + * Preset to 1, IBSPCloseSocket will decrement it, and switch socket + * will be freed once it goes to zero after an upcall. + */ + socket_info->ref_cnt = 1; IBSP_TRACE( IBSP_DBG_SI, ("socket_info (%p)\n", socket_info) ); @@ -105,3 +110,44 @@ free_socket_info( IBSP_EXIT( IBSP_DBG_SI ); } + + +void +deref_socket_info( + IN struct ibsp_socket_info *p_socket ) +{ + int ret, error; + + if( !cl_atomic_dec( &p_socket->ref_cnt ) ) + { + if( p_socket->switch_socket != INVALID_SOCKET ) + { + /* ref_cnt hit zero - destroy the switch socket. */ + IBSP_TRACE1( IBSP_DBG_SI, + ("socket=0x%p calling lpWPUCloseSocketHandle=0x%p\n", + p_socket, p_socket->switch_socket) ); + + ret = g_ibsp.up_call_table.lpWPUCloseSocketHandle( + p_socket->switch_socket, &error ); + if( ret == SOCKET_ERROR ) + { + IBSP_ERROR( ("WPUCloseSocketHandle failed: %d\n", error) ); + } + else + { + STAT_DEC( wpusocket_num ); + } + + p_socket->switch_socket = INVALID_SOCKET; + } + + /* + * This only works because the socket doesn't have its own CQ. If it + * did CQ destruction would have to be async since IBSPCloseSocket can + * be invoked from the CQ callback thread context, and freeing the + * socket structure would need to be delayed until the CQ's destroy + * callback. + */ + free_socket_info( p_socket ); + } +} -- 2.41.0