Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit f7edd5fb authored by Linus Torvalds's avatar Linus Torvalds
Browse files
* '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
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -1720,7 +1720,7 @@ static void ipath_7220_put_tid(struct ipath_devdata *dd, u64 __iomem *tidptr,
				 "not 2KB aligned!\n", pa);
			return;
		}
		if (pa >= (1UL << IBA7220_TID_SZ_SHIFT)) {
		if (chippa >= (1UL << IBA7220_TID_SZ_SHIFT)) {
			ipath_dev_err(dd,
				      "BUG: Physical page address 0x%lx "
				      "larger than supported\n", pa);
+6 −2
Original line number Diff line number Diff line
@@ -267,6 +267,7 @@ int ipath_make_ud_req(struct ipath_qp *qp)
	u16 lrh0;
	u16 lid;
	int ret = 0;
	int next_cur;

	spin_lock_irqsave(&qp->s_lock, flags);

@@ -290,8 +291,9 @@ int ipath_make_ud_req(struct ipath_qp *qp)
		goto bail;

	wqe = get_swqe_ptr(qp, qp->s_cur);
	if (++qp->s_cur >= qp->s_size)
		qp->s_cur = 0;
	next_cur = qp->s_cur + 1;
	if (next_cur >= qp->s_size)
		next_cur = 0;

	/* Construct the header. */
	ah_attr = &to_iah(wqe->wr.wr.ud.ah)->attr;
@@ -315,6 +317,7 @@ int ipath_make_ud_req(struct ipath_qp *qp)
				qp->s_flags |= IPATH_S_WAIT_DMA;
				goto bail;
			}
			qp->s_cur = next_cur;
			spin_unlock_irqrestore(&qp->s_lock, flags);
			ipath_ud_loopback(qp, wqe);
			spin_lock_irqsave(&qp->s_lock, flags);
@@ -323,6 +326,7 @@ int ipath_make_ud_req(struct ipath_qp *qp)
		}
	}

	qp->s_cur = next_cur;
	extra_bytes = -wqe->length & 3;
	nwords = (wqe->length + extra_bytes) >> 2;

+9 −10
Original line number Diff line number Diff line
@@ -156,14 +156,8 @@ static int ipoib_stop(struct net_device *dev)

	netif_stop_queue(dev);

	/*
	 * Now flush workqueue to make sure a scheduled task doesn't
	 * bring our internal state back up.
	 */
	flush_workqueue(ipoib_workqueue);

	ipoib_ib_dev_down(dev, 1);
	ipoib_ib_dev_stop(dev, 1);
	ipoib_ib_dev_down(dev, 0);
	ipoib_ib_dev_stop(dev, 0);

	if (!test_bit(IPOIB_FLAG_SUBINTERFACE, &priv->flags)) {
		struct ipoib_dev_priv *cpriv;
@@ -1314,7 +1308,7 @@ sysfs_failed:

register_failed:
	ib_unregister_event_handler(&priv->event_handler);
	flush_scheduled_work();
	flush_workqueue(ipoib_workqueue);

event_failed:
	ipoib_dev_cleanup(priv->dev);
@@ -1373,7 +1367,12 @@ static void ipoib_remove_one(struct ib_device *device)

	list_for_each_entry_safe(priv, tmp, dev_list, list) {
		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);
		ipoib_dev_cleanup(priv->dev);
+9 −1
Original line number Diff line number Diff line
@@ -392,8 +392,16 @@ static int ipoib_mcast_join_complete(int status,
					   &priv->mcast_task, 0);
		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);
			rtnl_unlock();
		}

		return 0;
	}