Received: by 2002:a05:7412:e794:b0:fa:551:50a7 with SMTP id o20csp1541213rdd; Thu, 11 Jan 2024 02:13:13 -0800 (PST) X-Google-Smtp-Source: AGHT+IEWI/xYjKs8r1tWAjtFOr05PQuFkaXA3bZ8v8P1pV4dojFWN4rLZ9UknW7WaP13598YgZuz X-Received: by 2002:a17:902:ff02:b0:1d4:e210:9f71 with SMTP id f2-20020a170902ff0200b001d4e2109f71mr840403plj.95.1704967992746; Thu, 11 Jan 2024 02:13:12 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1704967992; cv=none; d=google.com; s=arc-20160816; b=e0S+xp06IryGmcs6c16y4260KL965rOQZozoX0kjRVkz7l7EXz8eCXOG9JXDa7OpxF 8ylaO5O3zik6U3VlU+Ez9PFPGt4zgm6HKu3VQgMIU+gOQQAfBKCXyRUJOmo5Tw52RyCg 6KtW7nyF1bNMR7kQKYJCb4FD5GDY0p1urSN54OB1WPXCuCYsJvfby2pDHX9A4FiyP30R x9ZCIMDgwTu6vm2Punf+IrGTOBoSYx6PXnOZ3Lcb2ZLBwcHyeNdLdhgAMOPSOp1XukFX DRmYS4rDAAejmIZVaGDWn3FokrvMM3d4nEVRBYr7MaHOCa9UxF0zrKQuj1h35kZL9Aon cbWg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=in-reply-to:content-disposition:mime-version:list-unsubscribe :list-subscribe:list-id:precedence:references:message-id:subject:cc :to:from:date; bh=IuvgF3FLgcm6DhbKgEWuyqcSdq5z5DWi3UsVpGeVpDo=; fh=tQwlSAgO1RlgqPrCNfv1UOdJwFa59X6SwKqTzJTpL5w=; b=hnRTnuROqhI+x5lWgono46z/CXP1YBoT/6yyy05zCeUjmqWdqbmau1f9jZ9U5T9Y1v 89R/Rncc0834epyveistO1Ynw9uUQHQcwPgDOOvs7JZ/iVN2aKExE5Fq19tUxEmwN651 1vQx97whSsP4a6Pc0N0Sg6l3VBwK6LYwQvaK/YJyyNLsLtqPIlXdRro3HmkScXawtFLH A8AclMJVjDXB7ixROcirnn3rSc4T7T1TGYzbUTIUt8/Peja9U28htQdONBfxEisKwBGs 7QVPCjjFNhDW3M1ny0zDuIwxdREl80n8Ny8eG/V/M5r4X6k/23IEILqffaV+Cs554U1J AJFw== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: domain of linux-kernel+bounces-23364-linux.lists.archive=gmail.com@vger.kernel.org designates 2604:1380:45e3:2400::1 as permitted sender) smtp.mailfrom="linux-kernel+bounces-23364-linux.lists.archive=gmail.com@vger.kernel.org"; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=arm.com Return-Path: Received: from sv.mirrors.kernel.org (sv.mirrors.kernel.org. [2604:1380:45e3:2400::1]) by mx.google.com with ESMTPS id jf6-20020a170903268600b001d5282ee8c8si751055plb.121.2024.01.11.02.13.12 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 11 Jan 2024 02:13:12 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel+bounces-23364-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; spf=pass (google.com: domain of linux-kernel+bounces-23364-linux.lists.archive=gmail.com@vger.kernel.org designates 2604:1380:45e3:2400::1 as permitted sender) smtp.mailfrom="linux-kernel+bounces-23364-linux.lists.archive=gmail.com@vger.kernel.org"; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=arm.com 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 318C228569F for ; Thu, 11 Jan 2024 10:13:12 +0000 (UTC) Received: from localhost.localdomain (localhost.localdomain [127.0.0.1]) by smtp.subspace.kernel.org (Postfix) with ESMTP id CF62C12E5B; Thu, 11 Jan 2024 10:13:06 +0000 (UTC) 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 600E311737; Thu, 11 Jan 2024 10:13:05 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 9A62EC433C7; Thu, 11 Jan 2024 10:13:03 +0000 (UTC) Date: Thu, 11 Jan 2024 10:13:01 +0000 From: Catalin Marinas To: Ido Schimmel Cc: Robin Murphy , joro@8bytes.org, will@kernel.org, iommu@lists.linux.dev, linux-kernel@vger.kernel.org, zhangzekun11@huawei.com, john.g.garry@oracle.com, dheerajkumar.srivastava@amd.com, jsnitsel@redhat.com Subject: Re: [PATCH v3 0/2] iommu/iova: Make the rcache depot properly flexible Message-ID: References: Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: On Thu, Jan 11, 2024 at 10:20:27AM +0200, Ido Schimmel wrote: > On Wed, Jan 10, 2024 at 05:58:15PM +0000, Catalin Marinas wrote: > > Transient false positives are possible, especially as the code doesn't > > use a double-linked list (for the latter, kmemleak does checksumming and > > detects the prev/next change, defers the reporting until the object > > becomes stable). That said, if a new scan is forced (echo scan > > > /sys/kernel/debug/kmemleak), are the same objects still listed as leaks? > > If yes, they may not be transient. > > We are doing "scan" and "clear" after each test. I will disable the > "clear" and see if the leaks persist. If it is indeed a false positive, you can try the patch below (I haven't given it any run-time test, only compiled): diff --git a/Documentation/dev-tools/kmemleak.rst b/Documentation/dev-tools/kmemleak.rst index 2cb00b53339f..7d784e03f3f9 100644 --- a/Documentation/dev-tools/kmemleak.rst +++ b/Documentation/dev-tools/kmemleak.rst @@ -161,6 +161,7 @@ See the include/linux/kmemleak.h header for the functions prototype. - ``kmemleak_free_percpu`` - notify of a percpu memory block freeing - ``kmemleak_update_trace`` - update object allocation stack trace - ``kmemleak_not_leak`` - mark an object as not a leak +- ``kmemleak_transient_leak`` - mark an object as a transient leak - ``kmemleak_ignore`` - do not scan or report an object as leak - ``kmemleak_scan_area`` - add scan areas inside a memory block - ``kmemleak_no_scan`` - do not scan a memory block diff --git a/drivers/iommu/iova.c b/drivers/iommu/iova.c index d30e453d0fb4..c1d0775080ff 100644 --- a/drivers/iommu/iova.c +++ b/drivers/iommu/iova.c @@ -6,6 +6,7 @@ */ #include +#include #include #include #include @@ -730,6 +731,11 @@ static struct iova_magazine *iova_depot_pop(struct iova_rcache *rcache) { struct iova_magazine *mag = rcache->depot; + /* + * As the mag->next pointer is moved to rcache->depot and reset via + * the mag->size assignment, mark the transient false positive. + */ + kmemleak_transient_leak(mag->next); rcache->depot = mag->next; mag->size = IOVA_MAG_SIZE; rcache->depot_size--; diff --git a/include/linux/kmemleak.h b/include/linux/kmemleak.h index 6a3cd1bf4680..93a73c076d16 100644 --- a/include/linux/kmemleak.h +++ b/include/linux/kmemleak.h @@ -26,6 +26,7 @@ extern void kmemleak_free_part(const void *ptr, size_t size) __ref; extern void kmemleak_free_percpu(const void __percpu *ptr) __ref; extern void kmemleak_update_trace(const void *ptr) __ref; extern void kmemleak_not_leak(const void *ptr) __ref; +extern void kmemleak_transient_leak(const void *ptr) __ref; extern void kmemleak_ignore(const void *ptr) __ref; extern void kmemleak_scan_area(const void *ptr, size_t size, gfp_t gfp) __ref; extern void kmemleak_no_scan(const void *ptr) __ref; @@ -93,6 +94,9 @@ static inline void kmemleak_update_trace(const void *ptr) static inline void kmemleak_not_leak(const void *ptr) { } +static inline void kmemleak_transient_leak(const void *ptr) +{ +} static inline void kmemleak_ignore(const void *ptr) { } diff --git a/mm/kmemleak.c b/mm/kmemleak.c index 5501363d6b31..9fd338063cea 100644 --- a/mm/kmemleak.c +++ b/mm/kmemleak.c @@ -915,6 +915,28 @@ static void make_black_object(unsigned long ptr, bool is_phys) paint_ptr(ptr, KMEMLEAK_BLACK, is_phys); } +/* + * Reset the checksum of an object. The immediate effect is that it will not + * be reported as a leak during the next scan until its checksum is updated. + */ +static void reset_checksum(unsigned long ptr) +{ + unsigned long flags; + struct kmemleak_object *object; + + object = find_and_get_object(ptr, 0); + if (!object) { + kmemleak_warn("Not resetting the checksum of an unknown object at 0x%08lx\n", + ptr); + return; + } + + raw_spin_lock_irqsave(&object->lock, flags); + object->checksum = 0; + raw_spin_unlock_irqrestore(&object->lock, flags); + put_object(object); +} + /* * Add a scanning area to the object. If at least one such area is added, * kmemleak will only scan these ranges rather than the whole memory block. @@ -1194,6 +1216,23 @@ void __ref kmemleak_not_leak(const void *ptr) } EXPORT_SYMBOL(kmemleak_not_leak); +/** + * kmemleak_transient_leak - mark an allocated object as transient false positive + * @ptr: pointer to beginning of the object + * + * Calling this function on an object will cause the memory block to not be + * reported as a leak temporarily. This may happen, for example, if the object + * is part of a singly linked list and the ->next reference it is changed. + */ +void __ref kmemleak_transient_leak(const void *ptr) +{ + pr_debug("%s(0x%px)\n", __func__, ptr); + + if (kmemleak_enabled && ptr && !IS_ERR(ptr)) + reset_checksum((unsigned long)ptr); +} +EXPORT_SYMBOL(kmemleak_transient_leak); + /** * kmemleak_ignore - ignore an allocated object * @ptr: pointer to beginning of the object -- Catalin