[ofw] patch: [WSD] Add APM failback support for WSD
Tzachi Dar
tzachid at mellanox.co.il
Sun Oct 18 05:25:29 PDT 2009
Applied on 2488.
Thanks
Tzachi
________________________________
From: ofw-bounces at lists.openfabrics.org
[mailto:ofw-bounces at lists.openfabrics.org] On Behalf Of Tzachi Dar
Sent: Thursday, October 15, 2009 8:02 PM
To: ofw at lists.openfabrics.org
Subject: [ofw] patch: [WSD] Add APM failback support for WSD
The following code allows WSD to load new apm paths after a
failure in an existing path.
Thanks
Tzachi
Index: ib_cm.c
===================================================================
--- ib_cm.c (revision 4959)
+++ ib_cm.c (working copy)
@@ -43,7 +43,7 @@
static void AL_API cm_rej_callback(IN ib_cm_rej_rec_t *
p_cm_rej_rec);
static void AL_API cm_mra_callback(IN ib_cm_mra_rec_t *
p_cm_mra_rec);
static void AL_API cm_dreq_callback(IN ib_cm_dreq_rec_t *
p_cm_dreq_rec);
-static void AL_API cm_apr_callback(IN ib_cm_apr_rec_t *
p_cm_apr_rec);
+void AL_API cm_apr_callback(IN ib_cm_apr_rec_t * p_cm_apr_rec);
/* Computes a service ID for a port. */
@@ -585,19 +585,32 @@
* A user-specified callback that is invoked after receiving a
load
* alternate path response message.
*/
-static void AL_API
+void AL_API
cm_apr_callback(
IN ib_cm_apr_rec_t *p_cm_apr_rec )
{
- /* TODO */
+ struct ibsp_socket_info *socket_info =
+ (struct ibsp_socket_info *)p_cm_apr_rec->qp_context;
+
IBSP_ENTER( IBSP_DBG_CM );
- UNUSED_PARAM( p_cm_apr_rec );
+ IBSP_PRINT_EXIT(TRACE_LEVEL_INFORMATION, IBSP_DBG_APM,
("cm_apr_callback called p_cm_apr_rec->cm_status = %d\n",
p_cm_apr_rec->cm_status) );
- IBSP_ERROR( ("not implemented") );
+ cl_spinlock_acquire( &g_ibsp.socket_info_mutex );
+ CL_ASSERT(socket_info->apm_state == APM_LAP_SENT);
- CL_ASSERT( 0 );
+ if ((p_cm_apr_rec->cm_status == IB_SUCCESS) &&
+ (p_cm_apr_rec->apr_status == IB_SUCCESS)){
+ socket_info->apm_state = APM_ARMED;
+ socket_info->SuccesfulMigrations++;
+ } else {
+ socket_info->apm_state = APM_MIGRATED;
+ }
+ cl_spinlock_release( &g_ibsp.socket_info_mutex );
+
+
+
IBSP_EXIT( IBSP_DBG_CM );
}
@@ -612,15 +625,31 @@
cm_lap_callback(
IN ib_cm_lap_rec_t *p_cm_lap_rec )
{
- /* TODO */
+ ib_cm_apr_t cm_apr;
+ struct ibsp_socket_info *socket_info =
+ (struct ibsp_socket_info *)p_cm_lap_rec->qp_context;
+
+ ib_api_status_t status;
+
IBSP_ENTER( IBSP_DBG_CM );
- UNUSED_PARAM( p_cm_lap_rec );
+ IBSP_PRINT_EXIT(TRACE_LEVEL_INFORMATION, IBSP_DBG_APM,
("called \n") );
- IBSP_ERROR( ("not implemented") );
- CL_ASSERT( 0 );
+ cl_memclr(&cm_apr, sizeof(cm_apr));
+ cm_apr.qp_type = IB_QPT_RELIABLE_CONN;
+ cm_apr.h_qp = socket_info->qp;
+
+ status = ib_cm_apr(p_cm_lap_rec->h_cm_lap, &cm_apr);
+ if( status != IB_SUCCESS ) {
+ // Actually not much that we can do at this stage.
+ // The other side will get timeout and retry
+ CL_ASSERT(FALSE);
+ IBSP_ERROR( ("ib_cm_apr returned %s\n", ib_get_err_str(
status )) );
+ }
+
+
IBSP_EXIT( IBSP_DBG_CM );
}
Index: ibsp_iblow.c
===================================================================
--- ibsp_iblow.c (revision 4959)
+++ ibsp_iblow.c (working copy)
@@ -1054,7 +1054,7 @@
qp_create.sq_signaled = TRUE;
status = ib_create_qp( socket_info->hca_pd, &qp_create,
socket_info, /* context */
- NULL, /* async handler */
+ qp_event_handler, /* async handler */
&socket_info->qp );
if( status )
{
Index: ibsp_ip.c
===================================================================
--- ibsp_ip.c (revision 4959)
+++ ibsp_ip.c (working copy)
@@ -418,7 +418,7 @@
return 0;
error:
- IBSP_ERROR_EXIT( ("query_ip_address failed\n") );
+ IBSP_ERROR_EXIT( ("query_pr failed\n") );
return 1;
}
Index: ibsp_mngt.c
===================================================================
--- ibsp_mngt.c (revision 4959)
+++ ibsp_mngt.c (working copy)
@@ -1,289 +0,0 @@
-/*
- * FileName: ibsp_mngt.c
- *
- * Copyright (c)
- *
- * Abstract: Hardware ressource management (HCA and ports).
- *
- * Author:
- *
- * Revision History:
- *
- */
-
-#include "ibspdll.h"
-
-/* Build a list of IP addresses associated with a port */
-int
-build_port_ip_list(IN struct ibsp_port *port)
-{
- struct ibsp_ip_addr *ip_addr;
- cl_list_item_t *item;
- int ret;
-
- CL_ENTER(IBSP_DBG_HW, gdbg_lvl);
- CL_TRACE(IBSP_DBG_HW, gdbg_lvl,
- ("build_port_ip_list for port %UI64x\n",
cl_ntoh64(port->guid)));
-
- cl_qlist_init(&port->ip_list);
-
- ret = query_ip_address(port, &port->ip_list);
- if (ret) {
- CL_ERROR(IBSP_DBG_HW, gdbg_lvl, ("query_ip_address failed
(%d)\n", ret));
- goto error;
- }
-
- CL_EXIT(IBSP_DBG_HW, gdbg_lvl);
- return 0;
-
- error:
- /* Free the list */
- while((item = cl_qlist_remove_head(&port->ip_list)) !=
cl_qlist_end(&port->ip_list)) {
-
- ip_addr = PARENT_STRUCT(item, struct ibsp_ip_addr, item);
-
- HeapFree(g_ibsp.heap, 0, ip_addr);
- }
-
- CL_EXIT_ERROR(IBSP_DBG_HW, gdbg_lvl,
- ("Failed to build list of IP addr for port %016UI64x\n",
- CL_HTON64(port->guid)));
-
- return 1;
-}
-
-/* Get the info from a port. Link it to the parent HCA. */
-int
-build_port_info(IN struct ibsp_hca *hca,
- IN ib_net64_t port_guid,
- IN uint8_t port_num, OUT struct ibsp_port **port_out)
-{
- int ret;
- struct ibsp_port *port;
- cl_list_item_t *item_ip;
-
- CL_ENTER(IBSP_DBG_HW, gdbg_lvl);
-
- port = HeapAlloc(g_ibsp.heap, HEAP_ZERO_MEMORY, sizeof(struct
ibsp_port));
-
- if (port == NULL) {
- CL_ERROR(IBSP_DBG_HW, gdbg_lvl,
- ("HeapAlloc failed (%d)\n", sizeof(struct ibsp_port)));
- ret = WSAEPROVIDERFAILEDINIT;
- goto done;
- }
-
- port->guid = port_guid;
- port->port_num = port_num;
- port->hca = hca;
-
- ret = build_port_ip_list(port);
-
- if (ret) {
- CL_ERROR(IBSP_DBG_HW, gdbg_lvl, ("build_port_ip_list failed
(%d)\n", ret));
- ret = WSAEPROVIDERFAILEDINIT;
- goto done;
- }
-
- /* Insert the new list of IP into the global list of IP
addresses. */
- for(item_ip = cl_qlist_head(&port->ip_list);
- item_ip != cl_qlist_end(&port->ip_list); item_ip =
cl_qlist_next(item_ip)) {
-
- struct ibsp_ip_addr *ip = PARENT_STRUCT(item_ip, struct
ibsp_ip_addr, item);
-
- cl_qlist_insert_tail(&g_ibsp.ip_list, &ip->item_global);
- }
-
- *port_out = port;
-
- CL_EXIT(IBSP_DBG_HW, gdbg_lvl);
-
- ret = 0;
-
- done:
- if (ret) {
- HeapFree(g_ibsp.heap, 0, port);
- }
-
- CL_EXIT(IBSP_DBG_HW, gdbg_lvl);
-
- return ret;
-}
-
-/* Open and query the HCA for its ports */
-int
-build_hca_info(IN ib_net64_t hca_guid, OUT struct ibsp_hca
**hca_out)
-{
- struct ibsp_hca *hca = NULL;
- ib_ca_attr_t *ca_attr = NULL;
- size_t ca_attr_size = 0;
- uint8_t port_num;
- int ret;
- ib_api_status_t status;
-
- CL_ENTER(IBSP_DBG_HW, gdbg_lvl);
-
- hca = HeapAlloc(g_ibsp.heap, HEAP_ZERO_MEMORY, sizeof(struct
ibsp_hca));
- if (hca == NULL) {
- CL_ERROR(IBSP_DBG_HW, gdbg_lvl,
- ("can't get enough memory (%d)\n", sizeof(struct
ibsp_hca)));
- ret = WSAEPROVIDERFAILEDINIT;
- goto done;
- }
-
- hca->guid = hca_guid;
- cl_qlist_init(&hca->ports_list);
-
- status = ib_open_ca(g_ibsp.al_handle, hca->guid, NULL, /*
event handler */
- NULL, /* context */
- &hca->hca_handle);
-
- if (status != IB_SUCCESS) {
- CL_ERROR(IBSP_DBG_HW, gdbg_lvl, ("ib_open_ca failed (%d)\n",
status));
- ret = WSAEPROVIDERFAILEDINIT;
- goto done;
- }
-
- /* Build the list of ports of each HCAs */
- query_ca_again:
- status = ib_query_ca(hca->hca_handle, ca_attr, &ca_attr_size);
-
- if (status == IB_INSUFFICIENT_MEMORY) {
-
- CL_TRACE(IBSP_DBG_HW, gdbg_lvl, ("ib_query_ca needs %d
bytes\n", ca_attr_size));
-
- /* Allocate more memory */
- if (ca_attr) {
- HeapFree(g_ibsp.heap, 0, ca_attr);
- }
-
- ca_attr = HeapAlloc(g_ibsp.heap, 0, ca_attr_size);
-
- if (ca_attr)
- goto query_ca_again;
- else {
- CL_ERROR(IBSP_DBG_HW, gdbg_lvl, ("HeapAlloc failed\n"));
- ret = WSAEPROVIDERFAILEDINIT;
- goto done;
- }
- } else if (status != IB_SUCCESS) {
- CL_ERROR(IBSP_DBG_HW, gdbg_lvl, ("ib_query_ca failed (%d)\n",
status));
- ret = WSAEPROVIDERFAILEDINIT;
- goto done;
- }
-
- CL_TRACE(IBSP_DBG_HW, gdbg_lvl, ("found %d port on that
HCA\n", ca_attr->num_ports));
-
- for(port_num = 0; port_num < ca_attr->num_ports; port_num++) {
- struct ibsp_port *port;
-
- ret = build_port_info(hca,
ca_attr->p_port_attr[port_num].port_guid, port_num + 1, /* TODO: correct
or should query port info? */
- &port);
- if (ret) {
- CL_ERROR(IBSP_DBG_HW, gdbg_lvl, ("build_port_info failed
(%d)\n", ret));
- goto done;
- }
-
- cl_qlist_insert_tail(&hca->ports_list, &port->item);
- }
-
- *hca_out = hca;
-
- ret = 0;
-
- done:
- if (ca_attr) {
- HeapFree(g_ibsp.heap, 0, ca_attr);
- }
-
- if (ret) {
- if (hca) {
-
- if (hca->hca_handle) {
- status = ib_close_ca(hca->hca_handle, NULL);
-
- if (status != IB_SUCCESS) {
- CL_ERROR(IBSP_DBG_HW, gdbg_lvl,
- ("ib_close_ca failed (%d)\n", status));
- }
- }
-
- HeapFree(g_ibsp.heap, 0, hca);
- }
- }
-
- CL_TRACE_EXIT(IBSP_DBG_HW, gdbg_lvl, ("return code is %d\n",
ret));
-
- return ret;
-}
-
-/* Build the HCA tree. This allows for hotplug. Each HCA is
- * discovered, as well as each ports. */
-int
-build_hca_tree(void)
-{
- ib_net64_t *guid_list = NULL;
- ib_api_status_t status;
- int ret;
- unsigned int hca_num;
- size_t adapter_count;
-
- CL_ENTER(IBSP_DBG_HW, gdbg_lvl);
-
- /* Get the GUIDS of the adapters, so we can open them */
- status = ib_get_ca_guids(g_ibsp.al_handle, NULL,
&adapter_count);
- if (status != IB_INSUFFICIENT_MEMORY) {
- CL_ERROR(IBSP_DBG_HW, gdbg_lvl, ("first ib_get_ca_guids
failed\n"));
- ret = WSAEPROVIDERFAILEDINIT;
- goto done;
- }
-
- /* Make sure we have a reasonable number of HCAs */
- CL_ASSERT(adapter_count < 10);
-
- guid_list = HeapAlloc(g_ibsp.heap, 0, sizeof(ib_net64_t) *
adapter_count);
- if (guid_list == NULL) {
- CL_ERROR(IBSP_DBG_HW, gdbg_lvl,
- ("can't get enough memory (%d, %d)\n", sizeof(ib_net64_t),
- adapter_count));
- ret = WSAEPROVIDERFAILEDINIT;
- goto done;
- }
-
- status = ib_get_ca_guids(g_ibsp.al_handle, guid_list,
&adapter_count);
- if (status != IB_SUCCESS) {
- CL_ERROR(IBSP_DBG_HW, gdbg_lvl, ("second ib_get_ca_guids
failed (%d)\n", status));
- ret = WSAEPROVIDERFAILEDINIT;
- goto done;
- }
-
- CL_TRACE(IBSP_DBG_HW, gdbg_lvl, ("got %d adapter guid(s)\n",
adapter_count));
-
- for(hca_num = 0; hca_num < adapter_count; hca_num++) {
-
- struct ibsp_hca *hca;
-
- ret = build_hca_info(guid_list[hca_num], &hca);
- if (ret) {
- CL_ERROR(IBSP_DBG_HW, gdbg_lvl, ("build_hca_info failed
(%d)\n", ret));
- goto done;
- }
-
- cl_qlist_insert_tail(&g_ibsp.hca_list, &hca->item);
- }
-
- CL_ASSERT(adapter_count == cl_qlist_count(&g_ibsp.hca_list));
-
- CL_EXIT(IBSP_DBG_HW, gdbg_lvl);
-
- ret = 0;
-
- done:
- if (guid_list) {
- HeapFree(g_ibsp.heap, 0, guid_list);
- }
-
- CL_EXIT(IBSP_DBG_HW, gdbg_lvl);
-
- return ret;
-}
Index: ibspdebug.h
===================================================================
--- ibspdebug.h (revision 4959)
+++ ibspdebug.h (working copy)
@@ -70,10 +70,10 @@
WPP_DEFINE_BIT( IBSP_DBG_HW) \
WPP_DEFINE_BIT( IBSP_DBG_IO) \
WPP_DEFINE_BIT( IBSP_DBG_DUP) \
- WPP_DEFINE_BIT( IBSP_DBG_PERFMON))
+ WPP_DEFINE_BIT( IBSP_DBG_PERFMON) \
+ WPP_DEFINE_BIT( IBSP_DBG_APM))
-
#define WPP_LEVEL_FLAGS_ENABLED(lvl, flags)
(WPP_LEVEL_ENABLED(flags) && WPP_CONTROL(WPP_BIT_ ## flags).Level >=
lvl)
#define WPP_LEVEL_FLAGS_LOGGER(lvl,flags)
WPP_LEVEL_LOGGER(flags)
#define WPP_FLAG_ENABLED(flags)(WPP_LEVEL_ENABLED(flags) &&
WPP_CONTROL(WPP_BIT_ ## flags).Level >= TRACE_LEVEL_VERBOSE)
@@ -123,10 +123,11 @@
#define IBSP_DBG_CONN 0x00000100 /* connections */
#define IBSP_DBG_OPT 0x00000200 /* socket options */
#define IBSP_DBG_NEV 0x00000400 /* network events */
-#define IBSP_DBG_HW 0x00000800 /* Hardware */
+#define IBSP_DBG_HW 0x00000800 /* Hardware */
#define IBSP_DBG_IO 0x00001000 /* Overlapped I/O request */
#define IBSP_DBG_DUP 0x00002000 /* Socket Duplication */
#define IBSP_DBG_PERFMON 0x00004000 /* Performance Monitoring
*/
+#define IBSP_DBG_APM 0x00008000 /* APM handeling */
#define IBSP_DBG_ERROR (CL_DBG_ERROR | IBSP_DBG_ERR)
Index: ibspdll.c
===================================================================
--- ibspdll.c (revision 4959)
+++ ibspdll.c (working copy)
@@ -73,6 +73,9 @@
uint32_t g_ibsp_dbg_level = TRACE_LEVEL_ERROR;
uint32_t g_ibsp_dbg_flags = 0x1;
+BOOL InitApmLib();
+VOID ShutDownApmLib();
+
/*
* Function: DllMain
*
@@ -228,6 +231,11 @@
if( init_globals() )
return FALSE;
+ if (g_use_APM)
+ {
+ InitApmLib();
+ // We continue weather it succeeded or not
+ }
#ifdef PERFMON_ENABLED
IBSPPmInit();
#endif
@@ -827,6 +835,8 @@
IBSP_PRINT(TRACE_LEVEL_INFORMATION, IBSP_DBG_CONN,
("lpCallerData=%p, lpCalleeData=%p\n", lpCallerData,
lpCalleeData) );
+
+ socket_info->active_side = TRUE;
/* Sanity checks */
if( lpCallerData )
{
@@ -872,6 +882,7 @@
*lpErrno = g_connect_err;
return SOCKET_ERROR;
}
+ socket_info->dest_port_guid = dest_port_guid;
IBSP_PRINT(TRACE_LEVEL_INFORMATION, IBSP_DBG_CONN, ("got GUID
%I64x for IP %s\n",
CL_NTOH64( dest_port_guid ), inet_ntoa( addr->sin_addr )) );
@@ -1766,6 +1777,19 @@
}
+void print_cur_apm_state(ib_qp_handle_t h_qp)
+{
+ ib_qp_attr_t qp_attr;
+ char *apm_states[] = { "IB_APM_MIGRATED", "IB_APM_REARM",
"IB_APM_ARMED" };
+
+ if (!ib_query_qp(h_qp, &qp_attr)) {
+ IBSP_ERROR(("Querying QP returned that APM FSM is %s (%d)\n",
+ (qp_attr.apm_state<1 || qp_attr.apm_state>3) ? "UNKNOWN" :
+ apm_states[qp_attr.apm_state-1], qp_attr.apm_state));
+ }
+ Sleep(10);
+}
+
/* Function: IBSPSend
*
* Description:
@@ -2230,6 +2254,7 @@
if( g_ibsp.entry_count == 0 )
{
IBSP_PRINT(TRACE_LEVEL_INFORMATION, IBSP_DBG_INIT,
("entry_count is 0 => cleaning up\n") );
+ ShutDownApmLib();
ib_release();
#ifdef PERFMON_ENABLED
@@ -2350,4 +2375,220 @@
}
+// TRUE means that all is well with socket, no need to recall
it
+BOOL rearm_socket(struct ibsp_socket_info *socket_info)
+{
+
+ ib_path_rec_t path_rec;
+ ib_cm_lap_t cm_lap;
+ int ret;
+ ib_api_status_t status;
+
+ ib_net64_t dest_port_guid;
+ ib_net64_t src_port_guid;
+
+ CL_ASSERT(socket_info->active_side == TRUE);
+ // Try to send the LAP message:
+
+
+ if ((socket_info->SuccesfulMigrations & 1) == 0)
+ {
+ src_port_guid = socket_info->port->guid;
+ dest_port_guid = socket_info->dest_port_guid;
+ }
+ else
+ {
+ src_port_guid = GetOtherPortGuid(socket_info->port->guid);
+ dest_port_guid =
GetOtherPortGuid(socket_info->dest_port_guid);
+ }
+ /* Get the path record */
+ ret = query_pr( src_port_guid, dest_port_guid,
socket_info->port->hca->dev_id, &path_rec );
+ if(ret != IB_SUCCESS)
+ {
+ IBSP_ERROR( ("query_pr for apm failed\n") );
+ return FALSE;
+ }
+
+ cl_memclr(&cm_lap, sizeof(cm_lap));
+ cm_lap.qp_type = IB_QPT_RELIABLE_CONN;
+ cm_lap.h_qp = socket_info->qp;
+ cm_lap.remote_resp_timeout = ib_path_rec_pkt_life( &path_rec )
+ CM_REMOTE_TIMEOUT;
+ cm_lap.p_alt_path = &path_rec;
+ cm_lap.pfn_cm_apr_cb = cm_apr_callback;
+ status = ib_cm_lap(&cm_lap);
+ if( status != IB_SUCCESS )
+ {
+ /* Note: a REJ has been automatically sent. */
+ IBSP_ERROR( ("ib_cm_lap returned %s\n", ib_get_err_str(
status )) );
+ return FALSE;
+ }
+ else
+ {
+ IBSP_PRINT_EXIT(TRACE_LEVEL_INFORMATION, IBSP_DBG_APM,
("ib_cm_lap returned succesfuly\n") );
+ socket_info->apm_state = APM_LAP_SENT;
+ }
+
+
+ // Actually we always return false, since we need to make sure
that the lap
+ // was realy successfull.
+ return FALSE;
+}
+
+
+
+VOID APMCallback(struct ibsp_socket_info *apm_socket_info)
+{
+ cl_list_item_t *socket_item = NULL;
+ BOOL found = FALSE;
+
+ if (g_ibsp.apm_data.hEvent== 0) {
+ // This means that we have failed to start our timer, not
much
+ // that we can do.
+ return;
+ }
+
+
+ // Find our socket and mark it as needs to load a new path.
+ // Avoid race by searching in the list
+ // BUGBUG: Need to have a better solution than this
+ cl_spinlock_acquire( &g_ibsp.socket_info_mutex );
+ for( socket_item = cl_qlist_head( &g_ibsp.socket_info_list );
+ socket_item != cl_qlist_end( &g_ibsp.socket_info_list );
+ socket_item = cl_qlist_next( socket_item ) )
+ {
+ struct ibsp_socket_info *socket_info = NULL;
+ socket_info = PARENT_STRUCT(socket_item, struct
ibsp_socket_info, item);
+ if (apm_socket_info == socket_info) {
+ if (apm_socket_info->active_side) {
+ CL_ASSERT(apm_socket_info->apm_state == APM_ARMED);
+ apm_socket_info->apm_state = APM_MIGRATED ;
+ }
+ found = TRUE;
+ break;
+ }
+ }
+ CL_ASSERT(found == TRUE); // The case that we are not found is
very rare
+ // and is probably a bug
+
+ SetEvent(g_ibsp.apm_data.hEvent);
+
+ cl_spinlock_release( &g_ibsp.socket_info_mutex );
+
+}
+
+DWORD WINAPI ApmThreadProc(
+ LPVOID lpParameter
+)
+{
+ DWORD dwTimeOut = INFINITE;
+ DWORD ret;
+ cl_list_item_t *socket_item = NULL;
+
+ UNREFERENCED_PARAMETER(lpParameter);
+
+ for(;;) {
+ BOOL AllSocketsDone = TRUE;
+ ret = WaitForSingleObject(g_ibsp.apm_data.hEvent, dwTimeOut);
+ if (g_ibsp.apm_data.ThreadExit) {
+ return 0;
+ }
+ cl_spinlock_acquire( &g_ibsp.socket_info_mutex );
+ for( socket_item = cl_qlist_head( &g_ibsp.socket_info_list );
+ socket_item != cl_qlist_end( &g_ibsp.socket_info_list );
+ socket_item = cl_qlist_next( socket_item ) )
+ {
+ struct ibsp_socket_info *socket_info = NULL;
+ socket_info = PARENT_STRUCT(socket_item, struct
ibsp_socket_info, item);
+ if(socket_info->apm_state == APM_MIGRATED)
+ {
+ AllSocketsDone &= rearm_socket(socket_info);
+ } else if(socket_info->apm_state == APM_LAP_SENT) {
+ AllSocketsDone = FALSE;
+ }
+ }
+ if (AllSocketsDone)
+ {
+ dwTimeOut = INFINITE;
+ }
+ else
+ {
+ dwTimeOut = 2000;
+ }
+
+ cl_spinlock_release( &g_ibsp.socket_info_mutex );
+
+
+ }
+}
+
+
+void qp_event_handler(ib_async_event_rec_t *p_event)
+{
+
+ if (p_event->code == IB_AE_QP_APM)
+ {
+ struct ibsp_socket_info *socket_info = (struct
ibsp_socket_info *)p_event->context;
+ IBSP_PRINT_EXIT(TRACE_LEVEL_INFORMATION,
IBSP_DBG_APM,("Received an APM event\n"));
+ APMCallback(socket_info);
+ }
+}
+
+
+
+BOOL InitApmLib()
+{
+ IBSP_PRINT_EXIT(TRACE_LEVEL_INFORMATION,
IBSP_DBG_APM,("called\n"));
+
+ g_ibsp.apm_data.hEvent = CreateEvent(NULL, FALSE, FALSE,
NULL);
+ if (g_ibsp.apm_data.hEvent == NULL) {
+ IBSP_ERROR_EXIT( ("CreateEvent failed with error %d\n",
GetLastError()));
+ return FALSE;
+ }
+
+ g_ibsp.apm_data.hThread = CreateThread(
+ NULL, // Default security attributes
+ 0,
+ ApmThreadProc,
+ NULL,
+ 0,
+ NULL
+ );
+ if (g_ibsp.apm_data.hThread == NULL) {
+ IBSP_ERROR_EXIT( ("CreateThread failed with error %d\n",
GetLastError()));
+ CloseHandle(g_ibsp.apm_data.hEvent);
+ g_ibsp.apm_data.hEvent = NULL;
+ return FALSE;
+ }
+
+
+ return TRUE;
+
+
+
+}
+
+
+VOID ShutDownApmLib()
+{
+ DWORD dwRet;
+
+ if (g_ibsp.apm_data.hEvent== 0) {
+ // This means that we have failed to start our timer, not
much
+ // that we can do.
+ return;
+ }
+
+ g_ibsp.apm_data.ThreadExit = TRUE;
+ SetEvent(g_ibsp.apm_data.hEvent);
+
+ dwRet = WaitForSingleObject(g_ibsp.apm_data.hThread,
INFINITE);
+ CL_ASSERT(dwRet == WAIT_OBJECT_0);
+
+ dwRet = CloseHandle(g_ibsp.apm_data.hThread);
+ CL_ASSERT(dwRet != 0);
+
+ dwRet = CloseHandle(g_ibsp.apm_data.hEvent);
+ CL_ASSERT(dwRet != 0);
+}
+
Index: ibspproto.h
===================================================================
--- ibspproto.h (revision 4959)
+++ ibspproto.h (working copy)
@@ -304,4 +304,8 @@
return DestPortGuid ^ 0x300000000000000;
}
+void AL_API cm_apr_callback(
+ IN ib_cm_apr_rec_t *p_cm_apr_rec );
+
+void qp_event_handler(ib_async_event_rec_t *p_event);
Index: ibspstruct.h
===================================================================
--- ibspstruct.h (revision 4959)
+++ ibspstruct.h (working copy)
@@ -220,6 +220,15 @@
struct ibsp_hca *hca; /* HCA to which this cq belongs. */
};
+
+enum APM_STATE {
+ APM_ARMED,
+ APM_MIGRATED,
+ APM_LAP_SENT
+
+};
+
+
/* Structure representing the context information stored for
each
* socket created */
struct ibsp_socket_info
@@ -322,6 +331,10 @@
GUID identifier; /* Unique identifier */
DWORD dwProcessId;
} duplicate;
+ BOOL active_side; // Tell if we have started this call
+ enum APM_STATE apm_state;
+ UINT SuccesfulMigrations;
+ ib_net64_t dest_port_guid;
#ifdef IBSP_LOGGING
DataLogger SendDataLogger;
@@ -413,6 +426,13 @@
struct cq_thread_info *cq_tinfo;
};
+struct apm_data_t
+{
+ HANDLE hThread;
+ HANDLE hEvent;
+ BOOL ThreadExit;
+};
+
/* There is only one instance of that structure. */
struct ibspdll_globals
{
@@ -442,6 +462,8 @@
cl_fmap_t ip_map; /* list of all IP addresses supported by
all the ports. */
cl_spinlock_t ip_mutex;
+ struct apm_data_t apm_data;
+
#ifdef _DEBUG_
/* Statistics */
atomic32_t qp_num;
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.openfabrics.org/pipermail/ofw/attachments/20091018/d4de9691/attachment.html>
More information about the ofw
mailing list