summaryrefslogtreecommitdiffstats
path: root/src/drivers/net
diff options
context:
space:
mode:
authorMichael Brown2008-10-03 01:07:52 +0200
committerMichael Brown2008-11-11 06:31:06 +0100
commitd9751edafa08b2ec3779004d4209400b95884cd4 (patch)
tree532aaeda86668006aee5fc6994e6f0b773c2a427 /src/drivers/net
parent[ne2k_isa] Restore support for ne2k isa cards (diff)
downloadipxe-d9751edafa08b2ec3779004d4209400b95884cd4.tar.gz
ipxe-d9751edafa08b2ec3779004d4209400b95884cd4.tar.xz
ipxe-d9751edafa08b2ec3779004d4209400b95884cd4.zip
[infiniband] Flush uncompleted work queue entries at QP teardown
Avoid leaking I/O buffers in ib_destroy_qp() by completing any outstanding work queue entries with a generic error code. This requires the completion handlers to be available to ib_destroy_qp(), which is done by making them static configuration parameters of the CQ (set by ib_create_cq()) rather than being provided on each call to ib_poll_cq(). This mimics the functionality of netdev_{tx,rx}_flush(). The netdev flush functions would previously have been catching any I/O buffers leaked by the IPoIB data queue (though not by the IPoIB metadata queue).
Diffstat (limited to 'src/drivers/net')
-rw-r--r--src/drivers/net/ipoib.c21
1 files changed, 16 insertions, 5 deletions
diff --git a/src/drivers/net/ipoib.c b/src/drivers/net/ipoib.c
index 812c11c95..a56ceb89e 100644
--- a/src/drivers/net/ipoib.c
+++ b/src/drivers/net/ipoib.c
@@ -278,13 +278,21 @@ static void ipoib_destroy_qset ( struct ipoib_device *ipoib,
*
* @v ipoib IPoIB device
* @v qset Queue set
+ * @v num_cqes Number of completion queue entries
+ * @v num_send_wqes Number of send work queue entries
+ * @v complete_send Send completion handler
+ * @v num_recv_wqes Number of receive work queue entries
+ * @v complete_recv Receive completion handler
+ * @v qkey Queue key
* @ret rc Return status code
*/
static int ipoib_create_qset ( struct ipoib_device *ipoib,
struct ipoib_queue_set *qset,
unsigned int num_cqes,
unsigned int num_send_wqes,
+ ib_completer_t complete_send,
unsigned int num_recv_wqes,
+ ib_completer_t complete_recv,
unsigned long qkey ) {
struct ib_device *ibdev = ipoib->ibdev;
int rc;
@@ -297,7 +305,8 @@ static int ipoib_create_qset ( struct ipoib_device *ipoib,
qset->recv_max_fill = num_recv_wqes;
/* Allocate completion queue */
- qset->cq = ib_create_cq ( ibdev, num_cqes );
+ qset->cq = ib_create_cq ( ibdev, num_cqes, complete_send,
+ complete_recv );
if ( ! qset->cq ) {
DBGC ( ipoib, "IPoIB %p could not allocate completion queue\n",
ipoib );
@@ -759,10 +768,8 @@ static void ipoib_poll ( struct net_device *netdev ) {
struct ipoib_device *ipoib = netdev->priv;
struct ib_device *ibdev = ipoib->ibdev;
- ib_poll_cq ( ibdev, ipoib->meta.cq, ipoib_meta_complete_send,
- ipoib_meta_complete_recv );
- ib_poll_cq ( ibdev, ipoib->data.cq, ipoib_data_complete_send,
- ipoib_data_complete_recv );
+ ib_poll_cq ( ibdev, ipoib->meta.cq );
+ ib_poll_cq ( ibdev, ipoib->data.cq );
ipoib_refill_recv ( ipoib, &ipoib->meta );
ipoib_refill_recv ( ipoib, &ipoib->data );
}
@@ -847,7 +854,9 @@ static int ipoib_open ( struct net_device *netdev ) {
if ( ( rc = ipoib_create_qset ( ipoib, &ipoib->meta,
IPOIB_META_NUM_CQES,
IPOIB_META_NUM_SEND_WQES,
+ ipoib_meta_complete_send,
IPOIB_META_NUM_RECV_WQES,
+ ipoib_meta_complete_recv,
IB_GLOBAL_QKEY ) ) != 0 ) {
DBGC ( ipoib, "IPoIB %p could not allocate metadata QP: %s\n",
ipoib, strerror ( rc ) );
@@ -858,7 +867,9 @@ static int ipoib_open ( struct net_device *netdev ) {
if ( ( rc = ipoib_create_qset ( ipoib, &ipoib->data,
IPOIB_DATA_NUM_CQES,
IPOIB_DATA_NUM_SEND_WQES,
+ ipoib_data_complete_send,
IPOIB_DATA_NUM_RECV_WQES,
+ ipoib_data_complete_recv,
IB_GLOBAL_QKEY ) ) != 0 ) {
DBGC ( ipoib, "IPoIB %p could not allocate data QP: %s\n",
ipoib, strerror ( rc ) );