Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
[infiniband] Allow for sending MADs via GMA without retransmission
  • Loading branch information
Michael Brown committed Jul 17, 2009
1 parent b4155c4 commit 3c77fe7
Show file tree
Hide file tree
Showing 3 changed files with 54 additions and 30 deletions.
2 changes: 1 addition & 1 deletion src/include/gpxe/ib_gma.h
Expand Up @@ -63,7 +63,7 @@ struct ib_gma {
};

extern int ib_gma_request ( struct ib_gma *gma, union ib_mad *mad,
struct ib_address_vector *av );
struct ib_address_vector *av, int retry );
extern int ib_create_gma ( struct ib_gma *gma, struct ib_device *ibdev,
unsigned long qkey );
extern void ib_destroy_gma ( struct ib_gma *gma );
Expand Down
80 changes: 52 additions & 28 deletions src/net/infiniband/ib_gma.c
Expand Up @@ -237,59 +237,73 @@ static struct ib_completion_queue_operations ib_gma_completion_ops = {
};

/**
* Handle MAD request timer expiry
* Transmit MAD request
*
* @v timer Retry timer
* @v expired Failure indicator
* @v gma General management agent
* @v request MAD request
* @ret rc Return status code
*/
static void ib_gma_timer_expired ( struct retry_timer *timer, int expired ) {
struct ib_mad_request *request =
container_of ( timer, struct ib_mad_request, timer );
struct ib_gma *gma = request->gma;
struct ib_device *ibdev = gma->ibdev;
static int ib_gma_send ( struct ib_gma *gma, struct ib_mad_request *request ) {
struct io_buffer *iobuf;
int rc;

/* Abandon TID if we have tried too many times */
if ( expired ) {
DBGC ( gma, "GMA %p abandoning TID %08x%08x\n",
gma, ntohl ( request->mad.hdr.tid[0] ),
ntohl ( request->mad.hdr.tid[1] ) );
list_del ( &request->list );
free ( request );
return;
}

DBGC ( gma, "GMA %p TX TID %08x%08x (%02x,%02x,%02x,%04x)\n",
gma, ntohl ( request->mad.hdr.tid[0] ),
ntohl ( request->mad.hdr.tid[1] ), request->mad.hdr.mgmt_class,
request->mad.hdr.class_version, request->mad.hdr.method,
ntohs ( request->mad.hdr.attr_id ) );
DBGC2_HDA ( gma, 0, &request->mad, sizeof ( request->mad ) );

/* Restart retransmission timer */
start_timer ( timer );

/* Construct I/O buffer */
iobuf = alloc_iob ( sizeof ( request->mad ) );
if ( ! iobuf ) {
DBGC ( gma, "GMA %p could not allocate buffer for TID "
"%08x%08x\n", gma, ntohl ( request->mad.hdr.tid[0] ),
ntohl ( request->mad.hdr.tid[1] ) );
return;
return -ENOMEM;
}
memcpy ( iob_put ( iobuf, sizeof ( request->mad ) ), &request->mad,
sizeof ( request->mad ) );

/* Post send request */
if ( ( rc = ib_post_send ( ibdev, gma->qp, &request->av,
/* Send I/O buffer */
if ( ( rc = ib_post_send ( gma->ibdev, gma->qp, &request->av,
iobuf ) ) != 0 ) {
DBGC ( gma, "GMA %p could not send TID %08x%08x: %s\n",
gma, ntohl ( request->mad.hdr.tid[0] ),
ntohl ( request->mad.hdr.tid[1] ), strerror ( rc ) );
free_iob ( iobuf );
return rc;
}

return 0;
}

/**
* Handle MAD request timer expiry
*
* @v timer Retry timer
* @v expired Failure indicator
*/
static void ib_gma_timer_expired ( struct retry_timer *timer, int expired ) {
struct ib_mad_request *request =
container_of ( timer, struct ib_mad_request, timer );
struct ib_gma *gma = request->gma;

/* Abandon TID if we have tried too many times */
if ( expired ) {
DBGC ( gma, "GMA %p abandoning TID %08x%08x\n",
gma, ntohl ( request->mad.hdr.tid[0] ),
ntohl ( request->mad.hdr.tid[1] ) );
list_del ( &request->list );
free ( request );
return;
}

/* Restart retransmission timer */
start_timer ( timer );

/* Resend request */
ib_gma_send ( gma, request );
}

/**
Expand All @@ -298,10 +312,11 @@ static void ib_gma_timer_expired ( struct retry_timer *timer, int expired ) {
* @v gma General management agent
* @v mad MAD request
* @v av Destination address, or NULL for SM
* @v retry Request should be retried until a response arrives
* @ret rc Return status code
*/
int ib_gma_request ( struct ib_gma *gma, union ib_mad *mad,
struct ib_address_vector *av ) {
struct ib_address_vector *av, int retry ) {
struct ib_device *ibdev = gma->ibdev;
struct ib_mad_request *request;

Expand All @@ -312,7 +327,6 @@ int ib_gma_request ( struct ib_gma *gma, union ib_mad *mad,
return -ENOMEM;
}
request->gma = gma;
list_add ( &request->list, &gma->requests );
request->timer.expired = ib_gma_timer_expired;

/* Determine address vector */
Expand All @@ -332,8 +346,18 @@ int ib_gma_request ( struct ib_gma *gma, union ib_mad *mad,
request->mad.hdr.tid[0] = htonl ( IB_GMA_TID_MAGIC );
request->mad.hdr.tid[1] = htonl ( ++next_request_tid );

/* Start timer to initiate transmission */
start_timer_nodelay ( &request->timer );
/* Send initial request. Ignore errors; the retry timer will
* take care of those we care about.
*/
ib_gma_send ( gma, request );

/* Add to list and start timer if applicable */
if ( retry ) {
list_add ( &request->list, &gma->requests );
start_timer ( &request->timer );
} else {
free ( request );
}

return 0;
}
Expand Down
2 changes: 1 addition & 1 deletion src/net/infiniband/ib_pathrec.c
Expand Up @@ -154,7 +154,7 @@ int ib_resolve_path ( struct ib_device *ibdev,
sizeof ( sa->sa_data.path_record.sgid ) );

/* Issue path record request */
if ( ( rc = ib_gma_request ( &ibdev->gma, &mad, NULL ) ) != 0 ) {
if ( ( rc = ib_gma_request ( &ibdev->gma, &mad, NULL, 1 ) ) != 0 ) {
DBGC ( ibdev, "IBDEV %p could not get path record: %s\n",
ibdev, strerror ( rc ) );
return rc;
Expand Down

0 comments on commit 3c77fe7

Please sign in to comment.