#include "ibspdll.h"\r
\r
\r
-static void ib_destroy_cq_tinfo( struct cq_thread_info *cq_tinfo );\r
-\r
-\r
typedef struct _io_comp_info\r
{\r
struct ibsp_socket_info *p_socket;\r
__LINE__, GetCurrentProcessId(), GetCurrentThreadId()));\r
}\r
\r
- } while( (cq_tinfo->ib_cq_thread_exit_wanted != TRUE) ||\r
- cl_qlist_count( &cq_tinfo->done_wr_list ) );\r
+ } while( !cq_tinfo->ib_cq_thread_exit_wanted );\r
\r
cl_status = cl_waitobj_destroy( cq_tinfo->cq_waitobj );\r
if( cl_status != CL_SUCCESS )\r
{\r
- IBSP_ERROR( ("cl_waitobj_destroy() (%d)\n", cl_status) );\r
+ IBSP_ERROR(\r
+ ("cl_waitobj_destroy() returned %s\n", CL_STATUS_MSG(cl_status)) );\r
}\r
HeapFree( g_ibsp.heap, 0, cq_tinfo );\r
\r
}\r
\r
\r
+/* Called with the HCA's CQ lock held. */\r
static struct cq_thread_info *\r
ib_alloc_cq_tinfo(\r
struct ibsp_hca *hca )\r
ib_cq_create_t cq_create;\r
ib_api_status_t status;\r
cl_status_t cl_status;\r
- int error;\r
\r
IBSP_ENTER( IBSP_DBG_HW );\r
\r
- cq_tinfo = HeapAlloc( g_ibsp.heap, HEAP_ZERO_MEMORY, sizeof(struct cq_thread_info) );\r
+ cq_tinfo = HeapAlloc(\r
+ g_ibsp.heap, HEAP_ZERO_MEMORY, sizeof(struct cq_thread_info) );\r
\r
- if( cq_tinfo == NULL )\r
+ if( !cq_tinfo )\r
{\r
- IBSP_ERROR( ("HeapAlloc() Failed.\n") );\r
- error = TRUE;\r
- goto done;\r
+ IBSP_ERROR_EXIT( ("HeapAlloc() Failed.\n") );\r
+ return NULL;\r
}\r
\r
cl_status = cl_waitobj_create( FALSE, &cq_tinfo->cq_waitobj );\r
if( cl_status != CL_SUCCESS )\r
{\r
cq_tinfo->cq_waitobj = NULL;\r
- IBSP_ERROR( ("cl_waitobj_create() (%d)\n", cl_status) );\r
- error = TRUE;\r
- goto done;\r
+ ib_destroy_cq_tinfo( cq_tinfo );\r
+ IBSP_ERROR_EXIT(\r
+ ("cl_waitobj_create() returned %s\n", CL_STATUS_MSG(cl_status)) );\r
+ return NULL;\r
}\r
\r
cq_tinfo->hca = hca;\r
\r
if( cq_tinfo->ib_cq_thread == NULL )\r
{\r
- IBSP_ERROR( ("CreateThread failed.") );\r
- error = TRUE;\r
- goto done;\r
+ ib_destroy_cq_tinfo( cq_tinfo );\r
+ IBSP_ERROR_EXIT( ("CreateThread failed (%d)", GetLastError()) );\r
+ return NULL;\r
}\r
\r
STAT_INC( thread_num );\r
&cq_tinfo->cq );\r
if( status )\r
{\r
- IBSP_ERROR( ("ib_create_cq failed (%d)\n", status) );\r
- error = TRUE;\r
- goto done;\r
+ ib_destroy_cq_tinfo( cq_tinfo );\r
+ IBSP_ERROR_EXIT(\r
+ ("ib_create_cq returned %s\n", ib_get_err_str( status )) );\r
+ return NULL;\r
}\r
\r
STAT_INC( cq_num );\r
status = ib_rearm_cq( cq_tinfo->cq, FALSE );\r
if( status )\r
{\r
- IBSP_ERROR( ("ib_rearm_cq failed (%d)\n", status) );\r
- error = TRUE;\r
- goto done;\r
+ ib_destroy_cq_tinfo( cq_tinfo );\r
+ IBSP_ERROR_EXIT(\r
+ ("ib_rearm_cq returned %s\n", ib_get_err_str( status )) );\r
+ return NULL;\r
}\r
\r
- cl_spinlock_init( &cq_tinfo->wr_mutex );\r
- cl_qlist_init( &cq_tinfo->done_wr_list );\r
cq_tinfo->cqe_size = IB_CQ_SIZE;\r
\r
- /* Only one CQ per HCA now */\r
- hca->cq_tinfo = cq_tinfo;\r
-\r
- error = FALSE;\r
-\r
-done:\r
- if( error == TRUE )\r
+ if( hca->cq_tinfo )\r
{\r
- ib_destroy_cq_tinfo( cq_tinfo );\r
- cq_tinfo = NULL;\r
+ __cl_primitive_insert(\r
+ &hca->cq_tinfo->list_item, &cq_tinfo->list_item );\r
+ }\r
+ else\r
+ {\r
+ /* Setup the list entry to point to itself. */\r
+ cq_tinfo->list_item.p_next = &cq_tinfo->list_item;\r
+ cq_tinfo->list_item.p_prev = &cq_tinfo->list_item;\r
}\r
\r
- IBSP_EXIT( IBSP_DBG_HW );\r
+ /* Upon allocation, the new CQ becomes the primary. */\r
+ hca->cq_tinfo = cq_tinfo;\r
\r
+ IBSP_EXIT( IBSP_DBG_HW );\r
return (cq_tinfo);\r
}\r
\r
\r
-static void\r
+void\r
ib_destroy_cq_tinfo(\r
struct cq_thread_info *cq_tinfo )\r
{\r
\r
IBSP_ENTER( IBSP_DBG_HW );\r
\r
- if( cq_tinfo == NULL )\r
- {\r
- return;\r
- }\r
+ CL_ASSERT( cq_tinfo );\r
+ CL_ASSERT( cq_tinfo->qp_count == 0 );\r
\r
if( cq_tinfo->cq )\r
{\r
wclist.p_next = NULL;\r
free_wclist = &wclist;\r
\r
- while( ib_poll_cq( cq_tinfo->cq, &free_wclist, &done_wclist ) == IB_SUCCESS )\r
+ while( ib_poll_cq(\r
+ cq_tinfo->cq, &free_wclist, &done_wclist ) == IB_SUCCESS )\r
{\r
- IBSP_TRACE( IBSP_DBG_WQ, ("%s():%d:0x%x:0x%x: free=%p, done=%p\n",\r
- __FUNCTION__,\r
- __LINE__, GetCurrentProcessId(),\r
- GetCurrentThreadId(),\r
- free_wclist, done_wclist) );\r
+ IBSP_TRACE1( IBSP_DBG_WQ,\r
+ ("free=%p, done=%p\n", free_wclist, done_wclist) );\r
}\r
\r
- IBSP_TRACE( IBSP_DBG_WQ, ("%s():%d:0x%x:0x%x: ib_destroy_cq() start..\n",\r
- __FUNCTION__,\r
- __LINE__, GetCurrentProcessId(),\r
- GetCurrentThreadId()) );\r
+ IBSP_TRACE4( IBSP_DBG_WQ, ("ib_destroy_cq() start..\n") );\r
\r
/*\r
* Called from cleanup thread, okay to block.\r
status = ib_destroy_cq( cq_tinfo->cq, ib_sync_destroy );\r
if( status )\r
{\r
- IBSP_ERROR( ("ib_destroy_cq failed (%d)\n", status) );\r
+ IBSP_ERROR(\r
+ ("ib_destroy_cq returned %s\n", ib_get_err_str( status )) );\r
}\r
else\r
{\r
- IBSP_TRACE( IBSP_DBG_WQ,\r
- ("%s():%d:0x%x:0x%x: ib_destroy_cq() finished.\n", __FUNCTION__,\r
- __LINE__, GetCurrentProcessId(), GetCurrentThreadId()) );\r
+ IBSP_TRACE4( IBSP_DBG_WQ, ("ib_destroy_cq() finished.\n") );\r
\r
cq_tinfo->cq = NULL;\r
\r
}\r
}\r
\r
- /* Currently only 1 CQ per HCA */\r
- cq_tinfo->hca = NULL;\r
-\r
if( cq_tinfo->ib_cq_thread )\r
{\r
/* ib_cq_thread() will release the cq_tinfo before exit. Don't\r
ib_acquire_cq_tinfo(\r
struct ibsp_hca *hca )\r
{\r
- struct cq_thread_info *cq_tinfo = NULL;\r
- uint32_t current_cqe_size;\r
+ struct cq_thread_info *cq_tinfo = NULL;\r
+ uint32_t cqe_size;\r
+ ib_api_status_t status;\r
\r
IBSP_ENTER( IBSP_DBG_HW );\r
\r
- /* \r
- * TODO: If future implementations require more than 1 cq_tinfo per HCA, then\r
- * search HCA cq_tinfo list for optimal cq_tinfo \r
- */\r
- if( hca->cq_tinfo == NULL )\r
+ cl_spinlock_acquire( &hca->cq_lock );\r
+\r
+ if( !hca->cq_tinfo )\r
{\r
cq_tinfo = ib_alloc_cq_tinfo( hca );\r
- if( cq_tinfo == NULL )\r
+ if( !cq_tinfo )\r
{\r
- IBSP_ERROR( ("ib_alloc_cq_tinfo() failed\n") );\r
+ IBSP_ERROR_EXIT( ("ib_alloc_cq_tinfo() failed\n") );\r
+ cl_spinlock_release( &hca->cq_lock );\r
return (NULL);\r
}\r
}\r
\r
CL_ASSERT( cq_tinfo != NULL );\r
\r
- current_cqe_size = cq_tinfo->qp_count * IB_CQ_SIZE;\r
-\r
- cl_atomic_inc( &cq_tinfo->qp_count );\r
+ cqe_size = (cq_tinfo->qp_count + 1) * IB_CQ_SIZE;\r
\r
- if( cq_tinfo->cqe_size < current_cqe_size )\r
+ if( cq_tinfo->cqe_size < cqe_size )\r
{\r
- ib_api_status_t status;\r
- status = ib_modify_cq( cq_tinfo->cq, ¤t_cqe_size );\r
- if( status )\r
- {\r
- /* \r
- * TODO: This could mean we are out of cqe and need to have\r
- * more than one cq per HCA in the future.\r
- */\r
- cl_atomic_dec( &cq_tinfo->qp_count );\r
- IBSP_ERROR_EXIT(\r
- ("ib_modify_cq() failed. (%d)\n", status) );\r
- return (NULL);\r
- }\r
- else\r
+ status = ib_modify_cq( cq_tinfo->cq, &cqe_size );\r
+ switch( status )\r
{\r
- cq_tinfo->cqe_size = current_cqe_size;\r
+ case IB_INVALID_CQ_SIZE:\r
+ cq_tinfo = ib_alloc_cq_tinfo( hca );\r
+ if( !cq_tinfo )\r
+ break;\r
+\r
+ cq_tinfo->qp_count++;\r
+ break;\r
+\r
+ case IB_SUCCESS:\r
+ cq_tinfo->cqe_size = cqe_size;\r
+\r
+ cq_tinfo->qp_count++;\r
+\r
fzprint(("%s():%d:0x%x:0x%x: New cq size=%d.\n",\r
__FUNCTION__,\r
__LINE__, GetCurrentProcessId(),\r
GetCurrentThreadId(), cq_tinfo->cqe_size));\r
+ break;\r
\r
+ default:\r
+ IBSP_ERROR_EXIT(\r
+ ("ib_modify_cq() returned %s\n", ib_get_err_str(status)) );\r
+ cq_tinfo = NULL;\r
}\r
}\r
+ else\r
+ {\r
+ cq_tinfo->qp_count++;\r
+ }\r
\r
+ cl_spinlock_release( &hca->cq_lock );\r
IBSP_EXIT( IBSP_DBG_HW );\r
-\r
return (cq_tinfo);\r
}\r
\r
{\r
IBSP_ENTER( IBSP_DBG_HW );\r
\r
- cl_atomic_dec( &cq_tinfo->qp_count );\r
+ CL_ASSERT( cq_tinfo );\r
+ CL_ASSERT( cq_tinfo->hca );\r
\r
- /* TODO: downsize the cq */\r
+ cl_spinlock_acquire( &cq_tinfo->hca->cq_lock );\r
+ /* If this CQ now has fewer QPs than the primary, make it the primary. */\r
+ if( --cq_tinfo->qp_count < cq_tinfo->hca->cq_tinfo->qp_count )\r
+ cq_tinfo->hca->cq_tinfo = cq_tinfo;\r
+ cl_spinlock_release( &cq_tinfo->hca->cq_lock );\r
\r
IBSP_EXIT( IBSP_DBG_HW );\r
}\r
{\r
struct ibsp_hca *hca = PARENT_STRUCT(item, struct ibsp_hca, item);\r
\r
- if( hca->cq_tinfo )\r
- {\r
- CL_ASSERT( hca->cq_tinfo->qp_count == 0 );\r
- ib_destroy_cq_tinfo( hca->cq_tinfo );\r
- }\r
-\r
pnp_ca_remove( hca );\r
}\r
\r
status));\r
if( status != IB_SUCCESS )\r
{\r
- IBSP_ERROR( ("ib_close_al failed (%d)\n", status) );\r
+ IBSP_ERROR(\r
+ ("ib_close_al returned %s\n", ib_get_err_str( status )) );\r
}\r
else\r
{\r
ib_create_socket(\r
IN OUT struct ibsp_socket_info *socket_info)\r
{\r
- struct cq_thread_info *cq_tinfo;\r
ib_qp_create_t qp_create;\r
ib_api_status_t status;\r
- int ret;\r
- struct ibsp_hca *hca;\r
ib_qp_attr_t qp_attr;\r
\r
IBSP_ENTER( IBSP_DBG_EP );\r
CL_ASSERT( socket_info->port != NULL );\r
CL_ASSERT( socket_info->qp == NULL );\r
\r
- hca = socket_info->port->hca;\r
- socket_info->hca_pd = hca->pd;\r
+ socket_info->hca_pd = socket_info->port->hca->pd;\r
\r
/* Get the completion queue and thread info for this socket */\r
- cq_tinfo = ib_acquire_cq_tinfo( hca );\r
- if( cq_tinfo == NULL )\r
+ socket_info->cq_tinfo = ib_acquire_cq_tinfo( socket_info->port->hca );\r
+ if( !socket_info->cq_tinfo )\r
{\r
- IBSP_ERROR( ("ib_acquire_cq_tinfo failed\n") );\r
- ret = WSAEPROVIDERFAILEDINIT;\r
- goto done;\r
+ IBSP_ERROR_EXIT( ("ib_acquire_cq_tinfo failed\n") );\r
+ return WSAENOBUFS;\r
}\r
- socket_info->cq_tinfo = cq_tinfo;\r
\r
/* Queue pair */\r
qp_create.qp_type = IB_QPT_RELIABLE_CONN;\r
qp_create.rq_depth = QP_ATTRIB_RQ_DEPTH;\r
qp_create.sq_sge = QP_ATTRIB_SQ_SGE;\r
qp_create.rq_sge = 1;\r
- qp_create.h_rq_cq = cq_tinfo->cq;\r
- qp_create.h_sq_cq = cq_tinfo->cq;\r
+ qp_create.h_rq_cq = socket_info->cq_tinfo->cq;\r
+ qp_create.h_sq_cq = socket_info->cq_tinfo->cq;\r
qp_create.sq_signaled = TRUE;\r
\r
status = ib_create_qp( socket_info->hca_pd, &qp_create, socket_info, /* context */\r
&socket_info->qp );\r
if( status )\r
{\r
- IBSP_ERROR( ("ib_create_qp failed (%d)\n", status));\r
- ret = WSAEPROVIDERFAILEDINIT;\r
- goto done;\r
+ IBSP_ERROR_EXIT(\r
+ ("ib_create_qp returned %s\n", ib_get_err_str( status )) );\r
+ return WSAENOBUFS;\r
}\r
\r
status = ib_query_qp( socket_info->qp, &qp_attr );\r
}\r
else\r
{\r
- IBSP_ERROR(\r
- ("ib_query_qp returned %s\n", ib_get_err_str( status )) );\r
+ IBSP_ERROR( ("ib_query_qp returned %s\n", ib_get_err_str( status )) );\r
socket_info->max_inline = 0;\r
}\r
\r
STAT_INC( qp_num );\r
\r
- ret = 0;\r
-\r
- done:\r
- if( ret )\r
- {\r
- ib_destroy_socket( socket_info );\r
- }\r
-\r
IBSP_EXIT( IBSP_DBG_EP );\r
-\r
- return ret;\r
+ return 0;\r
}\r
\r
\r