From: ftillier Date: Mon, 2 Oct 2006 23:58:56 +0000 (+0000) Subject: [WSD] Fix memory registration code: X-Git-Url: https://openfabrics.org/gitweb/?a=commitdiff_plain;h=01e422bfff9b337476518cf85f3b4218518e506c;p=~shefty%2Frdma-win.git [WSD] Fix memory registration code: - Fix access violation if registered memory is freed before WSD switch calls to deregister. - No need to set IB_AC_LOCAL_WRITE for MEM_READ registrations. git-svn-id: svn://openib.tc.cornell.edu/gen1@510 ad392aa1-c5ef-ae45-8dd8-e69d62a5ef86 --- diff --git a/trunk/ulp/wsd/user/extensions.c b/trunk/ulp/wsd/user/extensions.c index 3de9b070..6af9f961 100644 --- a/trunk/ulp/wsd/user/extensions.c +++ b/trunk/ulp/wsd/user/extensions.c @@ -199,20 +199,18 @@ IBSPRegisterRdmaMemory( return SOCKET_ERROR; } - access_ctrl = IB_AC_LOCAL_WRITE; - switch( dwFlags ) { case MEM_READ: - access_ctrl |= IB_AC_RDMA_READ; + access_ctrl = IB_AC_RDMA_READ; break; case MEM_WRITE: - access_ctrl |= IB_AC_RDMA_WRITE; + access_ctrl = IB_AC_LOCAL_WRITE | IB_AC_RDMA_WRITE; break; case MEM_READWRITE: - access_ctrl |= (IB_AC_RDMA_READ | IB_AC_RDMA_WRITE); + access_ctrl = IB_AC_LOCAL_WRITE | IB_AC_RDMA_READ | IB_AC_RDMA_WRITE; break; default: diff --git a/trunk/ulp/wsd/user/ibsp_mem.c b/trunk/ulp/wsd/user/ibsp_mem.c index 3e13c7f2..ea05e46e 100644 --- a/trunk/ulp/wsd/user/ibsp_mem.c +++ b/trunk/ulp/wsd/user/ibsp_mem.c @@ -205,7 +205,10 @@ static inline int __ibsp_dereg_mem_mr( { IBSP_ENTER( IBSP_DBG_MEM ); - cl_qlist_remove_item( &node->p_reg->node_list, &node->mr_item ); + // Underlying registration could be freed before the node. + if( node->p_reg ) + cl_qlist_remove_item( &node->p_reg->node_list, &node->mr_item ); + cl_qlist_remove_item( &node->s->mr_list, &node->socket_item ); HeapFree( g_ibsp.heap, 0, node ); @@ -257,13 +260,18 @@ ibsp_dereg_hca( struct memory_reg *p_reg = PARENT_STRUCT(item, struct memory_reg, item); ib_api_status_t status; - while( cl_qlist_count( &p_reg->node_list ) ) + /* + * Clear the pointer from the node to this registration. No need + * to remove from the list as we're about to free the registration. + */ + for( item = cl_qlist_head( &p_reg->node_list ); + item != cl_qlist_end( &p_reg->node_list ); + item = cl_qlist_next( item ) ) { struct memory_node *p_node = - PARENT_STRUCT( cl_qlist_head( &p_reg->node_list ), - struct memory_node, mr_item ); + PARENT_STRUCT( item, struct memory_node, mr_item ); - __ibsp_dereg_mem_mr( p_node ); + p_node->p_reg = NULL; } IBSP_TRACE2( IBSP_DBG_MEM, ("unpinning ,memory reg %p\n", p_reg) ); @@ -336,12 +344,14 @@ ibsp_hca_flush_mr_cache( IBSP_ENTER( IBSP_DBG_MEM ); cl_spinlock_acquire( &p_hca->rdma_mem_list.mutex ); - for( p_item = cl_qlist_head( &p_hca->rdma_mem_list.list ); - p_item != cl_qlist_end( &p_hca->rdma_mem_list.list ); - p_item = cl_qlist_next( p_item ) ) + p_item = cl_qlist_head( &p_hca->rdma_mem_list.list ); + while( p_item != cl_qlist_end( &p_hca->rdma_mem_list.list ) ) { p_reg = PARENT_STRUCT( p_item, struct memory_reg, item ); + /* Move to the next item now so we can remove the current. */ + p_item = cl_qlist_next( p_item ); + if( lpvAddress > p_reg->type.vaddr || ((uintn_t)lpvAddress) + Size < ((uintn_t)(uint64_t)p_reg->type.vaddr) + p_reg->type.length ) @@ -349,19 +359,21 @@ ibsp_hca_flush_mr_cache( continue; } - /* Release all socket's nodes that reference this registration. */ - while( cl_qlist_count( &p_reg->node_list ) ) + /* + * Clear the pointer from all sockets' nodes to this registration. + * No need to remove from the list as we're about to free the + * registration. + */ + for( p_item = cl_qlist_head( &p_reg->node_list ); + p_item != cl_qlist_end( &p_reg->node_list ); + p_item = cl_qlist_next( p_item ) ) { - struct memory_node *p_node = - PARENT_STRUCT( cl_qlist_head( &p_reg->node_list ), - struct memory_node, mr_item ); + struct memory_node *p_node = + PARENT_STRUCT( p_item, struct memory_node, mr_item ); - __ibsp_dereg_mem_mr( p_node ); + p_node->p_reg = NULL; } - /* Move to the previous item so the for loop properly moves forward. */ - p_item = cl_qlist_prev( p_item ); - cl_qlist_remove_item( &p_hca->rdma_mem_list.list, &p_reg->item ); status = ib_dereg_mr( p_reg->mr_handle );