Fix bug where failed ATS service registration would leave around stale handles
authorftillier <ftillier@ad392aa1-c5ef-ae45-8dd8-e69d62a5ef86>
Fri, 29 Jul 2005 05:50:41 +0000 (05:50 +0000)
committerftillier <ftillier@ad392aa1-c5ef-ae45-8dd8-e69d62a5ef86>
Fri, 29 Jul 2005 05:50:41 +0000 (05:50 +0000)
which could be freed upon cleanup, causing an access violation (dereferencing
freed memory).

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

ulp/ipoib/kernel/ipoib_adapter.h
ulp/ipoib/kernel/ipoib_driver.c

index c82572c..fd78643 100644 (file)
@@ -265,12 +265,25 @@ typedef struct _ipoib_adapter
 *********/\r
 \r
 \r
-typedef struct _net_address_item\r
+typedef struct _ats_reg\r
 {\r
-       /* This must be at the start of the structure */\r
-       cl_pool_item_t          pool_item;\r
        ipoib_adapter_t         *p_adapter;\r
        ib_reg_svc_handle_t     h_reg_svc;\r
+\r
+}      ats_reg_t;\r
+/*\r
+* FIELDS\r
+*      p_adapter\r
+*              Pointer to the adapter to which this address is assigned.\r
+*\r
+*      h_reg_svc\r
+*              Service registration handle.\r
+*********/\r
+\r
+\r
+typedef struct _net_address_item\r
+{\r
+       ats_reg_t                       *p_reg;\r
        union _net_address_item_address\r
        {\r
                ULONG                   as_ulong;\r
@@ -280,22 +293,22 @@ typedef struct _net_address_item
 }      net_address_item_t;\r
 /*\r
 * FIELDS\r
-*      pool_item\r
-*              Used to pool allocation of addresses and link the allocated addresses together\r
-*\r
-*      p_adapter\r
-*              Pointer to the adapter to which this address is assigned.\r
+*      p_reg\r
+*              Pointer to the ATS registration assigned to this address.\r
 *\r
 *      address\r
-*              Union representing the IP address as an unsigned long or as an array of bytes.\r
+*              Union representing the IP address as an unsigned long or as\r
+*              an array of bytes.\r
 *\r
 *      as_ulong\r
-*              The IP address represented as an unsigned long.  Windows stores IPs this way.\r
+*              The IP address represented as an unsigned long.  Windows stores\r
+*              IPs this way.\r
 *\r
 *      as_bytes\r
 *              The IP address represented as an array of bytes.\r
 *********/\r
 \r
+\r
 ib_api_status_t\r
 ipoib_create_adapter(\r
        IN              NDIS_HANDLE                     wrapper_config_context,\r
index 5ad31b2..38ec84e 100644 (file)
@@ -211,7 +211,7 @@ __ipoib_ats_reg_cb(
        IN                              ib_reg_svc_rec_t                        *p_reg_svc_rec );\r
 \r
 static void\r
-__ipoib_ats_unreg_cb(\r
+__ipoib_ats_dereg_cb(\r
        IN                              void                                            *context );\r
 \r
 static void\r
@@ -1901,10 +1901,18 @@ __ipoib_set_net_addr(
                                        p_addr_item->address.as_bytes[2],\r
                                        p_addr_item->address.as_bytes[3]));\r
 \r
-                       if( p_addr_item->h_reg_svc )\r
+                       if( p_addr_item->p_reg )\r
                        {\r
-                               p_adapter->p_ifc->dereg_svc( p_addr_item->h_reg_svc, NULL );\r
-                               p_addr_item->h_reg_svc = NULL;\r
+                               if( p_addr_item->p_reg->h_reg_svc )\r
+                               {\r
+                                       p_adapter->p_ifc->dereg_svc(\r
+                                               p_addr_item->p_reg->h_reg_svc, __ipoib_ats_dereg_cb );\r
+                               }\r
+                               else\r
+                               {\r
+                                       cl_free( p_addr_item->p_reg );\r
+                               }\r
+                               p_addr_item->p_reg = NULL;\r
                        }\r
                        p_addr_item->address.as_ulong = 0;\r
                }\r
@@ -1955,12 +1963,19 @@ __ipoib_set_net_addr(
                 * Copy the address information, but don't register yet - the port\r
                 * could be down.\r
                 */\r
-               p_addr_item->p_adapter = p_adapter;\r
-               if( p_addr_item->h_reg_svc )\r
+               if( p_addr_item->p_reg )\r
                {\r
                        /* If in use by some other address, deregister. */\r
-                       p_adapter->p_ifc->dereg_svc( p_addr_item->h_reg_svc, NULL );\r
-                       p_addr_item->h_reg_svc = NULL;\r
+                       if( p_addr_item->p_reg->h_reg_svc )\r
+                       {\r
+                               p_adapter->p_ifc->dereg_svc(\r
+                                       p_addr_item->p_reg->h_reg_svc, __ipoib_ats_dereg_cb );\r
+                       }\r
+                       else\r
+                       {\r
+                               cl_free( p_addr_item->p_reg );\r
+                       }\r
+                       p_addr_item->p_reg = NULL;\r
                }\r
                memcpy ((void *)&p_addr_item->address.as_ulong, (const void *)&p_ip_addr->in_addr, sizeof(ULONG) );\r
                IPOIB_TRACE( IPOIB_DBG_OID | IPOIB_DBG_INFO,\r
@@ -1980,10 +1995,18 @@ __ipoib_set_net_addr(
                        cl_vector_get_ptr( &p_adapter->ip_vector,\r
                        cl_vector_get_size( &p_adapter->ip_vector ) - 1 );\r
 \r
-               if( p_addr_item->h_reg_svc )\r
+               if( p_addr_item->p_reg )\r
                {\r
-                       p_adapter->p_ifc->dereg_svc( p_addr_item->h_reg_svc, NULL );\r
-                       p_addr_item->h_reg_svc = NULL;\r
+                       if( p_addr_item->p_reg->h_reg_svc )\r
+                       {\r
+                               p_adapter->p_ifc->dereg_svc(\r
+                                       p_addr_item->p_reg->h_reg_svc, __ipoib_ats_dereg_cb );\r
+                       }\r
+                       else\r
+                       {\r
+                               cl_free( p_addr_item->p_reg );\r
+                       }\r
+                       p_addr_item->p_reg = NULL;\r
                        p_addr_item->address.as_ulong = 0;\r
                }\r
 \r
@@ -2039,7 +2062,6 @@ ipoib_reg_addrs(
        ib_service.port_guid            = p_adapter->guids.port_guid;\r
        ib_service.timeout_ms           = DEFAULT_SA_TIMEOUT;\r
        ib_service.retry_cnt            = DEFAULT_SA_RETRIES;\r
-       ib_service.svc_context          = p_adapter;\r
 \r
        /* Can't set IB_FLAGS_SYNC here because I can't wait at dispatch */\r
        ib_service.flags                        = 0;\r
@@ -2062,9 +2084,17 @@ ipoib_reg_addrs(
                p_addr_item = (net_address_item_t*)\r
                        cl_vector_get_ptr(  &p_adapter->ip_vector, idx );\r
 \r
-               if( p_addr_item->h_reg_svc )\r
+               if( p_addr_item->p_reg )\r
                        continue;\r
 \r
+               p_addr_item->p_reg = cl_zalloc( sizeof(ats_reg_t) );\r
+               if( !p_addr_item->p_reg )\r
+                       break;\r
+\r
+               p_addr_item->p_reg->p_adapter = p_adapter;\r
+\r
+               ib_service.svc_context          = p_addr_item->p_reg;\r
+\r
                ib_service.svc_rec.service_id =\r
                        ATS_SERVICE_ID & CL_HTON64(0xFFFFFFFFFFFFFF00);\r
                /* ATS service IDs start at 0x10000CE100415453 */\r
@@ -2074,7 +2104,7 @@ ipoib_reg_addrs(
                        p_addr_item->address.as_bytes, IPV4_ADDR_SIZE );\r
 \r
                ib_status = p_adapter->p_ifc->reg_svc(\r
-                       p_adapter->h_al, &ib_service, &p_addr_item->h_reg_svc );\r
+                       p_adapter->h_al, &ib_service, &p_addr_item->p_reg->h_reg_svc );\r
                if( ib_status != IB_SUCCESS )\r
                {\r
                        if( ib_status == IB_INVALID_GUID )\r
@@ -2104,6 +2134,8 @@ ipoib_reg_addrs(
                                        p_adapter->p_ifc->get_err_str( ib_status )) );\r
                                p_adapter->hung = TRUE;\r
                        }\r
+                       cl_free( p_addr_item->p_reg );\r
+                       p_addr_item->p_reg = NULL;\r
                }\r
        }\r
 \r
@@ -2127,12 +2159,19 @@ __ipoib_dereg_addrs(
                p_addr_item = (net_address_item_t*)\r
                        cl_vector_get_ptr(  &p_adapter->ip_vector, idx );\r
 \r
-               if( !p_addr_item->h_reg_svc )\r
+               if( !p_addr_item->p_reg )\r
                        continue;\r
 \r
-               p_adapter->p_ifc->dereg_svc(\r
-                       p_addr_item->h_reg_svc, NULL );\r
-               p_addr_item->h_reg_svc = NULL;\r
+               if( p_addr_item->p_reg->h_reg_svc )\r
+               {\r
+                       p_adapter->p_ifc->dereg_svc(\r
+                               p_addr_item->p_reg->h_reg_svc, __ipoib_ats_dereg_cb );\r
+               }\r
+               else\r
+               {\r
+                       cl_free( p_addr_item->p_reg );\r
+               }\r
+               p_addr_item->p_reg = NULL;\r
        }\r
 \r
        IPOIB_EXIT( IPOIB_DBG_OID );\r
@@ -2143,7 +2182,7 @@ static void
 __ipoib_ats_reg_cb(\r
        IN                              ib_reg_svc_rec_t                        *p_reg_svc_rec )\r
 {\r
-       ipoib_adapter_t                 * p_adapter;\r
+       ats_reg_t                               *p_reg;\r
        uint8_t                                 port_num;\r
 \r
        IPOIB_ENTER( IPOIB_DBG_OID );\r
@@ -2151,8 +2190,10 @@ __ipoib_ats_reg_cb(
        CL_ASSERT( p_reg_svc_rec );\r
        CL_ASSERT( p_reg_svc_rec->svc_context );\r
 \r
-       p_adapter = (ipoib_adapter_t* __ptr64)p_reg_svc_rec->svc_context;\r
-       port_num = IPOIB_ADAPTER_GET_PORT_NUM( p_adapter );\r
+       p_reg = (ats_reg_t* __ptr64)p_reg_svc_rec->svc_context;\r
+       port_num = IPOIB_ADAPTER_GET_PORT_NUM( p_reg->p_adapter );\r
+\r
+       cl_obj_lock( &p_reg->p_adapter->obj );\r
 \r
        if( p_reg_svc_rec->req_status == IB_SUCCESS &&\r
                !p_reg_svc_rec->resp_status )\r
@@ -2176,9 +2217,20 @@ __ipoib_ats_reg_cb(
                                          p_reg_svc_rec->svc_rec.service_data8[ATS_IPV4_OFFSET+1],\r
                                          p_reg_svc_rec->svc_rec.service_data8[ATS_IPV4_OFFSET+2],\r
                                          p_reg_svc_rec->svc_rec.service_data8[ATS_IPV4_OFFSET+3],\r
-                                         p_adapter->p_ifc->get_err_str( p_reg_svc_rec->resp_status )) );\r
-               p_adapter->hung = TRUE;\r
+                                         p_reg->p_adapter->p_ifc->get_err_str( p_reg_svc_rec->resp_status )) );\r
+               p_reg->p_adapter->hung = TRUE;\r
+               p_reg->h_reg_svc = NULL;\r
        }\r
 \r
+       cl_obj_unlock( &p_reg->p_adapter->obj );\r
+\r
        IPOIB_EXIT( IPOIB_DBG_OID );\r
 }\r
+\r
+\r
+static void\r
+__ipoib_ats_dereg_cb(\r
+       IN                              void                                            *context )\r
+{\r
+       cl_free( context );\r
+}\r