mirror of https://github.com/ipxe/ipxe.git
[infiniband] Maintain queue fill level as a property of a work queue
Both queue owners and drivers often need to keep track of the fill level, so let's make it a generic property.pull/1/head
parent
d9751edafa
commit
0de5f7af6d
|
@ -57,8 +57,6 @@ struct ipoib_queue_set {
|
||||||
struct ib_completion_queue *cq;
|
struct ib_completion_queue *cq;
|
||||||
/** Queue pair */
|
/** Queue pair */
|
||||||
struct ib_queue_pair *qp;
|
struct ib_queue_pair *qp;
|
||||||
/** Receive work queue fill level */
|
|
||||||
unsigned int recv_fill;
|
|
||||||
/** Receive work queue maximum fill level */
|
/** Receive work queue maximum fill level */
|
||||||
unsigned int recv_max_fill;
|
unsigned int recv_max_fill;
|
||||||
};
|
};
|
||||||
|
@ -565,7 +563,7 @@ static void ipoib_data_complete_recv ( struct ib_device *ibdev __unused,
|
||||||
|
|
||||||
if ( completion->syndrome ) {
|
if ( completion->syndrome ) {
|
||||||
netdev_rx_err ( netdev, iobuf, -EIO );
|
netdev_rx_err ( netdev, iobuf, -EIO );
|
||||||
goto done;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
iob_put ( iobuf, completion->len );
|
iob_put ( iobuf, completion->len );
|
||||||
|
@ -574,7 +572,7 @@ static void ipoib_data_complete_recv ( struct ib_device *ibdev __unused,
|
||||||
"contain GRH\n", ipoib );
|
"contain GRH\n", ipoib );
|
||||||
DBGC_HD ( ipoib, iobuf->data, iob_len ( iobuf ) );
|
DBGC_HD ( ipoib, iobuf->data, iob_len ( iobuf ) );
|
||||||
netdev_rx_err ( netdev, iobuf, -EIO );
|
netdev_rx_err ( netdev, iobuf, -EIO );
|
||||||
goto done;
|
return;
|
||||||
}
|
}
|
||||||
iob_pull ( iobuf, sizeof ( struct ib_global_route_header ) );
|
iob_pull ( iobuf, sizeof ( struct ib_global_route_header ) );
|
||||||
|
|
||||||
|
@ -583,16 +581,13 @@ static void ipoib_data_complete_recv ( struct ib_device *ibdev __unused,
|
||||||
"contain IPoIB header\n", ipoib );
|
"contain IPoIB header\n", ipoib );
|
||||||
DBGC_HD ( ipoib, iobuf->data, iob_len ( iobuf ) );
|
DBGC_HD ( ipoib, iobuf->data, iob_len ( iobuf ) );
|
||||||
netdev_rx_err ( netdev, iobuf, -EIO );
|
netdev_rx_err ( netdev, iobuf, -EIO );
|
||||||
goto done;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
ipoib_pshdr = iob_push ( iobuf, sizeof ( *ipoib_pshdr ) );
|
ipoib_pshdr = iob_push ( iobuf, sizeof ( *ipoib_pshdr ) );
|
||||||
/* FIXME: fill in a MAC address for the sake of AoE! */
|
/* FIXME: fill in a MAC address for the sake of AoE! */
|
||||||
|
|
||||||
netdev_rx ( netdev, iobuf );
|
netdev_rx ( netdev, iobuf );
|
||||||
|
|
||||||
done:
|
|
||||||
ipoib->data.recv_fill--;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -732,7 +727,6 @@ static void ipoib_meta_complete_recv ( struct ib_device *ibdev __unused,
|
||||||
}
|
}
|
||||||
|
|
||||||
done:
|
done:
|
||||||
ipoib->meta.recv_fill--;
|
|
||||||
free_iob ( iobuf );
|
free_iob ( iobuf );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -747,7 +741,7 @@ static void ipoib_refill_recv ( struct ipoib_device *ipoib,
|
||||||
struct io_buffer *iobuf;
|
struct io_buffer *iobuf;
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
while ( qset->recv_fill < qset->recv_max_fill ) {
|
while ( qset->qp->recv.fill < qset->recv_max_fill ) {
|
||||||
iobuf = alloc_iob ( IPOIB_PKT_LEN );
|
iobuf = alloc_iob ( IPOIB_PKT_LEN );
|
||||||
if ( ! iobuf )
|
if ( ! iobuf )
|
||||||
break;
|
break;
|
||||||
|
@ -755,7 +749,6 @@ static void ipoib_refill_recv ( struct ipoib_device *ipoib,
|
||||||
free_iob ( iobuf );
|
free_iob ( iobuf );
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
qset->recv_fill++;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -66,6 +66,8 @@ struct ib_work_queue {
|
||||||
struct list_head list;
|
struct list_head list;
|
||||||
/** Number of work queue entries */
|
/** Number of work queue entries */
|
||||||
unsigned int num_wqes;
|
unsigned int num_wqes;
|
||||||
|
/** Number of occupied work queue entries */
|
||||||
|
unsigned int fill;
|
||||||
/** Next work queue entry index
|
/** Next work queue entry index
|
||||||
*
|
*
|
||||||
* This is the index of the next entry to be filled (i.e. the
|
* This is the index of the next entry to be filled (i.e. the
|
||||||
|
@ -355,70 +357,24 @@ extern void ib_destroy_qp ( struct ib_device *ibdev,
|
||||||
struct ib_queue_pair *qp );
|
struct ib_queue_pair *qp );
|
||||||
extern struct ib_work_queue * ib_find_wq ( struct ib_completion_queue *cq,
|
extern struct ib_work_queue * ib_find_wq ( struct ib_completion_queue *cq,
|
||||||
unsigned long qpn, int is_send );
|
unsigned long qpn, int is_send );
|
||||||
|
extern int ib_post_send ( struct ib_device *ibdev, struct ib_queue_pair *qp,
|
||||||
|
struct ib_address_vector *av,
|
||||||
|
struct io_buffer *iobuf );
|
||||||
|
extern int ib_post_recv ( struct ib_device *ibdev, struct ib_queue_pair *qp,
|
||||||
|
struct io_buffer *iobuf );
|
||||||
|
extern void ib_complete_send ( struct ib_device *ibdev,
|
||||||
|
struct ib_queue_pair *qp,
|
||||||
|
struct ib_completion *completion,
|
||||||
|
struct io_buffer *iobuf );
|
||||||
|
extern void ib_complete_recv ( struct ib_device *ibdev,
|
||||||
|
struct ib_queue_pair *qp,
|
||||||
|
struct ib_completion *completion,
|
||||||
|
struct io_buffer *iobuf );
|
||||||
extern struct ib_device * alloc_ibdev ( size_t priv_size );
|
extern struct ib_device * alloc_ibdev ( size_t priv_size );
|
||||||
extern int register_ibdev ( struct ib_device *ibdev );
|
extern int register_ibdev ( struct ib_device *ibdev );
|
||||||
extern void unregister_ibdev ( struct ib_device *ibdev );
|
extern void unregister_ibdev ( struct ib_device *ibdev );
|
||||||
extern void ib_link_state_changed ( struct ib_device *ibdev );
|
extern void ib_link_state_changed ( struct ib_device *ibdev );
|
||||||
|
|
||||||
/**
|
|
||||||
* Post send work queue entry
|
|
||||||
*
|
|
||||||
* @v ibdev Infiniband device
|
|
||||||
* @v qp Queue pair
|
|
||||||
* @v av Address vector
|
|
||||||
* @v iobuf I/O buffer
|
|
||||||
* @ret rc Return status code
|
|
||||||
*/
|
|
||||||
static inline __attribute__ (( always_inline )) int
|
|
||||||
ib_post_send ( struct ib_device *ibdev, struct ib_queue_pair *qp,
|
|
||||||
struct ib_address_vector *av, struct io_buffer *iobuf ) {
|
|
||||||
return ibdev->op->post_send ( ibdev, qp, av, iobuf );
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Post receive work queue entry
|
|
||||||
*
|
|
||||||
* @v ibdev Infiniband device
|
|
||||||
* @v qp Queue pair
|
|
||||||
* @v iobuf I/O buffer
|
|
||||||
* @ret rc Return status code
|
|
||||||
*/
|
|
||||||
static inline __attribute__ (( always_inline )) int
|
|
||||||
ib_post_recv ( struct ib_device *ibdev, struct ib_queue_pair *qp,
|
|
||||||
struct io_buffer *iobuf ) {
|
|
||||||
return ibdev->op->post_recv ( ibdev, qp, iobuf );
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Complete send work queue entry
|
|
||||||
*
|
|
||||||
* @v ibdev Infiniband device
|
|
||||||
* @v qp Queue pair
|
|
||||||
* @v completion Completion
|
|
||||||
* @v iobuf I/O buffer
|
|
||||||
*/
|
|
||||||
static inline __attribute__ (( always_inline )) void
|
|
||||||
ib_complete_send ( struct ib_device *ibdev, struct ib_queue_pair *qp,
|
|
||||||
struct ib_completion *completion,
|
|
||||||
struct io_buffer *iobuf ) {
|
|
||||||
return qp->send.cq->complete_send ( ibdev, qp, completion, iobuf );
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Complete receive work queue entry
|
|
||||||
*
|
|
||||||
* @v ibdev Infiniband device
|
|
||||||
* @v qp Queue pair
|
|
||||||
* @v completion Completion
|
|
||||||
* @v iobuf I/O buffer
|
|
||||||
*/
|
|
||||||
static inline __attribute__ (( always_inline )) void
|
|
||||||
ib_complete_recv ( struct ib_device *ibdev, struct ib_queue_pair *qp,
|
|
||||||
struct ib_completion *completion,
|
|
||||||
struct io_buffer *iobuf ) {
|
|
||||||
return qp->recv.cq->complete_recv ( ibdev, qp, completion, iobuf );
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Poll completion queue
|
* Poll completion queue
|
||||||
*
|
*
|
||||||
|
|
|
@ -244,6 +244,97 @@ struct ib_work_queue * ib_find_wq ( struct ib_completion_queue *cq,
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Post send work queue entry
|
||||||
|
*
|
||||||
|
* @v ibdev Infiniband device
|
||||||
|
* @v qp Queue pair
|
||||||
|
* @v av Address vector
|
||||||
|
* @v iobuf I/O buffer
|
||||||
|
* @ret rc Return status code
|
||||||
|
*/
|
||||||
|
int ib_post_send ( struct ib_device *ibdev, struct ib_queue_pair *qp,
|
||||||
|
struct ib_address_vector *av, struct io_buffer *iobuf ) {
|
||||||
|
int rc;
|
||||||
|
|
||||||
|
/* Check queue fill level */
|
||||||
|
if ( qp->send.fill >= qp->send.num_wqes ) {
|
||||||
|
DBGC ( ibdev, "IBDEV %p QPN %#lx send queue full\n",
|
||||||
|
ibdev, qp->qpn );
|
||||||
|
return -ENOBUFS;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Post to hardware */
|
||||||
|
if ( ( rc = ibdev->op->post_send ( ibdev, qp, av, iobuf ) ) != 0 ) {
|
||||||
|
DBGC ( ibdev, "IBDEV %p QPN %#lx could not post send WQE: "
|
||||||
|
"%s\n", ibdev, qp->qpn, strerror ( rc ) );
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
qp->send.fill++;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Post receive work queue entry
|
||||||
|
*
|
||||||
|
* @v ibdev Infiniband device
|
||||||
|
* @v qp Queue pair
|
||||||
|
* @v iobuf I/O buffer
|
||||||
|
* @ret rc Return status code
|
||||||
|
*/
|
||||||
|
int ib_post_recv ( struct ib_device *ibdev, struct ib_queue_pair *qp,
|
||||||
|
struct io_buffer *iobuf ) {
|
||||||
|
int rc;
|
||||||
|
|
||||||
|
/* Check queue fill level */
|
||||||
|
if ( qp->recv.fill >= qp->recv.num_wqes ) {
|
||||||
|
DBGC ( ibdev, "IBDEV %p QPN %#lx receive queue full\n",
|
||||||
|
ibdev, qp->qpn );
|
||||||
|
return -ENOBUFS;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Post to hardware */
|
||||||
|
if ( ( rc = ibdev->op->post_recv ( ibdev, qp, iobuf ) ) != 0 ) {
|
||||||
|
DBGC ( ibdev, "IBDEV %p QPN %#lx could not post receive WQE: "
|
||||||
|
"%s\n", ibdev, qp->qpn, strerror ( rc ) );
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
qp->recv.fill++;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Complete send work queue entry
|
||||||
|
*
|
||||||
|
* @v ibdev Infiniband device
|
||||||
|
* @v qp Queue pair
|
||||||
|
* @v completion Completion
|
||||||
|
* @v iobuf I/O buffer
|
||||||
|
*/
|
||||||
|
void ib_complete_send ( struct ib_device *ibdev, struct ib_queue_pair *qp,
|
||||||
|
struct ib_completion *completion,
|
||||||
|
struct io_buffer *iobuf ) {
|
||||||
|
qp->send.cq->complete_send ( ibdev, qp, completion, iobuf );
|
||||||
|
qp->send.fill--;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Complete receive work queue entry
|
||||||
|
*
|
||||||
|
* @v ibdev Infiniband device
|
||||||
|
* @v qp Queue pair
|
||||||
|
* @v completion Completion
|
||||||
|
* @v iobuf I/O buffer
|
||||||
|
*/
|
||||||
|
void ib_complete_recv ( struct ib_device *ibdev, struct ib_queue_pair *qp,
|
||||||
|
struct ib_completion *completion,
|
||||||
|
struct io_buffer *iobuf ) {
|
||||||
|
qp->recv.cq->complete_recv ( ibdev, qp, completion, iobuf );
|
||||||
|
qp->recv.fill--;
|
||||||
|
}
|
||||||
|
|
||||||
/***************************************************************************
|
/***************************************************************************
|
||||||
*
|
*
|
||||||
* Management datagram operations
|
* Management datagram operations
|
||||||
|
|
Loading…
Reference in New Issue