ceb4ce88753a46435a61189e2cedce7438ab5d35
[mirror/winof/.git] / ulp / wsd / user / ibspstruct.h
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 <complib/cl_qlist.h>\r
33 #include <complib/cl_fleximap.h>\r
34 #include <complib/cl_rbmap.h>\r
35 #include <complib/cl_spinlock.h>\r
36 #include <complib/cl_debug.h>\r
37 \r
38 \r
39 enum ibsp_socket_state\r
40 {\r
41         IBSP_CREATE = 0,\r
42         IBSP_BIND,\r
43         IBSP_CONNECT,\r
44         IBSP_LISTEN,\r
45         IBSP_CONNECTED,\r
46         IBSP_DUPLICATING_OLD,           /* duplicating socket on the original controlling process */\r
47         IBSP_DUPLICATING_NEW,           /* duplicating socket on the new controlling process */\r
48         IBSP_DUPLICATING_REMOTE,        /* duplicating socket on the remote side */\r
49         IBSP_DISCONNECTED,\r
50         IBSP_CLOSED,\r
51         IBSP_NUM_STATES\r
52 };\r
53 \r
54 extern char *ibsp_socket_state_str[IBSP_NUM_STATES];\r
55 \r
56 #define IBSP_SOCKET_STATE_STR(state) \\r
57         (state < IBSP_NUM_STATES)?ibsp_socket_state_str[state]:"INVALID"\r
58 \r
59 /* Socket Options structure */\r
60 struct ibsp_socket_options\r
61 {\r
62         BOOL debug;                                     /* SO_DEBUG */\r
63         GROUP group_id;                         /* SO_GROUP_ID */\r
64         int group_priority;                     /* SO_GROUP_PRIORITY */\r
65         unsigned int max_msg_size;      /* SO_MAX_MSG_SIZE */\r
66         int max_rdma_size;                      /* SO_MAX_RDMA_SIZE */\r
67         int rdma_threshold_size;        /* SO_RDMA_THRESHOLD_SIZE */\r
68 };\r
69 \r
70 /* Used to discriminate between various listen on the same ports. \r
71  * We need this for socket duplication. \r
72  * { 0, 0 } is a standard connection request. */\r
73 struct listen_req_param\r
74 {\r
75         DWORD dwProcessId;\r
76         DWORD identifier;\r
77 };\r
78 \r
79 /* Parameters given to establish a connection */\r
80 struct cm_req_params\r
81 {\r
82         struct listen_req_param listen_req_param;\r
83         struct sockaddr_in dest;\r
84         struct sockaddr_in source;      /* Source of connect() */\r
85 };\r
86 \r
87 /* Listen structure.\r
88  * Used to remember an incoming connection. */\r
89 struct listen_incoming\r
90 {\r
91         cl_list_item_t                  item;\r
92 \r
93         ib_cm_req_rec_t                 cm_req_received;\r
94         struct cm_req_params    params;\r
95 };\r
96 \r
97 \r
98 /* Keeps track of the posted WR */\r
99 struct _wr\r
100 {\r
101         LPWSAOVERLAPPED                         lpOverlapped;\r
102         struct ibsp_socket_info         *socket_info;\r
103 };\r
104 \r
105 \r
106 /* Keeps track of the posted WR */\r
107 struct _recv_wr\r
108 {\r
109         struct _wr              wr;\r
110         ib_recv_wr_t    recv;\r
111         ib_local_ds_t   ds_array[QP_ATTRIB_RQ_SGE];\r
112 };\r
113 \r
114 \r
115 /* Keeps track of the registered MRs */\r
116 struct mr_list\r
117 {\r
118         cl_qlist_t list;                        /* Regions registered through IBSPRegisterMemory */\r
119         cl_spinlock_t mutex;            /* Protects the list */\r
120 };\r
121 \r
122 /* Information necessary to duplicate sockets */\r
123 struct ibsp_duplicate_info\r
124 {\r
125         ib_net64_t port_guid;\r
126         struct ibsp_socket_options socket_options;\r
127         struct sockaddr_in local_addr;\r
128         struct sockaddr_in peer_addr;\r
129         DWORD dwProcessId;\r
130 };\r
131 \r
132 /* Give the reason for disconnections */\r
133 struct disconnect_reason\r
134 {\r
135         enum\r
136         {\r
137                 DISC_INVALID,\r
138                 DISC_SHUTDOWN,                  /* normal shutdown */\r
139                 DISC_DUPLICATING                /* socket duplication */\r
140         } type;\r
141 \r
142         struct _disconnect_reason_dup\r
143         {\r
144                 DWORD identifier;\r
145                 DWORD dwProcessId;\r
146 \r
147         }       duplicating;\r
148 };\r
149 \r
150 /* Internal node describing a registered region. */\r
151 struct memory_node\r
152 {\r
153 \r
154         cl_list_item_t item;\r
155 \r
156 #ifdef _DEBUG_\r
157 #define MR_NODE_MAGIC 0x7fba43ce\r
158         int magic;\r
159 #endif\r
160 \r
161         /* Everytime the same region is registered, this counter is\r
162          * increased. When it reaches 0, the memory can be released. */\r
163         int refcount;\r
164 \r
165         /* Characteristics of that region. */\r
166         ib_mr_create_t type;\r
167 \r
168         /* Memory registration parameters, returned by ib_reg_mem. */\r
169         uint32_t lkey;\r
170         uint32_t rkey;\r
171         ib_mr_handle_t mr_handle;\r
172 };\r
173 \r
174 /* Descriptor given back to WSPRegisterRdmaMemory */\r
175 struct rdma_memory_desc\r
176 {\r
177         uint64_t iova;\r
178         uint32_t lkey;\r
179         uint32_t rkey;\r
180         struct memory_node *node;       /* valid only on registering node */\r
181 };\r
182 \r
183 struct cq_thread_info\r
184 {\r
185         cl_list_item_t          list_item;\r
186 \r
187         cl_waitobj_handle_t cq_waitobj;\r
188         ib_cq_handle_t cq;\r
189 \r
190         /* Number of qp's using this cq */\r
191         atomic32_t qp_count;\r
192 \r
193         /* Current cqe size */\r
194         uint32_t cqe_size;\r
195 \r
196         HANDLE ib_cq_thread;\r
197         DWORD   ib_cq_thread_id;\r
198         BOOL ib_cq_thread_exit_wanted;\r
199 \r
200         struct ibsp_hca *hca;           /* HCA to which this cq belongs. */\r
201 };\r
202 \r
203 /* Structure representing the context information stored for each\r
204  * socket created */\r
205 struct ibsp_socket_info\r
206 {\r
207         cl_list_item_t item;            /* Link to next SOCKET_INFO in the global list */\r
208         cl_rbmap_item_t conn_item;\r
209         cl_spinlock_t mutex;            /* protect this structure */\r
210 \r
211         /* Switch socket handle created by WPUCreateSocketHandle. */\r
212         SOCKET switch_socket;\r
213 \r
214         /* IP address and port this socket is bound to. Set by WSPBind */\r
215         struct sockaddr_in local_addr;\r
216 \r
217         /* Remote address of peer entity after connect/accept is complete */\r
218         struct sockaddr_in peer_addr;\r
219 \r
220         /* Back pointer to the port to which this socket is\r
221          * bound. It is NULL until the socket is bound, except if the listen\r
222          * binds to INADDR_ANY. */\r
223         struct ibsp_port *port;\r
224 \r
225         enum ibsp_socket_state socket_state;    /* represents current socket state */\r
226 \r
227         struct\r
228         {\r
229                 /* Listening socket */\r
230                 unsigned int backlog;   /* Maximum number of pending connections */\r
231                 cl_qlist_t list;        /* list of pending connections */\r
232                 ib_listen_handle_t handle;\r
233                 struct listen_req_param listen_req_param;\r
234         } listen;\r
235 \r
236         /* Event for blocking accept, and connect */\r
237         HANDLE  h_event;\r
238 \r
239         /* Variables associated with IBSPSelectEvent */\r
240         WSAEVENT event_select;          /* Handle to Event Object */\r
241         long event_mask;                        /* Events we care about */\r
242         long network_events;            /* Events that happenned */\r
243         int errno_connect;                      /* errno code (if any) returned by connect */\r
244 \r
245         struct ibsp_socket_options socket_options;      /* Socket Options */\r
246 \r
247         /* Infiniband ressources */\r
248         ib_pd_handle_t hca_pd;          /* Copy of the HCA PD, for faster access. */\r
249 \r
250         /* Pointer to completion queue and thread assigned to this socket */\r
251         struct cq_thread_info *cq_tinfo;\r
252 \r
253         ib_qp_handle_t          qp;\r
254         uint32_t                        max_inline;\r
255 \r
256         /* State on the QP. This is only valid when the socket state is IBSP_CONNECTED.\r
257          *   0  : good\r
258          *   <0 : an error occurred, contains a windoes error *ie WSAExxxx\r
259          *   -1 : disconected, for duplication process.\r
260          */\r
261         int qp_error;\r
262 \r
263         /* Send request processing. */\r
264         cl_spinlock_t   send_lock;\r
265         ib_send_opt_t   send_opt;\r
266         struct _wr              send_wr[QP_ATTRIB_SQ_DEPTH];\r
267         uint8_t                 send_idx;\r
268         atomic32_t              send_cnt; /* Used to limit access to send_wr array. */\r
269 \r
270         /* Receive request processing. */\r
271         cl_spinlock_t   recv_lock;\r
272         struct _recv_wr recv_wr[QP_ATTRIB_RQ_DEPTH];\r
273         uint8_t                 recv_idx;\r
274         atomic32_t              recv_cnt; /* Used to limit access to recv_wr array. */\r
275 \r
276         /*\r
277          * Used to stall destruction of switch socket until all completion\r
278          * upcalls have unwound.\r
279          */\r
280         atomic32_t              ref_cnt;\r
281 \r
282 #ifdef _DEBUG_\r
283         atomic32_t              send_comp;\r
284         atomic32_t              recv_comp;\r
285 #endif\r
286 \r
287         struct _recv_wr dup_wr[QP_ATTRIB_RQ_DEPTH];\r
288         uint8_t                 dup_idx;\r
289         atomic32_t              dup_cnt;\r
290 \r
291         /* Memory management. \r
292          * From what I saw, the regions registered through IBSPRegisterMemory will \r
293          * only be used by this socket. And there will be only one registration for \r
294          * send buffers and one for receive buffers for the whole life of the socket. \r
295          * Thus these won't be cached. A later optimization would be not to release \r
296          * those regions, but to store them in the HCA structure in case another socket\r
297          * binds the same area again. */\r
298         struct mr_list buf_mem_list;\r
299 \r
300         /* Stuff for socket duplication */\r
301         struct\r
302         {\r
303                 HANDLE mmap_handle;\r
304                 DWORD identifier;               /* Unique identifier */\r
305                 DWORD dwProcessId;\r
306         } duplicate;\r
307 };\r
308 \r
309 \r
310 inline void\r
311 ibsp_css(\r
312                                         char                                            *calling_func,\r
313                                         int                                                     line,\r
314                                         struct ibsp_socket_info         *s,\r
315                                         enum ibsp_socket_state          new_state )\r
316 {\r
317         enum ibsp_socket_state old_state;\r
318 \r
319         UNUSED_PARAM( calling_func );\r
320         UNUSED_PARAM( line );\r
321 \r
322         old_state = s->socket_state;\r
323 \r
324         if( old_state == new_state )\r
325         {\r
326                 /* Nothing to change */\r
327                 return;\r
328         }\r
329 \r
330         /* IBSP_CLOSED is a dead end state */\r
331         if( old_state == IBSP_CLOSED )\r
332         {\r
333                 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));\r
334                 return;\r
335         }\r
336 \r
337         fzprint(("%s():0x%x:0x%x: socket=0x%p %s to %s, called by %s():%d\n", __FUNCTION__,\r
338                          GetCurrentProcessId(),\r
339                          GetCurrentThreadId(), s,\r
340                          IBSP_SOCKET_STATE_STR(old_state),\r
341                          IBSP_SOCKET_STATE_STR(new_state), calling_func, line));\r
342 \r
343         s->socket_state = new_state;\r
344 }\r
345 \r
346 #define IBSP_CHANGE_SOCKET_STATE(socket_info, new_state) \\r
347         ibsp_css(__FUNCTION__, __LINE__, socket_info, new_state)\r
348 \r
349 \r
350 /*--------------------------------------------------------------------------*/\r
351 \r
352 /* Describes an IP address */\r
353 struct ibsp_ip_addr\r
354 {\r
355         cl_fmap_item_t          item;                   /* next IP for that port */\r
356 \r
357         struct ibsp_port        *p_port;                /* port that owns this IP address */\r
358         struct in_addr          ip_addr;                /* IPv4 address */\r
359 };\r
360 \r
361 /* describes a port */\r
362 struct ibsp_port\r
363 {\r
364         cl_list_item_t item;\r
365 \r
366         struct ibsp_hca *hca;           /* HCA to which this port belong. */\r
367 \r
368         ib_net64_t guid;\r
369         uint8_t port_num;\r
370 };\r
371 \r
372 /* Describes a hca */\r
373 struct ibsp_hca\r
374 {\r
375         cl_list_item_t item;\r
376 \r
377         ib_net64_t guid;\r
378         uint16_t        dev_id; /* Device ID to selectively cap MTU to 1K for Tavor. */\r
379         ib_ca_handle_t hca_handle;\r
380 \r
381         ib_pd_handle_t pd;\r
382 \r
383         /* Memory management */\r
384         struct mr_list rdma_mem_list;   /* Regions registered through IBSPRegisterRdmaMemory */\r
385 \r
386         cl_spinlock_t   port_lock;\r
387         cl_qlist_t              port_list;\r
388 \r
389         /*\r
390          * The CQ list is a circular list without an end.  The pointer here\r
391          * points to the entry that should be used for the next allocation.\r
392          */\r
393         cl_spinlock_t   cq_lock;\r
394         struct cq_thread_info *cq_tinfo;\r
395 };\r
396 \r
397 /* There is only one instance of that structure. */\r
398 struct ibspdll_globals\r
399 {\r
400         /* Special values. Keep first and in this order. These are not reset\r
401          * between WSAStartupEx and WSACleanup calls. */\r
402         cl_spinlock_t mutex;\r
403         UINT entry_count;\r
404 \r
405         /* Provider */\r
406         WSPUPCALLTABLEEX up_call_table; /* MUST keep afetr entry_count */\r
407         HANDLE heap;\r
408         cl_qlist_t socket_info_list;    /* List of all the created sockets */\r
409         cl_rbmap_t conn_map;    /* rb tree of all connections to ensure unique 4-tuple */\r
410         cl_spinlock_t socket_info_mutex;\r
411 \r
412         WSAPROTOCOL_INFOW protocol_info;\r
413 \r
414         /* Infiniband */\r
415         ib_al_handle_t al_handle;\r
416         ib_pnp_handle_t pnp_handle_ca;\r
417         ib_pnp_handle_t pnp_handle_port;\r
418 \r
419         cl_qlist_t hca_list;\r
420         cl_spinlock_t hca_mutex;\r
421 \r
422         cl_fmap_t               ip_map;                 /* list of all IP addresses supported by all the ports. */\r
423         cl_spinlock_t   ip_mutex;\r
424 \r
425 #ifdef _DEBUG_\r
426         /* Statistics */\r
427         atomic32_t qp_num;\r
428         atomic32_t cq_num;\r
429         atomic32_t pd_num;\r
430         atomic32_t al_num;\r
431         atomic32_t mr_num;\r
432         atomic32_t ca_num;\r
433         atomic32_t listen_num;\r
434         atomic32_t pnp_num;\r
435         atomic32_t thread_num;\r
436         atomic32_t wpusocket_num;\r
437 \r
438         atomic32_t overlap_h0_count;\r
439         atomic32_t overlap_h1_comp_count;\r
440         atomic32_t overlap_h1_count;\r
441         atomic32_t max_comp_count;\r
442         atomic32_t send_count;\r
443         atomic32_t recv_count;\r
444         atomic32_t CloseSocket_count;\r
445 #endif\r
446 };\r