ib_pathrec.c File Reference

Infiniband path lookups. More...

#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include <byteswap.h>
#include <errno.h>
#include <gpxe/infiniband.h>
#include <gpxe/ib_mi.h>
#include <gpxe/ib_pathrec.h>

Go to the source code of this file.

Data Structures

struct  ib_cached_path
 A cached path. More...

Defines

#define IB_NUM_CACHED_PATHS   4
 Number of path cache entries.

Functions

 FILE_LICENCE (GPL2_OR_LATER)
static void ib_path_complete (struct ib_device *ibdev, struct ib_mad_interface *mi, struct ib_mad_transaction *madx, int rc, union ib_mad *mad, struct ib_address_vector *av __unused)
 Handle path transaction completion.
struct ib_pathib_create_path (struct ib_device *ibdev, struct ib_address_vector *av, struct ib_path_operations *op)
 Create path.
void ib_destroy_path (struct ib_device *ibdev, struct ib_path *path)
 Destroy path.
static struct ib_cached_pathib_find_path_cache_entry (struct ib_device *ibdev, struct ib_gid *dgid)
 Find path cache entry.
static void ib_cached_path_complete (struct ib_device *ibdev, struct ib_path *path, int rc, struct ib_address_vector *av __unused)
 Handle cached path transaction completion.
int ib_resolve_path (struct ib_device *ibdev, struct ib_address_vector *av)
 Resolve path.

Variables

static struct
ib_mad_transaction_operations 
ib_path_op
 Path transaction completion operations.
static struct ib_cached_path ib_path_cache [IB_NUM_CACHED_PATHS]
 Path cache.
static unsigned int ib_path_cache_idx
 Oldest path cache entry index.
static struct ib_path_operations ib_cached_path_op
 Cached path transaction completion operations.


Detailed Description

Infiniband path lookups.

Definition in file ib_pathrec.c.


Define Documentation

#define IB_NUM_CACHED_PATHS   4

Number of path cache entries.

Must be a power of two.

Definition at line 160 of file ib_pathrec.c.

Referenced by ib_find_path_cache_entry(), and ib_resolve_path().


Function Documentation

FILE_LICENCE ( GPL2_OR_LATER   ) 

static void ib_path_complete ( struct ib_device ibdev,
struct ib_mad_interface mi,
struct ib_mad_transaction madx,
int  rc,
union ib_mad mad,
struct ib_address_vector *av  __unused 
) [static]

Handle path transaction completion.

Parameters:
ibdev Infiniband device
mi Management interface
madx Management transaction
rc Status code
mad Received MAD (or NULL on error)
av Source address vector (or NULL on error)

Definition at line 46 of file ib_pathrec.c.

References ib_path::av, ib_path_operations::complete, DBGC, ib_path_record::dlid, ib_gid::dwords, ENETUNREACH, ib_address_vector::gid, ib_mad::hdr, htonl, htons, ib_destroy_madx(), ib_madx_get_ownerdata(), IB_MGMT_STATUS_OK, ib_address_vector::lid, ib_path::madx, ntohs, NULL, ib_path::op, ib_sa_data::path_record, ib_address_vector::rate, ib_path_record::rate_selector__rate, ib_path_record::reserved__sl, ib_mad::sa, ib_mad_sa::sa_data, ib_address_vector::sl, ib_mad_hdr::status, strerror(), and ib_gid::u.

