]> git.openfabrics.org - ~shefty/rdma-win.git/commitdiff
[IPoIB] Avoid the SM (2/4)
authorleonidk <leonidk@ad392aa1-c5ef-ae45-8dd8-e69d62a5ef86>
Wed, 24 Sep 2008 19:22:55 +0000 (19:22 +0000)
committerleonidk <leonidk@ad392aa1-c5ef-ae45-8dd8-e69d62a5ef86>
Wed, 24 Sep 2008 19:22:55 +0000 (19:22 +0000)
This patch adds a new IOCTL to IPoIB for converting a destination Ethernet MAC address to a path record.  The path records is created using information from the broadcast group and previous work completions.

The limitations of this patch is that the rate is that of the broadcast group, which in a mixed rate fabric (SDR/DDR/QDR) will result in suboptimal data transfer rates.

Signed-off-by: Fab Tillier <ftillier@microsoft.com>
git-svn-id: svn://openib.tc.cornell.edu/gen1@1611 ad392aa1-c5ef-ae45-8dd8-e69d62a5ef86

branches/WOF2-0/trunk/inc/iba/ib_at_ioctl.h
branches/WOF2-0/trunk/ulp/ipoib/kernel/ipoib_ibat.c
branches/WOF2-0/trunk/ulp/ipoib/kernel/ipoib_port.c
branches/WOF2-0/trunk/ulp/ipoib/kernel/ipoib_port.h

index fd12699e97c813c28eef03c5696347a20bb51425..a3df636df39acdee6aded52dcaa0589e8529c325 100644 (file)
@@ -146,6 +146,24 @@ typedef struct _IOCTL_IBAT_IP_TO_PORT_OUT
 } IOCTL_IBAT_IP_TO_PORT_OUT;\r
 \r
 \r
+/** This IRP is used to convert a remote MAC addresses to a remote GID */\r
+#define        IOCTL_IBAT_MAC_TO_PATH IOCTL_IBAT( 5 )\r
+\r
+typedef struct _IOCTL_IBAT_MAC_TO_PATH_IN\r
+{\r
+       ULONG                           Version;\r
+       UINT64                          PortGuid;\r
+       UCHAR                           DestMac[IBAT_MAC_LEN];\r
+\r
+} IOCTL_IBAT_MAC_TO_PATH_IN;\r
+\r
+typedef struct _IOCTL_IBAT_MAC_TO_PATH_OUT\r
+{\r
+       ib_path_rec_t           Path;\r
+\r
+} IOCTL_IBAT_MAC_TO_PATH_OUT;\r
+\r
+\r
 #define        IBAT_DEV_NAME   L"\\Device\\ibat"\r
 #define        IBAT_DOS_DEV_NAME L"\\DosDevices\\Global\\ibat"\r
 #define        IBAT_WIN32_NAME L"\\\\.\\ibat"\r
index 55ef84c1dda5b4898eea134a99812a46d3172da8..01fc02a83ce1a1d39837d041db22597a63300943 100644 (file)
@@ -328,6 +328,80 @@ __ibat_mac_to_gid(
 }\r
 \r
 \r
