From patchwork Thu Apr 27 00:08:43 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Anthony Yznaga X-Patchwork-Id: 13225031 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 9DA1BC77B60 for ; Thu, 27 Apr 2023 00:09:49 +0000 (UTC) Received: by kanga.kvack.org (Postfix) id 2BD496B0074; Wed, 26 Apr 2023 20:09:47 -0400 (EDT) Received: by kanga.kvack.org (Postfix, from userid 40) id 26C076B0075; Wed, 26 Apr 2023 20:09:47 -0400 (EDT) X-Delivered-To: int-list-linux-mm@kvack.org Received: by kanga.kvack.org (Postfix, from userid 63042) id 0BEEE6B0078; Wed, 26 Apr 2023 20:09:47 -0400 (EDT) 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 ED3516B0074 for ; Wed, 26 Apr 2023 20:09:46 -0400 (EDT) Received: from smtpin02.hostedemail.com (a10.router.float.18 [10.200.18.1]) by unirelay05.hostedemail.com (Postfix) with ESMTP id BF95A40531 for ; Thu, 27 Apr 2023 00:09:46 +0000 (UTC) X-FDA: 80725237572.02.284907F Received: from mx0a-00069f02.pphosted.com (mx0a-00069f02.pphosted.com [205.220.165.32]) by imf17.hostedemail.com (Postfix) with ESMTP id B6CC340009 for ; Thu, 27 Apr 2023 00:09:44 +0000 (UTC) Authentication-Results: imf17.hostedemail.com; dkim=pass header.d=oracle.com header.s=corp-2023-03-30 header.b=vTo9B+vv; spf=pass (imf17.hostedemail.com: domain of anthony.yznaga@oracle.com designates 205.220.165.32 as permitted sender) smtp.mailfrom=anthony.yznaga@oracle.com; dmarc=pass (policy=none) header.from=oracle.com ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=hostedemail.com; s=arc-20220608; t=1682554184; h=from:from:sender:reply-to:subject:subject:date:date: message-id:message-id:to:to:cc:cc:mime-version:content-type: content-transfer-encoding:in-reply-to:in-reply-to: references:references:dkim-signature; bh=kCxexgjquhm43uIqnCzaCKme8/lW/JHqc5BFLC3zBqE=; b=IQs/GDg3UmIuyuPIo80NBmqP4FSRcxl7cwNAEii8KWBxc4oRaWVMXA0Yv3lGFCcKUm8Ip1 flKH3DEdLa+bTt3ny2vJlgO2Ebw2zo0jjUKOIypBdNMnaeE5YGjHHp8arIC1u/zMDhUbFc bpwydAb2odOwfciIF/E256LvVlZFR+U= ARC-Authentication-Results: i=1; imf17.hostedemail.com; dkim=pass header.d=oracle.com header.s=corp-2023-03-30 header.b=vTo9B+vv; spf=pass (imf17.hostedemail.com: domain of anthony.yznaga@oracle.com designates 205.220.165.32 as permitted sender) smtp.mailfrom=anthony.yznaga@oracle.com; dmarc=pass (policy=none) header.from=oracle.com ARC-Seal: i=1; s=arc-20220608; d=hostedemail.com; t=1682554184; a=rsa-sha256; cv=none; b=Y2aTnE3oUvFZphhZ3Gn+G0GYQ6laVAcD3fWT7vsBiXEaWQw0XS38M5npSrgSkDKb/wm450 2cerO6eMvTWwZ+5u9CGUwPjIGIPI1jMLojil9LIHl1gab9T+Oiv8u1rPR0IaomHRkxigSm f9avYKjZFv/nv1z4dxGRS2E0ltkw0UM= Received: from pps.filterd (m0246627.ppops.net [127.0.0.1]) by mx0b-00069f02.pphosted.com (8.17.1.19/8.17.1.19) with ESMTP id 33QGxDTf025309; Thu, 27 Apr 2023 00:09:16 GMT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=oracle.com; h=from : to : cc : subject : date : message-id : in-reply-to : references; s=corp-2023-03-30; bh=kCxexgjquhm43uIqnCzaCKme8/lW/JHqc5BFLC3zBqE=; b=vTo9B+vvAjWpZl5sA4oPL1lKBhlH5A1X8UCeXo14KQCHh4gDG9JGTe8jsA8SvhWEA6lX rCwXFo16cZYMNfr4aZeivRf7u3DFx56P7YgMJx3riVsOHDgVAViRH21ldwmNdxF2DBeb JqNRvOwjMdpuYY+yWWgDEzFFodnBKgAjYlQhjn5Sy84JLsimXJOqFOWvEWcUM7WH2Ae3 yxJTV377SDejfMR/5XEMdNkOD2spr/zEOAXfZVFI3I7cKVkYN4JLeqnXL9DqpOG7fOVy E/grQ+ERNydeVl9TX0aKf+NA2mkgf95PlZu+WMDNVMhFHDqzhiq9/daDDPxs4kFFdds/ 8A== Received: from phxpaimrmta01.imrmtpd1.prodappphxaev1.oraclevcn.com (phxpaimrmta01.appoci.oracle.com [138.1.114.2]) by mx0b-00069f02.pphosted.com (PPS) with ESMTPS id 3q46622ty0-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Thu, 27 Apr 2023 00:09:15 +0000 Received: from pps.filterd (phxpaimrmta01.imrmtpd1.prodappphxaev1.oraclevcn.com [127.0.0.1]) by phxpaimrmta01.imrmtpd1.prodappphxaev1.oraclevcn.com (8.17.1.19/8.17.1.19) with ESMTP id 33QMwjOd007159; Thu, 27 Apr 2023 00:09:15 GMT Received: from pps.reinject (localhost [127.0.0.1]) by phxpaimrmta01.imrmtpd1.prodappphxaev1.oraclevcn.com (PPS) with ESMTPS id 3q4618mpep-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Thu, 27 Apr 2023 00:09:15 +0000 Received: from phxpaimrmta01.imrmtpd1.prodappphxaev1.oraclevcn.com (phxpaimrmta01.imrmtpd1.prodappphxaev1.oraclevcn.com [127.0.0.1]) by pps.reinject (8.17.1.5/8.17.1.5) with ESMTP id 33R0938a013888; Thu, 27 Apr 2023 00:09:14 GMT Received: from ca-qasparc-x86-2.us.oracle.com (ca-qasparc-x86-2.us.oracle.com [10.147.24.103]) by phxpaimrmta01.imrmtpd1.prodappphxaev1.oraclevcn.com (PPS) with ESMTP id 3q4618mp42-8; Thu, 27 Apr 2023 00:09:14 +0000 From: Anthony Yznaga To: linux-mm@kvack.org, linux-kernel@vger.kernel.org Cc: tglx@linutronix.de, mingo@redhat.com, bp@alien8.de, x86@kernel.org, hpa@zytor.com, dave.hansen@linux.intel.com, luto@kernel.org, peterz@infradead.org, rppt@kernel.org, akpm@linux-foundation.org, ebiederm@xmission.com, keescook@chromium.org, graf@amazon.com, jason.zeng@intel.com, lei.l.li@intel.com, steven.sistare@oracle.com, fam.zheng@bytedance.com, mgalaxy@akamai.com, kexec@lists.infradead.org Subject: [RFC v3 07/21] mm: PKRAM: introduce super block Date: Wed, 26 Apr 2023 17:08:43 -0700 Message-Id: <1682554137-13938-8-git-send-email-anthony.yznaga@oracle.com> X-Mailer: git-send-email 1.9.4 In-Reply-To: <1682554137-13938-1-git-send-email-anthony.yznaga@oracle.com> References: <1682554137-13938-1-git-send-email-anthony.yznaga@oracle.com> X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.254,Aquarius:18.0.942,Hydra:6.0.573,FMLib:17.11.170.22 definitions=2023-04-26_10,2023-04-26_03,2023-02-09_01 X-Proofpoint-Spam-Details: rule=notspam policy=default score=0 suspectscore=0 phishscore=0 bulkscore=0 mlxlogscore=999 malwarescore=0 mlxscore=0 spamscore=0 adultscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.12.0-2303200000 definitions=main-2304270000 X-Proofpoint-ORIG-GUID: JPUChGVr1Ox4-7b8jQIrZtvAKfFxOq23 X-Proofpoint-GUID: JPUChGVr1Ox4-7b8jQIrZtvAKfFxOq23 X-Rspam-User: X-Rspamd-Server: rspam04 X-Rspamd-Queue-Id: B6CC340009 X-Stat-Signature: wccu1xiukz8rbx63mkreu4bsoktf4d4y X-HE-Tag: 1682554184-613556 X-HE-Meta: U2FsdGVkX186EEXg7BRoMPGy5HzbnvnTDt+phDvI7KaenZoGmix3eDW03tyKd1O3JQa5ujX5f+xZckXUrKWW3uizHap5Ed7/ciaVspxi5d7+hEWPety+SQJK7bRrdsdVFqOS3vu31cEwvGJ97QskaaUDZMPkIcsBX/xfh6JeB9e/5/sgJiFP1fbEHG9Sl3NJ1xI3VZ9TUtFVpQJBB3iYZd5Oqis6MqN9UdOzxrlViYKMqlmVipIBjAFI3FMJU3PN0V6SDfVAWpx2SyfPfklcESPOTtw+8W/tTcgSGqcvbsWKZ22lcrg2TCcOF7zA/AqWVU25IPF0XefX1RzBOdEBQ8BQ48lx8cFkxO024NOqzkP118xcKnIE8iW1RymFenrZEY/GV2e1e6/ngKomddOdMZ6SZIkXEwNLn82duttsROtOncgpO1Sw2v+j8Zg9HnbP28f9vNVtkrog72hMpUOLiVM7Zv1R35bxP96OTIXdQHBWYs0u6bxNCjyUUmF6Xa67EAWk5gWcNn8YskHyCqqbNbtC6+wP1H0tK4lbI5znL/BO/Um8d/RhGMuR2hOGwxzq7DxifH929pB0dEdfGbnlz2ZhOZt7g3qmkM6uwCi7UADC/YVD72DQ2kv77BfMOszcLlngpRbLf6rvKlJKJOPZb+BJudRzve/MVii+cguSAwEANMrCcFhi4sPKt5c5M/OdPpdCslFo2yKBOmo/bMG4i/rAZRPFRnXLiBunehWl7bxZ4XL6bM+EyNI0cCBi0i/X1Z65np5r6ZchTJDu+H0z7afjFDcM/bWvoQ8kRaP1W/EtY5POywBPA+2hVqLj0v7fo+aDFL+keK2+Pa1+C1DbEGwtZDb9UsSFEJ/S50u9CnziMolh8atOtD/rGy2muPg7tAlBFHG4lS/Rre11oaX84m2HR/A2JgysGJyncgnbNfJqAh2rHeX2FsBERecVxrlODJz6xZZtrgPKS7lh9IO UhHog0fT lsoDfgOt+b9N94wMten6IiqttIwJeohbngygtQvAtIzPQ6ay1RkW8ZXHqsFjq3iJTdiCAazZgZfeJG+RFutOtFzoCVOTDnG/khDGjBkmMUvQHorFxZasjtZ2I0BZdiwKvZF2c9NFsXyMOFz+B83WNgCLSZfrS0xaAJ4pe X-Bogosity: Ham, tests=bogofilter, spamicity=0.000000, version=1.2.4 Sender: owner-linux-mm@kvack.org Precedence: bulk X-Loop: owner-majordomo@kvack.org List-ID: The PKRAM super block is the starting point for restoring preserved memory. By providing the super block to the new kernel at boot time, preserved memory can be reserved and made available to be restored. To point the kernel to the location of the super block, one passes its pfn via the 'pkram' boot param. For that purpose, the pkram super block pfn is exported via /sys/kernel/pkram. If none is passed, any preserved memory will not be kept, and a new super block will be allocated. Originally-by: Vladimir Davydov Signed-off-by: Anthony Yznaga --- mm/pkram.c | 102 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 100 insertions(+), 2 deletions(-) diff --git a/mm/pkram.c b/mm/pkram.c index da166cb6afb7..c66b2ae4d520 100644 --- a/mm/pkram.c +++ b/mm/pkram.c @@ -5,15 +5,18 @@ #include #include #include +#include #include #include #include #include #include +#include #include #include #include #include +#include #include #include "internal.h" @@ -82,12 +85,38 @@ struct pkram_node { #define PKRAM_ACCMODE_MASK 3 /* + * The PKRAM super block contains data needed to restore the preserved memory + * structure on boot. The pointer to it (pfn) should be passed via the 'pkram' + * boot param if one wants to restore preserved data saved by the previously + * executing kernel. For that purpose the kernel exports the pfn via + * /sys/kernel/pkram. If none is passed, preserved memory if any will not be + * preserved and a new clean page will be allocated for the super block. + * + * The structure occupies a memory page. + */ +struct pkram_super_block { + __u64 node_pfn; /* first element of the node list */ +}; + +static unsigned long pkram_sb_pfn __initdata; +static struct pkram_super_block *pkram_sb; + +/* * For convenience sake PKRAM nodes are kept in an auxiliary doubly-linked list * connected through the lru field of the page struct. */ static LIST_HEAD(pkram_nodes); /* linked through page::lru */ static DEFINE_MUTEX(pkram_mutex); /* serializes open/close */ +/* + * The PKRAM super block pfn, see above. + */ +static int __init parse_pkram_sb_pfn(char *arg) +{ + return kstrtoul(arg, 16, &pkram_sb_pfn); +} +early_param("pkram", parse_pkram_sb_pfn); + static inline struct page *pkram_alloc_page(gfp_t gfp_mask) { return alloc_page(gfp_mask); @@ -270,6 +299,7 @@ static void pkram_stream_init(struct pkram_stream *ps, * @gfp_mask specifies the memory allocation mask to be used when saving data. * * Error values: + * %ENODEV: PKRAM not available * %ENAMETOOLONG: name len >= PKRAM_NAME_MAX * %ENOMEM: insufficient memory available * %EEXIST: node with specified name already exists @@ -285,6 +315,9 @@ int pkram_prepare_save(struct pkram_stream *ps, const char *name, gfp_t gfp_mask struct pkram_node *node; int err = 0; + if (!pkram_sb) + return -ENODEV; + if (strlen(name) >= PKRAM_NAME_MAX) return -ENAMETOOLONG; @@ -404,6 +437,7 @@ void pkram_discard_save(struct pkram_stream *ps) * Returns 0 on success, -errno on failure. * * Error values: + * %ENODEV: PKRAM not available * %ENOENT: node with specified name does not exist * %EBUSY: save to required node has not finished yet * @@ -414,6 +448,9 @@ int pkram_prepare_load(struct pkram_stream *ps, const char *name) struct pkram_node *node; int err = 0; + if (!pkram_sb) + return -ENODEV; + mutex_lock(&pkram_mutex); node = pkram_find_node(name); if (!node) { @@ -825,6 +862,13 @@ static void __pkram_reboot(void) node->node_pfn = node_pfn; node_pfn = page_to_pfn(page); } + + /* + * Zero out pkram_sb completely since it may have been passed from + * the previous boot. + */ + memset(pkram_sb, 0, PAGE_SIZE); + pkram_sb->node_pfn = node_pfn; } static int pkram_reboot(struct notifier_block *notifier, @@ -832,7 +876,8 @@ static int pkram_reboot(struct notifier_block *notifier, { if (val != SYS_RESTART) return NOTIFY_DONE; - __pkram_reboot(); + if (pkram_sb) + __pkram_reboot(); return NOTIFY_OK; } @@ -840,9 +885,62 @@ static int pkram_reboot(struct notifier_block *notifier, .notifier_call = pkram_reboot, }; +static ssize_t show_pkram_sb_pfn(struct kobject *kobj, + struct kobj_attribute *attr, char *buf) +{ + unsigned long pfn = pkram_sb ? PFN_DOWN(__pa(pkram_sb)) : 0; + + return sprintf(buf, "%lx\n", pfn); +} + +static struct kobj_attribute pkram_sb_pfn_attr = + __ATTR(pkram, 0444, show_pkram_sb_pfn, NULL); + +static struct attribute *pkram_attrs[] = { + &pkram_sb_pfn_attr.attr, + NULL, +}; + +static struct attribute_group pkram_attr_group = { + .attrs = pkram_attrs, +}; + +/* returns non-zero on success */ +static int __init pkram_init_sb(void) +{ + unsigned long pfn; + struct pkram_node *node; + + if (!pkram_sb) { + struct page *page; + + page = pkram_alloc_page(GFP_KERNEL | __GFP_ZERO); + if (!page) { + pr_err("PKRAM: Failed to allocate super block\n"); + return 0; + } + pkram_sb = page_address(page); + } + + /* + * Build auxiliary doubly-linked list of nodes connected through + * page::lru for convenience sake. + */ + pfn = pkram_sb->node_pfn; + while (pfn) { + node = pfn_to_kaddr(pfn); + pkram_insert_node(node); + pfn = node->node_pfn; + } + return 1; +} + static int __init pkram_init(void) { - register_reboot_notifier(&pkram_reboot_notifier); + if (pkram_init_sb()) { + register_reboot_notifier(&pkram_reboot_notifier); + sysfs_update_group(kernel_kobj, &pkram_attr_group); + } return 0; } module_init(pkram_init);