[ofw] patch: [WSD] Add APM failback support for WSD

Tzachi Dar tzachid at mellanox.co.il
Thu Oct 15 11:01:41 PDT 2009


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/20091015/587500ab/attachment.html>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: wsd_apm_failback.diff
Type: application/octet-stream
Size: 21206 bytes
Desc: wsd_apm_failback.diff
URL: <http://lists.openfabrics.org/pipermail/ofw/attachments/20091015/587500ab/attachment.obj>


More information about the ofw mailing list