diff options
Diffstat (limited to 'drivers/infiniband/ulp/ipoib/ipoib_ib.c')
-rw-r--r-- | drivers/infiniband/ulp/ipoib/ipoib_ib.c | 52 |
1 files changed, 31 insertions, 21 deletions
diff --git a/drivers/infiniband/ulp/ipoib/ipoib_ib.c b/drivers/infiniband/ulp/ipoib/ipoib_ib.c index 1a77e79f6b43..5063dd509ad2 100644 --- a/drivers/infiniband/ulp/ipoib/ipoib_ib.c +++ b/drivers/infiniband/ulp/ipoib/ipoib_ib.c | |||
@@ -267,11 +267,10 @@ static void ipoib_ib_handle_tx_wc(struct net_device *dev, struct ib_wc *wc) | |||
267 | 267 | ||
268 | spin_lock_irqsave(&priv->tx_lock, flags); | 268 | spin_lock_irqsave(&priv->tx_lock, flags); |
269 | ++priv->tx_tail; | 269 | ++priv->tx_tail; |
270 | if (unlikely(test_bit(IPOIB_FLAG_NETIF_STOPPED, &priv->flags)) && | 270 | if (unlikely(--priv->tx_outstanding == ipoib_sendq_size >> 1) && |
271 | priv->tx_head - priv->tx_tail <= ipoib_sendq_size >> 1) { | 271 | netif_queue_stopped(dev) && |
272 | clear_bit(IPOIB_FLAG_NETIF_STOPPED, &priv->flags); | 272 | test_bit(IPOIB_FLAG_ADMIN_UP, &priv->flags)) |
273 | netif_wake_queue(dev); | 273 | netif_wake_queue(dev); |
274 | } | ||
275 | spin_unlock_irqrestore(&priv->tx_lock, flags); | 274 | spin_unlock_irqrestore(&priv->tx_lock, flags); |
276 | 275 | ||
277 | if (wc->status != IB_WC_SUCCESS && | 276 | if (wc->status != IB_WC_SUCCESS && |
@@ -301,14 +300,18 @@ poll_more: | |||
301 | for (i = 0; i < n; i++) { | 300 | for (i = 0; i < n; i++) { |
302 | struct ib_wc *wc = priv->ibwc + i; | 301 | struct ib_wc *wc = priv->ibwc + i; |
303 | 302 | ||
304 | if (wc->wr_id & IPOIB_CM_OP_SRQ) { | 303 | if (wc->wr_id & IPOIB_OP_RECV) { |
305 | ++done; | ||
306 | ipoib_cm_handle_rx_wc(dev, wc); | ||
307 | } else if (wc->wr_id & IPOIB_OP_RECV) { | ||
308 | ++done; | 304 | ++done; |
309 | ipoib_ib_handle_rx_wc(dev, wc); | 305 | if (wc->wr_id & IPOIB_OP_CM) |
310 | } else | 306 | ipoib_cm_handle_rx_wc(dev, wc); |
311 | ipoib_ib_handle_tx_wc(dev, wc); | 307 | else |
308 | ipoib_ib_handle_rx_wc(dev, wc); | ||
309 | } else { | ||
310 | if (wc->wr_id & IPOIB_OP_CM) | ||
311 | ipoib_cm_handle_tx_wc(dev, wc); | ||
312 | else | ||
313 | ipoib_ib_handle_tx_wc(dev, wc); | ||
314 | } | ||
312 | } | 315 | } |
313 | 316 | ||
314 | if (n != t) | 317 | if (n != t) |
@@ -401,10 +404,9 @@ void ipoib_send(struct net_device *dev, struct sk_buff *skb, | |||
401 | address->last_send = priv->tx_head; | 404 | address->last_send = priv->tx_head; |
402 | ++priv->tx_head; | 405 | ++priv->tx_head; |
403 | 406 | ||
404 | if (priv->tx_head - priv->tx_tail == ipoib_sendq_size) { | 407 | if (++priv->tx_outstanding == ipoib_sendq_size) { |
405 | ipoib_dbg(priv, "TX ring full, stopping kernel net queue\n"); | 408 | ipoib_dbg(priv, "TX ring full, stopping kernel net queue\n"); |
406 | netif_stop_queue(dev); | 409 | netif_stop_queue(dev); |
407 | set_bit(IPOIB_FLAG_NETIF_STOPPED, &priv->flags); | ||
408 | } | 410 | } |
409 | } | 411 | } |
410 | } | 412 | } |
@@ -436,7 +438,8 @@ void ipoib_reap_ah(struct work_struct *work) | |||
436 | __ipoib_reap_ah(dev); | 438 | __ipoib_reap_ah(dev); |
437 | 439 | ||
438 | if (!test_bit(IPOIB_STOP_REAPER, &priv->flags)) | 440 | if (!test_bit(IPOIB_STOP_REAPER, &priv->flags)) |
439 | queue_delayed_work(ipoib_workqueue, &priv->ah_reap_task, HZ); | 441 | queue_delayed_work(ipoib_workqueue, &priv->ah_reap_task, |
442 | round_jiffies_relative(HZ)); | ||
440 | } | 443 | } |
441 | 444 | ||
442 | int ipoib_ib_dev_open(struct net_device *dev) | 445 | int ipoib_ib_dev_open(struct net_device *dev) |
@@ -472,7 +475,8 @@ int ipoib_ib_dev_open(struct net_device *dev) | |||
472 | } | 475 | } |
473 | 476 | ||
474 | clear_bit(IPOIB_STOP_REAPER, &priv->flags); | 477 | clear_bit(IPOIB_STOP_REAPER, &priv->flags); |
475 | queue_delayed_work(ipoib_workqueue, &priv->ah_reap_task, HZ); | 478 | queue_delayed_work(ipoib_workqueue, &priv->ah_reap_task, |
479 | round_jiffies_relative(HZ)); | ||
476 | 480 | ||
477 | set_bit(IPOIB_FLAG_INITIALIZED, &priv->flags); | 481 | set_bit(IPOIB_FLAG_INITIALIZED, &priv->flags); |
478 | 482 | ||
@@ -561,12 +565,17 @@ void ipoib_drain_cq(struct net_device *dev) | |||
561 | if (priv->ibwc[i].status == IB_WC_SUCCESS) | 565 | if (priv->ibwc[i].status == IB_WC_SUCCESS) |
562 | priv->ibwc[i].status = IB_WC_WR_FLUSH_ERR; | 566 | priv->ibwc[i].status = IB_WC_WR_FLUSH_ERR; |
563 | 567 | ||
564 | if (priv->ibwc[i].wr_id & IPOIB_CM_OP_SRQ) | 568 | if (priv->ibwc[i].wr_id & IPOIB_OP_RECV) { |
565 | ipoib_cm_handle_rx_wc(dev, priv->ibwc + i); | 569 | if (priv->ibwc[i].wr_id & IPOIB_OP_CM) |
566 | else if (priv->ibwc[i].wr_id & IPOIB_OP_RECV) | 570 | ipoib_cm_handle_rx_wc(dev, priv->ibwc + i); |
567 | ipoib_ib_handle_rx_wc(dev, priv->ibwc + i); | 571 | else |
568 | else | 572 | ipoib_ib_handle_rx_wc(dev, priv->ibwc + i); |
569 | ipoib_ib_handle_tx_wc(dev, priv->ibwc + i); | 573 | } else { |
574 | if (priv->ibwc[i].wr_id & IPOIB_OP_CM) | ||
575 | ipoib_cm_handle_tx_wc(dev, priv->ibwc + i); | ||
576 | else | ||
577 | ipoib_ib_handle_tx_wc(dev, priv->ibwc + i); | ||
578 | } | ||
570 | } | 579 | } |
571 | } while (n == IPOIB_NUM_WC); | 580 | } while (n == IPOIB_NUM_WC); |
572 | } | 581 | } |
@@ -612,6 +621,7 @@ int ipoib_ib_dev_stop(struct net_device *dev, int flush) | |||
612 | DMA_TO_DEVICE); | 621 | DMA_TO_DEVICE); |
613 | dev_kfree_skb_any(tx_req->skb); | 622 | dev_kfree_skb_any(tx_req->skb); |
614 | ++priv->tx_tail; | 623 | ++priv->tx_tail; |
624 | --priv->tx_outstanding; | ||
615 | } | 625 | } |
616 | 626 | ||
617 | for (i = 0; i < ipoib_recvq_size; ++i) { | 627 | for (i = 0; i < ipoib_recvq_size; ++i) { |