From: Waiman Long <longman@redhat.com>
To: Andrey Ryabinin <ryabinin.a.a@gmail.com>,
Alexander Potapenko <glider@google.com>,
Andrey Konovalov <andreyknvl@gmail.com>,
Dmitry Vyukov <dvyukov@google.com>,
Vincenzo Frascino <vincenzo.frascino@arm.com>,
Andrew Morton <akpm@linux-foundation.org>,
Sebastian Andrzej Siewior <bigeasy@linutronix.de>,
Clark Williams <clrkwllms@kernel.org>,
Steven Rostedt <rostedt@goodmis.org>
Cc: kasan-dev@googlegroups.com, linux-mm@kvack.org,
linux-kernel@vger.kernel.org, linux-rt-devel@lists.linux.dev,
Nico Pache <npache@redhat.com>, Waiman Long <longman@redhat.com>
Subject: [PATCH v2] kasan: Don't call find_vm_area() in RT kernel
Date: Wed, 12 Feb 2025 11:21:51 -0500 [thread overview]
Message-ID: <20250212162151.1599059-1-longman@redhat.com> (raw)
The following bug report appeared with a test run in a RT debug kernel.
[ 3359.353842] BUG: sleeping function called from invalid context at kernel/locking/spinlock_rt.c:48
[ 3359.353848] in_atomic(): 1, irqs_disabled(): 1, non_block: 0, pid: 140605, name: kunit_try_catch
[ 3359.353853] preempt_count: 1, expected: 0
:
[ 3359.353933] Call trace:
:
[ 3359.353955] rt_spin_lock+0x70/0x140
[ 3359.353959] find_vmap_area+0x84/0x168
[ 3359.353963] find_vm_area+0x1c/0x50
[ 3359.353966] print_address_description.constprop.0+0x2a0/0x320
[ 3359.353972] print_report+0x108/0x1f8
[ 3359.353976] kasan_report+0x90/0xc8
[ 3359.353980] __asan_load1+0x60/0x70
Commit e30a0361b851 ("kasan: make report_lock a raw spinlock")
changes report_lock to a raw_spinlock_t to avoid a similar RT problem.
The print_address_description() function is called with report_lock
acquired and interrupt disabled. However, the find_vm_area() function
still needs to acquire a spinlock_t which becomes a sleeping lock in
the RT kernel. IOW, we can't call find_vm_area() in a RT kernel and
changing report_lock to a raw_spinlock_t is not enough to completely
solve this RT kernel problem.
Fix this bug report by skipping the find_vm_area() call in this case
and just print out the address as is.
For !RT kernel, follow the example set in commit 0cce06ba859a
("debugobjects,locking: Annotate debug_object_fill_pool() wait type
violation") and use DEFINE_WAIT_OVERRIDE_MAP() to avoid a spinlock_t
inside raw_spinlock_t warning.
Fixes: e30a0361b851 ("kasan: make report_lock a raw spinlock")
Signed-off-by: Waiman Long <longman@redhat.com>
---
mm/kasan/report.c | 47 ++++++++++++++++++++++++++++++++++-------------
1 file changed, 34 insertions(+), 13 deletions(-)
[v2] Encapsulate the change into a new
kasan_print_vmalloc_info_ret_page() helper
diff --git a/mm/kasan/report.c b/mm/kasan/report.c
index 3fe77a360f1c..9580ac3f3203 100644
--- a/mm/kasan/report.c
+++ b/mm/kasan/report.c
@@ -370,6 +370,38 @@ static inline bool init_task_stack_addr(const void *addr)
sizeof(init_thread_union.stack));
}
+/*
+ * RT kernel cannot call find_vm_area() in atomic context. For !RT kernel,
+ * prevent spinlock_t inside raw_spinlock_t warning by raising wait-type
+ * to WAIT_SLEEP.
+ *
+ * Return: page pointer or NULL
+ */
+static inline struct page *kasan_print_vmalloc_info_ret_page(void *addr)
+{
+ if (!IS_ENABLED(CONFIG_PREEMPT_RT)) {
+ static DEFINE_WAIT_OVERRIDE_MAP(vmalloc_map, LD_WAIT_SLEEP);
+ struct page *page = NULL;
+ struct vm_struct *va;
+
+ lock_map_acquire_try(&vmalloc_map);
+ va = find_vm_area(addr);
+ if (va) {
+ pr_err("The buggy address belongs to the virtual mapping at\n"
+ " [%px, %px) created by:\n"
+ " %pS\n",
+ va->addr, va->addr + va->size, va->caller);
+ pr_err("\n");
+
+ page = vmalloc_to_page(addr);
+ }
+ lock_map_release(&vmalloc_map);
+ return page;
+ }
+ pr_err("The buggy address %px belongs to a vmalloc virtual mapping\n", addr);
+ return NULL;
+}
+
static void print_address_description(void *addr, u8 tag,
struct kasan_report_info *info)
{
@@ -398,19 +430,8 @@ static void print_address_description(void *addr, u8 tag,
pr_err("\n");
}
- if (is_vmalloc_addr(addr)) {
- struct vm_struct *va = find_vm_area(addr);
-
- if (va) {
- pr_err("The buggy address belongs to the virtual mapping at\n"
- " [%px, %px) created by:\n"
- " %pS\n",
- va->addr, va->addr + va->size, va->caller);
- pr_err("\n");
-
- page = vmalloc_to_page(addr);
- }
- }
+ if (is_vmalloc_addr(addr))
+ page = kasan_print_vmalloc_info_ret_page(addr);
if (page) {
pr_err("The buggy address belongs to the physical page:\n");
--
2.48.1
next reply other threads:[~2025-02-12 16:22 UTC|newest]
Thread overview: 5+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-02-12 16:21 Waiman Long [this message]
2025-02-12 17:54 ` [PATCH v2] kasan: Don't call find_vm_area() in RT kernel Andrey Ryabinin
2025-02-13 1:48 ` Andrey Konovalov
2025-02-13 3:00 ` Waiman Long
2025-02-17 3:29 ` Waiman Long
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20250212162151.1599059-1-longman@redhat.com \
--to=longman@redhat.com \
--cc=akpm@linux-foundation.org \
--cc=andreyknvl@gmail.com \
--cc=bigeasy@linutronix.de \
--cc=clrkwllms@kernel.org \
--cc=dvyukov@google.com \
--cc=glider@google.com \
--cc=kasan-dev@googlegroups.com \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-mm@kvack.org \
--cc=linux-rt-devel@lists.linux.dev \
--cc=npache@redhat.com \
--cc=rostedt@goodmis.org \
--cc=ryabinin.a.a@gmail.com \
--cc=vincenzo.frascino@arm.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.