]> git.openfabrics.org - ~shefty/rdma-win.git/commitdiff
Changed how SA requests are handled from user-mode. Synchronous requests
authorftillier <ftillier@ad392aa1-c5ef-ae45-8dd8-e69d62a5ef86>
Wed, 6 Jul 2005 18:59:19 +0000 (18:59 +0000)
committerftillier <ftillier@ad392aa1-c5ef-ae45-8dd8-e69d62a5ef86>
Wed, 6 Jul 2005 18:59:19 +0000 (18:59 +0000)
now use synchronous IOCTL processing rather than blocking in user-mode and
waiting for the IOCTL completion callback.  This eliminates the potential
for deadlocks resulting from clients making synchronous SA queries from
a callback thread context.

git-svn-id: svn://openib.tc.cornell.edu/gen1@23 ad392aa1-c5ef-ae45-8dd8-e69d62a5ef86

branches/fab_cm_branch/core/al/al_mcast.c
branches/fab_cm_branch/core/al/al_query.c
branches/fab_cm_branch/core/al/al_query.h
branches/fab_cm_branch/core/al/al_reg_svc.c
branches/fab_cm_branch/core/al/al_reg_svc.h
branches/fab_cm_branch/core/al/kernel/al_proxy_subnet.c
branches/fab_cm_branch/core/al/kernel/al_sa_req.c
branches/fab_cm_branch/core/al/user/ual_sa_req.c

index 0111a2371437a35b11f0c93a2a09564189775ab3..14cb159b3ba01a76b4f4403b96144dc6c2464c6c 100644 (file)
@@ -264,7 +264,7 @@ __destroying_mcast(
 \r
        ref_al_obj( &h_mcast->obj );\r
        status = al_send_sa_req(\r
-               &h_mcast->sa_dereg_req, h_mcast->port_guid, 500, 0, &sa_mad_data );\r
+               &h_mcast->sa_dereg_req, h_mcast->port_guid, 500, 0, &sa_mad_data, 0 );\r
        if( status != IB_SUCCESS )\r
                deref_al_obj( &h_mcast->obj );\r
 \r
@@ -395,7 +395,7 @@ send_join(
 \r
        p_mcast->state = SA_REG_STARTING;\r
        status = al_send_sa_req( &p_mcast->sa_reg_req, p_mcast->port_guid,\r
-               p_mcast_req->timeout_ms, p_mcast_req->retry_cnt, &sa_mad_data );\r
+               p_mcast_req->timeout_ms, p_mcast_req->retry_cnt, &sa_mad_data, 0 );\r
 \r
        CL_EXIT( AL_DBG_MCAST, g_al_dbg_lvl );\r
        return status;\r
index 00c6c6f4d02d76764a27757c8e690fb3c06ba18c..f6fd620d0313d9e180fd09511fb47273391f1e66 100644 (file)
 static ib_api_status_t\r
 query_sa(\r
        IN                              al_query_t                                      *p_query,\r
-       IN              const   ib_query_req_t* const           p_query_req );\r
+       IN              const   ib_query_req_t* const           p_query_req,\r
+       IN              const   ib_al_flags_t                           flags );\r
 \r
 void\r
 query_req_cb(\r
        IN                              al_sa_req_t                                     *p_sa_req,\r
        IN                              ib_mad_element_t                        *p_mad_response );\r
 \r
