[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