From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mail-pj1-f51.google.com (mail-pj1-f51.google.com [209.85.216.51]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id A39E03D3314 for ; Tue, 28 Apr 2026 08:19:25 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.216.51 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1777364367; cv=none; b=gOn8OgyUjKCNWsIvEJDeedWMzdEOIKA+LP8tymb2V7dUwOKsT+hTcMe3/m4OPg0/eC+8THEgNnvb+25sLySMPgzhHVU7Jq3hGUNOivoDqkF0Q1oKbAPax/XqYKXsHplzsuMQY7Xk8+yLw6+MlzVHy/a2kphBCTyb8oN4s2y38U8= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1777364367; c=relaxed/simple; bh=C4xXtEXsz0ixhX8JiretKLDxPoi22KeWMdBYVODC6is=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=VRE+cutVXNeOiOB3np9sYh1ZwyEjZHKB39NsXJ3X+aZUVewh6QOG5SrN+wH/x12p++LpO7Gm+ho5ZiQrTUoYT8NyCdU4aYgOBzo7ztULO0fbOfo9l5YPBTPs3/Q5zQxzPeFVqE81P9xO/n6cb2Qe+9GdcRRqLr6XpPnzy+qcXDc= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=bytedance.com; spf=pass smtp.mailfrom=bytedance.com; dkim=pass (2048-bit key) header.d=bytedance.com header.i=@bytedance.com header.b=Xcv6nuLZ; arc=none smtp.client-ip=209.85.216.51 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=bytedance.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=bytedance.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=bytedance.com header.i=@bytedance.com header.b="Xcv6nuLZ" Received: by mail-pj1-f51.google.com with SMTP id 98e67ed59e1d1-35fc258aaa4so6937279a91.2 for ; Tue, 28 Apr 2026 01:19:25 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bytedance.com; s=google; t=1777364365; x=1777969165; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=rL183+C/B0Npg+SiHlF1+/ufB8oZmfwNupE6AmX40Ic=; b=Xcv6nuLZbW6bEKophNnpsam4Jk5GgH8DfF2UZvjY1c2UsFrqRHPpsxBRYWSezuy+ME EKAlKINuZu/ABcAk8XuGI90py0qfbpHS+4VVrqOD6AGjKnV3e6UGYklTYsBgN7qCsCKF M3MTDZ1Jj7o34O7BMBeCRJZvGOEhN+ESzRLi8L+coVbUPgtG1BJpmd6y/bNuTVaowKS8 LTOO21n6fmRn3m60ttJX+oIqGTSELvJmcRfRdDhpNdsBo8CBmCQoZ++mgRXMjmqTGSZJ 24pjfGz7nbjWqLccYn0RVUMdW2xssX/FcSeM8jkQ9cxty9g10JjtgqRDeJ2HDWORS0DX lZjA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1777364365; x=1777969165; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to; bh=rL183+C/B0Npg+SiHlF1+/ufB8oZmfwNupE6AmX40Ic=; b=i69MADirZsFo8iYYp/jmhkSFkiL4AW8GMgmFnz4FJupgajpJ6GorMq372S97YL+5t+ AXNDQAnuHhyc5F67iqZlG7la3cO/0V5BMFOGBSuBKLxSBdaKgUiUnGrsTXo31BnUWnco 8nS4nKHQ3zv/RaXgOficHHZv02dP0B55oRDiPnPp+Nt3isI7ricoQ3EtjTmorr1zyqSk EEViutSlVzmzsTDbuBJ3hEUizWGD5dXrQ/xYu/aG27VPcmDwzGvnz8MeZ5JPOHpPZlnD T8EuwgR03FgclY5/YzE7LmJLjxdN9CzUQbknfcmA+5kUIZ/xJt6tSP927r0F38ovizE7 mPLw== X-Forwarded-Encrypted: i=1; AFNElJ8CthsK9qnosG3E2QdFlpUX7V8ZHkSgNhHFJvXuQQ96v5szZATYPUHmD5+SFVwYvigfEgvu5fkZZsYH98g=@vger.kernel.org X-Gm-Message-State: AOJu0YxZLs3TFnPMZFj5JvP+zqs/aACntGaqkqmSYDuadHY/NolhXD73 /c3OxQezdatAuMjn9xbMSvoMsMDaJ9BLMvQIublrGZEr6z/buPbgByOMqXApwQFjiLo= X-Gm-Gg: AeBDieteRL02liaN3xLSMJbOjXUwAY946ryLSHdnP/5Qx9sz0SsaTKtMqKctfMWB+Jr d9HXROuLm5qgMolLyB0O6yXZxZXCSxWiLzpTa79ghwJq4gvkhkU1rQYZqnH2UzmHkn5yyTGFZXI DcSvBboxwZSd6tCTPFUnT3GvUL/anlELCI1+BCHNohqTwTAYzAYG0Yevys2sFghtpFyzTvQ/4ML tFRDHKtRtM69NEGx0UudOHaMK6QPw9+d207APog6WZuLFlmxgIdlOaFIjCfaG+BMR9YcQekyUxe PCA4AB+Lhtz42ZcVkxzHCaod3+bRs8Fxc9wOlN6FyqrRUhKyYCvqn0QOkEOldSlW2xP5qL2FcwM jVhMWa2yt97OGWAPk178aSLEXivgB2ra4DAfTzfUkmdEE/rrvkPHkUVOpcc8c6in0eT20PyxP50 yYY1fttuaYIbjJm8G3Hx7yHDXhKFVgrTWthQ+wxwl+njMono4I7qvZT2TByJLAaZplSg== X-Received: by 2002:a17:90b:56cf:b0:35b:96bb:47ba with SMTP id 98e67ed59e1d1-364921a915dmr2295268a91.26.1777364364837; Tue, 28 Apr 2026 01:19:24 -0700 (PDT) Received: from n232-176-004.byted.org ([36.110.163.101]) by smtp.gmail.com with ESMTPSA id 98e67ed59e1d1-3649003650esm2181356a91.8.2026.04.28.01.19.19 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 28 Apr 2026 01:19:24 -0700 (PDT) From: Muchun Song To: Andrew Morton , David Hildenbrand , Muchun Song , Oscar Salvador , Michael Ellerman , Madhavan Srinivasan Cc: Lorenzo Stoakes , "Liam R . Howlett" , Vlastimil Babka , Mike Rapoport , Suren Baghdasaryan , Michal Hocko , Nicholas Piggin , Christophe Leroy , aneesh.kumar@linux.ibm.com, joao.m.martins@oracle.com, linux-mm@kvack.org, linuxppc-dev@lists.ozlabs.org, linux-kernel@vger.kernel.org, Muchun Song , stable@vger.kernel.org Subject: [PATCH v8 4/6] mm/sparse-vmemmap: Fix DAX vmemmap accounting with optimization Date: Tue, 28 Apr 2026 16:18:53 +0800 Message-Id: <20260428081855.1249045-5-songmuchun@bytedance.com> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20260428081855.1249045-1-songmuchun@bytedance.com> References: <20260428081855.1249045-1-songmuchun@bytedance.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: 8bit When vmemmap optimization is enabled for DAX, the nr_memmap_pages counter in /proc/vmstat is incorrect. The current code always accounts for the full, non-optimized vmemmap size, but vmemmap optimization reduces the actual number of vmemmap pages by reusing tail pages. This causes the system to overcount vmemmap usage, leading to inaccurate page statistics in /proc/vmstat. Fix this by introducing section_nr_vmemmap_pages(), which returns the exact vmemmap page count for a given pfn range based on whether optimization is in effect. Fixes: 15995a352474 ("mm: report per-page metadata information") Cc: stable@vger.kernel.org Signed-off-by: Muchun Song Acked-by: Mike Rapoport (Microsoft) Acked-by: Oscar Salvador Acked-by: David Hildenbrand (Arm) --- v7-v8: - Move VM_WARN_ON_ONCE(nr_pages > PAGES_PER_SECTION); to the top of section_nr_vmemmap_pages(). - Add Acked-by from David. --- mm/sparse-vmemmap.c | 34 ++++++++++++++++++++++++++++++---- 1 file changed, 30 insertions(+), 4 deletions(-) diff --git a/mm/sparse-vmemmap.c b/mm/sparse-vmemmap.c index 3340f6d30b01..932082296e8d 100644 --- a/mm/sparse-vmemmap.c +++ b/mm/sparse-vmemmap.c @@ -652,6 +652,31 @@ void offline_mem_sections(unsigned long start_pfn, unsigned long end_pfn) } } +static int __meminit section_nr_vmemmap_pages(unsigned long pfn, unsigned long nr_pages, + struct vmem_altmap *altmap, struct dev_pagemap *pgmap) +{ + const unsigned int order = pgmap ? pgmap->vmemmap_shift : 0; + const unsigned long pages_per_compound = 1UL << order; + + VM_WARN_ON_ONCE(!IS_ALIGNED(pfn | nr_pages, PAGES_PER_SUBSECTION)); + VM_WARN_ON_ONCE(nr_pages > PAGES_PER_SECTION); + + if (!vmemmap_can_optimize(altmap, pgmap)) + return DIV_ROUND_UP(nr_pages * sizeof(struct page), PAGE_SIZE); + + if (order < PFN_SECTION_SHIFT) { + VM_WARN_ON_ONCE(!IS_ALIGNED(pfn | nr_pages, pages_per_compound)); + return VMEMMAP_RESERVE_NR * nr_pages / pages_per_compound; + } + + VM_WARN_ON_ONCE(!IS_ALIGNED(pfn | nr_pages, PAGES_PER_SECTION)); + + if (IS_ALIGNED(pfn, pages_per_compound)) + return VMEMMAP_RESERVE_NR; + + return 0; +} + static struct page * __meminit populate_section_memmap(unsigned long pfn, unsigned long nr_pages, int nid, struct vmem_altmap *altmap, struct dev_pagemap *pgmap) @@ -659,7 +684,7 @@ static struct page * __meminit populate_section_memmap(unsigned long pfn, struct page *page = __populate_section_memmap(pfn, nr_pages, nid, altmap, pgmap); - memmap_pages_add(DIV_ROUND_UP(nr_pages * sizeof(struct page), PAGE_SIZE)); + memmap_pages_add(section_nr_vmemmap_pages(pfn, nr_pages, altmap, pgmap)); return page; } @@ -670,7 +695,7 @@ static void depopulate_section_memmap(unsigned long pfn, unsigned long nr_pages, unsigned long start = (unsigned long) pfn_to_page(pfn); unsigned long end = start + nr_pages * sizeof(struct page); - memmap_pages_add(-1L * (DIV_ROUND_UP(nr_pages * sizeof(struct page), PAGE_SIZE))); + memmap_pages_add(-section_nr_vmemmap_pages(pfn, nr_pages, altmap, pgmap)); vmemmap_free(start, end, altmap); } @@ -678,9 +703,10 @@ static void free_map_bootmem(struct page *memmap) { unsigned long start = (unsigned long)memmap; unsigned long end = (unsigned long)(memmap + PAGES_PER_SECTION); + unsigned long pfn = page_to_pfn(memmap); - memmap_boot_pages_add(-1L * (DIV_ROUND_UP(PAGES_PER_SECTION * sizeof(struct page), - PAGE_SIZE))); + memmap_boot_pages_add(-section_nr_vmemmap_pages(pfn, PAGES_PER_SECTION, + NULL, NULL)); vmemmap_free(start, end, NULL); } -- 2.20.1