Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1947386AbbEBThk (ORCPT ); Sat, 2 May 2015 15:37:40 -0400 Received: from mail.linuxfoundation.org ([140.211.169.12]:46022 "EHLO mail.linuxfoundation.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1947345AbbEBThg (ORCPT ); Sat, 2 May 2015 15:37:36 -0400 From: Greg Kroah-Hartman To: linux-kernel@vger.kernel.org Cc: Greg Kroah-Hartman , stable@vger.kernel.org, Max Filippov Subject: [PATCH 3.19 131/177] xtensa: ISS: fix locking in TAP network adapter Date: Sat, 2 May 2015 21:02:33 +0200 Message-Id: <20150502190126.064520000@linuxfoundation.org> X-Mailer: git-send-email 2.3.7 In-Reply-To: <20150502190119.666291882@linuxfoundation.org> References: <20150502190119.666291882@linuxfoundation.org> User-Agent: quilt/0.64 MIME-Version: 1.0 Content-Type: text/plain; charset=ISO-8859-15 Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Length: 4131 Lines: 142 3.19-stable review patch. If anyone has any objections, please let me know. ------------------ From: Max Filippov commit 24e94454c8cb6a13634f5a2f5a01da53a546a58d upstream. - don't lock lp->lock in the iss_net_timer for the call of iss_net_poll, it will lock it itself; - invert order of lp->lock and opened_lock acquisition in the iss_net_open to make it consistent with iss_net_poll; - replace spin_lock with spin_lock_bh when acquiring locks used in iss_net_timer from non-atomic context; - replace spin_lock_irqsave with spin_lock_bh in the iss_net_start_xmit as the driver doesn't use lp->lock in the hard IRQ context; - replace __SPIN_LOCK_UNLOCKED(lp.lock) with spin_lock_init, otherwise lockdep is unhappy about using non-static key. Signed-off-by: Max Filippov Signed-off-by: Greg Kroah-Hartman --- arch/xtensa/platforms/iss/network.c | 29 +++++++++++++++-------------- 1 file changed, 15 insertions(+), 14 deletions(-) --- a/arch/xtensa/platforms/iss/network.c +++ b/arch/xtensa/platforms/iss/network.c @@ -349,8 +349,8 @@ static void iss_net_timer(unsigned long { struct iss_net_private *lp = (struct iss_net_private *)priv; - spin_lock(&lp->lock); iss_net_poll(); + spin_lock(&lp->lock); mod_timer(&lp->timer, jiffies + lp->timer_val); spin_unlock(&lp->lock); } @@ -361,7 +361,7 @@ static int iss_net_open(struct net_devic struct iss_net_private *lp = netdev_priv(dev); int err; - spin_lock(&lp->lock); + spin_lock_bh(&lp->lock); err = lp->tp.open(lp); if (err < 0) @@ -376,9 +376,11 @@ static int iss_net_open(struct net_devic while ((err = iss_net_rx(dev)) > 0) ; - spin_lock(&opened_lock); + spin_unlock_bh(&lp->lock); + spin_lock_bh(&opened_lock); list_add(&lp->opened_list, &opened); - spin_unlock(&opened_lock); + spin_unlock_bh(&opened_lock); + spin_lock_bh(&lp->lock); init_timer(&lp->timer); lp->timer_val = ISS_NET_TIMER_VALUE; @@ -387,7 +389,7 @@ static int iss_net_open(struct net_devic mod_timer(&lp->timer, jiffies + lp->timer_val); out: - spin_unlock(&lp->lock); + spin_unlock_bh(&lp->lock); return err; } @@ -395,7 +397,7 @@ static int iss_net_close(struct net_devi { struct iss_net_private *lp = netdev_priv(dev); netif_stop_queue(dev); - spin_lock(&lp->lock); + spin_lock_bh(&lp->lock); spin_lock(&opened_lock); list_del(&opened); @@ -405,18 +407,17 @@ static int iss_net_close(struct net_devi lp->tp.close(lp); - spin_unlock(&lp->lock); + spin_unlock_bh(&lp->lock); return 0; } static int iss_net_start_xmit(struct sk_buff *skb, struct net_device *dev) { struct iss_net_private *lp = netdev_priv(dev); - unsigned long flags; int len; netif_stop_queue(dev); - spin_lock_irqsave(&lp->lock, flags); + spin_lock_bh(&lp->lock); len = lp->tp.write(lp, &skb); @@ -438,7 +439,7 @@ static int iss_net_start_xmit(struct sk_ pr_err("%s: %s failed(%d)\n", dev->name, __func__, len); } - spin_unlock_irqrestore(&lp->lock, flags); + spin_unlock_bh(&lp->lock); dev_kfree_skb(skb); return NETDEV_TX_OK; @@ -466,9 +467,9 @@ static int iss_net_set_mac(struct net_de if (!is_valid_ether_addr(hwaddr->sa_data)) return -EADDRNOTAVAIL; - spin_lock(&lp->lock); + spin_lock_bh(&lp->lock); memcpy(dev->dev_addr, hwaddr->sa_data, ETH_ALEN); - spin_unlock(&lp->lock); + spin_unlock_bh(&lp->lock); return 0; } @@ -520,11 +521,11 @@ static int iss_net_configure(int index, *lp = (struct iss_net_private) { .device_list = LIST_HEAD_INIT(lp->device_list), .opened_list = LIST_HEAD_INIT(lp->opened_list), - .lock = __SPIN_LOCK_UNLOCKED(lp.lock), .dev = dev, .index = index, - }; + }; + spin_lock_init(&lp->lock); /* * If this name ends up conflicting with an existing registered * netdevice, that is OK, register_netdev{,ice}() will notice this -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/