#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_path * | ib_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_path * | ib_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. | |
Definition in file ib_pathrec.c.
| #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().
| 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.
| 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.
| ibdev | Infiniband device | |
| av | Address vector to complete | |
| op | Path operations |
| 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 }
Destroy path.
| 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.
| ibdev | Infiniband device | |
| dgid | Destination GID |
| 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.
| 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.
| ibdev | Infiniband device | |
| av | Address vector to complete |
| rc | Return status code |
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 }
struct ib_mad_transaction_operations ib_path_op [static] |
Initial value:
{
.complete = ib_path_complete,
}
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().
struct ib_path_operations ib_cached_path_op [static] |
Initial value:
{
.complete = ib_cached_path_complete,
}
Definition at line 228 of file ib_pathrec.c.
1.5.7.1