Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1759638AbdLRQYg (ORCPT ); Mon, 18 Dec 2017 11:24:36 -0500 Received: from mail.linuxfoundation.org ([140.211.169.12]:45512 "EHLO mail.linuxfoundation.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S936454AbdLRQSM (ORCPT ); Mon, 18 Dec 2017 11:18:12 -0500 From: Greg Kroah-Hartman To: linux-kernel@vger.kernel.org Cc: Greg Kroah-Hartman , stable@vger.kernel.org, Alex Vesker , Sasha Levin Subject: [PATCH 4.14 167/178] IB/ipoib: Grab rtnl lock on heavy flush when calling ndo_open/stop Date: Mon, 18 Dec 2017 16:50:03 +0100 Message-Id: <20171218152927.855193134@linuxfoundation.org> X-Mailer: git-send-email 2.15.1 In-Reply-To: <20171218152920.567991776@linuxfoundation.org> References: <20171218152920.567991776@linuxfoundation.org> User-Agent: quilt/0.65 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Length: 1236 Lines: 41 4.14-stable review patch. If anyone has any objections, please let me know. ------------------ From: Alex Vesker [ Upstream commit b4b678b06f6eef18bff44a338c01870234db0bc9 ] When ndo_open and ndo_stop are called RTNL lock should be held. In this specific case ipoib_ib_dev_open calls the offloaded ndo_open which re-sets the number of TX queue assuming RTNL lock is held. Since RTNL lock is not held, RTNL assert will fail. Signed-off-by: Alex Vesker Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/infiniband/ulp/ipoib/ipoib_ib.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) --- a/drivers/infiniband/ulp/ipoib/ipoib_ib.c +++ b/drivers/infiniband/ulp/ipoib/ipoib_ib.c @@ -1203,10 +1203,15 @@ static void __ipoib_ib_dev_flush(struct ipoib_ib_dev_down(dev); if (level == IPOIB_FLUSH_HEAVY) { + rtnl_lock(); if (test_bit(IPOIB_FLAG_INITIALIZED, &priv->flags)) ipoib_ib_dev_stop(dev); - if (ipoib_ib_dev_open(dev) != 0) + + result = ipoib_ib_dev_open(dev); + rtnl_unlock(); + if (result) return; + if (netif_queue_stopped(dev)) netif_start_queue(dev); }