ffe5d7df8411f41ebe26ab3ed027a389807c6496
[mirror/winof/.git] / ulp / dapl2 / test / dapltest / test / dapl_transaction_util.c
1 /*
2  * Copyright (c) 2002-2005, Network Appliance, Inc. All rights reserved.
3  *
4  * This Software is licensed under one of the following licenses:
5  *
6  * 1) under the terms of the "Common Public License 1.0" a copy of which is
7  *    in the file LICENSE.txt in the root directory. The license is also
8  *    available from the Open Source Initiative, see
9  *    http://www.opensource.org/licenses/cpl.php.
10  *
11  * 2) under the terms of the "The BSD License" a copy of which is in the file
12  *    LICENSE2.txt in the root directory. The license is also available from
13  *    the Open Source Initiative, see
14  *    http://www.opensource.org/licenses/bsd-license.php.
15  *
16  * 3) under the terms of the "GNU General Public License (GPL) Version 2" a 
17  *    copy of which is in the file LICENSE3.txt in the root directory. The 
18  *    license is also available from the Open Source Initiative, see
19  *    http://www.opensource.org/licenses/gpl-license.php.
20  *
21  * Licensee has the right to choose one of the above licenses.
22  *
23  * Redistributions of source code must retain the above copyright
24  * notice and one of the license notices.
25  *
26  * Redistributions in binary form must reproduce both the above copyright
27  * notice, one of the license notices in the documentation
28  * and/or other materials provided with the distribution.
29  */
30
31 #include "dapl_proto.h"
32
33 /* -----------------------------------------------------------
34  * Post a recv buffer on each of this thread's EPs.
35  */
36 bool
37 DT_handle_post_recv_buf(DT_Tdep_Print_Head * phead,
38                         Ep_Context_t * ep_context,
39                         unsigned int num_eps, int op_indx)
40 {
41         unsigned int i, j;
42
43         for (i = 0; i < num_eps; i++) {
44                 Transaction_Test_Op_t *op = &ep_context[i].op[op_indx];
45                 DAT_LMR_TRIPLET *iov = DT_Bpool_GetIOV(op->bp, 0);
46                 DAT_DTO_COOKIE cookie;
47                 DAT_RETURN ret;
48
49                 /* Prep the inputs */
50                 for (j = 0; j < op->num_segs; j++) {
51                         iov[j].virtual_address = (DAT_VADDR) (uintptr_t)
52                             DT_Bpool_GetBuffer(op->bp, j);
53                         iov[j].segment_length = op->seg_size;
54                         iov[j].lmr_context = DT_Bpool_GetLMR(op->bp, j);
55                 }
56                 cookie.as_64 = ((((DAT_UINT64) i) << 32)
57                                 | (((uintptr_t) DT_Bpool_GetBuffer(op->bp, 0)) &
58                                    0xffffffffUL));
59
60                 /* Post the recv */
61                 ret = dat_ep_post_recv(ep_context[i].ep_handle,
62                                        op->num_segs,
63                                        iov,
64                                        cookie, DAT_COMPLETION_DEFAULT_FLAG);
65
66                 if (ret != DAT_SUCCESS) {
67                         DT_Tdep_PT_Printf(phead,
68                                           "Test Error: dat_ep_post_recv failed: %s\n",
69                                           DT_RetToString(ret));
70                         DT_Test_Error();
71                         return false;
72                 }
73         }
74
75         return true;
76 }
77
78 /* -----------------------------------------------------------
79  * Post a send buffer on each of this thread's EPs.
80  */
81 bool
82 DT_handle_send_op(DT_Tdep_Print_Head * phead,
83                   Ep_Context_t * ep_context,
84                   unsigned int num_eps, int op_indx, bool poll)
85 {
86         unsigned int i, j;
87         unsigned char *completion_reaped;
88
89         completion_reaped = DT_Mdep_Malloc(num_eps * sizeof(unsigned char));
90
91         if (!completion_reaped) {
92                 return false;
93         }
94
95         for (i = 0; i < num_eps; i++) {
96                 Transaction_Test_Op_t *op = &ep_context[i].op[op_indx];
97                 DAT_LMR_TRIPLET *iov = DT_Bpool_GetIOV(op->bp, 0);
98                 DAT_DTO_COOKIE cookie;
99                 DAT_RETURN ret;
100
101                 /* Prep the inputs */
102                 for (j = 0; j < op->num_segs; j++) {
103                         iov[j].virtual_address = (DAT_VADDR) (uintptr_t)
104                             DT_Bpool_GetBuffer(op->bp, j);
105                         iov[j].segment_length = op->seg_size;
106                         iov[j].lmr_context = DT_Bpool_GetLMR(op->bp, j);
107                 }
108                 cookie.as_64 = ((((DAT_UINT64) i) << 32)
109                                 | (((uintptr_t) DT_Bpool_GetBuffer(op->bp, 0)) &
110                                    0xffffffffUL));
111
112                 /* Post the send */
113                 ret = dat_ep_post_send(ep_context[i].ep_handle,
114                                        op->num_segs,
115                                        iov,
116                                        cookie, DAT_COMPLETION_DEFAULT_FLAG);
117
118                 if (ret != DAT_SUCCESS) {
119                         DT_Tdep_PT_Printf(phead,
120                                           "Test Error: dat_ep_post_send failed: %s\n",
121                                           DT_RetToString(ret));
122                         DT_Test_Error();
123                         DT_Mdep_Free(completion_reaped);
124                         return false;
125                 }
126         }
127
128         for (i = 0; i < num_eps; i++) {
129                 Transaction_Test_Op_t *op = &ep_context[i].op[op_indx];
130
131                 if (op->reap_send_on_recv && !op->server_initiated) {
132                         /* we will reap the send on the recv (Client SR) */
133                         DT_Mdep_Free(completion_reaped);
134                         return true;
135                 }
136         }
137
138         bzero((void *)completion_reaped, sizeof(unsigned char) * num_eps);
139
140         /* reap the send completion */
141         for (i = 0; i < num_eps; i++) {
142                 Transaction_Test_Op_t *op;
143                 DAT_DTO_COMPLETION_EVENT_DATA dto_stat;
144                 DAT_DTO_COOKIE dto_cookie;
145                 unsigned int epnum;
146
147                 if (!DT_dto_event_reap
148                     (phead, ep_context[i].reqt_evd_hdl, poll, &dto_stat)) {
149                         DT_Mdep_Free(completion_reaped);
150                         return false;
151                 }
152
153                 epnum = dto_stat.user_cookie.as_64 >> 32;
154                 if (epnum > num_eps) {
155                         DT_Tdep_PT_Printf(phead,
156                                           "Test Error: Send: Invalid endpoint completion reaped.\n"
157                                           "\tEndpoint: 0x%p, Cookie: 0x" F64x
158                                           ", Length: " F64u "\n",
159                                           dto_stat.ep_handle,
160                                           dto_stat.user_cookie.as_64,
161                                           dto_stat.transfered_length);
162                         DT_Test_Error();
163                         DT_Mdep_Free(completion_reaped);
164                         return false;
165                 }
166
167                 op = &ep_context[epnum].op[op_indx];
168
169                 dto_cookie.as_64 = ((((DAT_UINT64) epnum) << 32)
170                                     |
171                                     (((uintptr_t) DT_Bpool_GetBuffer(op->bp, 0))
172                                      & 0xffffffffUL));
173
174                 if (!DT_dto_check(phead,
175                                   &dto_stat,
176                                   ep_context[epnum].ep_handle,
177                                   op->num_segs * op->seg_size,
178                                   dto_cookie, "Send")) {
179                         DT_Mdep_Free(completion_reaped);
180                         return false;
181                 }
182
183                 if (completion_reaped[epnum]) {
184                         DT_Tdep_PT_Printf(phead,
185                                           "Test Error: Send: Secondary completion seen for endpoint 0x%p (%d)\n",
186                                           ep_context[epnum].ep_handle, epnum);
187                         DT_Test_Error();
188                         DT_Mdep_Free(completion_reaped);
189                         return (false);
190                 }
191                 completion_reaped[epnum] = 1;
192         }
193
194         for (i = 0; i < num_eps; i++) {
195                 if (completion_reaped[i] == 0) {
196                         DT_Tdep_PT_Printf(phead,
197                                           "Test Error: Send: No completion seen for endpoint 0x%p (#%d)\n",
198                                           ep_context[i].ep_handle, i);
199                         DT_Test_Error();
200                         DT_Mdep_Free(completion_reaped);
201                         return (false);
202                 }
203         }
204
205         DT_Mdep_Free(completion_reaped);
206         return true;
207 }
208
209 /* -----------------------------------------------------------
210  * Reap a recv op on each of this thread's EPs,
211  * then if requested reap the corresponding send ops,
212  * and re-post all of the recv buffers.
213  */
214 bool
215 DT_handle_recv_op(DT_Tdep_Print_Head * phead,
216                   Ep_Context_t * ep_context,
217                   unsigned int num_eps,
218                   int op_indx, bool poll, bool repost_recv)
219 {
220         unsigned int i;
221         unsigned char *recv_completion_reaped;
222         unsigned char *send_completion_reaped;
223
224         recv_completion_reaped = DT_Mdep_Malloc(num_eps);
225         if (recv_completion_reaped == NULL) {
226                 return false;
227         }
228
229         send_completion_reaped = DT_Mdep_Malloc(num_eps);
230         if (send_completion_reaped == NULL) {
231                 DT_Mdep_Free(recv_completion_reaped);
232                 return false;
233         }
234
235         /* Foreach EP, reap */
236         bzero((void *)recv_completion_reaped, sizeof(unsigned char) * num_eps);
237         bzero((void *)send_completion_reaped, sizeof(unsigned char) * num_eps);
238         for (i = 0; i < num_eps; i++) {
239                 Transaction_Test_Op_t *op;
240                 DAT_DTO_COMPLETION_EVENT_DATA dto_stat;
241                 DAT_DTO_COOKIE dto_cookie;
242                 unsigned int epnum;
243
244                 /* First reap the recv DTO event */
245                 if (!DT_dto_event_reap
246                     (phead, ep_context[i].recv_evd_hdl, poll, &dto_stat)) {
247                         DT_Mdep_Free(recv_completion_reaped);
248                         DT_Mdep_Free(send_completion_reaped);
249                         return false;
250                 }
251
252                 epnum = dto_stat.user_cookie.as_64 >> 32;
253                 if (epnum > num_eps) {
254                         DT_Tdep_PT_Printf(phead,
255                                           "Test Error: Receive: Invalid endpoint completion reaped.\n"
256                                           "\tEndpoint: 0x%p, Cookie: 0x" F64x
257                                           ", Length: " F64u "\n",
258                                           dto_stat.ep_handle,
259                                           dto_stat.user_cookie.as_64,
260                                           dto_stat.transfered_length);
261                         DT_Test_Error();
262                         DT_Mdep_Free(recv_completion_reaped);
263                         DT_Mdep_Free(send_completion_reaped);
264                         return false;
265                 }
266
267                 op = &ep_context[epnum].op[op_indx];
268                 dto_cookie.as_64 = ((((DAT_UINT64) epnum) << 32)
269                                     |
270                                     (((uintptr_t) DT_Bpool_GetBuffer(op->bp, 0))
271                                      & 0xffffffffUL));
272
273                 if (!DT_dto_check(phead,
274                                   &dto_stat,
275                                   ep_context[epnum].ep_handle,
276                                   op->num_segs * op->seg_size,
277                                   dto_cookie, "Recv")) {
278                         DT_Tdep_PT_Printf(phead,
279                                           "Test Error: recv DTO problem\n");
280                         DT_Test_Error();
281                         DT_Mdep_Free(recv_completion_reaped);
282                         DT_Mdep_Free(send_completion_reaped);
283                         return false;
284                 }
285
286                 if (recv_completion_reaped[epnum]) {
287                         DT_Tdep_PT_Printf(phead,
288                                           "Test Error: Receive: Secondary completion seen for endpoint 0x%p (%d)\n",
289                                           ep_context[epnum].ep_handle, epnum);
290                         DT_Test_Error();
291                         DT_Mdep_Free(recv_completion_reaped);
292                         DT_Mdep_Free(send_completion_reaped);
293                         return (false);
294                 }
295                 recv_completion_reaped[epnum] = 1;
296
297                 /*
298                  * Check the current op to see whether we are supposed
299                  * to reap the previous send op now.
300                  */
301                 if (op->reap_send_on_recv && op->server_initiated) {
302                         if (op_indx <= 0)
303                                 /* shouldn't happen, but let's be certain */
304                         {
305                                 DT_Tdep_PT_Printf(phead,
306                                                   "Internal Error: reap_send_on_recv"
307                                                   " but current op == #%d\n",
308                                                   op_indx);
309                                 DT_Mdep_Free(recv_completion_reaped);
310                                 DT_Mdep_Free(send_completion_reaped);
311                                 return false;
312                         }
313
314                         if (!DT_dto_event_reap
315                             (phead, ep_context[i].reqt_evd_hdl, poll,
316                              &dto_stat)) {
317                                 DT_Mdep_Free(recv_completion_reaped);
318                                 DT_Mdep_Free(send_completion_reaped);
319                                 return false;
320                         }
321
322                         epnum = dto_stat.user_cookie.as_64 >> 32;
323                         if (epnum > num_eps) {
324                                 DT_Tdep_PT_Printf(phead,
325                                                   "Test Error: Send (ror): Invalid endpoint completion reaped.\n"
326                                                   "\tEndpoint: 0x%p, Cookie: 0x"
327                                                   F64x ", Length: " F64u "\n",
328                                                   dto_stat.ep_handle,
329                                                   dto_stat.user_cookie.as_64,
330                                                   dto_stat.transfered_length);
331                                 DT_Test_Error();
332                                 DT_Mdep_Free(recv_completion_reaped);
333                                 DT_Mdep_Free(send_completion_reaped);
334                                 return false;
335                         }
336
337                         /*
338                          * We're reaping the last transaction, a
339                          * send completion that we skipped when it was sent.
340                          */
341                         op = &ep_context[epnum].op[op_indx - 1];
342
343                         dto_cookie.as_64 = ((((DAT_UINT64) epnum) << 32)
344                                             |
345                                             (((uintptr_t)
346                                               DT_Bpool_GetBuffer(op->bp, 0))
347                                              & 0xffffffffUL));
348
349                         /*
350                          * If we have multiple EPs we can't guarantee the order of
351                          * completions, so disable ep_handle check
352                          */
353                         if (!DT_dto_check(phead,
354                                           &dto_stat,
355                                           num_eps ==
356                                           1 ? ep_context[i].ep_handle : NULL,
357                                           op->num_segs * op->seg_size,
358                                           dto_cookie, "Send-reaped-on-recv")) {
359                                 DT_Tdep_PT_Printf(phead,
360                                                   "Test Error: send DTO problem\n");
361                                 DT_Test_Error();
362                                 DT_Mdep_Free(recv_completion_reaped);
363                                 DT_Mdep_Free(send_completion_reaped);
364                                 return false;
365                         }
366
367                         if (send_completion_reaped[epnum]) {
368                                 DT_Tdep_PT_Printf(phead,
369                                                   "Test Error: Send (ror): Secondary completion seen for endpoint 0x%p (%d)\n",
370                                                   ep_context[epnum].ep_handle,
371                                                   epnum);
372                                 DT_Test_Error();
373                                 DT_Mdep_Free(recv_completion_reaped);
374                                 DT_Mdep_Free(send_completion_reaped);
375                                 return (false);
376                         }
377                         send_completion_reaped[epnum] = 1;
378                 }
379         }
380
381         for (i = 0; i < num_eps; i++) {
382                 if (recv_completion_reaped[i] == 0) {
383                         DT_Tdep_PT_Printf(phead,
384                                           "Test Error: Receive: No completion seen for endpoint 0x%p (#%d)\n",
385                                           ep_context[i].ep_handle, i);
386                         DT_Test_Error();
387                         DT_Mdep_Free(recv_completion_reaped);
388                         DT_Mdep_Free(send_completion_reaped);
389                         return (false);
390                 }
391         }
392
393         if (ep_context[0].op[op_indx].reap_send_on_recv
394             && ep_context[0].op[op_indx].server_initiated) {
395                 for (i = 0; i < num_eps; i++) {
396                         if (send_completion_reaped[i] == 0) {
397                                 DT_Tdep_PT_Printf(phead,
398                                                   "Test Error: Send (ror): No completion seen for endpoint 0x%p (#%d)\n",
399                                                   ep_context[i].ep_handle, i);
400                                 DT_Test_Error();
401                                 DT_Mdep_Free(recv_completion_reaped);
402                                 DT_Mdep_Free(send_completion_reaped);
403                                 return (false);
404                         }
405                 }
406         }
407
408         if (repost_recv) {
409                 /* repost the receive buffer */
410                 if (!DT_handle_post_recv_buf
411                     (phead, ep_context, num_eps, op_indx)) {
412                         DT_Tdep_PT_Printf(phead,
413                                           "Test Error: recv re-post problem\n");
414                         DT_Test_Error();
415                         DT_Mdep_Free(recv_completion_reaped);
416                         DT_Mdep_Free(send_completion_reaped);
417                         return false;
418                 }
419         }
420
421         DT_Mdep_Free(recv_completion_reaped);
422         DT_Mdep_Free(send_completion_reaped);
423         return true;
424 }
425
426 /* -----------------------------------------------------------
427  * Initiate an RDMA op (synchronous) on each of this thread's EPs.
428  */
429 bool
430 DT_handle_rdma_op(DT_Tdep_Print_Head * phead,
431                   Ep_Context_t * ep_context,
432                   unsigned int num_eps,
433                   DT_Transfer_Type opcode, int op_indx, bool poll)
434 {
435         unsigned int i, j;
436         DAT_RETURN ret;
437         unsigned char *completion_reaped;
438
439         completion_reaped = DT_Mdep_Malloc(num_eps * sizeof(unsigned char));
440
441         if (!completion_reaped) {
442                 return false;
443         }
444
445         /* Initiate the operation */
446         for (i = 0; i < num_eps; i++) {
447                 Transaction_Test_Op_t *op = &ep_context[i].op[op_indx];
448                 DAT_LMR_TRIPLET *iov = DT_Bpool_GetIOV(op->bp, 0);
449                 DAT_DTO_COOKIE cookie;
450                 DAT_RMR_TRIPLET rmr_triplet;
451
452                 /* Prep the inputs */
453                 for (j = 0; j < op->num_segs; j++) {
454                         iov[j].virtual_address = (DAT_VADDR) (uintptr_t)
455                             DT_Bpool_GetBuffer(op->bp, j);
456                         iov[j].segment_length = op->seg_size;
457                         iov[j].lmr_context = DT_Bpool_GetLMR(op->bp, j);
458                 }
459                 cookie.as_64 = ((((DAT_UINT64) i) << 32)
460                                 | (((uintptr_t) DT_Bpool_GetBuffer(op->bp, 0)) &
461                                    0xffffffffUL));
462
463                 rmr_triplet.virtual_address =
464                     (DAT_VADDR) (uintptr_t) op->Rdma_Address;
465                 rmr_triplet.segment_length = op->seg_size * op->num_segs;
466                 rmr_triplet.rmr_context = op->Rdma_Context;
467
468                 DT_Tdep_PT_Debug(3, (phead,
469                                      "Call dat_ep_post_rdma_%s [" F64x ", sz="
470                                      F64x ", ctxt=%x]\n",
471                                      (opcode == RDMA_WRITE ? "write" : "read"),
472                                      rmr_triplet.virtual_address,
473                                      rmr_triplet.segment_length,
474                                      rmr_triplet.rmr_context));
475
476                 /* Post the operation */
477                 if (opcode == RDMA_WRITE) {
478
479                         ret = dat_ep_post_rdma_write(ep_context[i].ep_handle,
480                                                      op->num_segs,
481                                                      iov,
482                                                      cookie,
483                                                      &rmr_triplet,
484                                                      DAT_COMPLETION_DEFAULT_FLAG);
485
486                 } else {        /* opcode == RDMA_READ */
487
488                         ret = dat_ep_post_rdma_read(ep_context[i].ep_handle,
489                                                     op->num_segs,
490                                                     iov,
491                                                     cookie,
492                                                     &rmr_triplet,
493                                                     DAT_COMPLETION_DEFAULT_FLAG);
494
495                 }
496                 if (ret != DAT_SUCCESS) {
497                         DT_Tdep_PT_Printf(phead,
498                                           "Test Error: dat_ep_post_rdma_%s failed: %s\n",
499                                           (opcode ==
500                                            RDMA_WRITE ? "write" : "read"),
501                                           DT_RetToString(ret));
502                         DT_Test_Error();
503                         DT_Mdep_Free(completion_reaped);
504                         return (false);
505                 } else {
506                         DT_Tdep_PT_Debug(3, (phead,
507                                              "Done dat_ep_post_rdma_%s %s\n",
508                                              (opcode ==
509                                               RDMA_WRITE ? "write" : "read"),
510                                              " ()  Waiting ..."));
511                 }
512         }
513
514         bzero((void *)completion_reaped, sizeof(unsigned char) * num_eps);
515         /* Wait for it to happen */
516         for (i = 0; i < num_eps; i++) {
517                 Transaction_Test_Op_t *op;
518                 DAT_DTO_COMPLETION_EVENT_DATA dto_stat;
519                 DAT_DTO_COOKIE dto_cookie;
520                 unsigned int epnum;
521
522                 if (!DT_dto_event_reap
523                     (phead, ep_context[i].reqt_evd_hdl, poll, &dto_stat)) {
524                         DT_Mdep_Free(completion_reaped);
525                         return (false);
526                 }
527
528                 epnum = dto_stat.user_cookie.as_64 >> 32;
529                 if (epnum > num_eps) {
530                         DT_Tdep_PT_Printf(phead,
531                                           "Test Error: %s: Invalid endpoint completion reaped.\n"
532                                           "\tEndpoint: 0x%p, Cookie: 0x" F64x
533                                           ", Length: " F64u "\n",
534                                           opcode ==
535                                           RDMA_WRITE ? "RDMA/WR" : "RDMA/RD",
536                                           dto_stat.ep_handle,
537                                           dto_stat.user_cookie.as_64,
538                                           dto_stat.transfered_length);
539                         DT_Test_Error();
540                         DT_Mdep_Free(completion_reaped);
541                         return false;
542                 }
543                 op = &ep_context[epnum].op[op_indx];
544
545                 dto_cookie.as_64 = ((((DAT_UINT64) epnum) << 32)
546                                     |
547                                     (((uintptr_t) DT_Bpool_GetBuffer(op->bp, 0))
548                                      & 0xffffffffUL));
549
550                 if (!DT_dto_check(phead,
551                                   &dto_stat,
552                                   ep_context[epnum].ep_handle,
553                                   op->num_segs * op->seg_size,
554                                   dto_cookie,
555                                   (opcode ==
556                                    RDMA_WRITE ? "RDMA/WR" : "RDMA/RD"))) {
557                         DT_Mdep_Free(completion_reaped);
558                         return (false);
559                 }
560
561                 if (completion_reaped[epnum]) {
562                         DT_Tdep_PT_Printf(phead,
563                                           "Test Error: %s: Secondary completion seen for endpoint 0x%p (%d)\n",
564                                           opcode ==
565                                           RDMA_WRITE ? "RDMA/WR" : "RDMA/RD",
566                                           ep_context[epnum].ep_handle, epnum);
567                         DT_Test_Error();
568                         DT_Mdep_Free(completion_reaped);
569                         return (false);
570                 }
571                 completion_reaped[epnum] = 1;
572
573                 DT_Tdep_PT_Debug(3, (phead,
574                                      "dat_ep_post_rdma_%s OK\n",
575                                      (opcode ==
576                                       RDMA_WRITE ? "RDMA/WR" : "RDMA/RD")));
577         }
578
579         for (i = 0; i < num_eps; i++) {
580                 if (completion_reaped[i] == 0) {
581                         DT_Tdep_PT_Printf(phead,
582                                           "Test Error: %s: No completion seen for endpoint 0x%p (#%d)\n",
583                                           opcode ==
584                                           RDMA_WRITE ? "RDMA/WR" : "RDMA/RD",
585                                           ep_context[i].ep_handle, i);
586                         DT_Test_Error();
587                         DT_Mdep_Free(completion_reaped);
588                         return (false);
589                 }
590         }
591
592         DT_Mdep_Free(completion_reaped);
593
594         return (true);
595 }
596
597 /* -----------------------------------------------------------
598  * Verify whether we (the client side) can support
599  * the requested 'T' test.
600  */
601 bool DT_check_params(Per_Test_Data_t * pt_ptr, char *module)
602 {
603         Transaction_Cmd_t *cmd = &pt_ptr->Params.u.Transaction_Cmd;
604         unsigned long num_recvs = 0U;
605         unsigned long num_sends = 0U;
606         unsigned long num_rdma_rd = 0U;
607         unsigned long num_rdma_wr = 0U;
608         unsigned long max_size = 0U;
609         unsigned long max_segs = 0U;
610         bool rval = true;
611         unsigned int i;
612         DT_Tdep_Print_Head *phead;
613
614         phead = pt_ptr->Params.phead;
615
616         /* Count up what's requested (including -V appended sync points) */
617         for (i = 0; i < cmd->num_ops; i++) {
618                 unsigned int xfer_size;
619
620                 xfer_size = cmd->op[i].num_segs * cmd->op[i].seg_size;
621                 if (xfer_size > max_size) {
622                         max_size = xfer_size;
623                 }
624                 if (cmd->op[i].num_segs > max_segs) {
625                         max_segs = cmd->op[i].num_segs;
626                 }
627
628                 switch (cmd->op[i].transfer_type) {
629                 case SEND_RECV:
630                         {
631                                 if (cmd->op[i].server_initiated) {
632                                         num_recvs++;
633                                 } else {
634                                         num_sends++;
635                                 }
636                                 break;
637                         }
638
639                 case RDMA_READ:
640                         {
641                                 num_rdma_rd++;
642                                 break;
643                         }
644
645                 case RDMA_WRITE:
646                         {
647                                 num_rdma_wr++;
648                                 break;
649                         }
650                 }
651         }
652
653         /*
654          * Now check the IA and EP attributes, and check for some of the
655          * more obvious resource problems.  This is hardly exhaustive,
656          * and some things will inevitably fall through to run-time.
657          *
658          * We don't compare
659          *      num_rdma_rd > pt_ptr->ia_attr.max_rdma_read_per_ep
660          *      num_rdma_wr > pt_ptr->ia_attr.max_dto_per_ep
661          * because each thread has its own EPs, and transfers are issued
662          * synchronously (across a thread's EPs, and ignoring -f, which allows
663          * a per-EP pipeline depth of at most 2 and applies only to SR ops),
664          * so dapltest actually attempts almost no pipelining on a single EP.
665          * But we do check that pre-posted recv buffers will all fit.
666          */
667         if (num_recvs > pt_ptr->ia_attr.max_dto_per_ep ||
668             num_sends > pt_ptr->ia_attr.max_dto_per_ep) {
669                 DT_Tdep_PT_Printf(phead,
670                                   "%s: S/R: cannot supply %ld SR ops (maximum: %d)\n",
671                                   module,
672                                   num_recvs > num_sends ? num_recvs : num_sends,
673                                   pt_ptr->ia_attr.max_dto_per_ep);
674                 rval = false;
675         }
676         if (max_size > pt_ptr->ia_attr.max_lmr_block_size) {
677                 DT_Tdep_PT_Printf(phead,
678                                   "%s: buffer too large: 0x%lx (maximum: " F64x
679                                   " bytes)\n", module, max_size,
680                                   pt_ptr->ia_attr.max_lmr_block_size);
681                 rval = false;
682         }
683         if (max_segs > pt_ptr->ep_attr.max_recv_iov ||
684             max_segs > pt_ptr->ep_attr.max_request_iov) {
685                 /*
686                  * In an ideal world, we'd just ask for more segments
687                  * when creating the EPs for the test, rather than
688                  * checking against default EP attributes.
689                  */
690                 DT_Tdep_PT_Printf(phead,
691                                   "%s: cannot use %ld segments (maxima: S %d, R %d)\n",
692                                   module,
693                                   max_segs,
694                                   pt_ptr->ep_attr.max_request_iov,
695                                   pt_ptr->ep_attr.max_recv_iov);
696                 rval = false;
697         }
698
699         return (rval);
700 }
701
702 /* Empty function in which to set breakpoints.  */
703 void DT_Test_Error(void)
704 {
705         ;
706 }
707
708 void
709 DT_Transaction_Cmd_PT_Print(DT_Tdep_Print_Head * phead, Transaction_Cmd_t * cmd)
710 {
711         unsigned int i;
712         DT_Tdep_PT_Printf(phead, "-------------------------------------\n");
713         DT_Tdep_PT_Printf(phead, "TransCmd.server_name              : %s\n",
714                           cmd->server_name);
715         DT_Tdep_PT_Printf(phead, "TransCmd.num_iterations           : %d\n",
716                           cmd->num_iterations);
717         DT_Tdep_PT_Printf(phead, "TransCmd.num_threads              : %d\n",
718                           cmd->num_threads);
719         DT_Tdep_PT_Printf(phead, "TransCmd.eps_per_thread           : %d\n",
720                           cmd->eps_per_thread);
721         DT_Tdep_PT_Printf(phead, "TransCmd.validate                 : %d\n",
722                           cmd->validate);
723         DT_Tdep_PT_Printf(phead, "TransCmd.dapl_name                : %s\n",
724                           cmd->dapl_name);
725         DT_Tdep_PT_Printf(phead, "TransCmd.num_ops                  : %d\n",
726                           cmd->num_ops);
727
728         for (i = 0; i < cmd->num_ops; i++) {
729                 DT_Tdep_PT_Printf(phead,
730                                   "TransCmd.op[%d].transfer_type      : %s %s\n",
731                                   i,
732                                   cmd->op[i].transfer_type ==
733                                   0 ? "RDMA_READ" : cmd->op[i].transfer_type ==
734                                   1 ? "RDMA_WRITE" : "SEND_RECV",
735                                   cmd->op[i].
736                                   server_initiated ? " (server)" : " (client)");
737                 DT_Tdep_PT_Printf(phead,
738                                   "TransCmd.op[%d].seg_size           : %d\n",
739                                   i, cmd->op[i].seg_size);
740                 DT_Tdep_PT_Printf(phead,
741                                   "TransCmd.op[%d].num_segs           : %d\n",
742                                   i, cmd->op[i].num_segs);
743                 DT_Tdep_PT_Printf(phead,
744                                   "TransCmd.op[%d].reap_send_on_recv  : %d\n",
745                                   i, cmd->op[i].reap_send_on_recv);
746         }
747 }