00050                                                                        {
00051         struct ib_path *path = ib_madx_get_ownerdata ( madx );
00052         struct ib_gid *dgid = &path->av.gid;
00053         struct ib_path_record *pathrec = &mad->sa.sa_data.path_record;
00054 
00055         /* Report failures */
00056         if ( ( rc == 0 ) && ( mad->hdr.status != htons ( IB_MGMT_STATUS_OK ) ))
00057                 rc = -ENETUNREACH;
00058         if ( rc != 0 ) {
00059                 DBGC ( ibdev, "IBDEV %p path lookup for %08x:%08x:%08x:%08x "
00060                        "failed: %s\n", ibdev, htonl ( dgid->u.dwords[0] ),
00061                        htonl ( dgid->u.dwords[1] ),
00062                        htonl ( dgid->u.dwords[2] ),
00063                        htonl ( dgid->u.dwords[3] ), strerror ( rc ) );
00064                 goto out;
00065         }
00066 
00067         /* Extract values from MAD */
00068         path->av.lid = ntohs ( pathrec->dlid );
00069         path->av.sl = ( pathrec->reserved__sl & 0x0f );
00070         path->av.rate = ( pathrec->rate_selector__rate & 0x3f );
00071         DBGC ( ibdev, "IBDEV %p path to %08x:%08x:%08x:%08x is %04x sl %d "
00072                "rate %d\n", ibdev, htonl ( dgid->u.dwords[0] ),
00073                htonl ( dgid->u.dwords[1] ), htonl ( dgid->u.dwords[2] ),
00074                htonl ( dgid->u.dwords[3] ), path->av.lid, path->av.sl,
00075                path->av.rate );
00076 
00077  out:
00078         /* Destroy the completed transaction */
00079         ib_destroy_madx ( ibdev, mi, madx );
00080         path->madx = NULL;
00081 
00082         /* Hand off to upper completion handler */
00083         path->op->complete ( ibdev, path, rc, &path->av );
00084 }

struct ib_path* ib_create_path ( struct ib_device ibdev,
struct ib_address_vector av,
struct ib_path_operations op 
) [read]

Create path.

Parameters:
ibdev Infiniband device
av Address vector to complete
op Path operations
Return values:
path Path

Definition at line 100 of file ib_pathrec.c.

References ib_mad_hdr::attr_id, ib_path::av, ib_mad_hdr::class_version, ib_sa_hdr::comp_mask, ib_path_record::dgid, free(), ib_device::gid, ib_address_vector::gid, ib_device::gsi, htonl, htons, ib_create_madx(), ib_destroy_madx(), ib_madx_set_ownerdata(), IB_MGMT_CLASS_SUBN_ADM, IB_MGMT_METHOD_GET, IB_SA_ATTR_PATH_REC, IB_SA_CLASS_VERSION, IB_SA_PATH_REC_DGID, IB_SA_PATH_REC_SGID, ib_path::ibdev, ib_mad_sa::mad_hdr, ib_path::madx, memcpy, memset(), ib_mad_hdr::method, ib_mad_hdr::mgmt_class, NULL, ib_path::op, ib_sa_data::path_record, ib_mad::sa, ib_mad_sa::sa_data, ib_mad_sa::sa_hdr, ib_path_record::sgid, and zalloc().

Referenced by ib_create_conn(), and ib_resolve_path().

00101                                                  {
00102         struct ib_path *path;
00103         union ib_mad mad;
00104         struct ib_mad_sa *sa = &mad.sa;
00105 
00106         /* Allocate and initialise structure */
00107         path = zalloc ( sizeof ( *path ) );
00108         if ( ! path )
00109                 goto err_alloc_path;
00110         path->ibdev = ibdev;
00111         memcpy ( &path->av, av, sizeof ( path->av ) );
00112         path->op = op;
00113 
00114         /* Construct path request */
00115         memset ( sa, 0, sizeof ( *sa ) );
00116         sa->mad_hdr.mgmt_class = IB_MGMT_CLASS_SUBN_ADM;
00117         sa->mad_hdr.class_version = IB_SA_CLASS_VERSION;
00118         sa->mad_hdr.method = IB_MGMT_METHOD_GET;
00119         sa->mad_hdr.attr_id = htons ( IB_SA_ATTR_PATH_REC );
00120         sa->sa_hdr.comp_mask[1] =
00121                 htonl ( IB_SA_PATH_REC_DGID | IB_SA_PATH_REC_SGID );
00122         memcpy ( &sa->sa_data.path_record.dgid, &path->av.gid,
00123                  sizeof ( sa->sa_data.path_record.dgid ) );
00124         memcpy ( &sa->sa_data.path_record.sgid, &ibdev->gid,
00125                  sizeof ( sa->sa_data.path_record.sgid ) );
00126 
00127         /* Create management transaction */
00128         path->madx = ib_create_madx ( ibdev, ibdev->gsi, &mad, NULL,
00129                                       &ib_path_op );
00130         if ( ! path->madx )
00131                 goto err_create_madx;
00132         ib_madx_set_ownerdata ( path->madx, path );
00133 
00134         return path;
00135 
00136         ib_destroy_madx ( ibdev, ibdev->gsi, path->madx );
00137  err_create_madx:
00138         free ( path );
00139  err_alloc_path:
00140         return NULL;
00141 }

