From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mail-pg1-f172.google.com (mail-pg1-f172.google.com [209.85.215.172]) (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 AA132372ECD for ; Thu, 9 Jul 2026 07:39:04 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.215.172 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1783582748; cv=none; b=RZ1gjc/V8knrVcpKoyT+qFTP0RUOx+j6A9mZBsoJCj5zs7f4DXaTVBmf+qdSvgOiLsWhJduuuH85/t0WxF33z+1EWyqSkrqTrFJZgDqjOpoiDhjP2sEBoikCRI9WJI8MJiY66NbnaNdMhsLa2BBR0E3UTPCWZSphweqVEOr99s4= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1783582748; c=relaxed/simple; bh=F1OtV9JFfnoNhVqtdZttMg6Y3AdPAoOBuCipdhhLJWE=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version:Content-Type; b=gcdqDCGWe8JQTofjMjWMKy/d8mvctGJToXMmLz9lia/YxQdjLu/2z6miTW1F/aoJ052C3kQQkpWi0ENF4if2TQ6SMneDKtVN85ZKsewq/TMUz82OySNLuiKD9gYG6iMgLyXhYLFxD7mumdORTBMUEGkq9nNmxLl8SItbxLFfdrg= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=OPvbe/d7; arc=none smtp.client-ip=209.85.215.172 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="OPvbe/d7" Received: by mail-pg1-f172.google.com with SMTP id 41be03b00d2f7-c9c26a5fb98so408718a12.0 for ; Thu, 09 Jul 2026 00:39:04 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1783582743; x=1784187543; darn=vger.kernel.org; h=content-transfer-encoding:content-type:mime-version:references :in-reply-to:message-id:date:subject:cc:to:from:from:to:cc:subject :date:message-id:reply-to:content-type; bh=X8Oygze3XzRb05aYksCWsf/9oFhF4JAfcwkhh/Ls9Y4=; b=OPvbe/d73siDOU7F8hi+9igZV0EhR5zmI/a04wCNRzPtwnQ6Mr/UCuAcCDFt1JQwyV aaxg019nW5sV3TXRsWs0f0mZEj5ChaaCufKMqGwGZeE7ZTSfjw8HqIi2lPiGpol2rrjg pm5AxjVrnhPwsEhvOJ6cg70ZML9o9/hLoThYTYECqI7kBJLE4nsek9ezcfAzrveYFoX0 AySMt6vQMvGoz9+e0NhjhJ3npx6NF9IRj4ErKLnwa61XdtY6OakTLQNvzI4OuQOOZugI ZNDqI+eam+YDbJNC7D2zogn6YJhRcnyFFZk5QHu84Mevu/vAzdQc6ckseCELrwCdpvQf jIHA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1783582743; x=1784187543; h=content-transfer-encoding:content-type: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 :content-type; bh=X8Oygze3XzRb05aYksCWsf/9oFhF4JAfcwkhh/Ls9Y4=; b=LOmjojFHByDrWdss2XN6kiBJhy2WprQowu88C/8kt1brGVxZtf5UPunmBtmlYq2dgr hma5VN1dLPCNM+pMyJC7mtxee+lhmrduuiaO31H+PDiAqurCvsywTPEleKqifPwLgcHr aK4fcImIs3zVqtAYtAtFl7cVTCke6VpDJmLV/WExqP/vCaNps71unshBk80nBmKBq2Pg 8OalPaZNcqiQFI5lYjQD0+nlrrF1Lg6/KPfrJHzqYOlWWwjrcJlIVdj/ozN0WYqsqtth CWBvUVCJhttSKKXEddRN+GpmnVDd1+IDK9SX4bqfHHG1G0K+d4/C0lGU3OGu8SqnfSxO 9nQw== X-Forwarded-Encrypted: i=1; AHgh+RoMr4ckBWcX1+/3YOYgulhFlXfXhgYsLm4xgazmqJ73r7vQClcpi6Tonc4l1qqSU1vnhIHtNn79HYuJT9k=@vger.kernel.org X-Gm-Message-State: AOJu0Ywp4ffL2ey4w8gPaN5K6aEQLkBKAAN1/IMusNmfEw4QZMCGLekx Z+Lktb70Cduza5fBr/NAo1xZbveRiQtH1u76x7zwcGYu0NzNgxR3EEif X-Gm-Gg: AfdE7ckOKm5QfADSnNfuExZ/AWpv1OAF2h2T5lnXPmM8QKUfx8w/XPosMayU0qJFBVF OtUgLpGW842fIP/m/CoHc96zKvfyS7NlTqPa8kSA0etH3oU+lB0aD/JgGLlamGD1tJ6TtWBk3ic E1jFRWwR+oanv7pkMyipdIWD537CMNtINc4OH+Zx3mIJ+dIcKJEoa2aoM4o7ZwOZiNm3MfpkoBu e6TT3UNnXjE+kL8lcSg8YP/MQqCvUlRAJVbyZTmWbPVw2u1a00+gAgkI0kBVIX+wYl2R1wme7N9 8iZivq4KQceP2WDZhnCGaF6lZON63cnW3B2wDgI5EHkNJ4g/RnN4/dBXZJshCgHQK8VywoXne2m KJ7HmqO/J+aYe/BR3u7NZo+bocXrQ+GzIgYViF3cC9wMI/+Tgz57dZffbN0xYQGTTLzjdvJfw47 0mrvOHMI+9djgwGd9GwkDUqc5vTNf8IAN2RIAR0xaYHg1GDQ== X-Received: by 2002:a05:6300:2189:b0:3bf:98d3:f185 with SMTP id adf61e73a8af0-3c0d67a2905mr1940598637.14.1783582742678; Thu, 09 Jul 2026 00:39:02 -0700 (PDT) Received: from mi-OptiPlex-7060.mioffice.cn ([43.224.245.234]) by smtp.gmail.com with ESMTPSA id 41be03b00d2f7-ca5b3162a49sm3334902a12.15.2026.07.09.00.38.57 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 09 Jul 2026 00:39:02 -0700 (PDT) From: Wen Jiang X-Google-Original-From: Wen Jiang To: akpm@linux-foundation.org, catalin.marinas@arm.com, linux-mm@kvack.org, urezki@gmail.com, will@kernel.org Cc: Xueyuan.chen21@gmail.com, ajd@linux.ibm.com, anshuman.khandual@arm.com, david@kernel.org, linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org, rppt@kernel.org, ryan.roberts@arm.com, dev.jain@arm.com, "Barry Song (Xiaomi)" , Wen Jiang , Xueyuan Chen , Leo Yan Subject: [PATCH v6 5/6] mm/vmalloc: map contiguous pages in batches for vmap() if possible Date: Thu, 9 Jul 2026 15:38:22 +0800 Message-Id: <20260709073823.6643-6-jiangwen6@xiaomi.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20260709073823.6643-1-jiangwen6@xiaomi.com> References: <20260709073823.6643-1-jiangwen6@xiaomi.com> 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=UTF-8 Content-Transfer-Encoding: 8bit From: "Barry Song (Xiaomi)" In many cases, the pages passed to vmap() may include high-order pages. For example, the systemheap often allocates pages in descending order: order 8, then 4, then 0. Currently, vmap() iterates over every page individually—even pages inside a high-order block are handled one by one. This patch detects physically contiguous pages (regardless of whether they are compound or non-compound) by scanning with num_pages_contiguous(), and maps them as a single contiguous block whenever possible. The mapping order is determined by taking the minimum of the contiguous page count and the pfn alignment, allowing graceful degradation when pfn alignment is less than the contiguous range. Pages with the same page_shift are coalesced and mapped via vmap_pages_range_noflush_walk() to avoid page table rewalk. As users typically allocate memory in descending orders (e.g. 8 → 4 → 0), once an order-0 page is encountered, we stop scanning for contiguous pages since subsequent pages are likely order-0 as well. Signed-off-by: Barry Song (Xiaomi) Co-developed-by: Dev Jain Signed-off-by: Dev Jain Signed-off-by: Wen Jiang Tested-by: Xueyuan Chen Tested-by: Leo Yan --- mm/vmalloc.c | 87 ++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 85 insertions(+), 2 deletions(-) diff --git a/mm/vmalloc.c b/mm/vmalloc.c index d2a4d649af549..db0492151ad08 100644 --- a/mm/vmalloc.c +++ b/mm/vmalloc.c @@ -3543,6 +3543,89 @@ void vunmap(const void *addr) } EXPORT_SYMBOL(vunmap); +static inline unsigned int vm_shift(pgprot_t prot, unsigned long size) +{ + if (arch_vmap_pmd_supported(prot) && size >= PMD_SIZE) + return PMD_SHIFT; + + return arch_vmap_pte_supported_shift(size); +} + +static inline int get_vmap_batch_order(struct page **pages, + pgprot_t prot, unsigned int max_steps, unsigned int idx) +{ + unsigned int nr_contig; + int order; + + if (!IS_ENABLED(CONFIG_HAVE_ARCH_HUGE_VMAP)) + return 0; + + nr_contig = num_pages_contiguous(&pages[idx], max_steps); + if (nr_contig < 2) + return 0; + + order = ilog2(nr_contig); + + /* Limit order by pfn alignment */ + order = min_t(int, order, __ffs(page_to_pfn(pages[idx]))); + + if (vm_shift(prot, PAGE_SIZE << order) == PAGE_SHIFT) + return 0; + + return order; +} + +static int vmap_pages_range_batched(unsigned long addr, unsigned long end, + pgprot_t prot, struct page **pages) +{ + unsigned int count = (end - addr) >> PAGE_SHIFT; + unsigned int prev_shift = 0, idx = 0; + unsigned long map_addr = addr, batch_end = addr; + int err; + + err = kmsan_vmap_pages_range_noflush(addr, end, prot, pages, + PAGE_SHIFT, GFP_KERNEL); + if (err) + goto out; + + for (unsigned int i = 0; i < count; ) { + unsigned int shift = PAGE_SHIFT + + get_vmap_batch_order(pages, prot, count - i, i); + + if (!i) + prev_shift = shift; + + if (shift != prev_shift) { + err = vmap_pages_range_noflush_walk(map_addr, batch_end, + prot, pages + idx, prev_shift); + if (err) + goto out; + prev_shift = shift; + map_addr = batch_end; + idx = i; + } + + /* + * Once small pages are encountered, the remaining pages + * are likely small as well. + */ + if (shift == PAGE_SHIFT) + break; + + batch_end += 1UL << shift; + i += 1U << (shift - PAGE_SHIFT); + } + + /* Remaining */ + if (map_addr < end) + err = vmap_pages_range_noflush_walk(map_addr, end, + prot, pages + idx, prev_shift); + +out: + flush_cache_vmap(addr, end); + return err; +} + /** * vmap - map an array of pages into virtually contiguous space * @pages: array of page pointers @@ -3586,8 +3669,8 @@ void *vmap(struct page **pages, unsigned int count, return NULL; addr = (unsigned long)area->addr; - if (vmap_pages_range(addr, addr + size, pgprot_nx(prot), - pages, PAGE_SHIFT) < 0) { + if (vmap_pages_range_batched(addr, addr + size, pgprot_nx(prot), + pages) < 0) { vunmap(area->addr); return NULL; } -- 2.34.1