{\r
IBSP_ENTER( IBSP_DBG_MEM );\r
\r
- cl_qlist_remove_item( &node->p_reg->node_list, &node->mr_item );\r
+ // Underlying registration could be freed before the node.\r
+ if( node->p_reg )\r
+ cl_qlist_remove_item( &node->p_reg->node_list, &node->mr_item );\r
+\r
cl_qlist_remove_item( &node->s->mr_list, &node->socket_item );\r
\r
HeapFree( g_ibsp.heap, 0, node );\r
struct memory_reg *p_reg = PARENT_STRUCT(item, struct memory_reg, item);\r
ib_api_status_t status;\r
\r
- while( cl_qlist_count( &p_reg->node_list ) )\r
+ /*\r
+ * Clear the pointer from the node to this registration. No need\r
+ * to remove from the list as we're about to free the registration.\r
+ */\r
+ for( item = cl_qlist_head( &p_reg->node_list );\r
+ item != cl_qlist_end( &p_reg->node_list );\r
+ item = cl_qlist_next( item ) )\r
{\r
struct memory_node *p_node =\r
- PARENT_STRUCT( cl_qlist_head( &p_reg->node_list ),\r
- struct memory_node, mr_item );\r
+ PARENT_STRUCT( item, struct memory_node, mr_item );\r
\r
- __ibsp_dereg_mem_mr( p_node );\r
+ p_node->p_reg = NULL;\r
}\r
\r
IBSP_TRACE2( IBSP_DBG_MEM, ("unpinning ,memory reg %p\n", p_reg) );\r
IBSP_ENTER( IBSP_DBG_MEM );\r
\r
cl_spinlock_acquire( &p_hca->rdma_mem_list.mutex );\r
- for( p_item = cl_qlist_head( &p_hca->rdma_mem_list.list );\r
- p_item != cl_qlist_end( &p_hca->rdma_mem_list.list );\r
- p_item = cl_qlist_next( p_item ) )\r
+ p_item = cl_qlist_head( &p_hca->rdma_mem_list.list );\r
+ while( p_item != cl_qlist_end( &p_hca->rdma_mem_list.list ) )\r
{\r
p_reg = PARENT_STRUCT( p_item, struct memory_reg, item );\r
\r
+ /* Move to the next item now so we can remove the current. */\r
+ p_item = cl_qlist_next( p_item );\r
+\r
if( lpvAddress > p_reg->type.vaddr ||\r
((uintn_t)lpvAddress) + Size <\r
((uintn_t)(uint64_t)p_reg->type.vaddr) + p_reg->type.length )\r
continue;\r
}\r
\r
- /* Release all socket's nodes that reference this registration. */\r
- while( cl_qlist_count( &p_reg->node_list ) )\r
+ /*\r
+ * Clear the pointer from all sockets' nodes to this registration.\r
+ * No need to remove from the list as we're about to free the\r
+ * registration.\r
+ */\r
+ for( p_item = cl_qlist_head( &p_reg->node_list );\r
+ p_item != cl_qlist_end( &p_reg->node_list );\r
+ p_item = cl_qlist_next( p_item ) )\r
{\r
- struct memory_node *p_node =\r
- PARENT_STRUCT( cl_qlist_head( &p_reg->node_list ),\r
- struct memory_node, mr_item );\r
+ struct memory_node *p_node =\r
+ PARENT_STRUCT( p_item, struct memory_node, mr_item );\r
\r
- __ibsp_dereg_mem_mr( p_node );\r
+ p_node->p_reg = NULL;\r
}\r
\r
- /* Move to the previous item so the for loop properly moves forward. */\r
- p_item = cl_qlist_prev( p_item );\r
-\r
cl_qlist_remove_item( &p_hca->rdma_mem_list.list, &p_reg->item );\r
\r
status = ib_dereg_mr( p_reg->mr_handle );\r