mirror of https://github.com/ipxe/ipxe.git
[infiniband] Allow for sending MADs via GMA without retransmission
parent
b4155c4ab5
commit
3c77fe73a5
|
@ -63,7 +63,7 @@ struct ib_gma {
|
||||||
};
|
};
|
||||||
|
|
||||||
extern int ib_gma_request ( struct ib_gma *gma, union ib_mad *mad,
|
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,
|
extern int ib_create_gma ( struct ib_gma *gma, struct ib_device *ibdev,
|
||||||
unsigned long qkey );
|
unsigned long qkey );
|
||||||
extern void ib_destroy_gma ( struct ib_gma *gma );
|
extern void ib_destroy_gma ( struct ib_gma *gma );
|
||||||
|
|
|
@ -236,6 +236,48 @@ static struct ib_completion_queue_operations ib_gma_completion_ops = {
|
||||||
.complete_recv = ib_gma_complete_recv,
|
.complete_recv = ib_gma_complete_recv,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Transmit MAD request
|
||||||
|
*
|
||||||
|
* @v gma General management agent
|
||||||
|
* @v request MAD request
|
||||||
|
* @ret rc Return status code
|
||||||
|
*/
|
||||||
|
static int ib_gma_send ( struct ib_gma *gma, struct ib_mad_request *request ) {
|
||||||
|
struct io_buffer *iobuf;
|
||||||
|
int rc;
|
||||||
|
|
||||||
|
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 ) );
|
||||||
|
|
||||||
|
/* 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 -ENOMEM;
|
||||||
|
}
|
||||||
|
memcpy ( iob_put ( iobuf, sizeof ( request->mad ) ), &request->mad,
|
||||||
|
sizeof ( request->mad ) );
|
||||||
|
|
||||||
|
/* 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
|
* Handle MAD request timer expiry
|
||||||
*
|
*
|
||||||
|
@ -246,9 +288,6 @@ static void ib_gma_timer_expired ( struct retry_timer *timer, int expired ) {
|
||||||
struct ib_mad_request *request =
|
struct ib_mad_request *request =
|
||||||
container_of ( timer, struct ib_mad_request, timer );
|
container_of ( timer, struct ib_mad_request, timer );
|
||||||
struct ib_gma *gma = request->gma;
|
struct ib_gma *gma = request->gma;
|
||||||
struct ib_device *ibdev = gma->ibdev;
|
|
||||||
struct io_buffer *iobuf;
|
|
||||||
int rc;
|
|
||||||
|
|
||||||
/* Abandon TID if we have tried too many times */
|
/* Abandon TID if we have tried too many times */
|
||||||
if ( expired ) {
|
if ( expired ) {
|
||||||
|
@ -260,36 +299,11 @@ static void ib_gma_timer_expired ( struct retry_timer *timer, int expired ) {
|
||||||
return;
|
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 */
|
/* Restart retransmission timer */
|
||||||
start_timer ( timer );
|
start_timer ( timer );
|
||||||
|
|
||||||
/* Construct I/O buffer */
|
/* Resend request */
|
||||||
iobuf = alloc_iob ( sizeof ( request->mad ) );
|
ib_gma_send ( gma, request );
|
||||||
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;
|
|
||||||
}
|
|
||||||
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,
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -298,10 +312,11 @@ static void ib_gma_timer_expired ( struct retry_timer *timer, int expired ) {
|
||||||
* @v gma General management agent
|
* @v gma General management agent
|
||||||
* @v mad MAD request
|
* @v mad MAD request
|
||||||
* @v av Destination address, or NULL for SM
|
* @v av Destination address, or NULL for SM
|
||||||
|
* @v retry Request should be retried until a response arrives
|
||||||
* @ret rc Return status code
|
* @ret rc Return status code
|
||||||
*/
|
*/
|
||||||
int ib_gma_request ( struct ib_gma *gma, union ib_mad *mad,
|
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_device *ibdev = gma->ibdev;
|
||||||
struct ib_mad_request *request;
|
struct ib_mad_request *request;
|
||||||
|
|
||||||
|
@ -312,7 +327,6 @@ int ib_gma_request ( struct ib_gma *gma, union ib_mad *mad,
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
}
|
}
|
||||||
request->gma = gma;
|
request->gma = gma;
|
||||||
list_add ( &request->list, &gma->requests );
|
|
||||||
request->timer.expired = ib_gma_timer_expired;
|
request->timer.expired = ib_gma_timer_expired;
|
||||||
|
|
||||||
/* Determine address vector */
|
/* 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[0] = htonl ( IB_GMA_TID_MAGIC );
|
||||||
request->mad.hdr.tid[1] = htonl ( ++next_request_tid );
|
request->mad.hdr.tid[1] = htonl ( ++next_request_tid );
|
||||||
|
|
||||||
/* Start timer to initiate transmission */
|
/* Send initial request. Ignore errors; the retry timer will
|
||||||
start_timer_nodelay ( &request->timer );
|
* 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;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -154,7 +154,7 @@ int ib_resolve_path ( struct ib_device *ibdev,
|
||||||
sizeof ( sa->sa_data.path_record.sgid ) );
|
sizeof ( sa->sa_data.path_record.sgid ) );
|
||||||
|
|
||||||
/* Issue path record request */
|
/* 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",
|
DBGC ( ibdev, "IBDEV %p could not get path record: %s\n",
|
||||||
ibdev, strerror ( rc ) );
|
ibdev, strerror ( rc ) );
|
||||||
return rc;
|
return rc;
|
||||||
|
|
Loading…
Reference in New Issue