Received: by 2002:a05:7412:d8a:b0:e2:908c:2ebd with SMTP id b10csp2819711rdg; Mon, 16 Oct 2023 16:32:57 -0700 (PDT) X-Google-Smtp-Source: AGHT+IHuzydEMkaDS76kW1HXhHi/K2dBLHZFtFq2OljheAAnyQtFf4tcklv3Hdiiif1SbRc2CjMX X-Received: by 2002:a05:6a00:248f:b0:6bc:f819:fcf0 with SMTP id c15-20020a056a00248f00b006bcf819fcf0mr742414pfv.1.1697499177559; Mon, 16 Oct 2023 16:32:57 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1697499177; cv=none; d=google.com; s=arc-20160816; b=YQH05t1504+3DTgybuIWUpQ5dzsbxVcPVLqBo9RrTUPliBRBQpEszhv59uI5V0BEUO Gwwm0AvFHJxYU3GcUqOwySn1zwP3QmrgKBOtzZaNF9ovZDMKGe/MlIparFRk1y5jKxJ7 XmSKuvT1Gh/wmOm6v4NId8ddtx5SxMqX2Tpm+dVru5ZEh90rFLjztFZgiwo839wKcY/X 0pilmAGZeB4gFxBkm/j3qHwVQ+EhOyENMibesnE9hQSaywCE5iIHEyYVnRpXkWSn1Cur a2NNT7kOQ45MWsqI+Zh440ti2hVtx5mvriH3WOsNqWrm9TPraQSsIBXCoTN/nXqOQvbL ikGg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :references:in-reply-to:message-id:date:subject:to:from :dkim-signature:dkim-filter; bh=7Kg0kDVRT4XUsyYitTfP8a+YwKQXAgc1KQikAOX3WAY=; fh=QvBREeObeZx1N+80DqwmVjqUC+p/g9/4gdsZ6e4dydM=; b=gGJiy+Od+AItOuFAvLntFgJaddmWDg0jz0gTN6KYpcWv0j/d8yvMZq4zAN8rGxXi4P GOATH8FfwTlzJ+l1bN2wTiUSeQ+QBnc9xygweFrXyqzGFVJ5mMdKRHJCvCW8ggW8bM2f 4Bjyu4Fr3hPIFOuKaX2SCHgLH8ooePEHcWYWO7Rxgjnpjf/2GW/6BcqJV1mZiPaDX6dH jZk+QfXMt0xtKUJ2fV1mRv+0mVYj6KZf2X5GcPj6LGOhIJzaq8OeUVXuwYvyanJuXOh+ 7QZO3baHT9ChbKN0MBupEzCMVbedlQhcxe4K8o3ItYX8+Qq/3y0dosIh5PLXpVwD2Tq0 o1gQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linux.microsoft.com header.s=default header.b=Yt8+5vTS; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::3:7 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linux.microsoft.com Return-Path: Received: from snail.vger.email (snail.vger.email. [2620:137:e000::3:7]) by mx.google.com with ESMTPS id f21-20020a056a00239500b006b8e367ed42si315139pfc.54.2023.10.16.16.32.57 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 16 Oct 2023 16:32:57 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::3:7 as permitted sender) client-ip=2620:137:e000::3:7; Authentication-Results: mx.google.com; dkim=pass header.i=@linux.microsoft.com header.s=default header.b=Yt8+5vTS; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::3:7 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linux.microsoft.com Received: from out1.vger.email (depot.vger.email [IPv6:2620:137:e000::3:0]) by snail.vger.email (Postfix) with ESMTP id 945E58025B68; Mon, 16 Oct 2023 16:32:56 -0700 (PDT) X-Virus-Status: Clean X-Virus-Scanned: clamav-milter 0.103.10 at snail.vger.email Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S233949AbjJPXcr (ORCPT + 99 others); Mon, 16 Oct 2023 19:32:47 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:53166 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S233854AbjJPXci (ORCPT ); Mon, 16 Oct 2023 19:32:38 -0400 Received: from linux.microsoft.com (linux.microsoft.com [13.77.154.182]) by lindbergh.monkeyblade.net (Postfix) with ESMTP id 8AA3692 for ; Mon, 16 Oct 2023 16:32:36 -0700 (PDT) Received: from localhost.localdomain (unknown [47.186.13.91]) by linux.microsoft.com (Postfix) with ESMTPSA id 628DF20B74C4; Mon, 16 Oct 2023 16:32:35 -0700 (PDT) DKIM-Filter: OpenDKIM Filter v2.11.0 linux.microsoft.com 628DF20B74C4 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linux.microsoft.com; s=default; t=1697499156; bh=7Kg0kDVRT4XUsyYitTfP8a+YwKQXAgc1KQikAOX3WAY=; h=From:To:Subject:Date:In-Reply-To:References:From; b=Yt8+5vTSKf0oAErSwOtHn6FQjCOGeLisGeuub6q/djLn2p+T5pP7eOxRYSGmL6t3n rmGVIM80mpjIhbpqL9f/XXorAr0bZQkq3mlx1BLzOZNid96fWsO7hN5QGHtO+eT2SX zBHgeRKFsB0wU1vyi0WE4hJoh3zRyfs5hhdvcEsQ= From: madvenka@linux.microsoft.com To: gregkh@linuxfoundation.org, pbonzini@redhat.com, rppt@kernel.org, jgowans@amazon.com, graf@amazon.de, arnd@arndb.de, keescook@chromium.org, stanislav.kinsburskii@gmail.com, anthony.yznaga@oracle.com, linux-mm@kvack.org, linux-kernel@vger.kernel.org, madvenka@linux.microsoft.com, jamorris@linux.microsoft.com Subject: [RFC PATCH v1 04/10] mm/prmem: Implement a page allocator for persistent memory Date: Mon, 16 Oct 2023 18:32:09 -0500 Message-Id: <20231016233215.13090-5-madvenka@linux.microsoft.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20231016233215.13090-1-madvenka@linux.microsoft.com> References: <1b1bc25eb87355b91fcde1de7c2f93f38abb2bf9> <20231016233215.13090-1-madvenka@linux.microsoft.com> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Spam-Status: No, score=-17.5 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,ENV_AND_HDR_SPF_MATCH,RCVD_IN_DNSWL_BLOCKED, SPF_HELO_PASS,SPF_PASS,USER_IN_DEF_DKIM_WL,USER_IN_DEF_SPF_WL autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org X-Greylist: Sender passed SPF test, not delayed by milter-greylist-4.6.4 (snail.vger.email [0.0.0.0]); Mon, 16 Oct 2023 16:32:56 -0700 (PDT) From: "Madhavan T. Venkataraman" Define the following convenience wrapper functions for allocating and freeing pages: - prmem_alloc_pages() - prmem_free_pages() The functions look similar to alloc_pages() and __free_pages(). However, the only GFP flag that is processed is __GFP_ZERO to zero out the allocated memory. Signed-off-by: Madhavan T. Venkataraman --- include/linux/prmem.h | 7 ++++ kernel/prmem/Makefile | 1 + kernel/prmem/prmem_allocator.c | 74 ++++++++++++++++++++++++++++++++++ kernel/prmem/prmem_init.c | 2 + 4 files changed, 84 insertions(+) create mode 100644 kernel/prmem/prmem_allocator.c diff --git a/include/linux/prmem.h b/include/linux/prmem.h index f43f5b0d2b9c..108683933c82 100644 --- a/include/linux/prmem.h +++ b/include/linux/prmem.h @@ -75,6 +75,7 @@ extern unsigned long prmem_metadata; extern unsigned long prmem_pa; extern size_t prmem_size; extern bool prmem_inited; +extern spinlock_t prmem_lock; /* Kernel API. */ void prmem_reserve_early(void); @@ -83,11 +84,17 @@ void prmem_init(void); void prmem_fini(void); int prmem_cmdline_size(void); +/* Allocator API. */ +struct page *prmem_alloc_pages(unsigned int order, gfp_t gfp); +void prmem_free_pages(struct page *pages, unsigned int order); + /* Internal functions. */ struct prmem_region *prmem_add_region(unsigned long pa, size_t size); bool prmem_create_pool(struct prmem_region *region, bool new_region); void *prmem_alloc_pool(struct prmem_region *region, size_t size, int align); void prmem_free_pool(struct prmem_region *region, void *va, size_t size); +void *prmem_alloc_pages_locked(unsigned int order); +void prmem_free_pages_locked(void *va, unsigned int order); unsigned long prmem_checksum(void *start, size_t size); bool __init prmem_validate(void); void prmem_cmdline(char *cmdline); diff --git a/kernel/prmem/Makefile b/kernel/prmem/Makefile index 9b0a693bfee1..99bb19f0afd3 100644 --- a/kernel/prmem/Makefile +++ b/kernel/prmem/Makefile @@ -1,3 +1,4 @@ # SPDX-License-Identifier: GPL-2.0 obj-y += prmem_parse.o prmem_reserve.o prmem_init.o prmem_region.o prmem_misc.o +obj-y += prmem_allocator.o diff --git a/kernel/prmem/prmem_allocator.c b/kernel/prmem/prmem_allocator.c new file mode 100644 index 000000000000..07a5a430630c --- /dev/null +++ b/kernel/prmem/prmem_allocator.c @@ -0,0 +1,74 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Persistent-Across-Kexec memory feature (prmem) - Allocator. + * + * Copyright (C) 2023 Microsoft Corporation + * Author: Madhavan T. Venkataraman (madvenka@linux.microsoft.com) + */ +#include + +/* Page Allocation functions. */ + +void *prmem_alloc_pages_locked(unsigned int order) +{ + struct prmem_region *region; + void *va; + size_t size = (1UL << order) << PAGE_SHIFT; + + list_for_each_entry(region, &prmem->regions, node) { + va = prmem_alloc_pool(region, size, size); + if (va) + return va; + } + return NULL; +} + +struct page *prmem_alloc_pages(unsigned int order, gfp_t gfp) +{ + void *va; + size_t size = (1UL << order) << PAGE_SHIFT; + bool zero = !!(gfp & __GFP_ZERO); + + if (!prmem_inited || order > MAX_ORDER) + return NULL; + + spin_lock(&prmem_lock); + va = prmem_alloc_pages_locked(order); + spin_unlock(&prmem_lock); + + if (va) { + if (zero) + memset(va, 0, size); + return virt_to_page(va); + } + return NULL; +} +EXPORT_SYMBOL_GPL(prmem_alloc_pages); + +void prmem_free_pages_locked(void *va, unsigned int order) +{ + struct prmem_region *region; + size_t size = (1UL << order) << PAGE_SHIFT; + void *eva = va + size; + void *region_va; + + list_for_each_entry(region, &prmem->regions, node) { + /* The region structure is at the base of the region memory. */ + region_va = region; + if (va >= region_va && eva <= (region_va + region->size)) { + prmem_free_pool(region, va, size); + return; + } + } +} + +void prmem_free_pages(struct page *pages, unsigned int order) +{ + if (!prmem_inited || order > MAX_ORDER) + return; + + spin_lock(&prmem_lock); + prmem_free_pages_locked(page_to_virt(pages), order); + spin_unlock(&prmem_lock); +} +EXPORT_SYMBOL_GPL(prmem_free_pages); diff --git a/kernel/prmem/prmem_init.c b/kernel/prmem/prmem_init.c index 56df1e6d3ebc..d23833d296fe 100644 --- a/kernel/prmem/prmem_init.c +++ b/kernel/prmem/prmem_init.c @@ -9,6 +9,8 @@ bool prmem_inited; +DEFINE_SPINLOCK(prmem_lock); + void __init prmem_init(void) { if (!prmem) -- 2.25.1