From patchwork Wed Dec 25 08:09:12 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Weikang Guo X-Patchwork-Id: 13920648 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 A3B0FE7718D for ; Wed, 25 Dec 2024 08:09:27 +0000 (UTC) Received: by kanga.kvack.org (Postfix) id B67C46B007B; Wed, 25 Dec 2024 03:09:26 -0500 (EST) Received: by kanga.kvack.org (Postfix, from userid 40) id B16746B0083; Wed, 25 Dec 2024 03:09:26 -0500 (EST) X-Delivered-To: int-list-linux-mm@kvack.org Received: by kanga.kvack.org (Postfix, from userid 63042) id 9DD946B0085; Wed, 25 Dec 2024 03:09:26 -0500 (EST) X-Delivered-To: linux-mm@kvack.org Received: from relay.hostedemail.com (smtprelay0016.hostedemail.com [216.40.44.16]) by kanga.kvack.org (Postfix) with ESMTP id 8053A6B007B for ; Wed, 25 Dec 2024 03:09:26 -0500 (EST) Received: from smtpin18.hostedemail.com (a10.router.float.18 [10.200.18.1]) by unirelay07.hostedemail.com (Postfix) with ESMTP id CB26A1603B2 for ; Wed, 25 Dec 2024 08:09:25 +0000 (UTC) X-FDA: 82932755850.18.431EB10 Received: from mail-yb1-f174.google.com (mail-yb1-f174.google.com [209.85.219.174]) by imf12.hostedemail.com (Postfix) with ESMTP id 8F87440008 for ; Wed, 25 Dec 2024 08:09:06 +0000 (UTC) Authentication-Results: imf12.hostedemail.com; dkim=pass header.d=gmail.com header.s=20230601 header.b="DKUW/nH8"; dmarc=pass (policy=none) header.from=gmail.com; spf=pass (imf12.hostedemail.com: domain of guoweikang.kernel@gmail.com designates 209.85.219.174 as permitted sender) smtp.mailfrom=guoweikang.kernel@gmail.com ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=hostedemail.com; s=arc-20220608; t=1735114145; 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:content-transfer-encoding:in-reply-to: references:dkim-signature; bh=I5RJDQoHtZ3t4AYT7GLBqeRBAtJgELgJvtSO/falmXk=; b=U3y+3/9Ui5BYTHSJh4PyA15pu3QPV+v3d/ZoQhAvnbpuj8tkbAOsOE93A0F2wz6yEnQ7nT 0mvcdhmMyb4bVodufEpMH4Zp4otktrVgt51THdIeMafAsn52O2BAt0KD8H2Et7/FZoEwb1 OrcRTyiB+mAma0ZaG/HCJVnDt1tsFrw= ARC-Seal: i=1; s=arc-20220608; d=hostedemail.com; t=1735114145; a=rsa-sha256; cv=none; b=kPYpF7gOBERgDVrqx77mtXgbt44OkS20s+qvAEBcIRhJKh5aB8KqfiMMViIZ4UhFOPCySC gT0yjnL4mUJqCti779m6yJImu+TSV2M5GaC+6fvMHGAPfzK6IczTy2kSxQZNScthy0mEXq y25n1gUsiLAJqmbUjx7Wt/saayTJZJU= ARC-Authentication-Results: i=1; imf12.hostedemail.com; dkim=pass header.d=gmail.com header.s=20230601 header.b="DKUW/nH8"; dmarc=pass (policy=none) header.from=gmail.com; spf=pass (imf12.hostedemail.com: domain of guoweikang.kernel@gmail.com designates 209.85.219.174 as permitted sender) smtp.mailfrom=guoweikang.kernel@gmail.com Received: by mail-yb1-f174.google.com with SMTP id 3f1490d57ef6-e53ef7462b6so83359276.3 for ; Wed, 25 Dec 2024 00:09:23 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1735114163; x=1735718963; darn=kvack.org; h=content-transfer-encoding:cc:to:subject:message-id:date:from :mime-version:from:to:cc:subject:date:message-id:reply-to; bh=I5RJDQoHtZ3t4AYT7GLBqeRBAtJgELgJvtSO/falmXk=; b=DKUW/nH8fCUnVw0HLtq2hXTzGUdG5ux2LigCG1lqSVLj070K2i3H6hD4cmiFCM1j0d QypbDsRUHF+rLNw3O8Dq85FSHynlqUCooz7MrPqsP1DIlTIOulVyG0YInTC/ms7wG872 sCJZ0f96p8hasWCHoRLOJqlEf5MCO0aRGcg5j71yZouEAUGnasaYsmBtSRfg5d516VzH 9bZ1VibtGD+hSVwfUdhcHDQvzvFWZxG/+so08k9+AAmyGG2kGcio9qHzaTMpTFq3UADN j4pl4RkZq+Y6e2uU+qp2IVBvPyRvkI6xQwkU9XablbAjVXKiyM2iQ0bmFQvwgd06YDbk Zisw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1735114163; x=1735718963; h=content-transfer-encoding:cc:to:subject:message-id:date:from :mime-version:x-gm-message-state:from:to:cc:subject:date:message-id :reply-to; bh=I5RJDQoHtZ3t4AYT7GLBqeRBAtJgELgJvtSO/falmXk=; b=JpyI6huTJTrv7nKRDNIZFqz+Faloj+sW+R7JK/KelKXgWpZ+DGYX1MzhJXnOosPSBX vtoClITo+9QUw4l6rAoJPVZN0m/WOBuk6/vtVn4naY+BavHEudwZu3N8p/sSwpWhjqlr b8lQQvQOjH0Nc4wjQbmxKaazm1e8+XPot+ZhVJsg1TxS0VNjFh0wLc0Qpm0zbpbBAVH0 OMCxkL+mVV/ZPju69dM2fGGBiGiJT/homVIkkry2CfmY5fLS7E5is3pa7unNquqjScrb IKu2i+tA9EH1RJgneAHQQgwaoktHX9Tbu7/IxGzM1ez1OusRrBkuKlxDDPtKmhIBX5wk WCHQ== X-Gm-Message-State: AOJu0YzXTDBY6M/0O48X/FGydxL5inyM5mtA452CRZColCbFHj1AOtzb Ovu9yCtr8iwgNiqwCfFGZayRHm34c3ENOe9HVyqqjtqtb+BGVVQDimEO4T6JyqwAkUY0s2GgdVx OA1+2rYfDh0m2nKVeDbmREN+P40c= X-Gm-Gg: ASbGncu0WLwzUOROV1zRze3YHdE/muAmxFU9WwmsTBgBQwSggEmM8K9aTu5xSP8y/kV AsSgcxZTdt0SK9cmEIM3mJWT/9ULJg+6Z8s7AR8Y= X-Google-Smtp-Source: AGHT+IEO22SHxxKY8sn59okYEevvhOeq+mcb/gj0nCDxxgIsuTnY6LudvxThZor19wniGJ/a7r1htnvV8f0oGztpXMA= X-Received: by 2002:a05:690c:9986:b0:6ef:79d1:2f69 with SMTP id 00721157ae682-6f3f8213f2fmr163950257b3.31.1735114163118; Wed, 25 Dec 2024 00:09:23 -0800 (PST) MIME-Version: 1.0 From: Weikang Guo Date: Wed, 25 Dec 2024 16:09:12 +0800 Message-ID: Subject: Potential Double Scanning of struct page Physical Memory by kmemleak To: Catalin Marinas , Andrew Morton Cc: Linux Memory Management List , linux-kernel@vger.kernel.org X-Stat-Signature: ofoziebysx67ffdq46tjsujogyupdyuq X-Rspamd-Queue-Id: 8F87440008 X-Rspam-User: X-Rspamd-Server: rspam01 X-HE-Tag: 1735114146-940721 X-HE-Meta: U2FsdGVkX1/Zaw2yQiL1VEVDeSKclFRyYf3xJto97VN65igWTevSlKVecBtTwV0n/HEyNTjeTjbDOK9hpbg7tmts3v4EeFALVOf4g0N765SNDudo10vJ05g4RYVwyZ+Je+cDZEYlvKYKUBb6NJQ0PjGHHz6xTFReIzhp0dozn8bxofdijpxe8Gdmqj7avEgOA2P7zzeThX6KTMR35Srhk6NWU1dFrs5ULVSOcUMoPdrGJhjJvSS3dfKBmjJuPcNaf48A3X2aByC1hf2XZCfzQeXOrnJr6gm44/olD0jkA4i9NT47bXBqBOVUH6oYPIWQTv73Wq2J3mVWEGQ2JeWNUFGbZO2sK4ccHzT4wbvkvCyhzHcWVv1/u6UMf7zdxzcRuVac1Wm0xgI9GSxjPKrhsJgudOPYs0h+kA6ggIFZbGHA5wqpe0Mo6mTXYgmPOshW9D4jPnXFeIj/0CPP55W+Y+oUbs9wI5PRpxoD+2dXvof3/9YoxyfVg52Te9Ki/iLAJd+HDWYGkpHtImE6LBIzNEJvLxFvCiu9PCo4vY954+3wL6hn4cEHNxFchl8SRFgfDT3cwaBH6Pi4YgPIoH73NXjRYqioMjf9gciQKnQ8KwEreUw01REu7k/as0tFBhdeUTfj33szAfBXmqfcICw49FpcEFaD7Nr2iW/MNbijBQO1Tj1cKn0E4s0nv2osEqjYSfU7SueHz6mM1Q99+EbAcItlBePAx8W7KWN+d+9RsTMSu4AbtPdvmHi7e5hOXUdFXwIc8bmdFnSmkmkGk2n0I1ntOxP0Dl0LP7KqTQ5/CV5dgiaSdo1h/mUZceDZun+8D5GFVWVH7lCi34jaE0DCTIdTT4EdKg0sV4MMw0mvIo+TZ18IkvDg+Vac5642KvGZrq73lovuPvU2Eu+/Al9GDPSVt/vDgxQSnD19SLV7POHL+bLAFBhyaNU10jdKszhXieRVLEOQ8/pKZ4C6aH3 fK9Ep9c4 SJE6nzZ/bqVjzhAIVnwz+cdX7XcrLACWKY6njspZFLQaLRt/xHDm1oMkiHO9LWuQJ8smAj+Stllj41dcbwmsHYlAsKM4n4ykY2eY04ORNrpkvVdcORI6SJb2waqbRGmolLDLioxdRoG01yk0t9cOPRDDaV2a7WXrzQMHMdveYDb3LOes7uULF4OyphVlOh0rxZkHQIdOJAxJMTVGecB7GTZn050DiarhaEZCfVAlLb/mJVeqa2014ZluIeCzb28xnDVEdyCxj2Ppx+D51lv3DHeh4LAqXBxF9sjpNgGHCh2Y1WBcVaKEXwqoHPyXKFA2t8DiTFXQiSBwp39npbr4UL7/SHVSX0TBdVfQsivqnA95skkMIYiPXwGloOIA2wh3PSVf0sz/Bqi9qMeQ= X-Bogosity: Ham, tests=bogofilter, spamicity=0.000005, version=1.2.4 Sender: owner-linux-mm@kvack.org Precedence: bulk X-Loop: owner-majordomo@kvack.org List-ID: List-Subscribe: List-Unsubscribe: Dear Catalin and Andrew, I hope this message finds you well. While reviewing the implementation of kmemleak, I noticed a potential issue where the physical memory occupied by struct page may be scanned twice by kmemleak. To verify this hypothesis, I added some logging to the code, and I would like to discuss my findings with you. Below are the details of my environment, the logic I used, and the relevant log output. Test Platform: Architecture: ARM64 Platform: qemu branch: local branch based on V6.12 defconfig: use defconfig with CONFIG_KMEMLEAK open Problem Description: When CONFIG_SPARSEMEM is enabled, the memory for `struct page`objects in the sections is allocated via `sparse_buffer` using the `memblock_alloc_xxx` interface. Since memblock does not explicitly specify `MEMBLOCK_ALLOC_NOLEAKTRACE`, kmemleak will treat the memory as a gray object with mincount=0. In other words, the physical memory occupied by `struct page` will be scanned by kmemleak as a gray object during the scan thread. Additionally, kmemleak also traverses and scans valid struct page objects in the zone . As a result, the physical memory occupied by struct page may end up being scanned twice by scan thread. Logging Added: To investigate further, I added the following logs: Logs for the memory allocated for `struct page` objects through sparse memblock. scan_block(start, next, object); @@ -1677,6 +1680,8 @@ static void kmemleak_scan(void) * Struct page scanning for each node. */ for_each_populated_zone(zone) { + static int print_scan_page = 0; + unsigned long start_pfn = zone->zone_start_pfn; unsigned long end_pfn = zone_end_pfn(zone); unsigned long pfn; @@ -1696,6 +1701,14 @@ static void kmemleak_scan(void) /* only scan if page is in use */ if (page_count(page) == 0) continue; + + + if (print_scan_page == 0) { + pr_info("======= scan page [0x%08lx:0x%08lx] \n", + page, page+1); + print_scan_page++; + } + scan_block(page, page + 1, NULL); } } The log output is as follows: [ 0.000000] sparse buf alloc VA: [0xffff39253b600000: 0xffff39253f600000] to PA: [0x13b600000: 0x13f600000] [ 0.000000] ==== vmemap 2M: VA:0xfffffee451000000 to PA:0x13b600000 [ 0.000000] ==== vmemap 2M: VA:0xfffffee451200000 to PA:0x13b800000 [ 0.000000] ==== vmemap 2M: VA:0xfffffee451400000 to PA:0x13ba00000 [ 0.000000] ==== vmemap 2M: VA:0xfffffee451600000 to PA:0x13bc00000 [ 0.000000] ==== vmemap 2M: VA:0xfffffee451800000 to PA:0x13be00000 [ 0.000000] ==== vmemap 2M: VA:0xfffffee451a00000 to PA:0x13c000000 [ 0.000000] ==== vmemap 2M: VA:0xfffffee451c00000 to PA:0x13c200000 [ 0.000000] ==== vmemap 2M: VA:0xfffffee451e00000 to PA:0x13c400000 [ 0.000000] ==== vmemap 2M: VA:0xfffffee452000000 to PA:0x13c600000 [ 0.000000] ==== vmemap 2M: VA:0xfffffee452200000 to PA:0x13c800000 [ 0.000000] ==== vmemap 2M: VA:0xfffffee452400000 to PA:0x13ca00000 [ 0.000000] ==== vmemap 2M: VA:0xfffffee452600000 to PA:0x13cc00000 [ 0.000000] ==== vmemap 2M: VA:0xfffffee452800000 to PA:0x13ce00000 [ 0.000000] ==== vmemap 2M: VA:0xfffffee452a00000 to PA:0x13d000000 [ 0.000000] ==== vmemap 2M: VA:0xfffffee452c00000 to PA:0x13d200000 [ 0.000000] ==== vmemap 2M: VA:0xfffffee452e00000 to PA:0x13d400000 [ 0.000000] ==== vmemap 2M: VA:0xfffffee453000000 to PA:0x13d600000 [ 0.000000] ==== vmemap 2M: VA:0xfffffee453200000 to PA:0x13d800000 [ 0.000000] ==== vmemap 2M: VA:0xfffffee453400000 to PA:0x13da00000 [ 0.000000] ==== vmemap 2M: VA:0xfffffee453600000 to PA:0x13dc00000 [ 0.000000] ==== vmemap 2M: VA:0xfffffee453800000 to PA:0x13de00000 [ 0.000000] ==== vmemap 2M: VA:0xfffffee453a00000 to PA:0x13e000000 [ 0.000000] ==== vmemap 2M: VA:0xfffffee453c00000 to PA:0x13e200000 [ 0.000000] ==== vmemap 2M: VA:0xfffffee453e00000 to PA:0x13e400000 [ 0.000000] ==== vmemap 2M: VA:0xfffffee454000000 to PA:0x13e600000 [ 0.000000] ==== vmemap 2M: VA:0xfffffee454200000 to PA:0x13e800000 [ 0.000000] ==== vmemap 2M: VA:0xfffffee454400000 to PA:0x13ea00000 [ 0.000000] ==== vmemap 2M: VA:0xfffffee454600000 to PA:0x13ec00000 [ 0.000000] ==== vmemap 2M: VA:0xfffffee454800000 to PA:0x13ee00000 [ 0.000000] ==== vmemap 2M: VA:0xfffffee454a00000 to PA:0x13f000000 [ 0.000000] ==== vmemap 2M: VA:0xfffffee454c00000 to PA:0x13f200000 [ 0.000000] ==== vmemap 2M: VA:0xfffffee454e00000 to PA:0x13f400000 [ 62.480979] kmemleak: ======= scan page [0xfffffee451008400:0xfffffee451008440] [ 62.705876] kmemleak: ======= scan memblock OBJECT_PHYS:[0xffff39253b600000:0xffff39253f600000] scan_page: VMEMAP VA is [ 0xfffffee451008400 - 0xfffffee451008440] scan_page:Real PA is [0x13b608400 - 0x13b608440] scan OBJECT_PHYS: VA is [0xffff39253b600000:0xffff39253f600000] scan OBJECT_PHYS: PA is [0x13b600000:0x13f600000] The first record page `0x13b608400` was scanned twice Could you please help confirm whether this issue exists and if it could lead to any unintended consequences? I would appreciate any insights or suggestions you may have. Possible solution: Specify `MEMBLOCK_ALLOC_NOLEAKTRACE` when alloc `struct page memory` Thank you for your time and assistance. Best regards, Guo diff --git a/mm/sparse.c b/mm/sparse.c index 3174b3ca3e9e..f2465b394344 100644 --- a/mm/sparse.c +++ b/mm/sparse.c @@ -362,6 +362,9 @@ static void __init sparse_buffer_init(unsigned long size, int nid) */ sparsemap_buf = memmap_alloc(size, section_map_size(), addr, nid, true); sparsemap_buf_end = sparsemap_buf + size; + pr_info("sparse buf alloc VA: [0x%08lx: 0x%08lx] to PA: \ + [0x%08lx: 0x%08lx]\n",sparsemap_buf, sparsemap_buf_end, + virt_to_phys(sparsemap_buf), virt_to_phys(sparsemap_buf_end)); #ifndef CONFIG_SPARSEMEM_VMEMMAP memmap_boot_pages_add(DIV_ROUND_UP(size, PAGE_SIZE)); #endif Logs to show the mapping between VMEMAP VA and PA. diff --git a/mm/sparse-vmemmap.c b/mm/sparse-vmemmap.c index c0388b2e959d..f1a312f2a281 100644 --- a/mm/sparse-vmemmap.c +++ b/mm/sparse-vmemmap.c @@ -342,6 +342,8 @@ int __meminit vmemmap_populate_hugepages(unsigned long start, unsigned long end, p = vmemmap_alloc_block_buf(PMD_SIZE, node, altmap); if (p) { + pr_info("==== vmemap 2M: VA:0x%08lx to PA:0x%08lx \n", + start, virt_to_phys(p)); vmemmap_set_pmd(pmd, p, node, addr, next); continue; } else if (altmap) { Logs showing the memblock and struct page objects scanned by kmemleak. diff --git a/mm/kmemleak.c b/mm/kmemleak.c index 0efa41d77bcc..a803825dcb18 100644 --- a/mm/kmemleak.c +++ b/mm/kmemleak.c @@ -1529,7 +1529,10 @@ static void scan_object(struct kmemleak_object *object) (void *)object->pointer; void *end = start + object->size; void *next; - + if (object->flags & OBJECT_PHYS) { + pr_info("======= scan memblock OBJECT_PHYS:[0x%08lx:0x%08lx]\n", + start, end); + } do { next = min(start + MAX_SCAN_SIZE, end);