[LIMITS] Add new unit test to test MR, CQ, and CQ resize limits.
authorftillier <ftillier@ad392aa1-c5ef-ae45-8dd8-e69d62a5ef86>
Tue, 29 Nov 2005 21:34:06 +0000 (21:34 +0000)
committerftillier <ftillier@ad392aa1-c5ef-ae45-8dd8-e69d62a5ef86>
Tue, 29 Nov 2005 21:34:06 +0000 (21:34 +0000)
The test, depending on settings, will:
- Allocate 8K buffers in a loop and register them.  Once allocation or
registration fails, repeat 1000 times.  Deregister and free all MRs.
- Allocate CQs with 4K CQEs in a loop.  When CQ creation fails, repeat
1000 times.  Free all CQs.
- Allocate CQs with 32 CQEs in a loop.  For each run through the loop,
resize the CQ to increasing multiples of 256 entries.  When resize
fails, repeat 100 times.  Repeat CQ creation and resize until CQ
creation fails, then 1000 more times for good measure.  Cleanup all
CQs.

git-svn-id: svn://openib.tc.cornell.edu/gen1/trunk@188 ad392aa1-c5ef-ae45-8dd8-e69d62a5ef86

tests/limits/dirs [new file with mode: 0644]
tests/limits/user/SOURCES [new file with mode: 0644]
tests/limits/user/main.c [new file with mode: 0644]
tests/limits/user/makefile [new file with mode: 0644]