+static NTSTATUS\r
+__ibat_mac_to_path(\r
+       IN                              IRP                                                     *pIrp,\r
+       IN                              IO_STACK_LOCATION                       *pIoStack )\r
+{\r
+       NTSTATUS                                        status = STATUS_INVALID_PARAMETER;\r
+       IOCTL_IBAT_MAC_TO_PATH_IN       *pIn;\r
+       IOCTL_IBAT_MAC_TO_PATH_OUT      *pOut;\r
+       KLOCK_QUEUE_HANDLE                      hdl;\r
+       cl_list_item_t                          *pItem;\r
+       ipoib_adapter_t                         *pAdapter;\r
+\r
+       IPOIB_ENTER(IPOIB_DBG_IOCTL);\r
+\r
+       if( pIoStack->Parameters.DeviceIoControl.InputBufferLength !=\r
+               sizeof(IOCTL_IBAT_MAC_TO_PATH_IN) )\r
+       {\r
+               IPOIB_PRINT_EXIT( TRACE_LEVEL_ERROR, IPOIB_DBG_ERROR,\r
+                       ("Invalid input buffer size.\n") );\r
+               return STATUS_INVALID_PARAMETER;\r
+       }\r
+       \r
+       if( pIoStack->Parameters.DeviceIoControl.OutputBufferLength !=\r
+               sizeof(IOCTL_IBAT_MAC_TO_PATH_OUT) )\r
+       {\r
+               IPOIB_PRINT_EXIT( TRACE_LEVEL_ERROR, IPOIB_DBG_ERROR,\r
+                       ("Invalid output buffer size.\n") );\r
+               return STATUS_INVALID_PARAMETER;\r
+       }\r
+\r
+       pIn = pIrp->AssociatedIrp.SystemBuffer;\r
+       pOut = pIrp->AssociatedIrp.SystemBuffer;\r
+\r
+       if( pIn->Version != IBAT_IOCTL_VERSION )\r
+       {\r
+               IPOIB_PRINT_EXIT( TRACE_LEVEL_ERROR, IPOIB_DBG_ERROR,\r
+                       ("Invalid version.\n") );\r
+               return STATUS_INVALID_PARAMETER;\r
+       }\r
+\r
+       KeAcquireInStackQueuedSpinLock( &g_ipoib.lock, &hdl );\r
+\r
+       for( pItem = cl_qlist_head( &g_ipoib.adapter_list );\r
+               pItem != cl_qlist_end( &g_ipoib.adapter_list );\r
+               pItem = cl_qlist_next( pItem ) )\r
+       {\r
+               pAdapter = CONTAINING_RECORD( pItem, ipoib_adapter_t, entry );\r
+               if( pIn->PortGuid != pAdapter->guids.port_guid.guid )\r
+                       continue;\r
+\r
+               /* Found the port - lookup the MAC. */\r
+               cl_obj_lock( &pAdapter->obj );\r
+               if( pAdapter->p_port )\r
+               {\r
+                       status = ipoib_mac_to_path(\r
+                               pAdapter->p_port, *(mac_addr_t*)pIn->DestMac, &pOut->Path );\r
+\r
+                       if( NT_SUCCESS( status ) )\r
+                       {\r
+                               pIrp->IoStatus.Information =\r
+                                       sizeof(IOCTL_IBAT_MAC_TO_PATH_OUT);\r
+                       }\r
+               }\r
+               cl_obj_unlock( &pAdapter->obj );\r
+               break;\r
+       }\r
+\r
+       KeReleaseInStackQueuedSpinLock( &hdl );\r
+\r
+       IPOIB_EXIT( IPOIB_DBG_IOCTL );\r
+       return status;\r
+}\r
+\r
+\r
 static NTSTATUS\r
 __ibat_ip_to_port(\r
        IN                              IRP                                                     *pIrp,\r
@@ -573,6 +647,12 @@ __ipoib_dispatch(
                status = __ibat_ip_to_port( pIrp, pIoStack );\r
                break;\r
 \r
+       case IOCTL_IBAT_MAC_TO_PATH:\r
+               IPOIB_PRINT(TRACE_LEVEL_INFORMATION, IPOIB_DBG_IOCTL,\r
+                       ("IOCTL_IBAT_MAC_TO_PATH received\n" ));\r
+               status = __ibat_mac_to_path( pIrp, pIoStack );\r
+               break;\r
+\r
        default:\r
                IPOIB_PRINT( TRACE_LEVEL_WARNING, IPOIB_DBG_IOCTL,\r
                        ("unknow IOCTL code = 0x%x\n",\r
index 6e1e56c3f2ffd0496cb06fc80467b995ca80dbdf..92c2fcea15a02d175b986206ca1f64fd845df6d8 100644 (file)
@@ -4683,6 +4683,86 @@ ipoib_mac_to_gid(
 }\r
 \r
 \r
+NTSTATUS\r
+ipoib_mac_to_path(\r
+       IN                              ipoib_port_t* const                     p_port,\r
+       IN              const   mac_addr_t                                      mac,\r
+               OUT                     ib_path_rec_t*                          p_path )\r
+{\r
+       ipoib_endpt_t*  p_endpt;\r
+       cl_map_item_t   *p_item;\r
+       uint64_t                key = 0;\r
+       uint8_t                 sl;\r
+       net32_t                 flow_lbl;\r
+       uint8_t                 hop_limit;\r
+\r
+       IPOIB_ENTER( IPOIB_DBG_ENDPT );\r
+\r
+       cl_memcpy( &key, &mac, sizeof(mac_addr_t) );\r
+\r
+       cl_obj_lock( &p_port->obj );\r
+\r
+       if( p_port->p_local_endpt == NULL )\r
+       {\r
+               cl_obj_unlock( &p_port->obj );\r
+               IPOIB_PRINT_EXIT( TRACE_LEVEL_ERROR, IPOIB_DBG_ERROR,\r
+                       ("No local endpoint.\n") );\r
+               return STATUS_INVALID_PARAMETER;\r
+       }\r
+\r
+       if( mac.addr[0] == 0 && mac.addr[1] == 0 && mac.addr[2] == 0 &&\r
+               mac.addr[3] == 0 && mac.addr[4] == 0 && mac.addr[5] == 0 )\r
+       {\r
+               p_endpt = p_port->p_local_endpt;\r
+       }\r
+       else\r
+       {\r
+               p_item = cl_qmap_get( &p_port->endpt_mgr.mac_endpts, key );\r
+               if( p_item == cl_qmap_end( &p_port->endpt_mgr.mac_endpts ) )\r
+               {\r
+                       cl_obj_unlock( &p_port->obj );\r
+                       IPOIB_PRINT_EXIT( TRACE_LEVEL_ERROR, IPOIB_DBG_ERROR,\r
+                               ("Failed endpoint lookup.\n") );\r
+                       return STATUS_INVALID_PARAMETER;\r
+               }\r
+\r
+               p_endpt = PARENT_STRUCT( p_item, ipoib_endpt_t, mac_item );\r
+       }\r
+\r
+       p_path->resv0 = 0;\r
+       p_path->dgid = p_endpt->dgid;\r
+       p_path->sgid = p_port->p_local_endpt->dgid;\r
+       p_path->dlid = p_endpt->dlid;\r
+       p_path->slid = p_port->p_local_endpt->dlid;\r
+\r
+       ib_member_get_sl_flow_hop(\r
+               p_port->ib_mgr.bcast_rec.sl_flow_hop,\r
+               &sl,\r
+               &flow_lbl,\r
+               &hop_limit\r
+               );\r
+       ib_path_rec_set_hop_flow_raw( p_path, hop_limit, flow_lbl, FALSE );\r
+\r
+       p_path->tclass = p_port->ib_mgr.bcast_rec.tclass;\r
+       p_path->num_path = 1;\r
+       p_path->pkey = p_port->ib_mgr.bcast_rec.pkey;\r
+       p_path->mtu = p_port->ib_mgr.bcast_rec.mtu;\r
+       p_path->rate = p_port->ib_mgr.bcast_rec.rate;\r
+       if( p_path->slid == p_path->dlid )\r
+               p_path->pkt_life = 0;\r
+       else\r
+               p_path->pkt_life = p_port->ib_mgr.bcast_rec.pkt_life;\r
+       p_path->preference = 0;\r
+       p_path->resv1 = 0;\r
+       p_path->resv2 = 0;\r
+\r
+       cl_obj_unlock( &p_port->obj );\r
+\r
+       IPOIB_EXIT( IPOIB_DBG_ENDPT );\r
+       return STATUS_SUCCESS;\r
+}\r
+\r
+\r
 static inline NDIS_STATUS\r
 __endpt_mgr_ref(\r
        IN                              ipoib_port_t* const                     p_port,\r
index 4c8d6a2283819e88a6095554e337c25c9c186152..cfdec05108029627f18ffddfd8489ecc5830b713 100644 (file)
@@ -618,6 +618,12 @@ ipoib_mac_to_gid(
        IN              const   mac_addr_t                                      mac,\r
                OUT                     ib_gid_t*                                       p_gid );\r
 \r
+NTSTATUS\r
+ipoib_mac_to_path(\r
+       IN                              ipoib_port_t* const                     p_port,\r
+       IN              const   mac_addr_t                                      mac,\r
+               OUT                     ib_path_rec_t*                          p_path );\r
+\r
 inline void ipoib_port_ref(\r
        IN                              ipoib_port_t *                          p_port, \r
        IN                              int                                             type);\r