Received: by 2002:a89:d88:0:b0:1fa:5c73:8e2d with SMTP id eb8csp2085613lqb; Mon, 27 May 2024 07:26:47 -0700 (PDT) X-Forwarded-Encrypted: i=3; AJvYcCVr3Sx3ceZo9WGh2uKuvRHO0/6Qrf7wTM8yqn72T9hGjg04Jeky+rTCfP1y16LhRs99Pcc+CbueL4wnvYPZEXP/BJDNRUOHQtV4XZdIrQ== X-Google-Smtp-Source: AGHT+IE8r3vIv+CrfvdK1KBLFfkwG5hgz1qs865jx8GDVrmvhLHL+WPbfFmBOcHMcchvnn1jVxak X-Received: by 2002:a05:6a00:4206:b0:6ec:fd67:a27e with SMTP id d2e1a72fcca58-6f8f2c6c88fmr9927443b3a.1.1716820007156; Mon, 27 May 2024 07:26:47 -0700 (PDT) ARC-Seal: i=2; a=rsa-sha256; t=1716820007; cv=pass; d=google.com; s=arc-20160816; b=fTtJhaehVDYx7xyF4kCG4DCvFuEpPCJnr59P4GjMGZe1aZeAkkcNj9feRWg6qqQzFD eFck095Ha//WeYLITECgCoG2OqXJTk7uqYxdjJXWkvSZSRgixBO3DIo22gad8UpoDBSP I/UJiU1QacOXHw3Q1YfdPB+GrLYwZHsjITdUuglVhpvhNmuxoOynbwm9mg90OFck7uW+ 1D8ifQIaK/wptn9JSPfsxDy4kOZ4BNGm+4km2HROnwWi79oUe95luXoaAQ9Nnvt1+h1c 8mGNAhBXvNERCGkW6S28oi3rA1Z/MzWj71z8xPnwT4MOzgdRPT928oxwvbUXEYWJio2G uQ9A== ARC-Message-Signature: i=2; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=content-transfer-encoding:mime-version:list-unsubscribe :list-subscribe:list-id:precedence:references:in-reply-to:message-id :date:subject:cc:to:from:dkim-signature; bh=Z7I09tC2mfMj4u5yEUxe/GFWH7IYDTUEDKx989NsI2o=; fh=C5zcWYBREDdMyRJcCOEwGllcE49nyzggyvZ39YQnoS8=; b=CP4yIMNfsc9xcLj7IFLPQmstavYzI1TiVu/YkWn9ttBkSHOXEhxwfQg6JndMhjAq/l qvnDIwzvmCfOihLFZ2maOfNfLOfnzcIb8FxuKVrO+yPO02//V9zI0I7/kjBMrdncl4mi ZC5l3Fry+ol7KBr8VmtID5xh2LmcIbZ2xLTtN9zMB6vI021VXe03zwwX4V/92sqtDp6S xcsWtfDIP2kA3f2cyFpGWidCyOlVR6xfZBmx69/FBw3hxOAgfTSQ5q/3nksLJR+hIG/T 9gDeKeXlD+EjVguvBt40KyGEOuajrt/UF7P5wUsbuKAgA5NoYUYWqgLsRTPJLoavmgH+ /myg==; dara=google.com ARC-Authentication-Results: i=2; mx.google.com; dkim=pass header.i=@kernel.org header.s=k20201202 header.b=hmrK5nay; arc=pass (i=1 dkim=pass dkdomain=kernel.org); spf=pass (google.com: domain of linux-kernel+bounces-190852-linux.lists.archive=gmail.com@vger.kernel.org designates 2604:1380:45e3:2400::1 as permitted sender) smtp.mailfrom="linux-kernel+bounces-190852-linux.lists.archive=gmail.com@vger.kernel.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=kernel.org Return-Path: Received: from sv.mirrors.kernel.org (sv.mirrors.kernel.org. [2604:1380:45e3:2400::1]) by mx.google.com with ESMTPS id d2e1a72fcca58-6f8fc0511d5si6226200b3a.42.2024.05.27.07.26.46 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 27 May 2024 07:26:47 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel+bounces-190852-linux.lists.archive=gmail.com@vger.kernel.org designates 2604:1380:45e3:2400::1 as permitted sender) client-ip=2604:1380:45e3:2400::1; Authentication-Results: mx.google.com; dkim=pass header.i=@kernel.org header.s=k20201202 header.b=hmrK5nay; arc=pass (i=1 dkim=pass dkdomain=kernel.org); spf=pass (google.com: domain of linux-kernel+bounces-190852-linux.lists.archive=gmail.com@vger.kernel.org designates 2604:1380:45e3:2400::1 as permitted sender) smtp.mailfrom="linux-kernel+bounces-190852-linux.lists.archive=gmail.com@vger.kernel.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=kernel.org Received: from smtp.subspace.kernel.org (wormhole.subspace.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by sv.mirrors.kernel.org (Postfix) with ESMTPS id BC1292A5802 for ; Mon, 27 May 2024 14:26:46 +0000 (UTC) Received: from localhost.localdomain (localhost.localdomain [127.0.0.1]) by smtp.subspace.kernel.org (Postfix) with ESMTP id B27F8176FBB; Mon, 27 May 2024 14:14:50 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="hmrK5nay" Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id AA4CB1779BB; Mon, 27 May 2024 14:14:49 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1716819289; cv=none; b=JA34DX98CrMx4i9xbVeExpNerzD2Fe11KSe5Ysonqwml6kfrrcYjw5mtOMvrSS9LVvheRiOC2csVRNkX1t3CeVRUJT+NpqZN/cMPSJef2suOYWZ4RH63hCLkMWGo7k5tEOxtdTKWmYrNUcBnO1n/yre45zS/EY42hQHw9m0ROLo= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1716819289; c=relaxed/simple; bh=kSIQWxMW+5ATjLlcp7PiWc0aIQ8iIko0XVX0k4Svgtg=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=JQF6YYjqAecoVcyAZOT1mSniRcJz+qOJhCbTNN978+W66FCIo8TOG4rMdc6I349sq2DumDgBLUKTsMtq5nnauUhwkkwFz1S6nLJ5NUdlWsDUH62DZEeV5syN6E0xPQea+9c5PtxwLIv0K/z82aFnf5gPqP09Ir2UPTAGRJckqAE= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=hmrK5nay; arc=none smtp.client-ip=10.30.226.201 Received: by smtp.kernel.org (Postfix) with ESMTPSA id EE220C2BBFC; Mon, 27 May 2024 14:14:47 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1716819289; bh=kSIQWxMW+5ATjLlcp7PiWc0aIQ8iIko0XVX0k4Svgtg=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=hmrK5nay6mP2AfXSjizCwvWCyzFzXEtcFhQiTng/aNAqX1bec7J6yFX4kCU9nIfjM MOchoql/ycXAj/ffYo4exWzes6MjzqYdetGSBHh3Bl2js2VwLgN+i5CvpSg9B32SfY 69s0TULt/64kklPV5xpCEbyW9G/aTZRAezNtGDvjTeDNt1cQk/X2Mok8nk40YByDKU eSPeBuj02mxRzpb6u1zigstuYTHCZ6SdBc9xzht5vAv4RYsvzOjJQh6ZKFeydDWprV PKSE7rSQRDs23JmFiU8R3GukFSM4FKgEVo/1KvPRMg4ZTUSIw3/xzqlGhvGG0WrzGO qaj3dFD6fz6uA== From: Sasha Levin To: linux-kernel@vger.kernel.org, stable@vger.kernel.org Cc: Davide Caratti , Maxim Mikityanskiy , Xiumei Mu , Christoph Paasch , Paolo Abeni , Sasha Levin , davem@davemloft.net, edumazet@google.com, kuba@kernel.org, jhs@mojatatu.com, xiyou.wangcong@gmail.com, jiri@resnulli.us, netdev@vger.kernel.org Subject: [PATCH AUTOSEL 6.8 16/30] net/sched: fix false lockdep warning on qdisc root lock Date: Mon, 27 May 2024 10:13:25 -0400 Message-ID: <20240527141406.3852821-16-sashal@kernel.org> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20240527141406.3852821-1-sashal@kernel.org> References: <20240527141406.3852821-1-sashal@kernel.org> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-stable: review X-Patchwork-Hint: Ignore X-stable-base: Linux 6.8.11 Content-Transfer-Encoding: 8bit From: Davide Caratti [ Upstream commit af0cb3fa3f9ed258d14abab0152e28a0f9593084 ] Xiumei and Christoph reported the following lockdep splat, complaining of the qdisc root lock being taken twice: ============================================ WARNING: possible recursive locking detected 6.7.0-rc3+ #598 Not tainted -------------------------------------------- swapper/2/0 is trying to acquire lock: ffff888177190110 (&sch->q.lock){+.-.}-{2:2}, at: __dev_queue_xmit+0x1560/0x2e70 but task is already holding lock: ffff88811995a110 (&sch->q.lock){+.-.}-{2:2}, at: __dev_queue_xmit+0x1560/0x2e70 other info that might help us debug this: Possible unsafe locking scenario: CPU0 ---- lock(&sch->q.lock); lock(&sch->q.lock); *** DEADLOCK *** May be due to missing lock nesting notation 5 locks held by swapper/2/0: #0: ffff888135a09d98 ((&in_dev->mr_ifc_timer)){+.-.}-{0:0}, at: call_timer_fn+0x11a/0x510 #1: ffffffffaaee5260 (rcu_read_lock){....}-{1:2}, at: ip_finish_output2+0x2c0/0x1ed0 #2: ffffffffaaee5200 (rcu_read_lock_bh){....}-{1:2}, at: __dev_queue_xmit+0x209/0x2e70 #3: ffff88811995a110 (&sch->q.lock){+.-.}-{2:2}, at: __dev_queue_xmit+0x1560/0x2e70 #4: ffffffffaaee5200 (rcu_read_lock_bh){....}-{1:2}, at: __dev_queue_xmit+0x209/0x2e70 stack backtrace: CPU: 2 PID: 0 Comm: swapper/2 Not tainted 6.7.0-rc3+ #598 Hardware name: Red Hat KVM, BIOS 1.13.0-2.module+el8.3.0+7353+9de0a3cc 04/01/2014 Call Trace: dump_stack_lvl+0x4a/0x80 __lock_acquire+0xfdd/0x3150 lock_acquire+0x1ca/0x540 _raw_spin_lock+0x34/0x80 __dev_queue_xmit+0x1560/0x2e70 tcf_mirred_act+0x82e/0x1260 [act_mirred] tcf_action_exec+0x161/0x480 tcf_classify+0x689/0x1170 prio_enqueue+0x316/0x660 [sch_prio] dev_qdisc_enqueue+0x46/0x220 __dev_queue_xmit+0x1615/0x2e70 ip_finish_output2+0x1218/0x1ed0 __ip_finish_output+0x8b3/0x1350 ip_output+0x163/0x4e0 igmp_ifc_timer_expire+0x44b/0x930 call_timer_fn+0x1a2/0x510 run_timer_softirq+0x54d/0x11a0 __do_softirq+0x1b3/0x88f irq_exit_rcu+0x18f/0x1e0 sysvec_apic_timer_interrupt+0x6f/0x90 This happens when TC does a mirred egress redirect from the root qdisc of device A to the root qdisc of device B. As long as these two locks aren't protecting the same qdisc, they can be acquired in chain: add a per-qdisc lockdep key to silence false warnings. This dynamic key should safely replace the static key we have in sch_htb: it was added to allow enqueueing to the device "direct qdisc" while still holding the qdisc root lock. v2: don't use static keys anymore in HTB direct qdiscs (thanks Eric Dumazet) CC: Maxim Mikityanskiy CC: Xiumei Mu Reported-by: Christoph Paasch Closes: https://github.com/multipath-tcp/mptcp_net-next/issues/451 Signed-off-by: Davide Caratti Link: https://lore.kernel.org/r/7dc06d6158f72053cf877a82e2a7a5bd23692faa.1713448007.git.dcaratti@redhat.com Signed-off-by: Paolo Abeni Signed-off-by: Sasha Levin --- include/net/sch_generic.h | 1 + net/sched/sch_generic.c | 3 +++ net/sched/sch_htb.c | 22 +++------------------- 3 files changed, 7 insertions(+), 19 deletions(-) diff --git a/include/net/sch_generic.h b/include/net/sch_generic.h index 41ca14e81d55f..0014b9ee5e381 100644 --- a/include/net/sch_generic.h +++ b/include/net/sch_generic.h @@ -128,6 +128,7 @@ struct Qdisc { struct rcu_head rcu; netdevice_tracker dev_tracker; + struct lock_class_key root_lock_key; /* private data */ long privdata[] ____cacheline_aligned; }; diff --git a/net/sched/sch_generic.c b/net/sched/sch_generic.c index a498b5d7c5d60..7fd0167aa7ee1 100644 --- a/net/sched/sch_generic.c +++ b/net/sched/sch_generic.c @@ -944,7 +944,9 @@ struct Qdisc *qdisc_alloc(struct netdev_queue *dev_queue, __skb_queue_head_init(&sch->gso_skb); __skb_queue_head_init(&sch->skb_bad_txq); gnet_stats_basic_sync_init(&sch->bstats); + lockdep_register_key(&sch->root_lock_key); spin_lock_init(&sch->q.lock); + lockdep_set_class(&sch->q.lock, &sch->root_lock_key); if (ops->static_flags & TCQ_F_CPUSTATS) { sch->cpu_bstats = @@ -1067,6 +1069,7 @@ static void __qdisc_destroy(struct Qdisc *qdisc) if (ops->destroy) ops->destroy(qdisc); + lockdep_unregister_key(&qdisc->root_lock_key); module_put(ops->owner); netdev_put(dev, &qdisc->dev_tracker); diff --git a/net/sched/sch_htb.c b/net/sched/sch_htb.c index 7349233eaa9b6..19a578c31a91f 100644 --- a/net/sched/sch_htb.c +++ b/net/sched/sch_htb.c @@ -1039,13 +1039,6 @@ static void htb_work_func(struct work_struct *work) rcu_read_unlock(); } -static void htb_set_lockdep_class_child(struct Qdisc *q) -{ - static struct lock_class_key child_key; - - lockdep_set_class(qdisc_lock(q), &child_key); -} - static int htb_offload(struct net_device *dev, struct tc_htb_qopt_offload *opt) { return dev->netdev_ops->ndo_setup_tc(dev, TC_SETUP_QDISC_HTB, opt); @@ -1132,7 +1125,6 @@ static int htb_init(struct Qdisc *sch, struct nlattr *opt, return -ENOMEM; } - htb_set_lockdep_class_child(qdisc); q->direct_qdiscs[ntx] = qdisc; qdisc->flags |= TCQ_F_ONETXQUEUE | TCQ_F_NOPARENT; } @@ -1468,7 +1460,6 @@ static int htb_graft(struct Qdisc *sch, unsigned long arg, struct Qdisc *new, } if (q->offload) { - htb_set_lockdep_class_child(new); /* One ref for cl->leaf.q, the other for dev_queue->qdisc. */ qdisc_refcount_inc(new); old_q = htb_graft_helper(dev_queue, new); @@ -1733,11 +1724,8 @@ static int htb_delete(struct Qdisc *sch, unsigned long arg, new_q = qdisc_create_dflt(dev_queue, &pfifo_qdisc_ops, cl->parent->common.classid, NULL); - if (q->offload) { - if (new_q) - htb_set_lockdep_class_child(new_q); + if (q->offload) htb_parent_to_leaf_offload(sch, dev_queue, new_q); - } } sch_tree_lock(sch); @@ -1947,13 +1935,9 @@ static int htb_change_class(struct Qdisc *sch, u32 classid, new_q = qdisc_create_dflt(dev_queue, &pfifo_qdisc_ops, classid, NULL); if (q->offload) { - if (new_q) { - htb_set_lockdep_class_child(new_q); - /* One ref for cl->leaf.q, the other for - * dev_queue->qdisc. - */ + /* One ref for cl->leaf.q, the other for dev_queue->qdisc. */ + if (new_q) qdisc_refcount_inc(new_q); - } old_q = htb_graft_helper(dev_queue, new_q); /* No qdisc_put needed. */ WARN_ON(!(old_q->flags & TCQ_F_BUILTIN)); -- 2.43.0