From patchwork Wed Sep 4 18:39:53 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Taehee Yoo X-Patchwork-Id: 1157895 X-Patchwork-Delegate: davem@davemloft.net Return-Path: X-Original-To: patchwork-incoming-netdev@ozlabs.org Delivered-To: patchwork-incoming-netdev@ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=vger.kernel.org (client-ip=209.132.180.67; helo=vger.kernel.org; envelope-from=netdev-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="ZshX7DkS"; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 46Nt0l2zqMz9s4Y for ; Thu, 5 Sep 2019 04:40:07 +1000 (AEST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1733308AbfIDSkG (ORCPT ); Wed, 4 Sep 2019 14:40:06 -0400 Received: from mail-pg1-f195.google.com ([209.85.215.195]:43918 "EHLO mail-pg1-f195.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1730209AbfIDSkG (ORCPT ); Wed, 4 Sep 2019 14:40:06 -0400 Received: by mail-pg1-f195.google.com with SMTP id u72so7507185pgb.10 for ; Wed, 04 Sep 2019 11:40:05 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id; bh=Z97Ow6Uu2tS7g/PTIDrFXebWhPHzfnHD1Ve2g/wBaZI=; b=ZshX7DkSUSSsapoYockUVI4ImPQNeX+0XHdGlzV2Ip4I+TGNtW5465TVHlwcxW7mP9 M2GG2IcFOC0boYkgqJtAPICjr+Czc8ExXeyNGfrjwewlyw0ypbWcI9rTadkmK8pJBEpB hqWR07u98wJENdUkuolk+oQw/DSQwIrDgzhDauuwNLNmcFhcZGBkhovOzGwZpIyj5FiI PfhsnMZ2NjGqe1eKiyzd+vK8sbLfGmRRbrbpvXIjSgPCUbp80/zyxnMub69RY5lR5qkN EAouH76YXMCfYQB7rDrtnYBX12ntVTdMGJXlxFFEMM2db2BryiDHpAZYl3yHE3UI3Snj 026w== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id; bh=Z97Ow6Uu2tS7g/PTIDrFXebWhPHzfnHD1Ve2g/wBaZI=; b=LV4PgAohp46FE7Wrrs+1UCxSXgga8hQWYJKU9sL1mA79V3LQR5RBUoZENwrEVHCeEP ENt1oKe8V8E7B3LgB0xsgkxMpSIENHjWQ2N8j/s2GVR3Tdzejm5K20YXrdMN5eQs2kov jzCm72pVmDYYS+P+Hr03Bex5cmqVLYmYCNfqtcdojXsYlFclm7X7ABA/PGfO+8+qsdng t4mnYBdcK/CSJ5miA3VEHD22fMs/dL9tvVBnnDaPkyokofuAEWfckZFaZXWuoTqOhFgy MX8QNGcZc6rI/j9y6T38pJ9FRGPw1rFO2p6N/xzogJPUX8B4A/RHpmlQ9PsYaUOz37Sh jH/g== X-Gm-Message-State: APjAAAU0Byr59Yw+SiMA3fU7HMMEQLtwXG42b082yWaLV/oX0O9dJ1v7 KvtTunjGXKvWjWTHLpYqV/8= X-Google-Smtp-Source: APXvYqw8Zie7rIn0Y3WqzWmncZoOFR0zpQWQE7FayoKtS2mCVSP+2Acxof9D9UY5nblZMykGkaMiTg== X-Received: by 2002:aa7:8a86:: with SMTP id a6mr47898098pfc.76.1567622405238; Wed, 04 Sep 2019 11:40:05 -0700 (PDT) Received: from ap-To-be-filled-by-O-E-M.1.1.1.1 ([14.33.120.60]) by smtp.gmail.com with ESMTPSA id k14sm23713978pfi.98.2019.09.04.11.39.59 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 04 Sep 2019 11:40:04 -0700 (PDT) From: Taehee Yoo To: davem@davemloft.net, netdev@vger.kernel.org, j.vosburgh@gmail.com, vfalico@gmail.com, andy@greyhouse.net, jiri@resnulli.us, sd@queasysnail.net, roopa@cumulusnetworks.com, saeedm@mellanox.com, manishc@marvell.com, rahulv@marvell.com, kys@microsoft.com, haiyangz@microsoft.com, sthemmin@microsoft.com, sashal@kernel.org, hare@suse.de, varun@chelsio.com, ubraun@linux.ibm.com, kgraul@linux.ibm.com Cc: ap420073@gmail.com Subject: [PATCH net 05/11] team: use dynamic lockdep key instead of static key Date: Thu, 5 Sep 2019 03:39:53 +0900 Message-Id: <20190904183953.14960-1-ap420073@gmail.com> X-Mailer: git-send-email 2.17.1 Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org In the current code, all team devices have same static lockdep key and team devices could be nested so that it makes unnecessary lockdep warning. Test commands: ip link add team0 type team for i in {1..7} do let A=$i-1 ip link add team$i type team ip link set team$i master team$A done ip link del team0 Splat looks like: [ 137.406730] ============================================ [ 137.412685] WARNING: possible recursive locking detected [ 137.418642] 5.3.0-rc7+ #322 Not tainted [ 137.422941] -------------------------------------------- [ 137.428886] ip/1383 is trying to acquire lock: [ 137.433869] 0000000089571080 (&dev_addr_list_lock_key/1){+...}, at: dev_uc_sync_multiple+0xfa/0x1a0 [ 137.444034] [ 137.444034] but task is already holding lock: [ 137.450572] 00000000d9597252 (&dev_addr_list_lock_key/1){+...}, at: dev_uc_unsync+0x10c/0x1b0 [ 137.460142] [ 137.460142] other info that might help us debug this: [ 137.467458] Possible unsafe locking scenario: [ 137.467458] [ 137.474096] CPU0 [ 137.476828] ---- [ 137.479569] lock(&dev_addr_list_lock_key/1); [ 137.484554] lock(&dev_addr_list_lock_key/1); [ 137.489539] [ 137.489539] *** DEADLOCK *** [ 137.489539] [ 137.496178] May be due to missing lock nesting notation [ 137.496178] [ 137.503789] 5 locks held by ip/1383: [ 137.507797] #0: 00000000d497f415 (rtnl_mutex){+.+.}, at: rtnetlink_rcv_msg+0x466/0x8a0 [ 137.516786] #1: 000000008e4b4656 (&team->lock){+.+.}, at: team_uninit+0x3a/0x1a0 [team] [ 137.525882] #2: 000000005cf248d1 (&dev_addr_list_lock_key){+...}, at: dev_uc_unsync+0x98/0x1b0 [ 137.535649] #3: 00000000d9597252 (&dev_addr_list_lock_key/1){+...}, at: dev_uc_unsync+0x10c/0x1b0 [ 137.545709] #4: 00000000bec134c3 (rcu_read_lock){....}, at: team_set_rx_mode+0x5/0x1d0 [team] [ 137.555384] [ 137.555384] stack backtrace: [ 137.560277] CPU: 0 PID: 1383 Comm: ip Not tainted 5.3.0-rc7+ #322 [ 137.577826] Call Trace: [ 137.580586] dump_stack+0x7c/0xbb [ 137.584307] __lock_acquire+0x26a9/0x3de0 [ 137.588820] ? register_lock_class+0x14d0/0x14d0 [ 137.594008] ? register_lock_class+0x14d0/0x14d0 [ 137.599194] lock_acquire+0x164/0x3b0 [ 137.603310] ? dev_uc_sync_multiple+0xfa/0x1a0 [ 137.608307] _raw_spin_lock_nested+0x2e/0x60 [ 137.613105] ? dev_uc_sync_multiple+0xfa/0x1a0 [ 137.618095] dev_uc_sync_multiple+0xfa/0x1a0 [ 137.622900] team_set_rx_mode+0xa9/0x1d0 [team] [ 137.627993] dev_uc_unsync+0x151/0x1b0 [ 137.632205] team_port_del+0x304/0x790 [team] [ 137.637110] team_uninit+0xb0/0x1a0 [team] [ 137.641717] rollback_registered_many+0x728/0xda0 [ 137.647005] ? generic_xdp_install+0x310/0x310 [ 137.651994] ? __set_pages_p+0xf4/0x150 [ 137.656306] ? check_chain_key+0x236/0x5d0 [ 137.660914] ? __nla_validate_parse+0x98/0x1ad0 [ 137.666006] unregister_netdevice_many.part.120+0x13/0x1b0 [ 137.672167] rtnl_delete_link+0xbc/0x100 [ 137.676575] ? rtnl_af_register+0xc0/0xc0 [ 137.681084] rtnl_dellink+0x2e7/0x870 [ 137.685204] ? find_held_lock+0x39/0x1d0 [ ... ] Fixes: 3d249d4ca7d0 ("net: introduce ethernet teaming device") Signed-off-by: Taehee Yoo --- drivers/net/team/team.c | 61 ++++++++++++++++++++++++++++++++++++++--- include/linux/if_team.h | 5 ++++ 2 files changed, 62 insertions(+), 4 deletions(-) diff --git a/drivers/net/team/team.c b/drivers/net/team/team.c index e8089def5a46..bfcd6ed57493 100644 --- a/drivers/net/team/team.c +++ b/drivers/net/team/team.c @@ -1607,6 +1607,34 @@ static const struct team_option team_options[] = { }, }; +static void team_dev_set_lockdep_one(struct net_device *dev, + struct netdev_queue *txq, + void *_unused) +{ + struct team *team = netdev_priv(dev); + + lockdep_set_class(&txq->_xmit_lock, &team->xmit_lock_key); +} + +static struct lock_class_key qdisc_tx_busylock_key; +static struct lock_class_key qdisc_running_key; + +static void team_dev_set_lockdep_class(struct net_device *dev) +{ + struct team *team = netdev_priv(dev); + + dev->qdisc_tx_busylock = &qdisc_tx_busylock_key; + dev->qdisc_running_key = &qdisc_running_key; + + lockdep_register_key(&team->team_lock_key); + __mutex_init(&team->lock, "team->team_lock_key", &team->team_lock_key); + + lockdep_register_key(&team->addr_lock_key); + lockdep_set_class(&dev->addr_list_lock, &team->addr_lock_key); + + lockdep_register_key(&team->xmit_lock_key); + netdev_for_each_tx_queue(dev, team_dev_set_lockdep_one, NULL); +} static int team_init(struct net_device *dev) { @@ -1615,7 +1643,6 @@ static int team_init(struct net_device *dev) int err; team->dev = dev; - mutex_init(&team->lock); team_set_no_mode(team); team->pcpu_stats = netdev_alloc_pcpu_stats(struct team_pcpu_stats); @@ -1642,7 +1669,7 @@ static int team_init(struct net_device *dev) goto err_options_register; netif_carrier_off(dev); - netdev_lockdep_set_classes(dev); + team_dev_set_lockdep_class(dev); return 0; @@ -1673,6 +1700,11 @@ static void team_uninit(struct net_device *dev) team_queue_override_fini(team); mutex_unlock(&team->lock); netdev_change_features(dev); + + lockdep_unregister_key(&team->team_lock_key); + lockdep_unregister_key(&team->addr_lock_key); + lockdep_unregister_key(&team->xmit_lock_key); + } static void team_destructor(struct net_device *dev) @@ -1967,6 +1999,23 @@ static int team_add_slave(struct net_device *dev, struct net_device *port_dev, return err; } +static void team_update_lock_key(struct net_device *dev) +{ + struct team *team = netdev_priv(dev); + + lockdep_unregister_key(&team->team_lock_key); + lockdep_unregister_key(&team->addr_lock_key); + lockdep_unregister_key(&team->xmit_lock_key); + + lockdep_register_key(&team->team_lock_key); + lockdep_register_key(&team->addr_lock_key); + lockdep_register_key(&team->xmit_lock_key); + + lockdep_set_class(&team->lock, &team->team_lock_key); + lockdep_set_class(&dev->addr_list_lock, &team->addr_lock_key); + netdev_for_each_tx_queue(dev, team_dev_set_lockdep_one, NULL); +} + static int team_del_slave(struct net_device *dev, struct net_device *port_dev) { struct team *team = netdev_priv(dev); @@ -1976,8 +2025,12 @@ static int team_del_slave(struct net_device *dev, struct net_device *port_dev) err = team_port_del(team, port_dev); mutex_unlock(&team->lock); - if (!err) - netdev_change_features(dev); + if (err) + return err; + + if (netif_is_team_master(port_dev)) + team_update_lock_key(port_dev); + netdev_change_features(dev); return err; } diff --git a/include/linux/if_team.h b/include/linux/if_team.h index 06faa066496f..9c97bb19ed34 100644 --- a/include/linux/if_team.h +++ b/include/linux/if_team.h @@ -223,6 +223,11 @@ struct team { atomic_t count_pending; struct delayed_work dw; } mcast_rejoin; + + struct lock_class_key team_lock_key; + struct lock_class_key xmit_lock_key; + struct lock_class_key addr_lock_key; + long mode_priv[TEAM_MODE_PRIV_LONGS]; };