void ib_destroy_path ( struct ib_device ibdev,
struct ib_path path 
)

Destroy path.

Parameters:
ibdev Infiniband device
path Path

Definition at line 149 of file ib_pathrec.c.

References free(), ib_device::gsi, ib_destroy_madx(), and ib_path::madx.

Referenced by ib_cached_path_complete(), ib_cm_path_complete(), ib_create_conn(), ib_destroy_conn(), and ib_resolve_path().

00149                                                                        {
00150 
00151         if ( path->madx )
00152                 ib_destroy_madx ( ibdev, ibdev->gsi, path->madx );
00153         free ( path );
00154 }

static struct ib_cached_path* ib_find_path_cache_entry ( struct ib_device ibdev,
struct ib_gid dgid 
) [static, read]

Find path cache entry.

Parameters:
ibdev Infiniband device
dgid Destination GID
Return values:
path Path cache entry, or NULL

Definition at line 182 of file ib_pathrec.c.

References ib_path::av, ib_address_vector::gid, IB_NUM_CACHED_PATHS, ib_path_cache, ib_path::ibdev, memcmp(), NULL, and ib_cached_path::path.

Referenced by ib_resolve_path().

00182                                                                           {
00183         struct ib_cached_path *cached;
00184         unsigned int i;
00185 
00186         for ( i = 0 ; i < IB_NUM_CACHED_PATHS ; i++ ) {
00187                 cached = &ib_path_cache[i];
00188                 if ( ! cached->path )
00189                         continue;
00190                 if ( cached->path->ibdev != ibdev )
00191                         continue;
00192                 if ( memcmp ( &cached->path->av.gid, dgid,
00193                               sizeof ( cached->path->av.gid ) ) != 0 )
00194                         continue;
00195                 return cached;
00196         }
00197 
00198         return NULL;
00199 }

static void ib_cached_path_complete ( struct ib_device ibdev,
struct ib_path path,
int  rc,
struct ib_address_vector *av  __unused 
) [static]

Handle cached path transaction completion.

Parameters:
ibdev Infiniband device
path Path
rc Status code
av Address vector, or NULL on error

Definition at line 209 of file ib_pathrec.c.

References ib_destroy_path(), ib_path_get_ownerdata(), and memset().

00211                                                                               {
00212         struct ib_cached_path *cached = ib_path_get_ownerdata ( path );
00213 
00214         /* If the transaction failed, erase the cache entry */
00215         if ( rc != 0 ) {
00216                 /* Destroy the old cache entry */
00217                 ib_destroy_path ( ibdev, path );
00218                 memset ( cached, 0, sizeof ( *cached ) );
00219                 return;
00220         }
00221 
00222         /* Do not destroy the completed transaction; we still need to
00223          * refer to the resolved path.
00224          */
00225 }

int ib_resolve_path ( struct ib_device ibdev,
struct ib_address_vector av 
)

Resolve path.

Parameters:
ibdev Infiniband device
av Address vector to complete
Return values:
rc Return status code
This provides a non-transactional way to resolve a path, via a cache similar to ARP.

Definition at line 242 of file ib_pathrec.c.