-static void\r
-__free_query(\r
-       IN      OUT                     al_query_t                                      *p_query );\r
-\r
-\r
 \r
 ib_api_status_t\r
 ib_query(\r
@@ -69,8 +65,6 @@ ib_query(
 {\r
        al_query_t                              *p_query;\r
        ib_api_status_t                 status;\r
-       cl_status_t                             cl_status;\r
-       boolean_t                               sync;\r
 \r
        CL_ENTER( AL_DBG_QUERY, g_al_dbg_lvl );\r
 \r
@@ -98,23 +92,6 @@ ib_query(
                return IB_INSUFFICIENT_MEMORY;\r
        }\r
 \r
-       /* Check for synchronous operation. */\r
-       p_query->flags = p_query_req->flags;\r
-       cl_event_construct( &p_query->event );\r
-       sync = ( (p_query->flags & IB_FLAGS_SYNC) == IB_FLAGS_SYNC );\r
-       if( sync )\r
-       {\r
-               cl_status = cl_event_init( &p_query->event, TRUE );\r
-               if( cl_status != CL_SUCCESS )\r
-               {\r
-                       status = ib_convert_cl_status( cl_status );\r
-                       CL_TRACE_EXIT( AL_DBG_ERROR, g_al_dbg_lvl,\r
-                               ("cl_init_event failed: %s\n", ib_get_err_str(status) ) );\r
-                       __free_query( p_query );\r
-                       return status;\r
-               }\r
-       }\r
-\r
        /* Copy the query context information. */\r
        p_query->sa_req.pfn_sa_req_cb = query_req_cb;\r
        p_query->sa_req.user_context = p_query_req->query_context;\r
@@ -124,38 +101,26 @@ ib_query(
        /* Track the query with the AL instance. */\r
        al_insert_query( h_al, p_query );\r
 \r
+       /*\r
+        * Set the query handle now so that users that do sync queries\r
+        * can also cancel the queries.\r
+        */\r
+       if( ph_query )\r
+               *ph_query = p_query;\r
+\r
        /* Issue the MAD to the SA. */\r
-       status = query_sa( p_query, (ib_query_req_t*)p_query_req );\r
-       if( status == IB_SUCCESS )\r
-       {\r
-               /*\r
-                * Set the query handle now so that users that do sync queries\r
-                * can also cancel the queries.\r
-                */\r
-               if( ph_query )\r
-                       *ph_query = p_query;\r
-               /* If synchronous, wait for the completion. */\r
-               if( sync )\r
-               {\r
-                       do\r
-                       {\r
-                               cl_status = cl_event_wait_on(\r
-                                       &p_query->event, EVENT_NO_TIMEOUT, AL_WAIT_ALERTABLE );\r
-                       } while( cl_status == CL_NOT_DONE );\r
-                       CL_ASSERT( cl_status == CL_SUCCESS );\r
-               }\r
-       }\r
-       else if( status != IB_INVALID_GUID )\r
+       status = query_sa( p_query, p_query_req, p_query_req->flags );\r
+       if( status != IB_SUCCESS && status != IB_INVALID_GUID )\r
        {\r
                CL_TRACE( AL_DBG_ERROR, g_al_dbg_lvl,\r
                        ("query_sa failed: %s\n", ib_get_err_str(status) ) );\r
        }\r
 \r
        /* Cleanup from issuing the query if it failed or was synchronous. */\r
-       if( ( status != IB_SUCCESS ) || sync )\r
+       if( status != IB_SUCCESS )\r
        {\r
                al_remove_query( p_query );\r
-               __free_query( p_query );\r
+               cl_free( p_query );\r
        }\r
 \r
        CL_EXIT( AL_DBG_QUERY, g_al_dbg_lvl );\r
@@ -170,7 +135,8 @@ ib_query(
 static ib_api_status_t\r
 query_sa(\r
        IN                              al_query_t                                      *p_query,\r
-       IN              const   ib_query_req_t* const           p_query_req )\r
+       IN              const   ib_query_req_t* const           p_query_req,\r
+       IN              const   ib_al_flags_t                           flags )\r
 {\r
        ib_user_query_t                         sa_req, *p_sa_req;\r
        union _query_sa_recs\r
@@ -329,7 +295,7 @@ query_sa(
 \r
        status = al_send_sa_req(\r
                &p_query->sa_req, p_query_req->port_guid, p_query_req->timeout_ms,\r
-               p_query_req->retry_cnt, p_sa_req );\r
+               p_query_req->retry_cnt, p_sa_req, flags );\r
        CL_EXIT( AL_DBG_QUERY, g_al_dbg_lvl );\r
        return status;\r
 }\r
@@ -389,29 +355,9 @@ query_req_cb(
        /* Notify the user of the result. */\r
        p_query->pfn_query_cb( &query_rec );\r
 \r
-       /* Check for synchronous operation. */\r
-       if( (p_query->flags & IB_FLAGS_SYNC) == IB_FLAGS_SYNC )\r
-       {\r
-               cl_event_signal( &p_query->event );\r
-       }\r
-       else\r
-       {\r
-               /* Cleanup from issuing the query. */\r
-               al_remove_query( p_query );\r
-               __free_query( p_query );\r
-       }\r
+       /* Cleanup from issuing the query. */\r
+       al_remove_query( p_query );\r
+       cl_free( p_query );\r
 \r
        CL_EXIT( AL_DBG_QUERY, g_al_dbg_lvl );\r
 }\r
-\r
-\r
-\r
-static void\r
-__free_query(\r
-       IN      OUT                     al_query_t                                      *p_query )\r
-{\r
-       CL_ASSERT( p_query );\r
-\r
-       cl_event_destroy( &p_query->event );\r
-       cl_free( p_query );\r
-}\r
index 31b58905525a1673bc0fae54fb14494f1791dfa6..9186e9ee49f10c931a56c73ad84df72347748dd6 100644 (file)
@@ -92,6 +92,7 @@ typedef struct _al_sa_req
        sa_req_svc_t                            *p_sa_req_svc;  /* For cancellation */\r
        ib_mad_element_t                        *p_mad_response;\r
        ib_mad_element_t                        *p_mad_request; /* For cancellation */\r
+       KEVENT                                          *p_sync_event;\r
 #else  /* defined( CL_KERNEL ) */\r
        uint64_t                                        hdl;\r
        ual_send_sa_req_ioctl_t         ioctl;\r
@@ -108,10 +109,6 @@ typedef struct _al_query
 {\r
        al_sa_req_t                                     sa_req;         /* Must be first. */\r
 \r
-       /* Used to perform synchronous requests. */\r
-       ib_al_flags_t                           flags;\r
-       cl_event_t                                      event;\r
-\r
        ib_al_handle_t                          h_al;\r
        ib_pfn_query_cb_t                       pfn_query_cb;\r
        ib_query_type_t                         query_type;\r
@@ -130,7 +127,8 @@ al_send_sa_req(
        IN              const   net64_t                                         port_guid,\r
        IN              const   uint32_t                                        timeout_ms,\r
        IN              const   uint32_t                                        retry_cnt,\r
-       IN              const   ib_user_query_t* const          p_sa_req_data );\r
+       IN              const   ib_user_query_t* const          p_sa_req_data,\r
+       IN              const   ib_al_flags_t                           flags );\r
 \r
 #if defined( CL_KERNEL )\r
 static __inline void\r
index 2f16f106767641841cf43cc53c89c144e08789db..2dd0912395c550fa6922286c68e487bc0e67031e 100644 (file)
@@ -47,12 +47,16 @@ __dereg_svc_cb(
 {\r
        ib_reg_svc_handle_t             h_reg_svc;\r
 \r
-       h_reg_svc = PARENT_STRUCT ( p_sa_req, al_reg_svc_t, sa_req );\r
+       /*\r
+        * Note that we come into this callback with a reference\r
+        * on the registration object.\r
+        */\r
+       h_reg_svc = PARENT_STRUCT( p_sa_req, al_reg_svc_t, sa_req );\r
 \r
        if( p_mad_response )\r
                ib_put_mad( p_mad_response );\r
 \r
-       deref_al_obj( &h_reg_svc->obj );\r
+       h_reg_svc->obj.pfn_destroy( &h_reg_svc->obj, NULL );\r
 }\r
 \r
 \r
@@ -76,7 +80,7 @@ __sa_dereg_svc(
        sa_mad_data.comp_mask = ~CL_CONST64(0);\r
 \r
        if( al_send_sa_req( &h_reg_svc->sa_req, h_reg_svc->port_guid,\r
-               500, 0, &sa_mad_data ) != IB_SUCCESS )\r
+               500, 0, &sa_mad_data, 0 ) != IB_SUCCESS )\r
        {\r
                /* Cleanup from the registration. */\r
                deref_al_obj( &h_reg_svc->obj );\r
@@ -153,12 +157,15 @@ reg_svc_req_cb(
 \r
        h_reg_svc->pfn_reg_svc_cb( &reg_svc_rec );\r
 \r
-       /* Check for synchronous operation. */\r
-       if( (h_reg_svc->flags & IB_FLAGS_SYNC) == IB_FLAGS_SYNC )\r
-               cl_event_signal( &h_reg_svc->event );\r
-\r
-       /* Release the reference taken when issuing the request. */\r
-       deref_al_obj( &h_reg_svc->obj );\r
+       if( p_sa_req->status != IB_SUCCESS )\r
+       {\r
+               h_reg_svc->obj.pfn_destroy( &h_reg_svc->obj, NULL );\r
+       }\r
+       else\r
+       {\r
+               /* Release the reference taken when issuing the request. */\r
+               deref_al_obj( &h_reg_svc->obj );\r
+       }\r
 }\r
 \r
 \r
@@ -211,7 +218,6 @@ __free_sa_reg(
        h_sa_reg = PARENT_STRUCT( p_obj, al_reg_svc_t, obj );\r
 \r
        destroy_al_obj( p_obj );\r
-       cl_event_destroy( &h_sa_reg->event );\r
        cl_free( h_sa_reg );\r
 \r
        AL_EXIT( AL_DBG_SA_REQ );\r
@@ -224,7 +230,6 @@ sa_reg_svc(
        IN              const   ib_reg_svc_req_t* const         p_reg_svc_req )\r
 {\r
        ib_user_query_t                 sa_mad_data;\r
-       ib_api_status_t                 status;\r
 \r
        /* Set the request information. */\r
        h_reg_svc->sa_req.pfn_sa_req_cb = reg_svc_req_cb;\r
@@ -238,9 +243,9 @@ sa_reg_svc(
        sa_mad_data.comp_mask = p_reg_svc_req->svc_data_mask;\r
        sa_mad_data.p_attr = &h_reg_svc->svc_rec;\r
 \r
-       status = al_send_sa_req( &h_reg_svc->sa_req, h_reg_svc->port_guid,\r
-               p_reg_svc_req->timeout_ms, p_reg_svc_req->retry_cnt, &sa_mad_data );\r
-       return status;\r
+       return al_send_sa_req( &h_reg_svc->sa_req, h_reg_svc->port_guid,\r
+               p_reg_svc_req->timeout_ms, p_reg_svc_req->retry_cnt, &sa_mad_data,\r
+               p_reg_svc_req->flags );\r
 }\r
 \r
 \r
@@ -252,7 +257,6 @@ ib_reg_svc(
 {\r
        ib_reg_svc_handle_t             h_sa_reg = NULL;\r
        ib_api_status_t                 status;\r
-       cl_status_t                             cl_status;\r
 \r
        AL_ENTER( AL_DBG_SA_REQ );\r
 \r
@@ -275,8 +279,6 @@ ib_reg_svc(
                return IB_INSUFFICIENT_MEMORY;\r
        }\r
 \r
-       h_sa_reg->flags = p_reg_svc_req->flags;\r
-       cl_event_construct( &h_sa_reg->event );\r
        construct_al_obj( &h_sa_reg->obj, AL_OBJ_TYPE_H_SA_REG );\r
 \r
        status = init_al_obj( &h_sa_reg->obj, p_reg_svc_req->svc_context, TRUE,\r
@@ -299,20 +301,6 @@ ib_reg_svc(
                return status;\r
        }\r
 \r
-       /* Check for synchronous operation. */\r
-       if( h_sa_reg->flags & IB_FLAGS_SYNC )\r
-       {\r
-               cl_status = cl_event_init( &h_sa_reg->event, TRUE );\r
-               if( cl_status != CL_SUCCESS )\r
-               {\r
-                       status = ib_convert_cl_status( cl_status );\r
-                       AL_TRACE_EXIT( AL_DBG_ERROR,\r
-                               ("cl_init_event failed: %s\n", ib_get_err_str(status)) );\r
-                       h_sa_reg->obj.pfn_destroy( &h_sa_reg->obj, NULL );\r
-                       return status;\r
-               }\r
-       }\r
-\r
        /* Store the port GUID on which to issue the request. */\r
        h_sa_reg->port_guid = p_reg_svc_req->port_guid;\r
 \r
@@ -325,38 +313,18 @@ ib_reg_svc(
 \r
        /* Issue the MAD to the SA. */\r
        status = sa_reg_svc( h_sa_reg, p_reg_svc_req );\r
-       if( status == IB_SUCCESS )\r
-       {\r
-               /* If synchronous, wait for the completion. */\r
-               if( h_sa_reg->flags & IB_FLAGS_SYNC )\r
-               {\r
-                       do\r
-                       {\r
-                               cl_status = cl_event_wait_on(\r
-                                       &h_sa_reg->event, EVENT_NO_TIMEOUT, AL_WAIT_ALERTABLE );\r
-                       } while( cl_status == CL_NOT_DONE );\r
-                       CL_ASSERT( cl_status == CL_SUCCESS );\r
-\r
-                       /* Cleanup from issuing the request if it failed. */\r
-                       if( h_sa_reg->state == SA_REG_ERROR )\r
-                       {\r
-                               status = h_sa_reg->req_status;\r
-                               /* The callback released the reference from init_al_obj. */\r
-                               ref_al_obj( &h_sa_reg->obj );\r
-                       }\r
-               }\r
-       }\r
-       else\r
+       if( status != IB_SUCCESS )\r
        {\r
                AL_TRACE( AL_DBG_ERROR,\r
                        ("sa_reg_svc failed: %s\n", ib_get_err_str(status) ) );\r
                h_sa_reg->state = SA_REG_ERROR;\r
-       }\r
 \r
-       if( status != IB_SUCCESS )\r
                h_sa_reg->obj.pfn_destroy( &h_sa_reg->obj, NULL );\r
+       }\r
        else\r
+       {\r
                *ph_reg_svc = h_sa_reg;\r
+       }\r
 \r
        AL_EXIT( AL_DBG_SA_REQ );\r
        return status;\r
index c2d61c0be902b96ad0d5eb86e9c43425025e9bad..56f6dbc5a032f74725f56b1d49aa19ca0b3b4237 100644 (file)
@@ -51,10 +51,6 @@ typedef struct _al_reg_svc
        /* Additional status information returned in the registration response. */\r
        ib_net16_t                                      resp_status;\r
 \r
-       /* Used to perform synchronous requests. */\r
-       ib_al_flags_t                           flags;\r
-       cl_event_t                                      event;\r
-\r
        al_sa_reg_state_t                       state;\r
        ib_pfn_reg_svc_cb_t                     pfn_reg_svc_cb;\r
 \r
index 94b4e689308fb9c866682a538b9b364f782d22b8..73eddb1ab44db91a45f081e6f934abb7ad4e65a7 100644 (file)
@@ -214,7 +214,12 @@ proxy_send_sa_req(
        p_context = p_open_context;\r
 \r
        p_io_stack = IoGetCurrentIrpStackLocation( h_ioctl );\r
-       if( (uintn_t)p_io_stack->FileObject->FsContext2 != AL_OBJ_TYPE_SA_REQ_SVC )\r
+       /*\r
+        * We support SA requests coming in either through the main file object\r
+        * or the async file handle.\r
+        */\r
+       if( p_io_stack->FileObject->FsContext2 &&\r
+               (uintn_t)p_io_stack->FileObject->FsContext2 != AL_OBJ_TYPE_SA_REQ_SVC )\r
        {\r
                AL_TRACE_EXIT( AL_DBG_ERROR,\r
                        ("Invalid file object type for request: %d\n",\r
@@ -279,9 +284,14 @@ proxy_send_sa_req(
        /* Synchronize with callbacks. */\r
        cl_spinlock_acquire( &p_context->h_al->obj.lock );\r
 \r
+       /*\r
+        * We never pass the user-mode flag when sending SA requests - the\r
+        * I/O manager will perform all synchronization to make this IRP sync\r
+        * if it needs to.\r
+        */\r
        ib_status = al_send_sa_req( p_sa_req, p_ioctl->in.port_guid,\r
                p_ioctl->in.timeout_ms, p_ioctl->in.retry_cnt,\r
-               &p_ioctl->in.sa_req );\r
+               &p_ioctl->in.sa_req, 0 );\r
        if( ib_status == IB_SUCCESS )\r
        {\r
                /* Hold a reference on the proxy context until the request completes. */\r
index b4ed77b421f4fb4c2356f65fe0ad80cc2b453490..6671f5ba931ade24c9bacc4e05f433a18209dec9 100644 (file)
@@ -588,16 +588,35 @@ al_send_sa_req(
        IN              const   net64_t                                         port_guid,\r
        IN              const   uint32_t                                        timeout_ms,\r
        IN              const   uint32_t                                        retry_cnt,\r
-       IN              const   ib_user_query_t* const          p_sa_req_data )\r
+       IN              const   ib_user_query_t* const          p_sa_req_data,\r
+       IN              const   ib_al_flags_t                           flags )\r
 {\r
        ib_api_status_t                 status;\r
        sa_req_svc_t                    *p_sa_req_svc;\r
        ib_mad_element_t                *p_mad_request;\r
        ib_mad_t                                *p_mad_hdr;\r
        ib_sa_mad_t                             *p_sa_mad;\r
+       KEVENT                                  event;\r
 \r
        CL_ENTER( AL_DBG_SA_REQ, g_al_dbg_lvl );\r
-       \r
+\r
+       if( flags & IB_FLAGS_SYNC )\r
+       {\r
+               if( !cl_is_blockable() )\r
+               {\r
+                       AL_TRACE_EXIT( AL_DBG_ERROR,\r
+                               ("Thread context not blockable\n") );\r
+                       return IB_INVALID_SETTING;\r
+               }\r
+\r
+               KeInitializeEvent( &event, NotificationEvent, FALSE );\r
+               p_sa_req->p_sync_event = &event;\r
+       }\r
+       else\r
+       {\r
+               p_sa_req->p_sync_event = NULL;\r
+       }\r
+\r
        /* Locate the sa_req service to issue the sa_req on. */\r
        p_sa_req->p_sa_req_svc = acquire_sa_req_svc( port_guid );\r
        if( !p_sa_req->p_sa_req_svc )\r
@@ -662,6 +681,11 @@ al_send_sa_req(
                ib_put_mad( p_mad_request );\r
                deref_al_obj( &p_sa_req->p_sa_req_svc->obj );\r
        }\r
+       else if( flags & IB_FLAGS_SYNC )\r
+       {\r
+               /* Wait for the MAD completion. */\r
+               KeWaitForSingleObject( &event, Executive, KernelMode, FALSE, NULL );\r
+       }\r
 \r
        CL_EXIT( AL_DBG_SA_REQ, g_al_dbg_lvl );\r
        return status;\r
@@ -680,6 +704,7 @@ sa_req_send_comp_cb(
 {\r
        al_sa_req_t                     *p_sa_req;\r
        sa_req_svc_t            *p_sa_req_svc;\r
+       KEVENT                          *p_sync_event;\r
 \r
        CL_ENTER( AL_DBG_SA_REQ, g_al_dbg_lvl );\r
 \r
@@ -698,9 +723,12 @@ sa_req_send_comp_cb(
 \r
                p_sa_req = p_request_mad->send_context1;\r
                p_sa_req_svc = p_sa_req->p_sa_req_svc;\r
+               p_sync_event = p_sa_req->p_sync_event;\r
 \r
                p_sa_req->status = convert_wc_status( p_request_mad->status );\r
                p_sa_req->pfn_sa_req_cb( p_sa_req, NULL );\r
+               if( p_sync_event )\r
+                       KeSetEvent( p_sync_event, 0, FALSE );\r
                deref_al_obj( &p_sa_req_svc->obj );\r
        }\r
 \r
@@ -724,6 +752,7 @@ sa_req_recv_comp_cb(
        al_sa_req_t                     *p_sa_req;\r
        sa_req_svc_t            *p_sa_req_svc;\r
        ib_sa_mad_t                     *p_sa_mad;\r
+       KEVENT                          *p_sync_event;\r
 \r
        CL_ENTER( AL_DBG_SA_REQ, g_al_dbg_lvl );\r
 \r
@@ -732,6 +761,7 @@ sa_req_recv_comp_cb(
 \r
        p_sa_req = p_mad_response->send_context1;\r
        p_sa_req_svc = p_sa_req->p_sa_req_svc;\r
+       p_sync_event = p_sa_req->p_sync_event;\r
 \r
        //*** check for SA redirection...\r
 \r
@@ -745,6 +775,8 @@ sa_req_recv_comp_cb(
        /* Notify the requestor of the result. */\r
        CL_TRACE( AL_DBG_SA_REQ, g_al_dbg_lvl, ("notifying user\n") );\r
        p_sa_req->pfn_sa_req_cb( p_sa_req, p_mad_response );\r
+       if( p_sync_event )\r
+               KeSetEvent( p_sync_event, 0, FALSE );\r
        deref_al_obj( &p_sa_req_svc->obj );\r
 \r
        CL_EXIT( AL_DBG_SA_REQ, g_al_dbg_lvl );\r
index 4a989d0d9f089af1debf8a1b91f4d8ef6fca277f..1450d66cd532715f0c7aaf6d36e0f9416bff2825 100644 (file)
@@ -161,16 +161,18 @@ free_sa_req_mgr(
 }\r
 \r
 \r
-\r
 ib_api_status_t\r
 al_send_sa_req(\r
        IN                              al_sa_req_t                                     *p_sa_req,\r
        IN              const   net64_t                                         port_guid,\r
        IN              const   uint32_t                                        timeout_ms,\r
        IN              const   uint32_t                                        retry_cnt,\r
-       IN              const   ib_user_query_t* const          p_sa_req_data )\r
+       IN              const   ib_user_query_t* const          p_sa_req_data,\r
+       IN              const   ib_al_flags_t                           flags )\r
 {\r
        ib_api_status_t                 status;\r
+       HANDLE                                  h_dev;\r
+       DWORD                                   ret_bytes;\r
 \r
        AL_ENTER( AL_DBG_QUERY );\r
 \r
@@ -190,7 +192,12 @@ al_send_sa_req(
        p_sa_req->ioctl.in.ph_sa_req = &p_sa_req->hdl;\r
        p_sa_req->ioctl.in.p_status = &p_sa_req->status;\r
 \r
-       if( !DeviceIoControl( gp_sa_req_mgr->h_sa_dev, UAL_SEND_SA_REQ,\r
+       if( flags & IB_FLAGS_SYNC )\r
+               h_dev = g_al_device;\r
+       else\r
+               h_dev = gp_sa_req_mgr->h_sa_dev;\r
+\r
+       if( !DeviceIoControl( h_dev, UAL_SEND_SA_REQ,\r
                &p_sa_req->ioctl.in, sizeof(p_sa_req->ioctl.in),\r
                &p_sa_req->ioctl.out, sizeof(p_sa_req->ioctl.out),\r
                NULL, &p_sa_req->ov ) )\r
@@ -208,8 +215,18 @@ al_send_sa_req(
        }\r
        else\r
        {\r
-               CL_ASSERT( GetLastError() == ERROR_IO_PENDING );\r
-               status = IB_ERROR;\r
+               /* Completed synchronously. */\r
+               if( GetOverlappedResult( h_dev, &p_sa_req->ov, &ret_bytes, FALSE ) )\r
+               {\r
+                       status = IB_SUCCESS;\r
+                       /* Process the completion. */\r
+                       sa_req_cb( 0, ret_bytes, &p_sa_req->ov );\r
+               }\r
+               else\r
+               {\r
+                       sa_req_cb( GetLastError(), 0, &p_sa_req->ov );\r
+                       status = IB_ERROR;\r
+               }\r
        }\r
 \r
        AL_EXIT( AL_DBG_QUERY );\r
@@ -217,7 +234,6 @@ al_send_sa_req(
 }\r
 \r
 \r
-\r
 void CALLBACK\r
 sa_req_cb(\r
        IN                              DWORD                                           error_code,\r