Commit f7edd5fb authored by Linus Torvalds's avatar Linus Torvalds

Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/roland/infiniband

* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/roland/infiniband:
  IPoIB: Fix deadlock on RTNL in ipoib_stop()
  IB/ipath: Fix incorrect check for max physical address in TID
  IB/ipath: Fix lost UD send work request
parents a22c50c3 45dd75d8
...@@ -1720,7 +1720,7 @@ static void ipath_7220_put_tid(struct ipath_devdata *dd, u64 __iomem *tidptr, ...@@ -1720,7 +1720,7 @@ static void ipath_7220_put_tid(struct ipath_devdata *dd, u64 __iomem *tidptr,
"not 2KB aligned!\n", pa); "not 2KB aligned!\n", pa);
return; return;
} }
if (pa >= (1UL << IBA7220_TID_SZ_SHIFT)) { if (chippa >= (1UL << IBA7220_TID_SZ_SHIFT)) {
ipath_dev_err(dd, ipath_dev_err(dd,
"BUG: Physical page address 0x%lx " "BUG: Physical page address 0x%lx "
"larger than supported\n", pa); "larger than supported\n", pa);
......
...@@ -267,6 +267,7 @@ int ipath_make_ud_req(struct ipath_qp *qp) ...@@ -267,6 +267,7 @@ int ipath_make_ud_req(struct ipath_qp *qp)
u16 lrh0; u16 lrh0;
u16 lid; u16 lid;
int ret = 0; int ret = 0;
int next_cur;
spin_lock_irqsave(&qp->s_lock, flags); spin_lock_irqsave(&qp->s_lock, flags);
...@@ -290,8 +291,9 @@ int ipath_make_ud_req(struct ipath_qp *qp) ...@@ -290,8 +291,9 @@ int ipath_make_ud_req(struct ipath_qp *qp)
goto bail; goto bail;
wqe = get_swqe_ptr(qp, qp->s_cur); wqe = get_swqe_ptr(qp, qp->s_cur);
if (++qp->s_cur >= qp->s_size) next_cur = qp->s_cur + 1;
qp->s_cur = 0; if (next_cur >= qp->s_size)
next_cur = 0;
/* Construct the header. */ /* Construct the header. */
ah_attr = &to_iah(wqe->wr.wr.ud.ah)->attr; ah_attr = &to_iah(wqe->wr.wr.ud.ah)->attr;
...@@ -315,6 +317,7 @@ int ipath_make_ud_req(struct ipath_qp *qp) ...@@ -315,6 +317,7 @@ int ipath_make_ud_req(struct ipath_qp *qp)
qp->s_flags |= IPATH_S_WAIT_DMA; qp->s_flags |= IPATH_S_WAIT_DMA;
goto bail; goto bail;
} }
qp->s_cur = next_cur;
spin_unlock_irqrestore(&qp->s_lock, flags); spin_unlock_irqrestore(&qp->s_lock, flags);
ipath_ud_loopback(qp, wqe); ipath_ud_loopback(qp, wqe);
spin_lock_irqsave(&qp->s_lock, flags); spin_lock_irqsave(&qp->s_lock, flags);
...@@ -323,6 +326,7 @@ int ipath_make_ud_req(struct ipath_qp *qp) ...@@ -323,6 +326,7 @@ int ipath_make_ud_req(struct ipath_qp *qp)
} }
} }
qp->s_cur = next_cur;
extra_bytes = -wqe->length & 3; extra_bytes = -wqe->length & 3;
nwords = (wqe->length + extra_bytes) >> 2; nwords = (wqe->length + extra_bytes) >> 2;
......
...@@ -156,14 +156,8 @@ static int ipoib_stop(struct net_device *dev) ...@@ -156,14 +156,8 @@ static int ipoib_stop(struct net_device *dev)
netif_stop_queue(dev); netif_stop_queue(dev);
/* ipoib_ib_dev_down(dev, 0);
* Now flush workqueue to make sure a scheduled task doesn't ipoib_ib_dev_stop(dev, 0);
* bring our internal state back up.
*/
flush_workqueue(ipoib_workqueue);
ipoib_ib_dev_down(dev, 1);
ipoib_ib_dev_stop(dev, 1);
if (!test_bit(IPOIB_FLAG_SUBINTERFACE, &priv->flags)) { if (!test_bit(IPOIB_FLAG_SUBINTERFACE, &priv->flags)) {
struct ipoib_dev_priv *cpriv; struct ipoib_dev_priv *cpriv;
...@@ -1314,7 +1308,7 @@ static struct net_device *ipoib_add_port(const char *format, ...@@ -1314,7 +1308,7 @@ static struct net_device *ipoib_add_port(const char *format,
register_failed: register_failed:
ib_unregister_event_handler(&priv->event_handler); ib_unregister_event_handler(&priv->event_handler);
flush_scheduled_work(); flush_workqueue(ipoib_workqueue);
event_failed: event_failed:
ipoib_dev_cleanup(priv->dev); ipoib_dev_cleanup(priv->dev);
...@@ -1373,7 +1367,12 @@ static void ipoib_remove_one(struct ib_device *device) ...@@ -1373,7 +1367,12 @@ static void ipoib_remove_one(struct ib_device *device)
list_for_each_entry_safe(priv, tmp, dev_list, list) { list_for_each_entry_safe(priv, tmp, dev_list, list) {
ib_unregister_event_handler(&priv->event_handler); ib_unregister_event_handler(&priv->event_handler);
flush_scheduled_work();
rtnl_lock();
dev_change_flags(priv->dev, priv->dev->flags & ~IFF_UP);
rtnl_unlock();
flush_workqueue(ipoib_workqueue);
unregister_netdev(priv->dev); unregister_netdev(priv->dev);
ipoib_dev_cleanup(priv->dev); ipoib_dev_cleanup(priv->dev);
......
...@@ -392,8 +392,16 @@ static int ipoib_mcast_join_complete(int status, ...@@ -392,8 +392,16 @@ static int ipoib_mcast_join_complete(int status,
&priv->mcast_task, 0); &priv->mcast_task, 0);
mutex_unlock(&mcast_mutex); mutex_unlock(&mcast_mutex);
if (mcast == priv->broadcast) if (mcast == priv->broadcast) {
/*
* Take RTNL lock here to avoid racing with
* ipoib_stop() and turning the carrier back
* on while a device is being removed.
*/
rtnl_lock();
netif_carrier_on(dev); netif_carrier_on(dev);
rtnl_unlock();
}
return 0; return 0;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment