diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2008-08-22 11:21:48 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2008-08-22 11:21:48 -0400 |
commit | f7edd5fbde8af44fa06218f56e0f648fc7a527c8 (patch) | |
tree | 1c44c189813d678d700b8f3e1b94b16a70de7a0b /drivers | |
parent | a22c50c302c58ba2d1d2846e85239ba80da61a56 (diff) | |
parent | 45dd75d83cef8c4e4a8d78bc8ed072a01196d30c (diff) |
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
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/infiniband/hw/ipath/ipath_iba7220.c | 2 | ||||
-rw-r--r-- | drivers/infiniband/hw/ipath/ipath_ud.c | 8 | ||||
-rw-r--r-- | drivers/infiniband/ulp/ipoib/ipoib_main.c | 19 | ||||
-rw-r--r-- | drivers/infiniband/ulp/ipoib/ipoib_multicast.c | 10 |
4 files changed, 25 insertions, 14 deletions
diff --git a/drivers/infiniband/hw/ipath/ipath_iba7220.c b/drivers/infiniband/hw/ipath/ipath_iba7220.c index d90f5e9a54fa..9839e20119bc 100644 --- a/drivers/infiniband/hw/ipath/ipath_iba7220.c +++ b/drivers/infiniband/hw/ipath/ipath_iba7220.c | |||
@@ -1720,7 +1720,7 @@ static void ipath_7220_put_tid(struct ipath_devdata *dd, u64 __iomem *tidptr, | |||
1720 | "not 2KB aligned!\n", pa); | 1720 | "not 2KB aligned!\n", pa); |
1721 | return; | 1721 | return; |
1722 | } | 1722 | } |
1723 | if (pa >= (1UL << IBA7220_TID_SZ_SHIFT)) { | 1723 | if (chippa >= (1UL << IBA7220_TID_SZ_SHIFT)) { |
1724 | ipath_dev_err(dd, | 1724 | ipath_dev_err(dd, |
1725 | "BUG: Physical page address 0x%lx " | 1725 | "BUG: Physical page address 0x%lx " |
1726 | "larger than supported\n", pa); | 1726 | "larger than supported\n", pa); |
diff --git a/drivers/infiniband/hw/ipath/ipath_ud.c b/drivers/infiniband/hw/ipath/ipath_ud.c index 36aa242c487c..729446f56aab 100644 --- a/drivers/infiniband/hw/ipath/ipath_ud.c +++ b/drivers/infiniband/hw/ipath/ipath_ud.c | |||
@@ -267,6 +267,7 @@ int ipath_make_ud_req(struct ipath_qp *qp) | |||
267 | u16 lrh0; | 267 | u16 lrh0; |
268 | u16 lid; | 268 | u16 lid; |
269 | int ret = 0; | 269 | int ret = 0; |
270 | int next_cur; | ||
270 | 271 | ||
271 | spin_lock_irqsave(&qp->s_lock, flags); | 272 | spin_lock_irqsave(&qp->s_lock, flags); |
272 | 273 | ||
@@ -290,8 +291,9 @@ int ipath_make_ud_req(struct ipath_qp *qp) | |||
290 | goto bail; | 291 | goto bail; |
291 | 292 | ||
292 | wqe = get_swqe_ptr(qp, qp->s_cur); | 293 | wqe = get_swqe_ptr(qp, qp->s_cur); |
293 | if (++qp->s_cur >= qp->s_size) | 294 | next_cur = qp->s_cur + 1; |
294 | qp->s_cur = 0; | 295 | if (next_cur >= qp->s_size) |
296 | next_cur = 0; | ||
295 | 297 | ||
296 | /* Construct the header. */ | 298 | /* Construct the header. */ |
297 | ah_attr = &to_iah(wqe->wr.wr.ud.ah)->attr; | 299 | ah_attr = &to_iah(wqe->wr.wr.ud.ah)->attr; |
@@ -315,6 +317,7 @@ int ipath_make_ud_req(struct ipath_qp *qp) | |||
315 | qp->s_flags |= IPATH_S_WAIT_DMA; | 317 | qp->s_flags |= IPATH_S_WAIT_DMA; |
316 | goto bail; | 318 | goto bail; |
317 | } | 319 | } |
320 | qp->s_cur = next_cur; | ||
318 | spin_unlock_irqrestore(&qp->s_lock, flags); | 321 | spin_unlock_irqrestore(&qp->s_lock, flags); |
319 | ipath_ud_loopback(qp, wqe); | 322 | ipath_ud_loopback(qp, wqe); |
320 | spin_lock_irqsave(&qp->s_lock, flags); | 323 | spin_lock_irqsave(&qp->s_lock, flags); |
@@ -323,6 +326,7 @@ int ipath_make_ud_req(struct ipath_qp *qp) | |||
323 | } | 326 | } |
324 | } | 327 | } |
325 | 328 | ||
329 | qp->s_cur = next_cur; | ||
326 | extra_bytes = -wqe->length & 3; | 330 | extra_bytes = -wqe->length & 3; |
327 | nwords = (wqe->length + extra_bytes) >> 2; | 331 | nwords = (wqe->length + extra_bytes) >> 2; |
328 | 332 | ||
diff --git a/drivers/infiniband/ulp/ipoib/ipoib_main.c b/drivers/infiniband/ulp/ipoib/ipoib_main.c index f51201b17bfd..7e9e218738fa 100644 --- a/drivers/infiniband/ulp/ipoib/ipoib_main.c +++ b/drivers/infiniband/ulp/ipoib/ipoib_main.c | |||
@@ -156,14 +156,8 @@ static int ipoib_stop(struct net_device *dev) | |||
156 | 156 | ||
157 | netif_stop_queue(dev); | 157 | netif_stop_queue(dev); |
158 | 158 | ||
159 | /* | 159 | ipoib_ib_dev_down(dev, 0); |
160 | * Now flush workqueue to make sure a scheduled task doesn't | 160 | ipoib_ib_dev_stop(dev, 0); |
161 | * bring our internal state back up. | ||
162 | */ | ||
163 | flush_workqueue(ipoib_workqueue); | ||
164 | |||
165 | ipoib_ib_dev_down(dev, 1); | ||
166 | ipoib_ib_dev_stop(dev, 1); | ||
167 | 161 | ||
168 | if (!test_bit(IPOIB_FLAG_SUBINTERFACE, &priv->flags)) { | 162 | if (!test_bit(IPOIB_FLAG_SUBINTERFACE, &priv->flags)) { |
169 | struct ipoib_dev_priv *cpriv; | 163 | struct ipoib_dev_priv *cpriv; |
@@ -1314,7 +1308,7 @@ sysfs_failed: | |||
1314 | 1308 | ||
1315 | register_failed: | 1309 | register_failed: |
1316 | ib_unregister_event_handler(&priv->event_handler); | 1310 | ib_unregister_event_handler(&priv->event_handler); |
1317 | flush_scheduled_work(); | 1311 | flush_workqueue(ipoib_workqueue); |
1318 | 1312 | ||
1319 | event_failed: | 1313 | event_failed: |
1320 | ipoib_dev_cleanup(priv->dev); | 1314 | ipoib_dev_cleanup(priv->dev); |
@@ -1373,7 +1367,12 @@ static void ipoib_remove_one(struct ib_device *device) | |||
1373 | 1367 | ||
1374 | list_for_each_entry_safe(priv, tmp, dev_list, list) { | 1368 | list_for_each_entry_safe(priv, tmp, dev_list, list) { |
1375 | ib_unregister_event_handler(&priv->event_handler); | 1369 | ib_unregister_event_handler(&priv->event_handler); |
1376 | flush_scheduled_work(); | 1370 | |
1371 | rtnl_lock(); | ||
1372 | dev_change_flags(priv->dev, priv->dev->flags & ~IFF_UP); | ||
1373 | rtnl_unlock(); | ||
1374 | |||
1375 | flush_workqueue(ipoib_workqueue); | ||
1377 | 1376 | ||
1378 | unregister_netdev(priv->dev); | 1377 | unregister_netdev(priv->dev); |
1379 | ipoib_dev_cleanup(priv->dev); | 1378 | ipoib_dev_cleanup(priv->dev); |
diff --git a/drivers/infiniband/ulp/ipoib/ipoib_multicast.c b/drivers/infiniband/ulp/ipoib/ipoib_multicast.c index 8950e9546f4e..ac33c8f3ea85 100644 --- a/drivers/infiniband/ulp/ipoib/ipoib_multicast.c +++ b/drivers/infiniband/ulp/ipoib/ipoib_multicast.c | |||
@@ -392,8 +392,16 @@ static int ipoib_mcast_join_complete(int status, | |||
392 | &priv->mcast_task, 0); | 392 | &priv->mcast_task, 0); |
393 | mutex_unlock(&mcast_mutex); | 393 | mutex_unlock(&mcast_mutex); |
394 | 394 | ||
395 | if (mcast == priv->broadcast) | 395 | if (mcast == priv->broadcast) { |
396 | /* | ||
397 | * Take RTNL lock here to avoid racing with | ||
398 | * ipoib_stop() and turning the carrier back | ||
399 | * on while a device is being removed. | ||
400 | */ | ||
401 | rtnl_lock(); | ||
396 | netif_carrier_on(dev); | 402 | netif_carrier_on(dev); |
403 | rtnl_unlock(); | ||
404 | } | ||
397 | 405 | ||
398 | return 0; | 406 | return 0; |
399 | } | 407 | } |