References ib_path::av, DBGC, DBGC2, ib_gid::dwords, EINVAL, ENOENT, ENOMEM, ib_address_vector::gid, ib_address_vector::gid_present, htonl, ib_create_path(), ib_destroy_path(), ib_find_path_cache_entry(), IB_NUM_CACHED_PATHS, ib_path_cache, ib_path_cache_idx, ib_path_set_ownerdata(), ib_address_vector::lid, memset(), ib_cached_path::path, ib_address_vector::rate, ib_address_vector::sl, and ib_gid::u.

Referenced by ipoib_transmit().

00242                                                                               {
00243         struct ib_gid *gid = &av->gid;
00244         struct ib_cached_path *cached;
00245         unsigned int cache_idx;
00246 
00247         /* Sanity check */
00248         if ( ! av->gid_present ) {
00249                 DBGC ( ibdev, "IBDEV %p attempt to look up path "
00250                        "without GID\n", ibdev );
00251                 return -EINVAL;
00252         }
00253 
00254         /* Look in cache for a matching entry */
00255         cached = ib_find_path_cache_entry ( ibdev, gid );
00256         if ( cached && cached->path->av.lid ) {
00257                 /* Populated entry found */
00258                 av->lid = cached->path->av.lid;
00259                 av->rate = cached->path->av.rate;
00260                 av->sl = cached->path->av.sl;
00261                 DBGC2 ( ibdev, "IBDEV %p cache hit for %08x:%08x:%08x:%08x\n",
00262                         ibdev, htonl ( gid->u.dwords[0] ),
00263                         htonl ( gid->u.dwords[1] ), htonl ( gid->u.dwords[2] ),
00264                         htonl ( gid->u.dwords[3] ) );
00265                 return 0;
00266         }
00267         DBGC ( ibdev, "IBDEV %p cache miss for %08x:%08x:%08x:%08x%s\n",
00268                ibdev, htonl ( gid->u.dwords[0] ), htonl ( gid->u.dwords[1] ),
00269                htonl ( gid->u.dwords[2] ), htonl ( gid->u.dwords[3] ),
00270                ( cached ? " (in progress)" : "" ) );
00271 
00272         /* If lookup is already in progress, do nothing */
00273         if ( cached )
00274                 return -ENOENT;
00275 
00276         /* Locate a new cache entry to use */
00277         cache_idx = ( (ib_path_cache_idx++) % IB_NUM_CACHED_PATHS );
00278         cached = &ib_path_cache[cache_idx];
00279 
00280         /* Destroy the old cache entry */
00281         if ( cached->path )
00282                 ib_destroy_path ( ibdev, cached->path );
00283         memset ( cached, 0, sizeof ( *cached ) );
00284 
00285         /* Create new path */
00286         cached->path = ib_create_path ( ibdev, av, &ib_cached_path_op );
00287         if ( ! cached->path ) {
00288                 DBGC ( ibdev, "IBDEV %p could not create path\n",
00289                        ibdev );
00290                 return -ENOMEM;
00291         }
00292         ib_path_set_ownerdata ( cached->path, cached );
00293 
00294         /* Not found yet */
00295         return -ENOENT;
00296 }


Variable Documentation

Initial value:

 {
        .complete = ib_path_complete,
}
Path transaction completion operations.

Definition at line 87 of file ib_pathrec.c.

struct ib_cached_path ib_path_cache[IB_NUM_CACHED_PATHS] [static]

Path cache.

Definition at line 169 of file ib_pathrec.c.

Referenced by ib_find_path_cache_entry(), and ib_resolve_path().

unsigned int ib_path_cache_idx [static]

Oldest path cache entry index.

Definition at line 172 of file ib_pathrec.c.

Referenced by ib_resolve_path().

Initial value:

 {
        .complete = ib_cached_path_complete,
}
Cached path transaction completion operations.

Definition at line 228 of file ib_pathrec.c.


Generated on Tue Apr 6 20:01:55 2010 for gPXE by  doxygen 1.5.7.1