diff --git a/tests/limits/dirs b/tests/limits/dirs
new file mode 100644 (file)
index 0000000..389156f
--- /dev/null
@@ -0,0 +1,2 @@
+DIRS=\\r
+       user\r
diff --git a/tests/limits/user/SOURCES b/tests/limits/user/SOURCES
new file mode 100644 (file)
index 0000000..133f0ce
--- /dev/null
@@ -0,0 +1,20 @@
+TARGETNAME=ib_limits\r
+TARGETPATH=..\..\..\bin\user\obj$(BUILD_ALT_DIR)\r
+TARGETTYPE=PROGRAM\r
+UMTYPE=console\r
+USE_CRTDLL=1\r
+\r
+SOURCES=main.c\r
+\r
+INCLUDES=..\..\..\inc;..\..\..\inc\user;\r
+\r
+TARGETLIBS= \\r
+!if $(FREEBUILD)\r
+                       $(TARGETPATH)\*\complib.lib \\r
+                       $(TARGETPATH)\*\ibal.lib\r
+!else\r
+                       $(TARGETPATH)\*\complibd.lib \\r
+                       $(TARGETPATH)\*\ibald.lib\r
+!endif\r
+\r
+MSC_WARNING_LEVEL= /W3\r
diff --git a/tests/limits/user/main.c b/tests/limits/user/main.c
new file mode 100644 (file)
index 0000000..3216bc1
--- /dev/null
@@ -0,0 +1,529 @@
+/*\r
+ * Copyright (c) 2005 SilverStorm Technologies.  All rights reserved.\r
+ *\r
+ * This software is available to you under the OpenIB.org BSD license\r
+ * below:\r
+ *\r
+ *     Redistribution and use in source and binary forms, with or\r
+ *     without modification, are permitted provided that the following\r
+ *     conditions are met:\r
+ *\r
+ *      - Redistributions of source code must retain the above\r
+ *        copyright notice, this list of conditions and the following\r
+ *        disclaimer.\r
+ *\r
+ *      - Redistributions in binary form must reproduce the above\r
+ *        copyright notice, this list of conditions and the following\r
+ *        disclaimer in the documentation and/or other materials\r
+ *        provided with the distribution.\r
+ *\r
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,\r
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\r
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\r
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS\r
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN\r
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN\r
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\r
+ * SOFTWARE.\r
+ *\r
+ * $Id$\r
+ */\r
+\r
+\r
+/*\r
+ * Abstract:\r
+ *     Test limits for:\r
+ *             - memory registration\r
+ *             - CQ creation\r
+ *             - CQ resize\r
+ *             - QP creation\r
+ *\r
+ * Environment:\r
+ *     User Mode\r
+ */\r
+\r
+#include <stdio.h>\r
+#include <stdlib.h>\r
+#include <stdarg.h>\r
+#include <ctype.h>\r
+#include <complib/cl_atomic.h>\r
+#include <complib/cl_debug.h>\r
+#include <complib/cl_event.h>\r
+#include <complib/cl_math.h>\r
+#include <complib/cl_mutex.h>\r
+#include <complib/cl_qlist.h>\r
+#include <complib/cl_thread.h>\r
+#include <complib/cl_timer.h>\r
+#include <iba/ib_types.h>\r
+#include <iba/ib_al.h>\r
+\r
+\r
+/* Globals */\r
+#define        CMT_DBG_VERBOSE         1\r
+\r
+\r
+uint32_t       cmt_dbg_lvl = 0x80000000;\r
+\r
+\r
+/**********************************************************************\r
+ **********************************************************************/\r
+static void\r
+__show_usage()\r
+{\r
+       printf( "\n------- ib_limits - Usage and options ----------------------\n" );\r
+       printf( "Usage:   ib_limits [options]\n");\r
+       printf( "Options:\n" );\r
+       printf( "-m\n"\r
+                       "--memory\n"\r
+                       "\tThis option directs ib_limits to test memory registration\n" );\r
+       printf( "-c\n"\r
+                       "--cq\n"\r
+                       "\tThis option directs ib_limits to test CQ creation\n" );\r
+       printf( "-r\n"\r
+                       "--resize_cq\n"\r
+                       "\tThis option directs ib_limits to test CQ resize\n" );\r
+       printf( "-q\n"\r
+                       "--qp\n"\r
+                       "\tThis option directs ib_limits to test QP creation\n" );\r
+       printf( "-v\n"\r
+                       "--verbose\n"\r
+                       "          This option enables verbosity level to debug console.\n" );\r
+       printf( "-h\n"\r
+                       "--help\n"\r
+                       "          Display this usage info then exit.\n\n" );\r
+}\r
+\r
+\r
+/* Windows support. */\r
+struct option\r
+{\r
+       const char              *long_name;\r
+       unsigned long   flag;\r
+       void                    *pfn_handler;\r
+       char                    short_name;\r
+};\r
+\r
+static char                    *optarg;\r
+\r
+#define strtoull       strtoul\r
+\r
+\r
+boolean_t      test_mr, test_cq, test_resize, test_qp;\r
+\r
+\r
+char\r
+getopt_long(\r
+       int                                     argc,\r
+       char                            *argv[],\r
+       const char                      *short_option,\r
+       const struct option *long_option,\r
+       void                            *unused )\r
+{\r
+       static int i = 1;\r
+       int j;\r
+       char            ret = 0;\r
+\r
+       UNUSED_PARAM( unused );\r
+\r
+       if( i == argc )\r
+               return -1;\r
+\r
+       if( argv[i][0] != '-' )\r
+               return ret;\r
+\r
+       /* find the first character of the value. */\r
+       for( j = 1; isalpha( argv[i][j] ); j++ )\r
+               ;\r
+       optarg = &argv[i][j];\r
+\r
+       if( argv[i][1] == '-' )\r
+       {\r
+               /* Long option. */\r
+               for( j = 0; long_option[j].long_name; j++ )\r
+               {\r
+                       if( strncmp( &argv[i][2], long_option[j].long_name,\r
+                               optarg - argv[i] - 2 ) )\r
+                       {\r
+                               continue;\r
+                       }\r
+\r
+                       switch( long_option[j].flag )\r
+                       {\r
+                       case 1:\r
+                               if( *optarg == '\0' )\r
+                                       return 0;\r
+                       default:\r
+                               break;\r
+                       }\r
+                       ret = long_option[j].short_name;\r
+                       break;\r
+               }\r
+       }\r
+       else\r
+       {\r
+               for( j = 0; short_option[j] != '\0'; j++ )\r
+               {\r
+                       if( !isalpha( short_option[j] ) )\r
+                               return 0;\r
+\r
+                       if( short_option[j] == argv[i][1] )\r
+                       {\r
+                               ret = short_option[j];\r
+                               break;\r
+                       }\r
+\r
+                       if( short_option[j+1] == ':' )\r
+                       {\r
+                               if( *optarg == '\0' )\r
+                                       return 0;\r
+                               j++;\r
+                       }\r
+               }\r
+       }\r
+       i++;\r
+       return ret;\r
+}\r
+\r
+\r
+static boolean_t\r
+__parse_options(\r
+       int                                                     argc,\r
+       char*                                           argv[] )\r
+{\r
+       uint32_t                                        next_option;\r
+       const char* const                       short_option = "mcrq:vh";\r
+\r
+       /*\r
+               In the array below, the 2nd parameter specified the number\r
+               of arguments as follows:\r
+               0: no arguments\r
+               1: argument\r
+               2: optional\r
+       */\r
+       const struct option long_option[] =\r
+       {\r
+               {       "memory",       2,      NULL,   'm'},\r
+               {       "cq",           2,      NULL,   'c'},\r
+               {       "resize_cq",2,  NULL,   'r'},\r
+               {       "qp",           2,      NULL,   'q'},\r
+               {       "verbose",      0,      NULL,   'v'},\r
+               {       "help",         0,      NULL,   'h'},\r
+               {       NULL,           0,      NULL,    0 }    /* Required at end of array */\r
+       };\r
+\r
+       test_mr = FALSE;\r
+       test_cq = FALSE;\r
+       test_resize = FALSE;\r
+       test_qp = FALSE;\r
+\r
+       /* parse cmd line arguments as input params */\r
+       do\r
+       {\r
+               next_option = getopt_long( argc, argv, short_option,\r
+                       long_option, NULL );\r
+\r
+               switch( next_option )\r
+               {\r
+               case 'm':\r
+                       test_mr = TRUE;\r
+                       printf( "\tTest Memory Registration\n" );\r
+                       break;\r
+\r
+               case 'c':\r
+                       test_cq = TRUE;\r
+                       printf( "\tTest CQ\n" );\r
+                       break;\r
+\r
+               case 'r':\r
+                       test_resize = TRUE;\r
+                       printf( "\tTest CQ Resize\n" );\r
+                       break;\r
+\r
+               case 'q':\r
+                       test_qp = TRUE;\r
+                       printf( "\tTest QP\n" );\r
+                       break;\r
+\r
+               case 'v':\r
+                       cmt_dbg_lvl = 0xFFFFFFFF;\r
+                       printf( "\tverbose\n" );\r
+                       break;\r
+\r
+               case 'h':\r
+                       __show_usage();\r
+                       return FALSE;\r
+\r
+               case -1:\r
+                       break;\r
+\r
+               default: /* something wrong */\r
+                       __show_usage();\r
+                       return FALSE;\r
+               }\r
+       } while( next_option != -1 );\r
+\r
+       return TRUE;\r
+}\r
+\r
+\r
+struct __mr_buf\r
+{\r
+       cl_list_item_t  list_item;\r
+       ib_mr_handle_t  h_mr;\r
+       char                    buf[8192 - sizeof(ib_mr_handle_t) - sizeof(cl_list_item_t)];\r
+};\r
+\r
+static void\r
+__test_mr(\r
+       ib_pd_handle_t                          h_pd )\r
+{\r
+       ib_api_status_t         status = IB_SUCCESS;\r
+       struct __mr_buf         *p_mr;\r
+       int                                     i = 0;\r
+       ib_mr_create_t          mr_create;\r
+       cl_qlist_t                      mr_list;\r
+       net32_t                         lkey, rkey;\r
+       int64_t                         reg_time, dereg_time, tmp_time, cnt;\r
+\r
+       printf( "MR testing [\n" );\r
+\r
+       cl_qlist_init( &mr_list );\r
+       reg_time = 0;\r
+       dereg_time = 0;\r
+       cnt = 0;\r
+\r
+       do\r
+       {\r
+               p_mr = cl_malloc( sizeof(struct __mr_buf) );\r
+               if( !p_mr )\r
+               {\r
+                       i++;\r
+                       printf( "Failed to allocate memory.\n" );\r
+                       continue;\r
+               }\r
+\r
+               mr_create.vaddr = p_mr->buf;\r
+               mr_create.length = sizeof(p_mr->buf);\r
+               mr_create.access_ctrl =\r
+                       IB_AC_LOCAL_WRITE | IB_AC_RDMA_READ | IB_AC_RDMA_WRITE;\r
+\r
+               tmp_time = cl_get_time_stamp();\r
+               status = ib_reg_mem( h_pd, &mr_create, &lkey, &rkey, &p_mr->h_mr );\r
+               if( status != IB_SUCCESS )\r
+               {\r
+                       i++;\r
+                       printf( "ib_reg_mem returned %s\n", ib_get_err_str( status ) );\r
+                       cl_free( p_mr );\r
+                       continue;\r
+               }\r
+               reg_time += cl_get_time_stamp() - tmp_time;\r
+               cnt++;\r
+\r
+               cl_qlist_insert_tail( &mr_list, &p_mr->list_item );\r
+\r
+       }       while( status == IB_SUCCESS || i < 1000 );\r
+\r
+       while( cl_qlist_count( &mr_list ) )\r
+       {\r
+               p_mr = PARENT_STRUCT( cl_qlist_remove_head( &mr_list ),\r
+                       struct __mr_buf, list_item );\r
+\r
+               tmp_time = cl_get_time_stamp();\r
+               status = ib_dereg_mr( p_mr->h_mr );\r
+               if( status != IB_SUCCESS )\r
+                       printf( "ib_dereg_mr returned %s\n", ib_get_err_str( status ) );\r
+               dereg_time += cl_get_time_stamp() - tmp_time;\r
+\r
+               cl_free( p_mr );\r
+       }\r
+\r
+       printf( "reg time %f, dereg time %f\n", (double)reg_time/(double)cnt,\r
+               (double)dereg_time/(double)cnt );\r
+       printf( "MR testing ]\n" );\r
+}\r
+\r
+\r
+struct __cq\r
+{\r
+       cl_list_item_t          list_item;\r
+       ib_cq_handle_t          h_cq;\r
+};\r
+\r
+static void\r
+__test_cq(\r
+       ib_ca_handle_t                          h_ca,\r
+       boolean_t                                       resize )\r
+{\r
+       ib_api_status_t         status = IB_SUCCESS;\r
+       struct __cq                     *p_cq;\r
+       int                                     i = 0, j;\r
+       ib_cq_create_t          cq_create;\r
+       cl_qlist_t                      cq_list;\r
+       cl_waitobj_handle_t     h_waitobj;\r
+       uint32_t                        size;\r
+\r
+       printf( "CQ %stesting [\n", resize?"resize ":"" );\r
+\r
+       cl_qlist_init( &cq_list );\r
+\r
+       if( cl_waitobj_create( FALSE, &h_waitobj ) != CL_SUCCESS )\r
+       {\r
+               printf( "Failed to allocate CQ wait object.\n" );\r
+               return;\r
+       }\r
+\r
+       do\r
+       {\r
+               p_cq = cl_malloc( sizeof(*p_cq) );\r
+               if( !p_cq )\r
+               {\r
+                       i++;\r
+                       printf( "Failed to allocate memory.\n" );\r
+                       continue;\r
+               }\r
+\r
+               cq_create.h_wait_obj = h_waitobj;\r
+               cq_create.pfn_comp_cb = NULL;\r
+               if( resize )\r
+                       cq_create.size = 32;\r
+               else\r
+                       cq_create.size = 4096;\r
+\r
+               status = ib_create_cq( h_ca, &cq_create, NULL, NULL, &p_cq->h_cq );\r
+               if( status != IB_SUCCESS )\r
+               {\r
+                       i++;\r
+                       printf( "ib_create_cq returned %s\n", ib_get_err_str( status ) );\r
+                       cl_free( p_cq );\r
+                       continue;\r
+               }\r
+\r
+               if( resize )\r
+               {\r
+                       size = 256;\r
+                       j = 0;\r
+\r
+                       do\r
+                       {\r
+                               status = ib_modify_cq( p_cq->h_cq, &size );\r
+                               if( status == IB_SUCCESS )\r
+                               {\r
+                                       size += 256;\r
+                               }\r
+                               else\r
+                               {\r
+                                       j++;\r
+                                       printf( "ib_modify_cq returned %s\n",\r
+                                               ib_get_err_str( status ) );\r
+                               }\r
+\r
+                       } while( status == IB_SUCCESS || j < 100 );\r
+               }\r
+\r
+               cl_qlist_insert_tail( &cq_list, &p_cq->list_item );\r
+\r
+       }       while( status == IB_SUCCESS || i < 1000 );\r
+\r
+       while( cl_qlist_count( &cq_list ) )\r
+       {\r
+               p_cq = PARENT_STRUCT( cl_qlist_remove_head( &cq_list ),\r
+                       struct __cq, list_item );\r
+\r
+               status = ib_destroy_cq( p_cq->h_cq, NULL );\r
+               if( status != IB_SUCCESS )\r
+                       printf( "ib_destroy_cq returned %s\n", ib_get_err_str( status ) );\r
+\r
+               cl_free( p_cq );\r
+       }\r
+\r
+       printf( "CQ %stesting ]\n", resize?"resize ":"" );\r
+}\r
+\r
+/**********************************************************************\r
+ **********************************************************************/\r
+int __cdecl\r
+main(\r
+       int                                                     argc,\r
+       char*                                           argv[] )\r
+{\r
+       ib_api_status_t         status;\r
+       ib_al_handle_t          h_al;\r
+       ib_ca_handle_t          h_ca;\r
+       ib_pd_handle_t          h_pd;\r
+       size_t                          size;\r
+       net64_t                         *ca_guids;\r
+\r
+       /* Set defaults. */\r
+       if( !__parse_options( argc, argv ) )\r
+               return 1;\r
+\r
+       status = ib_open_al( &h_al );\r
+       if( status != IB_SUCCESS )\r
+       {\r
+               printf( "ib_open_al returned %s\n", ib_get_err_str( status ) );\r
+               return 1;\r
+       }\r
+\r
+       size = 0;\r
+       status = ib_get_ca_guids( h_al, NULL, &size );\r
+       if( status != IB_INSUFFICIENT_MEMORY )\r
+       {\r
+               printf( "ib_get_ca_guids for array size returned %s",\r
+                       ib_get_err_str( status ) );\r
+               goto done;\r
+       }\r
+\r
+       if( size == 0 )\r
+       {\r
+               printf( "No CAs installed.\n" );\r
+               goto done;\r
+       }\r
+\r
+       ca_guids = malloc( sizeof(net64_t) * size );\r
+       if( !ca_guids )\r
+       {\r
+               printf( "Failed to allocate CA GUID array.\n" );\r
+               goto done;\r
+       }\r
+\r
+       status = ib_get_ca_guids( h_al, ca_guids, &size );\r
+       if( status != IB_SUCCESS )\r
+       {\r
+               printf( "ib_get_ca_guids for CA guids returned %s",\r
+                       ib_get_err_str( status ) );\r
+               free( ca_guids );\r
+               goto done;\r
+       }\r
+\r
+       status = ib_open_ca( h_al, ca_guids[0], NULL, NULL, &h_ca );\r
+       free( ca_guids );\r
+       if( status != IB_SUCCESS )\r
+       {\r
+               printf( "ib_open_ca returned %s", ib_get_err_str( status ) );\r
+               goto done;\r
+       }\r
+\r
+       status = ib_alloc_pd( h_ca, IB_PDT_NORMAL, NULL, &h_pd );\r
+       if( status != IB_SUCCESS )\r
+       {\r
+               printf( "ib_alloc_pd returned %s", ib_get_err_str( status ) );\r
+               goto done;\r
+       }\r
+\r
+       if( test_mr )\r
+               __test_mr( h_pd );\r
+\r
+       if( test_cq )\r
+               __test_cq( h_ca, FALSE );\r
+\r
+       if( test_resize )\r
+               __test_cq( h_ca, TRUE );\r
+\r
+       //if( test_qp )\r
+       //      __test_qp( h_ca, h_pd );\r
+\r
+done:\r
+       ib_close_al( h_al );\r
+\r
+       return 0;\r
+}\r
diff --git a/tests/limits/user/makefile b/tests/limits/user/makefile
new file mode 100644 (file)
index 0000000..9c985f5
--- /dev/null
@@ -0,0 +1,7 @@
+#\r
+# DO NOT EDIT THIS FILE!!!  Edit .\sources. if you want to add a new source\r
+# file to this component.  This file merely indirects to the real make file\r
+# that is shared by all the driver components of the Windows NT DDK\r
+#\r
+\r
+!INCLUDE $(NTMAKEENV)\makefile.def\r