david/ipxe
david
/
ipxe
Archived
1
0
Fork 0

[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.
This commit is contained in:
Michael Brown 2008-10-03 03:04:21 +01:00
parent d9751edafa
commit 0de5f7af6d
3 changed files with 110 additions and 70 deletions

View File

@ -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++;
} }
} }

View File

@ -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
* *

View File

@ -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