diff options
author | Michael Brown <mcb30@etherboot.org> | 2009-07-07 16:01:51 +0100 |
---|---|---|
committer | Michael Brown <mcb30@etherboot.org> | 2009-07-17 23:06:34 +0100 |
commit | 3c77fe73a559ef223fb459ed82b7aaea44e1693a (patch) | |
tree | 99e95ea9e09b145309118498a4281f21eb4c09d1 | |
parent | b4155c4ab541693f35f2efe76d6dc75dd4cb7825 (diff) | |
download | ipxe-3c77fe73a559ef223fb459ed82b7aaea44e1693a.tar.gz |
[infiniband] Allow for sending MADs via GMA without retransmission
-rw-r--r-- | src/include/gpxe/ib_gma.h | 2 | ||||
-rw-r--r-- | src/net/infiniband/ib_gma.c | 80 | ||||
-rw-r--r-- | src/net/infiniband/ib_pathrec.c | 2 |
3 files changed, 54 insertions, 30 deletions
diff --git a/src/include/gpxe/ib_gma.h b/src/include/gpxe/ib_gma.h index c305a3a1..c921e251 100644 --- a/src/include/gpxe/ib_gma.h +++ b/src/include/gpxe/ib_gma.h @@ -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 ); diff --git a/src/net/infiniband/ib_gma.c b/src/net/infiniband/ib_gma.c index d599ea32..56c0fe95 100644 --- a/src/net/infiniband/ib_gma.c +++ b/src/net/infiniband/ib_gma.c @@ -237,29 +237,16 @@ 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, @@ -267,29 +254,56 @@ static void ib_gma_timer_expired ( struct retry_timer *timer, int expired ) { 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 ); } /** @@ -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; @@ -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 */ @@ -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; } diff --git a/src/net/infiniband/ib_pathrec.c b/src/net/infiniband/ib_pathrec.c index 89622d98..06101670 100644 --- a/src/net/infiniband/ib_pathrec.c +++ b/src/net/infiniband/ib_pathrec.c @@ -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; |