Message ID | 20240110032724.3339-1-xuewen.yan@unisoc.com |
---|---|
State | New |
Headers |
Return-Path: <linux-kernel+bounces-21687-ouuuleilei=gmail.com@vger.kernel.org> Delivered-To: ouuuleilei@gmail.com Received: by 2002:a05:7300:2411:b0:101:2151:f287 with SMTP id m17csp555636dyi; Tue, 9 Jan 2024 19:28:40 -0800 (PST) X-Google-Smtp-Source: AGHT+IEe8bNhB1JHWBb4bZs0xwmgRbjFI0EWQzPdw4+LCqC9kXpPkvLDn8GfKqJ2NQsfZykbT9AZ X-Received: by 2002:a17:907:7798:b0:a24:457d:9b26 with SMTP id ky24-20020a170907779800b00a24457d9b26mr102033ejc.241.1704857319983; Tue, 09 Jan 2024 19:28:39 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1704857319; cv=none; d=google.com; s=arc-20160816; b=jYvKBsV0l9ZDXWONaTNzMFG0OXR9i8wiZG/ht6ITstOJ+bfY1x+S97x8hDKCWRcGVd aN6tWgEAdcGXFLNSnvmYSau+VVagob2ovw++hqCnWyS+w/kzYIUOUBa/y+pPT2zTo3Zj 90KTpvIeSi3H6Ot5mbB9RAty3jGYO1tBZtuHBVtKRSFPL9qrAy+F/YydDLK59CBV7NWN rS2Vsai5CmBuAgkW8o/Niig5eR/f95dBiwYVduV0ciCnA8KH7YFywlVL6tSgXMleGS2e mbcBd4OCRgz6cAuzC+0ucjqi1l/YbDYzoyAfrAE7USxogkAT2/myyhOct3T9c9z968Og WMYg== ARC-Message-Signature: i=1; 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; bh=3XNv44Msfj47ACJixtraTWRYDtVZO397u4TT3msGGrg=; fh=jZRYkfcR557wdwi8PRnOLMjhyFMka7WhEMItN8mHyXA=; b=EM9kM8zMW99qITBVHxVYCvTX73ctvQ8TdHuDACfwczUpZ34Oz0bMEzpFNrQn0XmbpP Q4eR9nLf2YY4upYuJjzLKXYShdSjVcmhcmKLBdh6idltK4M/rVB/mHgFc0kCu2JfteC3 ZXrt9s32H5MI8gZBZiWSwMK7hkvyDqv7moH55e6eapx7VMwKXtWmU2xNFaxnwBxG9Zlo QhAmsvo5p+pof70O8x+myOUhX+IJ+mho3BYEJ51bdl82jZxJAg3ebvJo1q2n2k3ht/7I b2VNgpxBPqZ8bTP4JX3s3TAdIcdFzQEwv+LeBwYqvhkMX4+mYHPxfvKPct9MokFcRVqZ uaNQ== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: domain of linux-kernel+bounces-21687-ouuuleilei=gmail.com@vger.kernel.org designates 147.75.80.249 as permitted sender) smtp.mailfrom="linux-kernel+bounces-21687-ouuuleilei=gmail.com@vger.kernel.org" Received: from am.mirrors.kernel.org (am.mirrors.kernel.org. [147.75.80.249]) by mx.google.com with ESMTPS id bl14-20020a170906c24e00b00a26b42502d0si1403809ejb.403.2024.01.09.19.28.39 for <ouuuleilei@gmail.com> (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 09 Jan 2024 19:28:39 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel+bounces-21687-ouuuleilei=gmail.com@vger.kernel.org designates 147.75.80.249 as permitted sender) client-ip=147.75.80.249; Authentication-Results: mx.google.com; spf=pass (google.com: domain of linux-kernel+bounces-21687-ouuuleilei=gmail.com@vger.kernel.org designates 147.75.80.249 as permitted sender) smtp.mailfrom="linux-kernel+bounces-21687-ouuuleilei=gmail.com@vger.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 am.mirrors.kernel.org (Postfix) with ESMTPS id 95F981F2630C for <ouuuleilei@gmail.com>; Wed, 10 Jan 2024 03:28:39 +0000 (UTC) Received: from localhost.localdomain (localhost.localdomain [127.0.0.1]) by smtp.subspace.kernel.org (Postfix) with ESMTP id A1AF58C1E; Wed, 10 Jan 2024 03:28:12 +0000 (UTC) Received: from SHSQR01.spreadtrum.com (mx1.unisoc.com [222.66.158.135]) (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 57B7E63A7 for <linux-kernel@vger.kernel.org>; Wed, 10 Jan 2024 03:28:07 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=unisoc.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=unisoc.com Received: from dlp.unisoc.com ([10.29.3.86]) by SHSQR01.spreadtrum.com with ESMTP id 40A3Rdb8060328; Wed, 10 Jan 2024 11:27:39 +0800 (+08) (envelope-from Xuewen.Yan@unisoc.com) Received: from SHDLP.spreadtrum.com (bjmbx01.spreadtrum.com [10.0.64.7]) by dlp.unisoc.com (SkyGuard) with ESMTPS id 4T8tNW3c4Wz2QNS93; Wed, 10 Jan 2024 11:20:43 +0800 (CST) Received: from BJ10918NBW01.spreadtrum.com (10.0.73.73) by BJMBX01.spreadtrum.com (10.0.64.7) with Microsoft SMTP Server (TLS) id 15.0.1497.23; Wed, 10 Jan 2024 11:27:37 +0800 From: Xuewen Yan <xuewen.yan@unisoc.com> To: <tj@kernel.org>, <longman@redhat.com> CC: <jiangshanlai@gmail.com>, <ke.wang@unisoc.com>, <xuewen.yan94@gmail.com>, <linux-kernel@vger.kernel.org> Subject: [PATCH v2] workqueue: Add rcu lock check after work execute end Date: Wed, 10 Jan 2024 11:27:24 +0800 Message-ID: <20240110032724.3339-1-xuewen.yan@unisoc.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <9bed61e4-7c08-4c61-a7e4-bdd39335cec1@redhat.com> References: <9bed61e4-7c08-4c61-a7e4-bdd39335cec1@redhat.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: <linux-kernel.vger.kernel.org> List-Subscribe: <mailto:linux-kernel+subscribe@vger.kernel.org> List-Unsubscribe: <mailto:linux-kernel+unsubscribe@vger.kernel.org> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Content-Type: text/plain X-ClientProxiedBy: SHCAS01.spreadtrum.com (10.0.1.201) To BJMBX01.spreadtrum.com (10.0.64.7) X-MAIL: SHSQR01.spreadtrum.com 40A3Rdb8060328 X-getmail-retrieved-from-mailbox: INBOX X-GMAIL-THRID: 1787611010817058552 X-GMAIL-MSGID: 1787672469353077915 |
Series |
[v2] workqueue: Add rcu lock check after work execute end
|
|
Commit Message
Xuewen Yan
Jan. 10, 2024, 3:27 a.m. UTC
Now the workqueue just check the atomic and lock after
work execute end. However, sometimes, drivers's work
may don't unlock rcu after call rcu_read_lock().
And as a result, it would cause rcu stall, but the rcu stall warning
can not dump the work func, because the work has finished.
In order to quickly discover those works that do not call
rcu_read_unlock after rcu_read_lock(). Add the rcu lock check.
Use rcu_preempt_depth() to check the work's rcu status,
Normally, this value is 0. If this value is bigger than 0,
it means the work are still holding rcu lock.
At this time, we print err info and print the work func.
Signed-off-by: Xuewen Yan <xuewen.yan@unisoc.com>
---
V2:
- move check to unlikely() helper (Longman)
---
kernel/workqueue.c | 9 +++++----
1 file changed, 5 insertions(+), 4 deletions(-)
Comments
On Wed, Jan 10, 2024 at 11:27 AM Xuewen Yan <xuewen.yan@unisoc.com> wrote: > > Now the workqueue just check the atomic and lock after > work execute end. However, sometimes, drivers's work > may don't unlock rcu after call rcu_read_lock(). > And as a result, it would cause rcu stall, but the rcu stall warning > can not dump the work func, because the work has finished. > > In order to quickly discover those works that do not call > rcu_read_unlock after rcu_read_lock(). Add the rcu lock check. > > Use rcu_preempt_depth() to check the work's rcu status, > Normally, this value is 0. If this value is bigger than 0, > it means the work are still holding rcu lock. > At this time, we print err info and print the work func. > > Signed-off-by: Xuewen Yan <xuewen.yan@unisoc.com> > --- > V2: > - move check to unlikely() helper (Longman) > --- > kernel/workqueue.c | 9 +++++---- > 1 file changed, 5 insertions(+), 4 deletions(-) > > diff --git a/kernel/workqueue.c b/kernel/workqueue.c > index 2989b57e154a..c2a73364f5ad 100644 Reviewed-by: Lai Jiangshan <jiangshanlai@gmail.com> > --- a/kernel/workqueue.c > +++ b/kernel/workqueue.c > @@ -2634,11 +2634,12 @@ __acquires(&pool->lock) > lock_map_release(&lockdep_map); > lock_map_release(&pwq->wq->lockdep_map); > > - if (unlikely(in_atomic() || lockdep_depth(current) > 0)) { > - pr_err("BUG: workqueue leaked lock or atomic: %s/0x%08x/%d\n" > + if (unlikely(in_atomic() || lockdep_depth(current) > 0 || > + rcu_preempt_depth() > 0)) { > + pr_err("BUG: workqueue leaked lock or atomic: %s/0x%08x/%d/%d\n" > " last function: %ps\n", > - current->comm, preempt_count(), task_pid_nr(current), > - worker->current_func); > + current->comm, preempt_count(), rcu_preempt_depth(), > + task_pid_nr(current), worker->current_func); > debug_show_held_locks(current); > dump_stack(); > } > -- > 2.25.1 >
On 1/9/24 22:27, Xuewen Yan wrote: > Now the workqueue just check the atomic and lock after > work execute end. However, sometimes, drivers's work > may don't unlock rcu after call rcu_read_lock(). > And as a result, it would cause rcu stall, but the rcu stall warning > can not dump the work func, because the work has finished. > > In order to quickly discover those works that do not call > rcu_read_unlock after rcu_read_lock(). Add the rcu lock check. > > Use rcu_preempt_depth() to check the work's rcu status, > Normally, this value is 0. If this value is bigger than 0, > it means the work are still holding rcu lock. > At this time, we print err info and print the work func. > > Signed-off-by: Xuewen Yan <xuewen.yan@unisoc.com> > --- > V2: > - move check to unlikely() helper (Longman) > --- > kernel/workqueue.c | 9 +++++---- > 1 file changed, 5 insertions(+), 4 deletions(-) > > diff --git a/kernel/workqueue.c b/kernel/workqueue.c > index 2989b57e154a..c2a73364f5ad 100644 > --- a/kernel/workqueue.c > +++ b/kernel/workqueue.c > @@ -2634,11 +2634,12 @@ __acquires(&pool->lock) > lock_map_release(&lockdep_map); > lock_map_release(&pwq->wq->lockdep_map); > > - if (unlikely(in_atomic() || lockdep_depth(current) > 0)) { > - pr_err("BUG: workqueue leaked lock or atomic: %s/0x%08x/%d\n" > + if (unlikely(in_atomic() || lockdep_depth(current) > 0 || > + rcu_preempt_depth() > 0)) { > + pr_err("BUG: workqueue leaked lock or atomic: %s/0x%08x/%d/%d\n" > " last function: %ps\n", > - current->comm, preempt_count(), task_pid_nr(current), > - worker->current_func); > + current->comm, preempt_count(), rcu_preempt_depth(), > + task_pid_nr(current), worker->current_func); > debug_show_held_locks(current); > dump_stack(); > } This can be a useful additional sanity test. Reviewed-by: Waiman Long <longman@redhat.com>
Hello, I massaged the description for clarity and applied to wq/for-6.9. Thanks. From 1a65a6d17cbc58e1aeffb2be962acce49efbef9c Mon Sep 17 00:00:00 2001 From: Xuewen Yan <xuewen.yan@unisoc.com> Date: Wed, 10 Jan 2024 11:27:24 +0800 Subject: [PATCH] workqueue: Add rcu lock check at the end of work item execution Currently the workqueue just checks the atomic and locking states after work execution ends. However, sometimes, a work item may not unlock rcu after acquiring rcu_read_lock(). And as a result, it would cause rcu stall, but the rcu stall warning can not dump the work func, because the work has finished. In order to quickly discover those works that do not call rcu_read_unlock() after rcu_read_lock(), add the rcu lock check. Use rcu_preempt_depth() to check the work's rcu status. Normally, this value is 0. If this value is bigger than 0, it means the work are still holding rcu lock. If so, print err info and the work func. tj: Reworded the description for clarity. Minor formatting tweak. Signed-off-by: Xuewen Yan <xuewen.yan@unisoc.com> Reviewed-by: Lai Jiangshan <jiangshanlai@gmail.com> Reviewed-by: Waiman Long <longman@redhat.com> Signed-off-by: Tejun Heo <tj@kernel.org> --- kernel/workqueue.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/kernel/workqueue.c b/kernel/workqueue.c index ed442cefea7c..aec3efbaaf93 100644 --- a/kernel/workqueue.c +++ b/kernel/workqueue.c @@ -2640,11 +2640,12 @@ __acquires(&pool->lock) lock_map_release(&lockdep_map); lock_map_release(&pwq->wq->lockdep_map); - if (unlikely(in_atomic() || lockdep_depth(current) > 0)) { - pr_err("BUG: workqueue leaked lock or atomic: %s/0x%08x/%d\n" + if (unlikely(in_atomic() || lockdep_depth(current) > 0 || + rcu_preempt_depth() > 0)) { + pr_err("BUG: workqueue leaked lock or atomic: %s/0x%08x/%d/%d\n" " last function: %ps\n", - current->comm, preempt_count(), task_pid_nr(current), - worker->current_func); + current->comm, preempt_count(), rcu_preempt_depth(), + task_pid_nr(current), worker->current_func); debug_show_held_locks(current); dump_stack(); }
diff --git a/kernel/workqueue.c b/kernel/workqueue.c index 2989b57e154a..c2a73364f5ad 100644 --- a/kernel/workqueue.c +++ b/kernel/workqueue.c @@ -2634,11 +2634,12 @@ __acquires(&pool->lock) lock_map_release(&lockdep_map); lock_map_release(&pwq->wq->lockdep_map); - if (unlikely(in_atomic() || lockdep_depth(current) > 0)) { - pr_err("BUG: workqueue leaked lock or atomic: %s/0x%08x/%d\n" + if (unlikely(in_atomic() || lockdep_depth(current) > 0 || + rcu_preempt_depth() > 0)) { + pr_err("BUG: workqueue leaked lock or atomic: %s/0x%08x/%d/%d\n" " last function: %ps\n", - current->comm, preempt_count(), task_pid_nr(current), - worker->current_func); + current->comm, preempt_count(), rcu_preempt_depth(), + task_pid_nr(current), worker->current_func); debug_show_held_locks(current); dump_stack(); }