diff --git a/drivers/infiniband/ulp/ipoib/ipoib.h b/drivers/infiniband/ulp/ipoib/ipoib.h
index a0b3782c762504d957e63d018214ec700ed89734..158759e28a5bf3200872dde015de8181333da0ba 100644
--- a/drivers/infiniband/ulp/ipoib/ipoib.h
+++ b/drivers/infiniband/ulp/ipoib/ipoib.h
@@ -429,6 +429,7 @@ int ipoib_vlan_delete(struct net_device *pdev, unsigned short pkey);
 
 void ipoib_pkey_poll(struct work_struct *work);
 int ipoib_pkey_dev_delay_open(struct net_device *dev);
+void ipoib_drain_cq(struct net_device *dev);
 
 #ifdef CONFIG_INFINIBAND_IPOIB_CM
 
diff --git a/drivers/infiniband/ulp/ipoib/ipoib_cm.c b/drivers/infiniband/ulp/ipoib/ipoib_cm.c
index e8fcd628be73fcca1791b505c01471e0f0c42ca0..f133b56fd978dd4aefef36efe58ff849e06bb75e 100644
--- a/drivers/infiniband/ulp/ipoib/ipoib_cm.c
+++ b/drivers/infiniband/ulp/ipoib/ipoib_cm.c
@@ -726,6 +726,7 @@ void ipoib_cm_dev_stop(struct net_device *dev)
 		}
 		spin_unlock_irq(&priv->lock);
 		msleep(1);
+		ipoib_drain_cq(dev);
 		spin_lock_irq(&priv->lock);
 	}
 
diff --git a/drivers/infiniband/ulp/ipoib/ipoib_ib.c b/drivers/infiniband/ulp/ipoib/ipoib_ib.c
index c1aad06eb4e9b0222457b5c7efc8fc146a39b839..8404f05b2b6eefd04a018b5da67698b65cfb09fd 100644
--- a/drivers/infiniband/ulp/ipoib/ipoib_ib.c
+++ b/drivers/infiniband/ulp/ipoib/ipoib_ib.c
@@ -550,13 +550,30 @@ static int recvs_pending(struct net_device *dev)
 	return pending;
 }
 
+void ipoib_drain_cq(struct net_device *dev)
+{
+	struct ipoib_dev_priv *priv = netdev_priv(dev);
+	int i, n;
+	do {
+		n = ib_poll_cq(priv->cq, IPOIB_NUM_WC, priv->ibwc);
+		for (i = 0; i < n; ++i) {
+			if (priv->ibwc[i].wr_id & IPOIB_CM_OP_SRQ)
+				ipoib_cm_handle_rx_wc(dev, priv->ibwc + i);
+			else if (priv->ibwc[i].wr_id & IPOIB_OP_RECV)
+				ipoib_ib_handle_rx_wc(dev, priv->ibwc + i);
+			else
+				ipoib_ib_handle_tx_wc(dev, priv->ibwc + i);
+		}
+	} while (n == IPOIB_NUM_WC);
+}
+
 int ipoib_ib_dev_stop(struct net_device *dev, int flush)
 {
 	struct ipoib_dev_priv *priv = netdev_priv(dev);
 	struct ib_qp_attr qp_attr;
 	unsigned long begin;
 	struct ipoib_tx_buf *tx_req;
-	int i, n;
+	int i;
 
 	clear_bit(IPOIB_FLAG_INITIALIZED, &priv->flags);
 	netif_poll_disable(dev);
@@ -611,17 +628,7 @@ int ipoib_ib_dev_stop(struct net_device *dev, int flush)
 			goto timeout;
 		}
 
-		do {
-			n = ib_poll_cq(priv->cq, IPOIB_NUM_WC, priv->ibwc);
-			for (i = 0; i < n; ++i) {
-				if (priv->ibwc[i].wr_id & IPOIB_CM_OP_SRQ)
-					ipoib_cm_handle_rx_wc(dev, priv->ibwc + i);
-				else if (priv->ibwc[i].wr_id & IPOIB_OP_RECV)
-					ipoib_ib_handle_rx_wc(dev, priv->ibwc + i);
-				else
-					ipoib_ib_handle_tx_wc(dev, priv->ibwc + i);
-			}
-		} while (n == IPOIB_NUM_WC);
+		ipoib_drain_cq(dev);
 
 		msleep(1);
 	}