#include "dapl_ibal_util.h"
#include "dapl_name_service.h"
#include "dapl_ibal_name_service.h"
+#include "dapl_cookie.h"
#define IB_INFINITE_SERVICE_LEASE 0xFFFFFFFF
#define DAPL_ATS_SERVICE_ID ATS_SERVICE_ID //0x10000CE100415453
}
-static void
-dapli_ibal_listen_err_cb (
- IN ib_listen_err_rec_t *p_listen_err_rec )
+#if defined(DAPL_DBG)
+
+void dapli_print_private_data( char *prefix, const uint8_t *pd, int len )
{
- UNUSED_PARAM( p_listen_err_rec );
+ int i;
+
+ if ( !pd || len <= 0 )
+ return;
+
+ dapl_log ( DAPL_DBG_TYPE_CM, "--> %s: private_data:\n ",prefix);
- dapl_dbg_log (DAPL_DBG_TYPE_CM, "--> %s: CM callback listen error\n",
- "DiLEcb");
+ if (len > IB_MAX_REP_PDATA_SIZE)
+ {
+ dapl_log ( DAPL_DBG_TYPE_ERR,
+ " Private data size(%d) > Max(%d), ignored.\n ",
+ len,DAPL_MAX_PRIVATE_DATA_SIZE);
+ len = IB_MAX_REP_PDATA_SIZE;
+ }
+
+ for ( i = 0 ; i < len; i++ )
+ {
+ dapl_log ( DAPL_DBG_TYPE_CM, "%2x ", pd[i]);
+ if ( ((i+1) % 20) == 0 )
+ dapl_log ( DAPL_DBG_TYPE_CM, "\n ");
+ }
+ dapl_log ( DAPL_DBG_TYPE_CM, "\n");
}
+#endif
+
static void
dapli_ib_cm_apr_cb (
/*
* Connection Disconnect Request callback
+ * We received a DREQ, return a DREP (disconnect reply).
*/
static void
ep_ptr = (DAPL_EP * __ptr64) p_cm_dreq_rec->qp_context;
- if ( ep_ptr == NULL ||
- ep_ptr->header.magic == DAPL_MAGIC_INVALID )
+ if ( DAPL_BAD_PTR(ep_ptr) )
{
dapl_dbg_log (DAPL_DBG_TYPE_ERR,
- "--> DiCDcb: EP %lx invalid or FREED\n", ep_ptr);
+ "--> %s: BAD_PTR EP %lx\n", __FUNCTION__, ep_ptr);
+ return;
+ }
+ if ( ep_ptr->header.magic != DAPL_MAGIC_EP )
+ {
+ if ( ep_ptr->header.magic == DAPL_MAGIC_INVALID )
+ return;
+
+ dapl_dbg_log (DAPL_DBG_TYPE_ERR,
+ "--> %s: EP %p BAD_EP_MAGIC %x != wanted %x\n",
+ __FUNCTION__, ep_ptr, ep_ptr->header.magic,
+ DAPL_MAGIC_EP );
return;
}
+
dapl_dbg_log (DAPL_DBG_TYPE_CM,
- "--> %s() QP %lx EP %lx state %s sent_discreq %d\n",
- __FUNCTION__, ep_ptr->qp_handle, ep_ptr,
+ "--> %s() EP %p, %s sent_discreq %s\n",
+ __FUNCTION__,ep_ptr,
dapl_get_ep_state_str(ep_ptr->param.ep_state),
- ep_ptr->sent_discreq );
+ (ep_ptr->sent_discreq == DAT_TRUE ? "TRUE":"FALSE"));
dapl_os_lock (&ep_ptr->header.lock);
if ( ep_ptr->param.ep_state == DAT_EP_STATE_DISCONNECTED
/*|| ( ep_ptr->param.ep_state == DAT_EP_STATE_DISCONNECT_PENDING
- && ep_ptr->sent_discreq == DAT_FALSE)*/ )
+ && ep_ptr->sent_discreq == DAT_TRUE)*/ )
{
dapl_os_unlock (&ep_ptr->header.lock);
dapl_dbg_log (DAPL_DBG_TYPE_CM,
}
ep_ptr->param.ep_state = DAT_EP_STATE_DISCONNECT_PENDING;
-
ep_ptr->recv_discreq = DAT_TRUE;
dapl_os_unlock (&ep_ptr->header.lock);
- dapl_os_memzero (&cm_drep, sizeof ( ib_cm_drep_t));
+ dapl_os_memzero (&cm_drep, sizeof(ib_cm_drep_t));
/* Could fail if we received reply from other side, no need to retry */
- /* Wait for any transaction in process holding reference */
- while ( dapl_os_atomic_read(&ep_ptr->req_count) && bail-- > 0 )
+ /* Wait for any send ops in process holding reference */
+ while (dapls_cb_pending(&ep_ptr->req_buffer) && bail-- > 0 )
{
dapl_dbg_log (DAPL_DBG_TYPE_CM,
"--> DiCDcb: WAIT for EP=%lx req_count(%d) != 0\n",
- ep_ptr, dapl_os_atomic_read(&ep_ptr->req_count));
+ ep_ptr, dapls_cb_pending(&ep_ptr->req_buffer));
dapl_os_sleep_usec (100);
}
/*
* Connection Disconnect Reply callback
+ * We sent a DREQ and received a DREP.
*/
static void
ep_ptr = (DAPL_EP * __ptr64) p_cm_drep_rec->qp_context;
- if ( !ep_ptr || DAPL_BAD_HANDLE(ep_ptr, DAPL_MAGIC_EP) )
+ if (p_cm_drep_rec->cm_status)
{
dapl_dbg_log (DAPL_DBG_TYPE_CM,
+ "--> %s: DREP cm_status(%s) EP=%p\n", __FUNCTION__,
+ ib_get_err_str(p_cm_drep_rec->cm_status), ep_ptr);
+ }
+
+ if ( DAPL_BAD_HANDLE(ep_ptr, DAPL_MAGIC_EP) )
+ {
+ dapl_dbg_log (DAPL_DBG_TYPE_ERR,
"--> %s: BAD EP Handle EP=%lx\n", __FUNCTION__,ep_ptr);
return;
}
dapl_dbg_log (DAPL_DBG_TYPE_CM,
- "--> DiCDpcb: QP %lx EP %lx state %s cm_hdl %lx\n",
- ep_ptr->qp_handle, ep_ptr,
+ "--> DiCDpcb: EP %p state %s cm_hdl %p\n",ep_ptr,
dapl_get_ep_state_str(ep_ptr->param.ep_state),
ep_ptr->cm_handle);
}
}
+/*
+ * CM reply callback
+ */
static void
dapli_ib_cm_rep_cb (
dapl_os_assert (p_cm_rep_rec != NULL);
- dapl_os_memzero (&cm_rtu, sizeof ( ib_cm_rtu_t ));
-
- dapl_os_assert ( ((DAPL_HEADER * __ptr64)
- p_cm_rep_rec->qp_context)->magic == DAPL_MAGIC_EP );
-
ep_ptr = (DAPL_EP * __ptr64) p_cm_rep_rec->qp_context;
+
+ if ( DAPL_BAD_HANDLE(ep_ptr, DAPL_MAGIC_EP) )
+ {
+ dapl_dbg_log (DAPL_DBG_TYPE_ERR, "--> %s: EP %lx invalid or FREED\n",
+ __FUNCTION__, ep_ptr);
+ return;
+ }
dapl_dbg_log (DAPL_DBG_TYPE_CM,
"--> DiCRpcb: EP = %lx local_max_rdma_read_in %d\n",
ep_ptr, p_cm_rep_rec->resp_res);
p_ca = (dapl_ibal_ca_t *)
ep_ptr->header.owner_ia->hca_ptr->ib_hca_handle;
+ dapl_os_memzero (&cm_rtu, sizeof ( ib_cm_rtu_t ));
cm_rtu.pfn_cm_apr_cb = dapli_ib_cm_apr_cb;
cm_rtu.pfn_cm_dreq_cb = dapli_ib_cm_dreq_cb;
cm_rtu.p_rtu_pdata = NULL;
cm_cb_op = IB_CME_CONNECTED;
dapl_dbg_log (DAPL_DBG_TYPE_CM,
"--> DiCRpcb: EP %lx Connected req_count %d\n",
- ep_ptr, dapl_os_atomic_read(&ep_ptr->req_count));
+ ep_ptr, dapls_cb_pending(&ep_ptr->req_buffer));
}
else
{
prd_ptr = (DAPL_PRIVATE * __ptr64) p_cm_rep_rec->p_rep_pdata;
-#ifdef DAPL_DBG
-#if 0
- {
- int i;
-
- dapl_dbg_log ( DAPL_DBG_TYPE_EP, "--> DiCRpcb: private_data: ");
-
- for ( i = 0 ; i < IB_MAX_REP_PDATA_SIZE ; i++ )
- {
- dapl_dbg_log ( DAPL_DBG_TYPE_EP,
- "0x%x ", prd_ptr->private_data[i]);
-
- }
- dapl_dbg_log ( DAPL_DBG_TYPE_EP, "\n");
-
- }
-#endif
+#if defined(DAPL_DBG) && 0
+ dapli_print_private_data( "DiCRpcb",
+ prd_ptr->private_data,
+ IB_MAX_REP_PDATA_SIZE);
#endif
dapl_evd_connection_callback (
ep_ptr = (DAPL_EP * __ptr64) p_cm_rej_rec->qp_context;
+ if ( DAPL_BAD_HANDLE(ep_ptr, DAPL_MAGIC_EP) )
+ {
+ dapl_dbg_log (DAPL_DBG_TYPE_ERR, "--> %s: EP %lx invalid or FREED\n",
+ __FUNCTION__, ep_ptr);
+ return;
+ }
+
dapl_dbg_log (DAPL_DBG_TYPE_CM,
"--> DiCRjcb: EP = %lx QP = %lx rej reason = 0x%x\n",
ep_ptr,ep_ptr->qp_handle,CL_NTOH16(p_cm_rej_rec->rej_status));
ep_ptr = (DAPL_EP * __ptr64) p_cm_rtu_rec->qp_context;
+ if ( DAPL_BAD_HANDLE(ep_ptr, DAPL_MAGIC_EP) )
+ {
+ dapl_dbg_log (DAPL_DBG_TYPE_ERR, "--> %s: EP %lx invalid or FREED\n",
+ __FUNCTION__, ep_ptr);
+ return;
+ }
+
dapl_dbg_log (DAPL_DBG_TYPE_CM | DAPL_DBG_TYPE_CALLBACK,
"--> DiCRucb: EP %lx QP %lx\n", ep_ptr, ep_ptr->qp_handle);
IN DAT_EP_HANDLE ep_handle,
IN DAT_IA_ADDRESS_PTR remote_ia_address,
IN DAT_CONN_QUAL remote_conn_qual,
- IN DAT_COUNT prd_size,
- IN DAPL_PRIVATE *prd_ptr )
+ IN DAT_COUNT private_data_size,
+ IN DAT_PVOID private_data )
{
DAPL_EP *ep_ptr;
DAPL_IA *ia_ptr;
cm_req.p_alt_path = NULL;
cm_req.h_qp = ep_ptr->qp_handle;
cm_req.qp_type = IB_QPT_RELIABLE_CONN;
- cm_req.p_req_pdata = (uint8_t *) prd_ptr;
- cm_req.req_length = (uint8_t)prd_size;
+ cm_req.p_req_pdata = (uint8_t *) private_data;
+ cm_req.req_length = (uint8_t)
+ min(private_data_size,IB_MAX_REQ_PDATA_SIZE);
/* cm retry to send this request messages, IB max of 4 bits */
cm_req.max_cm_retries = 15; /* timer outside of call, s/be infinite */
/* qp retry to send any wr */
cm_req.init_depth = (uint8_t)ep_ptr->param.ep_attr.max_rdma_read_out;
/* time wait before retrying a pkt after receiving a RNR NAK */
- cm_req.rnr_nak_timeout = 12; /* 163.84ms */
+ cm_req.rnr_nak_timeout = IB_RNR_NAK_TIMEOUT;
/*
* number of time local QP should retry after receiving RNR NACK before
* reporting an error
*/
- cm_req.rnr_retry_cnt = 6; /* 7 is infinite */
+ cm_req.rnr_retry_cnt = IB_RNR_RETRY_CNT;
cm_req.remote_resp_timeout = 16; /* 250ms */
cm_req.local_resp_timeout = 16; /* 250ms */
dapls_ib_disconnect ( IN DAPL_EP *ep_ptr,
IN DAT_CLOSE_FLAGS disconnect_flags )
{
- DAPL_IA *ia_ptr;
- ib_api_status_t ib_status;
+ ib_api_status_t ib_status = IB_SUCCESS;
ib_cm_dreq_t cm_dreq;
- //UNUSED_PARAM( disconnect_flags );
-
dapl_os_assert(ep_ptr);
+
if ( DAPL_BAD_HANDLE(ep_ptr, DAPL_MAGIC_EP) )
{
dapl_dbg_log (DAPL_DBG_TYPE_CM,
return DAT_SUCCESS;
}
- dapl_dbg_log (DAPL_DBG_TYPE_CM, "--> %s() DsD: EP %lx QP %lx ep_state %s "
- "rx_drq %d tx_drq %d Close %s\n", __FUNCTION__,
- ep_ptr, ep_ptr->qp_handle,
- dapl_get_ep_state_str (ep_ptr->param.ep_state),
+ dapl_dbg_log (DAPL_DBG_TYPE_CM,
+ "--> %s() EP %p %s rx_drq %d tx_drq %d Close %s\n", __FUNCTION__,
+ ep_ptr, dapl_get_ep_state_str(ep_ptr->param.ep_state),
ep_ptr->recv_discreq, ep_ptr->sent_discreq,
- (disconnect_flags == DAT_CLOSE_ABRUPT_FLAG
- ? "Abrupt":"Graceful"));
+ (disconnect_flags == DAT_CLOSE_ABRUPT_FLAG ? "Abrupt":"Graceful"));
- if ( disconnect_flags == DAT_CLOSE_ABRUPT_FLAG ) {
- dapl_ep_legacy_post_disconnect(ep_ptr, disconnect_flags);
+ if ( disconnect_flags == DAT_CLOSE_ABRUPT_FLAG )
+ {
+ if ( ep_ptr->param.ep_state == DAT_EP_STATE_DISCONNECTED )
return DAT_SUCCESS;
- }
- if ( ep_ptr->param.ep_state != DAT_EP_STATE_CONNECTED )
+ if ( ep_ptr->param.ep_state != DAT_EP_STATE_DISCONNECT_PENDING )
{
- dapl_dbg_log (DAPL_DBG_TYPE_CM,
- "--> DsD: EP %lx NOT connected state %s\n",
- ep_ptr, dapl_get_ep_state_str (ep_ptr->param.ep_state));
+ dapl_dbg_log(DAPL_DBG_TYPE_CM,
+ "%s() calling legacy_post_disconnect()\n",__FUNCTION__);
+ dapl_ep_legacy_post_disconnect(ep_ptr, disconnect_flags);
+ return DAT_SUCCESS;
+ }
}
- ia_ptr = ep_ptr->header.owner_ia;
- ib_status = IB_SUCCESS;
dapl_os_memzero(&cm_dreq, sizeof(ib_cm_dreq_t));
cm_dreq.p_dreq_pdata = NULL;
cm_dreq.flags = IB_FLAGS_SYNC;
+ /*
+ * still need to send DREQ (disconnect request)?
+ */
if ( (ep_ptr->recv_discreq == DAT_FALSE)
- && (ep_ptr->sent_discreq == DAT_FALSE) )
+ && (ep_ptr->sent_discreq == DAT_FALSE)
+ && (ep_ptr->qp_state != IB_QPS_RESET) )
{
ep_ptr->sent_discreq = DAT_TRUE;
-
ib_status = ib_cm_dreq ( &cm_dreq );
+ /* tolerate INVALID_STATE error as the other side can race ahead and
+ * generate a DREQ before we do.
+ */
+ if ( ib_status == IB_INVALID_STATE )
+ ib_status = IB_SUCCESS;
+ if (ib_status)
+ {
+ dapl_dbg_log(DAPL_DBG_TYPE_ERR,
+ "%s() EP %p ib_cm_dreq() status %s\n",
+ __FUNCTION__,ep_ptr,ib_get_err_str(ib_status));
+ }
+ if ( ib_status == IB_SUCCESS )
dapl_dbg_log (DAPL_DBG_TYPE_CM,
- "--> DsD: EP %lx QP %lx DREQ SENT status %s\n",
- ep_ptr, ep_ptr->qp_handle,ib_get_err_str(ib_status));
+ "--> DsD: EP %p DREQ SENT\n", ep_ptr);
}
-
- return dapl_ib_status_convert (ib_status);
+ return ib_status;
}
ib_status = ib_cm_listen ( dapl_ibal_root.h_al,
&cm_listen,
- dapli_ibal_listen_err_cb,
(void *) sp_ptr,
&sp_ptr->cm_srvc_handle );
cm_rej.rej_status = IB_REJ_USER_DEFINED;
cm_rej.p_ari = (ib_ari_t *)&rej_table[reject_reason];
cm_rej.ari_length = (uint8_t)strlen (rej_table[reject_reason]);
- cm_rej.p_rej_pdata = NULL;
- cm_rej.rej_length = 0;
+
+ if (private_data_size >
+ dapls_ib_private_data_size(NULL,DAPL_PDATA_CONN_REJ,NULL))
+ {
+ dapl_dbg_log ( DAPL_DBG_TYPE_ERR,
+ "--> DsRjC: private_data size(%d) > Max(%d)\n",
+ private_data_size, IB_MAX_REJ_PDATA_SIZE );
+ return DAT_ERROR(DAT_INVALID_PARAMETER, DAT_INVALID_ARG3);
+ }
+
+ cm_rej.p_rej_pdata = private_data;
+ cm_rej.rej_length = private_data_size;
+
+#if defined(DAPL_DBG) && 0
+ dapli_print_private_data("DsRjC",private_data,private_data_size);
+#endif
ib_status = ib_cm_rej ( *ib_cm_handle, &cm_rej);
}
return ( dapl_ib_status_convert ( ib_status ) );
-
}
dapl_dbg_log ( DAPL_DBG_TYPE_ERR,"ib_query_qp(%lx) '%s'\n",
qp_handle, ib_get_err_str(ib_status) );
}
-#if 1
else
{
dapl_dbg_log ( DAPL_DBG_TYPE_CM, "--> QP(%lx) state %s "
qpa->init_depth,
qpa->access_ctrl );
}
-#endif
}
#endif
* Input:
* cr_handle
* ep_handle
- * private_data_size - ignored as DAT layer sets 0
- * private_data - ignored as DAT layer sets NULL
+ * private_data_size
+ * private_data
*
* Output:
* none
dapls_ib_accept_connection (
IN DAT_CR_HANDLE cr_handle,
IN DAT_EP_HANDLE ep_handle,
- IN DAT_COUNT p_size,
- IN DAPL_PRIVATE *prd_ptr )
+ IN DAT_COUNT private_data_size,
+ IN const DAT_PVOID private_data )
{
DAPL_CR *cr_ptr;
DAPL_EP *ep_ptr;
cm_rep.h_qp = ep_ptr->qp_handle;
cm_rep.qp_type = IB_QPT_RELIABLE_CONN;
- cm_rep.p_rep_pdata = (uint8_t *) cr_ptr->private_data;
- cm_rep.rep_length = IB_REQ_PDATA_SIZE;
-
-#if defined(DAPL_DBG) && 0
- {
- int i;
-
- dapl_dbg_log ( DAPL_DBG_TYPE_EP, "--> DsAC: private_data: ");
- for ( i = 0 ; i < IB_MAX_REP_PDATA_SIZE ; i++ )
- {
- dapl_dbg_log ( DAPL_DBG_TYPE_EP,
- "0x%x ", prd_ptr->private_data[i]);
+ if (private_data_size > IB_MAX_REP_PDATA_SIZE) {
+ dapl_dbg_log (DAPL_DBG_TYPE_ERR,
+ "--> DsIBAC: private_data_size(%d) > Max(%d)\n",
+ private_data_size, IB_MAX_REP_PDATA_SIZE);
+ return DAT_ERROR(DAT_LENGTH_ERROR, DAT_NO_SUBTYPE);
}
- dapl_dbg_log ( DAPL_DBG_TYPE_EP, "\n");
+ cm_rep.p_rep_pdata = (const uint8_t *)private_data;
+ cm_rep.rep_length = private_data_size;
- }
+#if defined(DAPL_DBG) && 0
+ dapli_print_private_data( "DsIBAC",
+ (const uint8_t*)private_data,
+ private_data_size );
#endif
cm_rep.pfn_cm_rej_cb = dapli_ib_cm_rej_cb;
cm_rep.flags = 0;
cm_rep.failover_accepted = IB_FAILOVER_ACCEPT_UNSUPPORTED;
cm_rep.target_ack_delay = 14;
- cm_rep.rnr_nak_timeout = 12;
- cm_rep.rnr_retry_cnt = 6;
+ cm_rep.rnr_nak_timeout = IB_RNR_NAK_TIMEOUT;
+ cm_rep.rnr_retry_cnt = IB_RNR_RETRY_CNT;
cm_rep.pp_recv_failure = NULL;
cm_rep.p_recv_wr = NULL;
dapl_dbg_log (DAPL_DBG_TYPE_CM,
"--> DsIBAC: cm_rep: acc %x init %d qp_type %x req_count %d\n",
cm_rep.access_ctrl, cm_rep.init_depth,cm_rep.qp_type,
- dapl_os_atomic_read(&ep_ptr->req_count));
+ dapls_cb_pending(&ep_ptr->req_buffer));
ib_status = ib_cm_rep ( *ep_ptr->cm_handle, &cm_rep );
* Return the size of private data given a connection op type
*
* Input:
- * hca_ptr hca pointer, needed for transport type
* prd_ptr private data pointer
* conn_op connection operation type
+ * hca_ptr hca pointer, needed for transport type
*
* If prd_ptr is NULL, this is a query for the max size supported by
* the provider, otherwise it is the actual size of the private data
*/
int
dapls_ib_private_data_size (
- IN DAPL_HCA *hca_ptr,
IN DAPL_PRIVATE *prd_ptr,
- IN DAPL_PDATA_OP conn_op)
+ IN DAPL_PDATA_OP conn_op,
+ IN DAPL_HCA *hca_ptr)
{
int size;
UNUSED_PARAM( prd_ptr );
+ UNUSED_PARAM( hca_ptr );
switch (conn_op)
{