[WSD] Fix MR caching to properly flush both local and RDMA registrations.
[mirror/winof/.git] / ulp / wsd / user / sockinfo.c
1 /*\r
2  * Copyright (c) 2005 SilverStorm Technologies.  All rights reserved.\r
3  *\r
4  * This software is available to you under the OpenIB.org BSD license\r
5  * below:\r
6  *\r
7  *     Redistribution and use in source and binary forms, with or\r
8  *     without modification, are permitted provided that the following\r
9  *     conditions are met:\r
10  *\r
11  *      - Redistributions of source code must retain the above\r
12  *        copyright notice, this list of conditions and the following\r
13  *        disclaimer.\r
14  *\r
15  *      - Redistributions in binary form must reproduce the above\r
16  *        copyright notice, this list of conditions and the following\r
17  *        disclaimer in the documentation and/or other materials\r
18  *        provided with the distribution.\r
19  *\r
20  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,\r
21  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\r
22  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\r
23  * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS\r
24  * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN\r
25  * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN\r
26  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\r
27  * SOFTWARE.\r
28  *\r
29  * $Id$\r
30  */\r
31 \r
32 #include "ibspdll.h"\r
33 \r
34 \r
35 static void\r
36 free_socket_info(\r
37         IN                              struct ibsp_socket_info         *socket_info );\r
38 \r
39 /* \r
40  * Function: create_socket_info\r
41  * \r
42  *  Description:\r
43  *    Allocates a new socket info context structure and initializes some fields.\r
44 */\r
45 struct ibsp_socket_info *\r
46 create_socket_info(\r
47         OUT                             LPINT                                           lpErrno )\r
48 {\r
49         struct ibsp_socket_info *socket_info;\r
50 \r
51         IBSP_ENTER( IBSP_DBG_SI );\r
52 \r
53         socket_info = HeapAlloc( g_ibsp.heap,\r
54                 HEAP_ZERO_MEMORY, sizeof(struct ibsp_socket_info) );\r
55         if( socket_info == NULL )\r
56         {\r
57                 IBSP_TRACE_EXIT( IBSP_DBG_SI,\r
58                         ("HeapAlloc() failed: %d\n", GetLastError()) );\r
59                 *lpErrno = WSAENOBUFS;\r
60                 return NULL;\r
61         }\r
62 \r
63         cl_spinlock_construct( &socket_info->mutex );\r
64         cl_spinlock_construct( &socket_info->send_lock );\r
65         cl_spinlock_construct( &socket_info->recv_lock );\r
66         cl_qlist_init( &socket_info->mr_list );\r
67         cl_qlist_init( &socket_info->listen.list );\r
68 \r
69         if( cl_spinlock_init( &socket_info->mutex ) != CL_SUCCESS )\r
70                 goto err;\r
71 \r
72         if( cl_spinlock_init( &socket_info->send_lock ) != CL_SUCCESS )\r
73                 goto err;\r
74 \r
75         if( cl_spinlock_init( &socket_info->recv_lock ) != CL_SUCCESS )\r
76                 goto err;\r
77 \r
78 #ifdef _DEBUG_\r
79         memset( socket_info->recv_wr, 0x38, sizeof(socket_info->send_wr) );\r
80         memset( socket_info->recv_wr, 0x38, sizeof(socket_info->recv_wr) );\r
81         memset( socket_info->recv_wr, 0x38, sizeof(socket_info->dup_wr) );\r
82 #endif\r
83 \r
84         socket_info->switch_socket =\r
85                 g_ibsp.up_call_table.lpWPUCreateSocketHandle(\r
86                 0, (DWORD_PTR)socket_info, lpErrno );\r
87 \r
88         if( socket_info->switch_socket == INVALID_SOCKET )\r
89         {\r
90                 IBSP_ERROR(\r
91                         ("WPUCreateSocketHandle() failed: %d", *lpErrno) );\r
92 err:\r
93                 free_socket_info( socket_info );\r
94                 IBSP_EXIT( IBSP_DBG_SI );\r
95                 return NULL;\r
96         }\r
97 \r
98         STAT_INC( wpusocket_num );\r
99 \r
100         /*\r
101          * Preset to 1, IBSPCloseSocket will decrement it, and switch socket\r
102          * will be freed once it goes to zero.\r
103          */\r
104         socket_info->ref_cnt = 1;\r
105 \r
106         IBSP_TRACE( IBSP_DBG_SI, ("socket_info (%p), switch socket (%p)\n",\r
107                 socket_info, socket_info->switch_socket) );\r
108 \r
109         IBSP_EXIT( IBSP_DBG_SI );\r
110         return socket_info;\r
111 }\r
112 \r
113 \r
114 static void\r
115 free_socket_info(\r
116         IN                              struct ibsp_socket_info         *p_socket )\r
117 {\r
118         int             ret, error;\r
119 \r
120         if( p_socket->switch_socket != INVALID_SOCKET )\r
121         {\r
122                 /* ref_cnt hit zero - destroy the switch socket. */\r
123                 IBSP_TRACE1( IBSP_DBG_SI,\r
124                         ("socket=0x%p calling lpWPUCloseSocketHandle=0x%p\n",\r
125                         p_socket, p_socket->switch_socket) );\r
126 \r
127                 ret = g_ibsp.up_call_table.lpWPUCloseSocketHandle(\r
128                         p_socket->switch_socket, &error );\r
129                 if( ret == SOCKET_ERROR )\r
130                         IBSP_ERROR( ("WPUCloseSocketHandle failed: %d\n", error) );\r
131                 else\r
132                         STAT_DEC( wpusocket_num );\r
133 \r
134                 p_socket->switch_socket = INVALID_SOCKET;\r
135         }\r
136 \r
137         CL_ASSERT( !p_socket->qp );\r
138         CL_ASSERT( !p_socket->conn_item.p_map );\r
139 \r
140         cl_spinlock_destroy( &p_socket->mutex );\r
141 \r
142         cl_spinlock_destroy( &p_socket->send_lock );\r
143         cl_spinlock_destroy( &p_socket->recv_lock );\r
144 \r
145         HeapFree( g_ibsp.heap, 0, p_socket );\r
146 }\r
147 \r
148 \r
149 /* \r
150  * Function: deref_sock_info\r
151  * \r
152  * Description:\r
153  *      This routine decrements a socket context's reference count, and if\r
154  *      it reaches zero, frees the socket context structure.\r
155  */\r
156 void AL_API\r
157 deref_socket_info(\r
158         IN                              struct ibsp_socket_info         *p_socket )\r
159 {\r
160         IBSP_ENTER( IBSP_DBG_SI );\r
161 \r
162         if( !cl_atomic_dec( &p_socket->ref_cnt ) )\r
163         {\r
164                 free_socket_info( p_socket );\r
165                 IBSP_TRACE( IBSP_DBG_SI, ("Freed socket_info (%p)\n", p_socket) );\r
166         }\r
167         IBSP_EXIT( IBSP_DBG_SI );\r
168 }\r