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;
|
||||
/** Queue pair */
|
||||
struct ib_queue_pair *qp;
|
||||
/** Receive work queue fill level */
|
||||
unsigned int recv_fill;
|
||||
/** Receive work queue maximum fill level */
|
||||
unsigned int recv_max_fill;
|
||||
};
|
||||
|
@ -565,7 +563,7 @@ static void ipoib_data_complete_recv ( struct ib_device *ibdev __unused,
|
|||
|
||||
if ( completion->syndrome ) {
|
||||
netdev_rx_err ( netdev, iobuf, -EIO );
|
||||
goto done;
|
||||
return;
|
||||
}
|
||||
|
||||
iob_put ( iobuf, completion->len );
|
||||
|
@ -574,7 +572,7 @@ static void ipoib_data_complete_recv ( struct ib_device *ibdev __unused,
|
|||
"contain GRH\n", ipoib );
|
||||
DBGC_HD ( ipoib, iobuf->data, iob_len ( iobuf ) );
|
||||
netdev_rx_err ( netdev, iobuf, -EIO );
|
||||
goto done;
|
||||
return;
|
||||
}
|
||||
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 );
|
||||
DBGC_HD ( ipoib, iobuf->data, iob_len ( iobuf ) );
|
||||
netdev_rx_err ( netdev, iobuf, -EIO );
|
||||
goto done;
|
||||
return;
|
||||
}
|
||||
|
||||
ipoib_pshdr = iob_push ( iobuf, sizeof ( *ipoib_pshdr ) );
|
||||
/* FIXME: fill in a MAC address for the sake of AoE! */
|
||||
|
||||
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:
|
||||
ipoib->meta.recv_fill--;
|
||||
free_iob ( iobuf );
|
||||
}
|
||||
|
||||
|
@ -747,7 +741,7 @@ static void ipoib_refill_recv ( struct ipoib_device *ipoib,
|
|||
struct io_buffer *iobuf;
|
||||
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 );
|
||||
if ( ! iobuf )
|
||||
break;
|
||||
|
@ -755,7 +749,6 @@ static void ipoib_refill_recv ( struct ipoib_device *ipoib,
|
|||
free_iob ( iobuf );
|
||||
break;
|
||||
}
|
||||
qset->recv_fill++;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -66,6 +66,8 @@ struct ib_work_queue {
|
|||
struct list_head list;
|
||||
/** Number of work queue entries */
|
||||
unsigned int num_wqes;
|
||||
/** Number of occupied work queue entries */
|
||||
unsigned int fill;
|
||||
/** Next work queue entry index
|
||||
*
|
||||
* 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 );
|
||||
extern struct ib_work_queue * ib_find_wq ( struct ib_completion_queue *cq,
|
||||
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 int register_ibdev ( struct ib_device *ibdev );
|
||||
extern void unregister_ibdev ( 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
|
||||
*
|
||||
|
|
|
@ -244,6 +244,97 @@ struct ib_work_queue * ib_find_wq ( struct ib_completion_queue *cq,
|
|||
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
|
||||
|
|
Loading…
Reference in New Issue