Applied on 2488.
 
Thanks
Tzachi

________________________________

        From: [email protected]
[mailto:[email protected]] On Behalf Of Tzachi Dar
        Sent: Thursday, October 15, 2009 8:02 PM
        To: [email protected]
        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;
        

_______________________________________________
ofw mailing list
[email protected]
http://lists.openfabrics.org/cgi-bin/mailman/listinfo/ofw

Reply via email to