From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from kanga.kvack.org (kanga.kvack.org [205.233.56.17]) by smtp.lore.kernel.org (Postfix) with ESMTP id DE5EFD44176 for ; Tue, 19 Nov 2024 15:45:21 +0000 (UTC) Received: by kanga.kvack.org (Postfix) id 6BA846B009E; Tue, 19 Nov 2024 10:45:21 -0500 (EST) Received: by kanga.kvack.org (Postfix, from userid 40) id 668826B00C4; Tue, 19 Nov 2024 10:45:21 -0500 (EST) X-Delivered-To: int-list-linux-mm@kvack.org Received: by kanga.kvack.org (Postfix, from userid 63042) id 46DA46B00C6; Tue, 19 Nov 2024 10:45:21 -0500 (EST) X-Delivered-To: linux-mm@kvack.org Received: from relay.hostedemail.com (smtprelay0012.hostedemail.com [216.40.44.12]) by kanga.kvack.org (Postfix) with ESMTP id 202B16B009E for ; Tue, 19 Nov 2024 10:45:21 -0500 (EST) Received: from smtpin08.hostedemail.com (a10.router.float.18 [10.200.18.1]) by unirelay08.hostedemail.com (Postfix) with ESMTP id C063B1405C1 for ; Tue, 19 Nov 2024 15:45:20 +0000 (UTC) X-FDA: 82803266532.08.5FF1D57 Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.129.124]) by imf30.hostedemail.com (Postfix) with ESMTP id 4CDE080021 for ; Tue, 19 Nov 2024 15:43:43 +0000 (UTC) Authentication-Results: imf30.hostedemail.com; dkim=pass header.d=redhat.com header.s=mimecast20190719 header.b=bnFvVpb2; spf=pass (imf30.hostedemail.com: domain of acarmina@redhat.com designates 170.10.129.124 as permitted sender) smtp.mailfrom=acarmina@redhat.com; dmarc=pass (policy=none) header.from=redhat.com ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=hostedemail.com; s=arc-20220608; t=1732030874; h=from:from:sender:reply-to:subject:subject:date:date: message-id:message-id:to:to:cc:cc:mime-version:mime-version: content-type:content-type:content-transfer-encoding: in-reply-to:in-reply-to:references:references:dkim-signature; bh=XlWnUbDMFHqxeyH5bT9q3dltHKtu3tyJ18YUYklWIgQ=; b=SivpMfgv24gsQI4+IgtJk+JNyT+BOzSgHDzSLN7nfGclzeIwDrAarSPL2J4RtHVLtPNGRJ XYkpbIjLKXXxZjkE+7aDngcv6+1o90CsYm/HQFknghodPZ0gVfv7jtRw5iqJ4BZUhHBYNb m25joANlggNzVCtANiOeAoNp9WLVieA= ARC-Authentication-Results: i=1; imf30.hostedemail.com; dkim=pass header.d=redhat.com header.s=mimecast20190719 header.b=bnFvVpb2; spf=pass (imf30.hostedemail.com: domain of acarmina@redhat.com designates 170.10.129.124 as permitted sender) smtp.mailfrom=acarmina@redhat.com; dmarc=pass (policy=none) header.from=redhat.com ARC-Seal: i=1; s=arc-20220608; d=hostedemail.com; t=1732030874; a=rsa-sha256; cv=none; b=XicdcPI3I1iJwZY/c4eZCXmmWzuSF/yZ/OFbqy1cVRv0LcUqK1s197YCvq09hGlXZWpB0c scEi+2OvfscSqc8Sastjw3vPKUuM/fv34gQJulNvdlzDsAtkWL/Vd71ALwrxxEcuzTk5d1 sY1OuZ1jDGtp8MqPtQACWwKKbdazJ+k= DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1732031117; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: in-reply-to:in-reply-to:references:references; bh=XlWnUbDMFHqxeyH5bT9q3dltHKtu3tyJ18YUYklWIgQ=; b=bnFvVpb2ph5w6mopvtAKGjYSfGSE2IwxjtCyX2eeDRh1PK9HC/ErcMOjyJUOjIcQqvznqV rI9Z+1CCgsChlrwhGbV3iOAE8Lp+P1H4d2gBHqM0gllsXQC2DyH3d84bu5vK889KWqlpGt ESQ1k02gjL/TU6b21rELXgmcoYf17ak= Received: from mail-pj1-f69.google.com (mail-pj1-f69.google.com [209.85.216.69]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-605-AyQhVOPvOBuD2HMkI4gzqQ-1; Tue, 19 Nov 2024 10:45:15 -0500 X-MC-Unique: AyQhVOPvOBuD2HMkI4gzqQ-1 X-Mimecast-MFC-AGG-ID: AyQhVOPvOBuD2HMkI4gzqQ Received: by mail-pj1-f69.google.com with SMTP id 98e67ed59e1d1-2e9ff7aa7eeso4593637a91.1 for ; Tue, 19 Nov 2024 07:45:15 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1732031115; x=1732635915; h=cc:to:subject:message-id:date:from:in-reply-to:references :mime-version:x-gm-message-state:from:to:cc:subject:date:message-id :reply-to; bh=XlWnUbDMFHqxeyH5bT9q3dltHKtu3tyJ18YUYklWIgQ=; b=sw22KTkQpJA4abEvJQB105j0ZVbNcp8xSjUgeI6ZQrawvosMqTFPcF29gmB6AvyNEB RXvKcpBOVqF41RdZ4sHPr7zj1+46IeAjTta5/yOTF0t16fl5pok/DAQvBae7iE6jJ5zv TkJ7VdqQNieZ+t6tfvVNakd/9yJy+0JF+qCHhr9u30AHcPFAxYNyo0u16NOoP/z3kWgq YmlQY6CPQnbvxboavzj2tw1SHRo8wOdwgnwb96OICWxOiLQ/grFLuy2rdPP4FuttwUyd qLBBSDeWEbXxaSNKmqujcXWeqBijFoqqg6Ve8Twkq+WzTVvpiPT1AC9pg8inmiBhhtHD WARw== X-Forwarded-Encrypted: i=1; AJvYcCXPHdFnImCFvlIdhBPpmEreOYtgh0dtGfkzclasKc0TUTmSJbZ+wBtEBjSh7Yx6I9A244B7PXPvEQ==@kvack.org X-Gm-Message-State: AOJu0YyGHuKkSJ8Mj1PAEkOGl+QHFTarCPEJMR0m5oHOE/igexSO8EWN 9CM/DJZOEVZiZTqd2p+BD93nzHODoxJ6rsIZzAqeBBGxp+xzv0u6JvwJTf5NKMMh+eEIaPfaSiJ 9fMd84ONUJX3Lf45fxYFAcX5HkIQGp0GPYwS+9VhK4ycyAatRkP6s1ZhhY0N6SX6dAKd8tMjMOD BCFEtCqoZyx2CHaCkP8weoEFU= X-Received: by 2002:a17:90b:39cd:b0:2ea:4633:1a65 with SMTP id 98e67ed59e1d1-2eaaa7b3cc5mr5727241a91.12.1732031114651; Tue, 19 Nov 2024 07:45:14 -0800 (PST) X-Google-Smtp-Source: AGHT+IG0FVfShTUnTZ+1ZJBNUdwmiAIwvS6DGJJt9a3vBsL3Zq2GQABxZZ8lzXCzP7KjBrMoOZGFHdIpGovJ+uH8q+0= X-Received: by 2002:a17:90b:39cd:b0:2ea:4633:1a65 with SMTP id 98e67ed59e1d1-2eaaa7b3cc5mr5727200a91.12.1732031114302; Tue, 19 Nov 2024 07:45:14 -0800 (PST) MIME-Version: 1.0 References: <20241115145410.114376-1-acarmina@redhat.com> <20241118151351-5a465d40-b8d0-45e4-bf9b-6d3add8ce98b@linutronix.de> In-Reply-To: <20241118151351-5a465d40-b8d0-45e4-bf9b-6d3add8ce98b@linutronix.de> From: Alessandro Carminati Date: Tue, 19 Nov 2024 16:45:03 +0100 Message-ID: Subject: Re: [RFC] mm/kmemleak: Fix sleeping function called from invalid context at print message To: =?UTF-8?Q?Thomas_Wei=C3=9Fschuh?= , Andrey Konovalov , Andrew Morton , Catalin Marinas Cc: Sebastian Andrzej Siewior , Clark Williams , Steven Rostedt , linux-mm@kvack.org, linux-kernel@vger.kernel.org, linux-rt-devel@lists.linux.dev, Alessandro Carminati , Juri Lelli , Gabriele Paoloni X-Mimecast-Spam-Score: 0 X-Mimecast-MFC-PROC-ID: aWTR3JVyl7_ePnWhShLX9yy-RR5pdgKC4HTrVv1_9XI_1732031115 X-Mimecast-Originator: redhat.com Content-Type: multipart/alternative; boundary="0000000000004ef1eb062745eb91" X-Rspamd-Server: rspam06 X-Rspamd-Queue-Id: 4CDE080021 X-Stat-Signature: qdirihfwdn5i7s6xzix8dk1w5ozrfru3 X-Rspam-User: X-HE-Tag: 1732031023-360884 X-HE-Meta: U2FsdGVkX1+5LOhO1A/EpWLRe9nvLIEiqi/6Z0PfIBap6Ovq+b9cgw+iFJTNdH2eIhg8a3B4C8ac+uWJofDGjUqwZ8CNiYa9XnyOhPbkgn34/LraheDqTMoc3UeS/HsMwC3o2tWZKFVePDXaxOt3hP9ZzGFOStYg7FIwgt1dLS4swRWk1ARZnBBIiJ6Xk1T50HMtESWUX6T4dDxoTWbbKnk/q9z2m3plTWR1FlDH77tdlbksc3h7L0kndldMcKt0MLp08ELwnrUm2HVZciMuLpTgu0SeFenyA9ezLW/NkCFkny5mBFAxD5r3n6zO9C8VHpLNwVp4x4VMZLAFCtYYxllTH9gJOsWJrZiKH6KM+zjUEFTB7ooBRKgAsYsBEweEGb0dm1jztmqvby69we5Rt1Cz8hUToWkF3C9PcC54myd50OiePW4IfqM11x6p1cw24vW7i3+tsp0xTxB2TurfcZWvxieBel3Ueba1Ub+npBRLOZE8qQJO+pUsz87gD6XzNKWC/xFsA/S+t4Px035YniQ82HOOGGFqXcPpmDVAm4wu7gECvjSccU0ISJ8S+HSpA37ADcgg/C1quTZybvzVtSTGH3ApJG1lq4kIq6Lt6UeYOjgnSFcyVjhgDbru21tCdEjmLN/j2lKtuqpARV2AGbKDVft1O9AQ2r73GwRJx70BHgIezy8949k9lKpQCqiwJhyfo4FH+OhuahG4QtIjCnSuYSMDZ59Ou/qe43I4W+Yq1oX8TlH2iM2+ykvJbr35nb1gf+JisSeaxZAmceup04VxC3/nsLWXrws0qaj3xvC2tV47zudz4biMy04vBWQbn0TPTF2jPlWKA4lhNrdg4afFVTUEW0cmFcm6L5XulCPP0tzq2WGF2So7/7jWtgoRgeldPvC7b9pH4dnzGQGo+W5CjUQgV7FSdRPFKIUD754JErhDBLBSR1Kt7zykF6PiS71UmvHZ1hpTmicJrsx hLje/OWi TA9eOCQWxSO3172x2nZYx6gMLeINrlagiZZ7f0N+SOfBWlE1ZxnM8q7EEf9UoPwnurGNEBoY+UJNMFq5l/5eh+3cr0wuzmTzpIpZV3yi2nqd4BoMcfOT5yVJwf8yht7exIzs8fnMrpVmgxYu5P3Rk41cTCDB1s+h+2/jc4wgZrU2O8FIMhVmgWKGf+FHGClnf0BK4CBjai95M67wkQeejoyAQQ2PSOx5Oe/qO73ygtRWXM2gB7CAA/N/7JdrhrwhzK+kE3Qo2rKRLKakiknGwe+S4fTZNyxp/+NeiA24sND/nOIz6q7RKX1beCNkZ5PWH583GMs5U5EWptWg8v3UXQveWLR5TrqKEeokcf+Iqf7G+pCtotCmIPncGmNS4FWtwgycMJBEWbwBHNrEieSY6ZQOso2KOdWIvVGUPhqPMGAeuD6VbbENROiHdcuDnhqI7/PS4 X-Bogosity: Ham, tests=bogofilter, spamicity=0.000000, version=1.2.4 Sender: owner-linux-mm@kvack.org Precedence: bulk X-Loop: owner-majordomo@kvack.org List-ID: List-Subscribe: List-Unsubscribe: --0000000000004ef1eb062745eb91 Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable Hello Thomas, Thanks for your suggestion. On Mon, Nov 18, 2024 at 3:29=E2=80=AFPM Thomas Wei=C3=9Fschuh < thomas.weissschuh@linutronix.de> wrote: > On Fri, Nov 15, 2024 at 02:54:10PM +0000, Alessandro Carminati wrote: > > Address a bug in the kernel that triggers a "sleeping function called > from > > invalid context" warning when /sys/kernel/debug/kmemleak is printed und= er > > specific conditions: > > - CONFIG_PREEMPT_RT=3Dy > > - Set SELinux as the LSM for the system > > - Set kptr_restrict to 1 > > - kmemleak buffer contains at least one item > > Ensure the kmemleak buffer contains at least one item > > Commit 8c96f1bc6fc49c724c4cdd22d3e99260263b7384 ("mm/kmemleak: turn > > kmemleak_lock and object->lock to raw_spinlock_t") introduced a change > > where kmemleak_seq_show is executed in atomic context within the RT > kernel. > > However, the SELinux capability check in this function flow still relie= s > on > > regular spinlocks, leading to potential race conditions that trigger an > > error when printing the kmemleak backtrace. > > Move the backtrace printing out of the critical section. Use a stack > > variable to store the backtrace pointers, avoiding spinlocks in the > atomic > > context. > > > > Implement delta encoding to minimize the stack memory footprint, > > addressing the potentially large memory demands for storing these > pointers > > on 64-bit systems. > > The stacktrace is already stored in the stackdepot. > Shouldn't it be possible to take a reference to the stackdepot entry > inside the critical section and then use that reference outside of the > critical section for printing? > Yes, it is indeed possible to do that. However, kmemleak operates in such a way that entries can be deleted, for example, if they are found to be false positives. My concern was that using a reference to a potentially deleted entry could cause problems. But after considering your suggestion, I verified that stack_depot_put, which is used to delete a stack depot entry, does not appear to be called when a kmemleak object is deleted. This makes me question whether that is the intended behavior. As things currently stand, it seems possible to remove all the code I added to store the trace in the stack and instead directly use the stack_depot handle. I would appreciate feedback from kmemleak and stackdepot experts regarding this approach. > > > Signed-off-by: Alessandro Carminati > > --- > > ``` > > [ 159.247069] BUG: sleeping function called from invalid context at > kernel/locking/spinlock_rt.c:48 > > [ 159.247193] in_atomic(): 1, irqs_disabled(): 1, non_block: 0, pid: > 136, name: cat > > [ 159.247241] preempt_count: 1, expected: 0 > > [ 159.247277] RCU nest depth: 2, expected: 2 > > [ 159.247388] 6 locks held by cat/136: > > [ 159.247438] #0: ffff32e64bcbf950 (&p->lock){+.+.}-{3:3}, at: > seq_read_iter+0xb8/0xe30 > > [ 159.248835] #1: ffffafe6aaa9dea0 (scan_mutex){+.+.}-{3:3}, at: > kmemleak_seq_start+0x34/0x128 > > [ 159.249053] #3: ffff32e6546b1cd0 (&object->lock){....}-{2:2}, at: > kmemleak_seq_show+0x3c/0x1e0 > > [ 159.249127] #4: ffffafe6aa8d8560 (rcu_read_lock){....}-{1:2}, at: > has_ns_capability_noaudit+0x8/0x1b0 > > [ 159.249205] #5: ffffafe6aabbc0f8 (notif_lock){+.+.}-{2:2}, at: > avc_compute_av+0xc4/0x3d0 > > [ 159.249364] irq event stamp: 136660 > > [ 159.249407] hardirqs last enabled at (136659): [] > _raw_spin_unlock_irqrestore+0xa8/0xd8 > > [ 159.249465] hardirqs last disabled at (136660): [] > _raw_spin_lock_irqsave+0x8c/0xb0 > > [ 159.249518] softirqs last enabled at (0): [] > copy_process+0x11d8/0x3df8 > > [ 159.249571] softirqs last disabled at (0): [<0000000000000000>] 0x0 > > [ 159.249970] Preemption disabled at: > > [ 159.249988] [] kmemleak_seq_show+0x3c/0x1e0 > > [ 159.250609] CPU: 1 UID: 0 PID: 136 Comm: cat Tainted: G E > 6.11.0-rt7+ #34 > > [ 159.250797] Tainted: [E]=3DUNSIGNED_MODULE > > [ 159.250822] Hardware name: linux,dummy-virt (DT) > > [ 159.251050] Call trace: > > [ 159.251079] dump_backtrace+0xa0/0x128 > > [ 159.251132] show_stack+0x1c/0x30 > > [ 159.251156] dump_stack_lvl+0xe8/0x198 > > [ 159.251180] dump_stack+0x18/0x20 > > [ 159.251227] rt_spin_lock+0x8c/0x1a8 > > [ 159.251273] avc_perm_nonode+0xa0/0x150 > > [ 159.251316] cred_has_capability.isra.0+0x118/0x218 > > [ 159.251340] selinux_capable+0x50/0x80 > > [ 159.251363] security_capable+0x7c/0xd0 > > [ 159.251388] has_ns_capability_noaudit+0x94/0x1b0 > > [ 159.251412] has_capability_noaudit+0x20/0x30 > > [ 159.251437] restricted_pointer+0x21c/0x4b0 > > [ 159.251461] pointer+0x298/0x760 > > [ 159.251482] vsnprintf+0x330/0xf70 > > [ 159.251504] seq_printf+0x178/0x218 > > [ 159.251526] print_unreferenced+0x1a4/0x2d0 > > [ 159.251551] kmemleak_seq_show+0xd0/0x1e0 > > [ 159.251576] seq_read_iter+0x354/0xe30 > > [ 159.251599] seq_read+0x250/0x378 > > [ 159.251622] full_proxy_read+0xd8/0x148 > > [ 159.251649] vfs_read+0x190/0x918 > > [ 159.251672] ksys_read+0xf0/0x1e0 > > [ 159.251693] __arm64_sys_read+0x70/0xa8 > > [ 159.251716] invoke_syscall.constprop.0+0xd4/0x1d8 > > [ 159.251767] el0_svc+0x50/0x158 > > [ 159.251813] el0t_64_sync+0x17c/0x180 > > ``` > > I have considered three potential approaches to address this matter: > > > > 1. Remove Raw Pointer Printing > > The simplest solution is to eliminate raw pointer printing from the > report. > > This approach involves minimal changes to the kernel code and is > > straightforward to implement. > > > > While I am confident that omitting the raw address would result in > > negligible information loss in most scenarios, some may perceive it as = a > > feature regression. Below is an example of the modification: > > ``` > > - warn_or_seq_printf(seq, " [<%pK>] %pS\n", ptr, ptr); > > + warn_or_seq_printf(seq, " %pS\n", ptr); > > ``` > > This change may be acceptable since the %pS format outputs a hex string > > if no kallsyms are available. However, it modifies the original behavio= r, > > and in the kallsyms scenario, the raw pointer would no longer be presen= t. > > > > 2. Modify SELinux to Avoid Sleeping Spinlocks > > Another option is to alter the SELinux capability check to use > > non-sleeping spinlocks. > > However, this approach is not advisable. The SELinux capability check i= s > > extensively used across the kernel and is far more critical than the > > kmemleak reporting feature. > > Adapting it to address this rare issue could unnecessarily introduce > > latency across the entire kernel, particularly as kmemleak is rarely us= ed > > in production environments. > > > > 3. Move Stack Trace Printing Outside the Atomic Section > > The third and preferred approach is to move the stack trace printing > > outside the atomic section. This would preserve the current functionali= ty > > without modifying SELinux. > > > > The primary challenge here lies in making the backtrace pointers > available > > after exiting the critical section, as they are captured within it. > > To address this, the backtrace pointers can be copied to a safe locatio= n, > > enabling access once the raw_spinlock is released. > > > > Options for Creating a Safe Location for Backtrace Pointers > > Several strategies have been considered for storing the backtrace > pointers > > safely: > > * Dynamic Allocation > > * Allocating memory with kmalloc cannot be done within a raw_spinlo= ck > > area. Using GFP_ATOMIC is also infeasible. > > * Since the code that prints the message is inside a loop, executed > > potentially multiple times, it is only within the raw_spinlock > > section that we can determine whether allocation is needed. > > * Allocating and deallocating memory on every loop iteration would = be > > prohibitively expensive. > > * Global Data Section > > * In this strategy, the message would be printed after exiting the > > raw_spinlock protected section. > > * However, this approach risks data corruption if another occurrenc= e > > of the issue arises before the first operation completes. > > * Per-CPU Data > > * The same concerns as with global data apply here. While data > > corruption is less likely, it is not impossible. > > * Stack > > * Using the stack is the best option since each thread has its own > > stack, ensuring data isolation. However, the size of the data pos= es > > a challenge. > > * Exporting a full stack trace pointer list requires considerable > space. > > A 32-level stack trace in a 64-bit system would require 256 bytes= , > > which is contrary to best practices for stack size management. > > > > To mitigate this, I propose using delta encoding to store the addresses= . > > This method reduces the size of each address from 8 bytes to 4 bytes on > > 64-bit systems. While this introduces some complexity, it significantly > > reduces memory usage and allows us to preserve the kmemleak reports in > their > > current form. > > mm/kmemleak.c | 78 ++++++++++++++++++++++++++++++++++++++++++++++----- > > 1 file changed, 71 insertions(+), 7 deletions(-) > > > > diff --git a/mm/kmemleak.c b/mm/kmemleak.c > > index 0400f5e8ac60..fc5869e09280 100644 > > --- a/mm/kmemleak.c > > +++ b/mm/kmemleak.c > > @@ -274,6 +274,44 @@ static void kmemleak_disable(void); > > pr_warn(fmt, ##__VA_ARGS__); \ > > } while (0) > > > > +#define PTR_STORAGE_OP_OK -1 > > +#define PTR_STORAGE_OP_FAIL 0 > > +#define PTR_STORAGE_CAPACITY 32 > > + > > +struct ptr_storage { > > + unsigned long base; > > + u32 data[PTR_STORAGE_CAPACITY]; > > + int nr_entries; > > +}; > > + > > +static int ptr_storage_insert(unsigned long p, struct ptr_storage *s) > > +{ > > + unsigned long diff_data; > > + > > + if (s->nr_entries !=3D 0) { > > + diff_data =3D s->base - p; > > + if (s->nr_entries < PTR_STORAGE_CAPACITY) { > > + s->data[((s->nr_entries - 1))] =3D diff_data & > 0xffffffff; > > + s->nr_entries++; > > + return PTR_STORAGE_OP_OK; > > + } > > + return PTR_STORAGE_OP_FAIL; > > + } > > + s->base =3D p; > > + s->nr_entries++; > > + return PTR_STORAGE_OP_OK; > > +} > > + > > +static void *ptr_storage_get(struct ptr_storage *s, int item_no) > > +{ > > + if (item_no < s->nr_entries && item_no > 0) > > + return (void *)s->base - (s32)s->data[(item_no - 1)]; > > + > > + if (item_no =3D=3D 0) > > + return (void *)s->base; > > + return NULL; > > +} > > + > > static void warn_or_seq_hex_dump(struct seq_file *seq, int prefix_type= , > > int rowsize, int groupsize, const void > *buf, > > size_t len, bool ascii) > > @@ -357,11 +395,13 @@ static bool unreferenced_object(struct > kmemleak_object *object) > > * print_unreferenced function must be called with the object->lock > held. > > */ > > static void print_unreferenced(struct seq_file *seq, > > - struct kmemleak_object *object) > > + struct kmemleak_object *object, > > + struct ptr_storage *s) > > { > > int i; > > unsigned long *entries; > > unsigned int nr_entries; > > + unsigned long tmp; > > > > nr_entries =3D stack_depot_fetch(object->trace_handle, &entries); > > warn_or_seq_printf(seq, "unreferenced object 0x%08lx (size > %zu):\n", > > @@ -372,8 +412,8 @@ static void print_unreferenced(struct seq_file *seq= , > > warn_or_seq_printf(seq, " backtrace (crc %x):\n", > object->checksum); > > > > for (i =3D 0; i < nr_entries; i++) { > > - void *ptr =3D (void *)entries[i]; > > - warn_or_seq_printf(seq, " [<%pK>] %pS\n", ptr, ptr); > > + tmp =3D (unsigned long)entries[i]; > > + ptr_storage_insert(tmp, s); > > } > > } > > > > @@ -1625,6 +1665,10 @@ static void kmemleak_scan(void) > > struct zone *zone; > > int __maybe_unused i; > > int new_leaks =3D 0; > > + struct ptr_storage s =3D {0}; > > + bool do_print =3D false; > > + void *tmp; > > + int inx; > > > > jiffies_last_scan =3D jiffies; > > > > @@ -1783,12 +1827,20 @@ static void kmemleak_scan(void) > > !(object->flags & OBJECT_REPORTED)) { > > object->flags |=3D OBJECT_REPORTED; > > > > - if (kmemleak_verbose) > > - print_unreferenced(NULL, object); > > + if (kmemleak_verbose) { > > + print_unreferenced(NULL, object, &s); > > + do_print =3D true; > > + } > > > > new_leaks++; > > } > > raw_spin_unlock_irq(&object->lock); > > + if (kmemleak_verbose && do_print) { > > + for (inx =3D 0; inx < s.nr_entries; inx++) { > > + tmp =3D ptr_storage_get(&s, i); > > + warn_or_seq_printf(NULL, " [<%pK>] > %pS\n", tmp, tmp); > > + } > > + } > > } > > rcu_read_unlock(); > > > > @@ -1939,11 +1991,23 @@ static int kmemleak_seq_show(struct seq_file > *seq, void *v) > > { > > struct kmemleak_object *object =3D v; > > unsigned long flags; > > + struct ptr_storage s =3D {0}; > > + void *tmp; > > + int i; > > + bool do_print =3D false; > > > > raw_spin_lock_irqsave(&object->lock, flags); > > - if ((object->flags & OBJECT_REPORTED) && > unreferenced_object(object)) > > - print_unreferenced(seq, object); > > + if ((object->flags & OBJECT_REPORTED) && > unreferenced_object(object)) { > > + print_unreferenced(seq, object, &s); > > + do_print =3D true; > > + } > > raw_spin_unlock_irqrestore(&object->lock, flags); > > + if (do_print) { > > + for (i =3D 0; i < s.nr_entries; i++) { > > + tmp =3D ptr_storage_get(&s, i); > > + warn_or_seq_printf(seq, " [<%pK>] %pS\n", tmp, > tmp); > > + } > > + } > > return 0; > > } > > > > -- > > 2.34.1 > > > > --=20 --- 172 --0000000000004ef1eb062745eb91 Content-Type: text/html; charset="UTF-8" Content-Transfer-Encoding: quoted-printable
Hello Thomas,
Thanks for your suggestion.
On Mon, N= ov 18, 2024 at 3:29=E2=80=AFPM Thomas Wei=C3=9Fschuh <thomas.weissschuh@linutronix.de> wr= ote:
On Fri, Nov= 15, 2024 at 02:54:10PM +0000, Alessandro Carminati wrote:
> Address a bug in the kernel that triggers a "sleeping function ca= lled from
> invalid context" warning when /sys/kernel/debug/kmemleak is print= ed under
> specific conditions:
> - CONFIG_PREEMPT_RT=3Dy
> - Set SELinux as the LSM for the system
> - Set kptr_restrict to 1
> - kmemleak buffer contains at least one item
> Ensure the kmemleak buffer contains at least one item
> Commit 8c96f1bc6fc49c724c4cdd22d3e99260263b7384 ("mm/kmemleak: tu= rn
> kmemleak_lock and object->lock to raw_spinlock_t") introduced = a change
> where kmemleak_seq_show is executed in atomic context within the RT ke= rnel.
> However, the SELinux capability check in this function flow still reli= es on
> regular spinlocks, leading to potential race conditions that trigger a= n
> error when printing the kmemleak backtrace.
> Move the backtrace printing out of the critical section. Use a stack > variable to store the backtrace pointers, avoiding spinlocks in the at= omic
> context.
>
> Implement delta encoding to minimize the stack memory footprint,
> addressing the potentially large memory demands for storing these poin= ters
> on 64-bit systems.

The stacktrace is already stored in the stackdepot.
Shouldn't it be possible to take a reference to the stackdepot entry inside the critical section and then use that reference outside of the
critical section for printing?

Yes, it = is indeed possible to do that.

However, kmemleak operates in such a = way that entries can be deleted, for
example, if they are found to be fa= lse positives.
My concern was that using a reference to a potentially de= leted entry could
cause problems. But after considering your suggestion,= I verified that
stack_depot_put, which is used to delete a stack depot = entry, does not
appear to be called when a kmemleak object is deleted. <= br>This makes me question whether that is the intended behavior.

As = things currently stand, it seems possible to remove all the code I addedto store the trace in the stack and instead directly use the stack_depot <= br>handle.

I would appreciate feedback from kmemleak and stackdepot = experts regarding
this approach.
=C2=A0

> Signed-off-by: Alessandro Carminati <acarmina@redhat.com>
> ---
> ```
> [=C2=A0 159.247069] BUG: sleeping function called from invalid context= at kernel/locking/spinlock_rt.c:48
> [=C2=A0 159.247193] in_atomic(): 1, irqs_disabled(): 1, non_block: 0, = pid: 136, name: cat
> [=C2=A0 159.247241] preempt_count: 1, expected: 0
> [=C2=A0 159.247277] RCU nest depth: 2, expected: 2
> [=C2=A0 159.247388] 6 locks held by cat/136:
> [=C2=A0 159.247438]=C2=A0 #0: ffff32e64bcbf950 (&p->lock){+.+.}= -{3:3}, at: seq_read_iter+0xb8/0xe30
> [=C2=A0 159.248835]=C2=A0 #1: ffffafe6aaa9dea0 (scan_mutex){+.+.}-{3:3= }, at: kmemleak_seq_start+0x34/0x128
> [=C2=A0 159.249053]=C2=A0 #3: ffff32e6546b1cd0 (&object->lock){= ....}-{2:2}, at: kmemleak_seq_show+0x3c/0x1e0
> [=C2=A0 159.249127]=C2=A0 #4: ffffafe6aa8d8560 (rcu_read_lock){....}-{= 1:2}, at: has_ns_capability_noaudit+0x8/0x1b0
> [=C2=A0 159.249205]=C2=A0 #5: ffffafe6aabbc0f8 (notif_lock){+.+.}-{2:2= }, at: avc_compute_av+0xc4/0x3d0
> [=C2=A0 159.249364] irq event stamp: 136660
> [=C2=A0 159.249407] hardirqs last=C2=A0 enabled at (136659): [<ffff= afe6a80fd7a0>] _raw_spin_unlock_irqrestore+0xa8/0xd8
> [=C2=A0 159.249465] hardirqs last disabled at (136660): [<ffffafe6a= 80fd85c>] _raw_spin_lock_irqsave+0x8c/0xb0
> [=C2=A0 159.249518] softirqs last=C2=A0 enabled at (0): [<ffffafe6a= 5d50b28>] copy_process+0x11d8/0x3df8
> [=C2=A0 159.249571] softirqs last disabled at (0): [<00000000000000= 00>] 0x0
> [=C2=A0 159.249970] Preemption disabled at:
> [=C2=A0 159.249988] [<ffffafe6a6598a4c>] kmemleak_seq_show+0x3c/= 0x1e0
> [=C2=A0 159.250609] CPU: 1 UID: 0 PID: 136 Comm: cat Tainted: G=C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 E=C2=A0 =C2=A0 =C2=A0 6.11.0-rt7+ #34 > [=C2=A0 159.250797] Tainted: [E]=3DUNSIGNED_MODULE
> [=C2=A0 159.250822] Hardware name: linux,dummy-virt (DT)
> [=C2=A0 159.251050] Call trace:
> [=C2=A0 159.251079]=C2=A0 dump_backtrace+0xa0/0x128
> [=C2=A0 159.251132]=C2=A0 show_stack+0x1c/0x30
> [=C2=A0 159.251156]=C2=A0 dump_stack_lvl+0xe8/0x198
> [=C2=A0 159.251180]=C2=A0 dump_stack+0x18/0x20
> [=C2=A0 159.251227]=C2=A0 rt_spin_lock+0x8c/0x1a8
> [=C2=A0 159.251273]=C2=A0 avc_perm_nonode+0xa0/0x150
> [=C2=A0 159.251316]=C2=A0 cred_has_capability.isra.0+0x118/0x218
> [=C2=A0 159.251340]=C2=A0 selinux_capable+0x50/0x80
> [=C2=A0 159.251363]=C2=A0 security_capable+0x7c/0xd0
> [=C2=A0 159.251388]=C2=A0 has_ns_capability_noaudit+0x94/0x1b0
> [=C2=A0 159.251412]=C2=A0 has_capability_noaudit+0x20/0x30
> [=C2=A0 159.251437]=C2=A0 restricted_pointer+0x21c/0x4b0
> [=C2=A0 159.251461]=C2=A0 pointer+0x298/0x760
> [=C2=A0 159.251482]=C2=A0 vsnprintf+0x330/0xf70
> [=C2=A0 159.251504]=C2=A0 seq_printf+0x178/0x218
> [=C2=A0 159.251526]=C2=A0 print_unreferenced+0x1a4/0x2d0
> [=C2=A0 159.251551]=C2=A0 kmemleak_seq_show+0xd0/0x1e0
> [=C2=A0 159.251576]=C2=A0 seq_read_iter+0x354/0xe30
> [=C2=A0 159.251599]=C2=A0 seq_read+0x250/0x378
> [=C2=A0 159.251622]=C2=A0 full_proxy_read+0xd8/0x148
> [=C2=A0 159.251649]=C2=A0 vfs_read+0x190/0x918
> [=C2=A0 159.251672]=C2=A0 ksys_read+0xf0/0x1e0
> [=C2=A0 159.251693]=C2=A0 __arm64_sys_read+0x70/0xa8
> [=C2=A0 159.251716]=C2=A0 invoke_syscall.constprop.0+0xd4/0x1d8
> [=C2=A0 159.251767]=C2=A0 el0_svc+0x50/0x158
> [=C2=A0 159.251813]=C2=A0 el0t_64_sync+0x17c/0x180
> ```
> I have considered three potential approaches to address this matter: >
> 1. Remove Raw Pointer Printing
> The simplest solution is to eliminate raw pointer printing from the re= port.
> This approach involves minimal changes to the kernel code and is
> straightforward to implement.
>
> While I am confident that omitting the raw address would result in
> negligible information loss in most scenarios, some may perceive it as= a
> feature regression. Below is an example of the modification:
> ```
> - warn_or_seq_printf(seq, "=C2=A0 =C2=A0 [<%pK>] %pS\n"= ;, ptr, ptr);
> + warn_or_seq_printf(seq, "=C2=A0 =C2=A0 %pS\n", ptr);
> ```
> This change may be acceptable since the %pS format outputs a hex strin= g
> if no kallsyms are available. However, it modifies the original behavi= or,
> and in the kallsyms scenario, the raw pointer would no longer be prese= nt.
>
> 2. Modify SELinux to Avoid Sleeping Spinlocks
> Another option is to alter the SELinux capability check to use
> non-sleeping spinlocks.
> However, this approach is not advisable. The SELinux capability check = is
> extensively used across the kernel and is far more critical than the > kmemleak reporting feature.
> Adapting it to address this rare issue could unnecessarily introduce > latency across the entire kernel, particularly as kmemleak is rarely u= sed
> in production environments.
>
> 3. Move Stack Trace Printing Outside the Atomic Section
> The third and preferred approach is to move the stack trace printing > outside the atomic section. This would preserve the current functional= ity
> without modifying SELinux.
>
> The primary challenge here lies in making the backtrace pointers avail= able
> after exiting the critical section, as they are captured within it. > To address this, the backtrace pointers can be copied to a safe locati= on,
> enabling access once the raw_spinlock is released.
>
> Options for Creating a Safe Location for Backtrace Pointers
> Several strategies have been considered for storing the backtrace poin= ters
> safely:
> * Dynamic Allocation
>=C2=A0 =C2=A0 =C2=A0* Allocating memory with kmalloc cannot be done wit= hin a raw_spinlock
>=C2=A0 =C2=A0 =C2=A0 =C2=A0area. Using GFP_ATOMIC is also infeasible. >=C2=A0 =C2=A0 =C2=A0* Since the code that prints the message is inside = a loop, executed
>=C2=A0 =C2=A0 =C2=A0 =C2=A0potentially multiple times, it is only withi= n the raw_spinlock
>=C2=A0 =C2=A0 =C2=A0 =C2=A0section that we can determine whether alloca= tion is needed.
>=C2=A0 =C2=A0 =C2=A0* Allocating and deallocating memory on every loop = iteration would be
>=C2=A0 =C2=A0 =C2=A0 =C2=A0prohibitively expensive.
> * Global Data Section
>=C2=A0 =C2=A0 =C2=A0* In this strategy, the message would be printed af= ter exiting the
>=C2=A0 =C2=A0 =C2=A0 =C2=A0raw_spinlock protected section.
>=C2=A0 =C2=A0 =C2=A0* However, this approach risks data corruption if a= nother occurrence
>=C2=A0 =C2=A0 =C2=A0 =C2=A0of the issue arises before the first operati= on completes.
> * Per-CPU Data
>=C2=A0 =C2=A0 =C2=A0* The same concerns as with global data apply here.= While data
>=C2=A0 =C2=A0 =C2=A0 =C2=A0corruption is less likely, it is not impossi= ble.
> * Stack
>=C2=A0 =C2=A0 =C2=A0* Using the stack is the best option since each thr= ead has its own
>=C2=A0 =C2=A0 =C2=A0 =C2=A0stack, ensuring data isolation. However, the= size of the data poses
>=C2=A0 =C2=A0 =C2=A0 =C2=A0a challenge.
>=C2=A0 =C2=A0 =C2=A0* Exporting a full stack trace pointer list require= s considerable space.
>=C2=A0 =C2=A0 =C2=A0 =C2=A0A 32-level stack trace in a 64-bit system wo= uld require 256 bytes,
>=C2=A0 =C2=A0 =C2=A0 =C2=A0which is contrary to best practices for stac= k size management.
>
> To mitigate this, I propose using delta encoding to store the addresse= s.
> This method reduces the size of each address from 8 bytes to 4 bytes o= n
> 64-bit systems. While this introduces some complexity, it significantl= y
> reduces memory usage and allows us to preserve the kmemleak reports in= their
> current form.
>=C2=A0 mm/kmemleak.c | 78 +++++++++++++++++++++++++++++++++++++++++++++= +-----
>=C2=A0 1 file changed, 71 insertions(+), 7 deletions(-)
>
> diff --git a/mm/kmemleak.c b/mm/kmemleak.c
> index 0400f5e8ac60..fc5869e09280 100644
> --- a/mm/kmemleak.c
> +++ b/mm/kmemleak.c
> @@ -274,6 +274,44 @@ static void kmemleak_disable(void);
>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0pr_warn(fmt, ##_= _VA_ARGS__);=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 \
>=C2=A0 } while (0)
>=C2=A0
> +#define PTR_STORAGE_OP_OK=C2=A0 =C2=A0 -1
> +#define PTR_STORAGE_OP_FAIL=C2=A0 0
> +#define PTR_STORAGE_CAPACITY 32
> +
> +struct ptr_storage {
> +=C2=A0 =C2=A0 =C2=A0unsigned long=C2=A0 =C2=A0base;
> +=C2=A0 =C2=A0 =C2=A0u32=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0data[PTR_STORAGE_CAPACITY];
> +=C2=A0 =C2=A0 =C2=A0int=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0nr_entries;
> +};
> +
> +static int ptr_storage_insert(unsigned long p, struct ptr_storage *s)=
> +{
> +=C2=A0 =C2=A0 =C2=A0unsigned long diff_data;
> +
> +=C2=A0 =C2=A0 =C2=A0if (s->nr_entries !=3D 0) {
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0diff_data =3D s->b= ase - p;
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0if (s->nr_entries = < PTR_STORAGE_CAPACITY) {
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0= =C2=A0s->data[((s->nr_entries - 1))] =3D diff_data & 0xffffffff;=
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0= =C2=A0s->nr_entries++;
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0= =C2=A0return PTR_STORAGE_OP_OK;
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0}
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0return PTR_STORAGE_OP= _FAIL;
> +=C2=A0 =C2=A0 =C2=A0}
> +=C2=A0 =C2=A0 =C2=A0s->base =3D p;
> +=C2=A0 =C2=A0 =C2=A0s->nr_entries++;
> +=C2=A0 =C2=A0 =C2=A0return PTR_STORAGE_OP_OK;
> +}
> +
> +static void *ptr_storage_get(struct ptr_storage *s, int item_no)
> +{
> +=C2=A0 =C2=A0 =C2=A0if (item_no < s->nr_entries && item= _no > 0)
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0return (void *)s->= base - (s32)s->data[(item_no - 1)];
> +
> +=C2=A0 =C2=A0 =C2=A0if (item_no =3D=3D 0)
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0return (void *)s->= base;
> +=C2=A0 =C2=A0 =C2=A0return NULL;
> +}
> +
>=C2=A0 static void warn_or_seq_hex_dump(struct seq_file *seq, int prefi= x_type,
>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 int rowsize, int groupsize, const= void *buf,
>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 size_t len, bool ascii)
> @@ -357,11 +395,13 @@ static bool unreferenced_object(struct kmemleak_= object *object)
>=C2=A0 =C2=A0* print_unreferenced function must be called with the obje= ct->lock held.
>=C2=A0 =C2=A0*/
>=C2=A0 static void print_unreferenced(struct seq_file *seq,
> -=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0= =C2=A0 =C2=A0 =C2=A0 =C2=A0 struct kmemleak_object *object)
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0= =C2=A0 =C2=A0 =C2=A0 =C2=A0 struct kmemleak_object *object,
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0= =C2=A0 =C2=A0 =C2=A0 =C2=A0 struct ptr_storage *s)
>=C2=A0 {
>=C2=A0 =C2=A0 =C2=A0 =C2=A0int i;
>=C2=A0 =C2=A0 =C2=A0 =C2=A0unsigned long *entries;
>=C2=A0 =C2=A0 =C2=A0 =C2=A0unsigned int nr_entries;
> +=C2=A0 =C2=A0 =C2=A0unsigned long tmp;
>=C2=A0
>=C2=A0 =C2=A0 =C2=A0 =C2=A0nr_entries =3D stack_depot_fetch(object->= trace_handle, &entries);
>=C2=A0 =C2=A0 =C2=A0 =C2=A0warn_or_seq_printf(seq, "unreferenced o= bject 0x%08lx (size %zu):\n",
> @@ -372,8 +412,8 @@ static void print_unreferenced(struct seq_file *se= q,
>=C2=A0 =C2=A0 =C2=A0 =C2=A0warn_or_seq_printf(seq, "=C2=A0 backtra= ce (crc %x):\n", object->checksum);
>=C2=A0
>=C2=A0 =C2=A0 =C2=A0 =C2=A0for (i =3D 0; i < nr_entries; i++) {
> -=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0void *ptr =3D (void *= )entries[i];
> -=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0warn_or_seq_printf(se= q, "=C2=A0 =C2=A0 [<%pK>] %pS\n", ptr, ptr);
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0tmp =3D (unsigned lon= g)entries[i];
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0ptr_storage_insert(tm= p, s);
>=C2=A0 =C2=A0 =C2=A0 =C2=A0}
>=C2=A0 }
>=C2=A0
> @@ -1625,6 +1665,10 @@ static void kmemleak_scan(void)
>=C2=A0 =C2=A0 =C2=A0 =C2=A0struct zone *zone;
>=C2=A0 =C2=A0 =C2=A0 =C2=A0int __maybe_unused i;
>=C2=A0 =C2=A0 =C2=A0 =C2=A0int new_leaks =3D 0;
> +=C2=A0 =C2=A0 =C2=A0struct ptr_storage s =3D {0};
> +=C2=A0 =C2=A0 =C2=A0bool do_print =3D false;
> +=C2=A0 =C2=A0 =C2=A0void *tmp;
> +=C2=A0 =C2=A0 =C2=A0int inx;
>=C2=A0
>=C2=A0 =C2=A0 =C2=A0 =C2=A0jiffies_last_scan =3D jiffies;
>=C2=A0
> @@ -1783,12 +1827,20 @@ static void kmemleak_scan(void)
>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0!(= object->flags & OBJECT_REPORTED)) {
>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0object->flags |=3D OBJECT_REPORTED;
>=C2=A0
> -=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0= =C2=A0if (kmemleak_verbose)
> -=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0= =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0print_unreferenced(NULL, object);
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0= =C2=A0if (kmemleak_verbose) {
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0= =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0print_unreferenced(NULL, object, &s)= ;
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0= =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0do_print =3D true;
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0= =C2=A0}
>=C2=A0
>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0new_leaks++;
>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0}
>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0raw_spin_unlock_= irq(&object->lock);
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0if (kmemleak_verbose = && do_print) {
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0= =C2=A0for (inx =3D 0; inx < s.nr_entries; inx++) {
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0= =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0tmp =3D ptr_storage_get(&s, i);
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0= =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0warn_or_seq_printf(NULL, "=C2=A0 = =C2=A0 [<%pK>] %pS\n", tmp, tmp);
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0= =C2=A0}
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0}
>=C2=A0 =C2=A0 =C2=A0 =C2=A0}
>=C2=A0 =C2=A0 =C2=A0 =C2=A0rcu_read_unlock();
>=C2=A0
> @@ -1939,11 +1991,23 @@ static int kmemleak_seq_show(struct seq_file *= seq, void *v)
>=C2=A0 {
>=C2=A0 =C2=A0 =C2=A0 =C2=A0struct kmemleak_object *object =3D v;
>=C2=A0 =C2=A0 =C2=A0 =C2=A0unsigned long flags;
> +=C2=A0 =C2=A0 =C2=A0struct ptr_storage s =3D {0};
> +=C2=A0 =C2=A0 =C2=A0void *tmp;
> +=C2=A0 =C2=A0 =C2=A0int i;
> +=C2=A0 =C2=A0 =C2=A0bool do_print =3D false;
>=C2=A0
>=C2=A0 =C2=A0 =C2=A0 =C2=A0raw_spin_lock_irqsave(&object->lock, = flags);
> -=C2=A0 =C2=A0 =C2=A0if ((object->flags & OBJECT_REPORTED) &= ;& unreferenced_object(object))
> -=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0print_unreferenced(se= q, object);
> +=C2=A0 =C2=A0 =C2=A0if ((object->flags & OBJECT_REPORTED) &= ;& unreferenced_object(object)) {
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0print_unreferenced(se= q, object, &s);
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0do_print =3D true; > +=C2=A0 =C2=A0 =C2=A0}
>=C2=A0 =C2=A0 =C2=A0 =C2=A0raw_spin_unlock_irqrestore(&object->l= ock, flags);
> +=C2=A0 =C2=A0 =C2=A0if (do_print) {
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0for (i =3D 0; i < = s.nr_entries; i++) {
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0= =C2=A0tmp =3D ptr_storage_get(&s, i);
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0= =C2=A0warn_or_seq_printf(seq, "=C2=A0 =C2=A0 [<%pK>] %pS\n"= ;, tmp, tmp);
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0}
> +=C2=A0 =C2=A0 =C2=A0}
>=C2=A0 =C2=A0 =C2=A0 =C2=A0return 0;
>=C2=A0 }
>=C2=A0
> --
> 2.34.1
>



--
---
172
--0000000000004ef1eb062745eb91--