From mboxrd@z Thu Jan 1 00:00:00 1970 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 A9101D2A523 for ; Wed, 16 Oct 2024 14:39:54 +0000 (UTC) Received: by kanga.kvack.org (Postfix) id 2FF976B008A; Wed, 16 Oct 2024 10:39:54 -0400 (EDT) Received: by kanga.kvack.org (Postfix, from userid 40) id 2AFA06B008C; Wed, 16 Oct 2024 10:39:54 -0400 (EDT) X-Delivered-To: int-list-linux-mm@kvack.org Received: by kanga.kvack.org (Postfix, from userid 63042) id 19EE16B0093; Wed, 16 Oct 2024 10:39:54 -0400 (EDT) X-Delivered-To: linux-mm@kvack.org Received: from relay.hostedemail.com (smtprelay0014.hostedemail.com [216.40.44.14]) by kanga.kvack.org (Postfix) with ESMTP id EF4C86B008A for ; Wed, 16 Oct 2024 10:39:53 -0400 (EDT) Received: from smtpin17.hostedemail.com (a10.router.float.18 [10.200.18.1]) by unirelay09.hostedemail.com (Postfix) with ESMTP id E7344804D2 for ; Wed, 16 Oct 2024 14:39:44 +0000 (UTC) X-FDA: 82679724120.17.35E8818 Received: from foss.arm.com (foss.arm.com [217.140.110.172]) by imf08.hostedemail.com (Postfix) with ESMTP id C8AB8160014 for ; Wed, 16 Oct 2024 14:39:45 +0000 (UTC) Authentication-Results: imf08.hostedemail.com; dkim=none; dmarc=pass (policy=none) header.from=arm.com; spf=pass (imf08.hostedemail.com: domain of ryan.roberts@arm.com designates 217.140.110.172 as permitted sender) smtp.mailfrom=ryan.roberts@arm.com ARC-Seal: i=1; s=arc-20220608; d=hostedemail.com; t=1729089485; a=rsa-sha256; cv=none; b=VE/qzGYFYounpUky6BL2oklmdeUwBkbbg9zfvp4gDMRHXWCiHtkxv7BWVYqxofBD18cJkg dSUwmczP5nR8FRgO+4RVRPqYgW3NJdIsJ0Vjp0tzbt/Qz68grznW+dANRjDfABo+Yk1X69 O+s7Izw7JFFdQUiFtv4VHD9aPkOf9Fk= ARC-Authentication-Results: i=1; imf08.hostedemail.com; dkim=none; dmarc=pass (policy=none) header.from=arm.com; spf=pass (imf08.hostedemail.com: domain of ryan.roberts@arm.com designates 217.140.110.172 as permitted sender) smtp.mailfrom=ryan.roberts@arm.com ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=hostedemail.com; s=arc-20220608; t=1729089485; 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:in-reply-to:references:references; bh=QFUFnoeaHaFecEM0+VPeLUc7kwWTEec7IG3DP/eeVzs=; b=eKZMum8xx3ClTuugL4fBEsZlqvkLfdk7H4sO0pY2AUemE9BntmYFNhUj1ZgGkV+7MRuhhO TcDmAKltbKtv5znpBITanDw7DRKKDHwKybB4IgO/3EbJMVziZ1yelYuUcbsDfPRHbbY28D aTEGUESgcbmO+QTGvx8tfdVJpwG4ms8= Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.121.207.14]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id B9F6AFEC; Wed, 16 Oct 2024 07:40:20 -0700 (PDT) Received: from [10.1.28.177] (XHFQ2J9959.cambridge.arm.com [10.1.28.177]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPSA id EFFEE3F71E; Wed, 16 Oct 2024 07:39:47 -0700 (PDT) Message-ID: Date: Wed, 16 Oct 2024 15:39:46 +0100 MIME-Version: 1.0 User-Agent: Mozilla Thunderbird Subject: Re: [RFC PATCH v1 14/57] pm/hibernate: Remove PAGE_SIZE compile-time constant assumption Content-Language: en-GB To: Andrew Morton , Anshuman Khandual , Ard Biesheuvel , Catalin Marinas , David Hildenbrand , Greg Marsden , Ivan Ivanov , Kalesh Singh , Marc Zyngier , Mark Rutland , Matthias Brugger , Miroslav Benes , Will Deacon , "Rafael J. Wysocki" , Len Brown , Pavel Machek Cc: linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org, linux-mm@kvack.org, linux-pm@vger.kernel.org References: <20241014105514.3206191-1-ryan.roberts@arm.com> <20241014105912.3207374-1-ryan.roberts@arm.com> <20241014105912.3207374-14-ryan.roberts@arm.com> From: Ryan Roberts In-Reply-To: <20241014105912.3207374-14-ryan.roberts@arm.com> Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 7bit X-Rspamd-Queue-Id: C8AB8160014 X-Rspam-User: X-Rspamd-Server: rspam05 X-Stat-Signature: 7hxm549posbuorxzezx9q3aq6ozmzg9p X-HE-Tag: 1729089585-481222 X-HE-Meta: U2FsdGVkX1+8z1xp+4f5r7qnZu2jkQWHyWDTe5zEypjKXLOTosp0Mmtj8nGlc9cmZKFBiNz96YCrDLGq1a9GdIflQahVxaVNPFppsRSNVcFGs4q7RIqUjsFPgsnVBgVC6c7dEubmR2JUbO8NZ7A/VIv0dq5boP4jwtFBcwxvl98koLVThcew62bX8Pc+opkVUXd1xVrQ7DeUmUORIp4f++J1R64NNXStlPU0UlHY4ozTE7FQ0EnFoZVxUgmqzs1dELPGYMlYLGj8h48RbluUbxg9i8yp+dkBbp5Zi+t5TqF3wjxa3CrD73a9bQaEq4QrrOvKavs4fGORsS3TKDNrHN7KYwhwkrgadGtR2EV6ojSN0MKA4cVX/H8dWkwO3bdRyz2jLsNvgRBaw3z8zLqYtUCeL75dD0uOfmxjJZ3HUzqYKEchxeefKdIj1KiEKWsC7qPBO87lCJoCd/2aXUT9wfENXr2X1q0DphWwMs3550dYgWzCxPjYYTQ7NR4R5sS54Rx/861Qfq1Aqof2bkAC9WgUHjRWyVWwlJokIrDmuruPAKR/rTVlg+f7u5nDcyCaig0/aDrPpG2FN3P6WaOj6QhO2FzXOGreBYL2ADtQ2HeePg18K2cs06cICyePOkiVLi+HWtZYZimYaBzsQwbgk5i+rzlk+FRA778Qj+Axea0yJLhbr/tm2Zmfy++ElxZsbLl8PiAMkPN+timpvRfhkWOuEqZpQdXflpR13uhpythQSTmHTDTpdHFGPUv18CGy2nEPUqGHZs5z1yFXwvJ/aVUA5kMOpKpaxbqi9qILc1gvLHdXtm+kHm6XDlUUtMwgkpHWzSmNHgCdXMnkesiIh2o2Bs57CDKR54AGVqOjKtbZw+DaFJnZEhBvb4j2vufWeIqFDIQ0bqcXxVfOECj1k3GjXHg2E0QtBv6IHkstl0o3D5oK+qjQAQn0nhIQtHBjbFgqUZ1c02MObdrKXFS DApH13x5 3kul5L/iT7S+h8gRRn0XGcqEClyWuUcETI35bdyPAphYZ3OYV3zm5StiHNvS9gsMrDtuTIiqmUQDwjy6r7IvBDBCiXQ/YRkk/INppt2OMXjMg9itcPtvCX5zEDp3y1N+/dLUsVXOkL0mOpBSxAKb/wxSngVvTYIujGuCFmC4cn5ake6E5NZ0UmOiS9C6PiZ0Btu7FgQLK72doqu3S9c1iN9l3BcVZQliNG9N0js0ooQ2yML/HoV53n/ecSi/ZggOOB6dO0ZMNJUfUSbjB6cl6r67AhQ== 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: List-Subscribe: List-Unsubscribe: + Rafael J. Wysocki, Len Brown, Pavel Machek This was a rather tricky series to get the recipients correct for and my script did not realize that "supporter" was a pseudonym for "maintainer" so you were missed off the original post. Appologies! More context in cover letter: https://lore.kernel.org/all/20241014105514.3206191-1-ryan.roberts@arm.com/ On 14/10/2024 11:58, Ryan Roberts wrote: > To prepare for supporting boot-time page size selection, refactor code > to remove assumptions about PAGE_SIZE being compile-time constant. Code > intended to be equivalent when compile-time page size is active. > > "struct linked_page", "struct swap_map_page" and "struct swsusp_header" > were all previously sized to be exactly PAGE_SIZE. Refactor those > structures to remove the padding, then superimpose them on a page at > runtime. > > "struct cmp_data" and "struct dec_data" previously contained embedded > "unc" and "cmp" arrays, who's sizes were derived from PAGE_SIZE. We > can't use flexible array approach here since there are 2 arrays in the > structure, so convert to pointers and define an allocator and > deallocator for each struct. > > Signed-off-by: Ryan Roberts > --- > > ***NOTE*** > Any confused maintainers may want to read the cover note here for context: > https://lore.kernel.org/all/20241014105514.3206191-1-ryan.roberts@arm.com/ > > kernel/power/power.h | 2 +- > kernel/power/snapshot.c | 2 +- > kernel/power/swap.c | 129 +++++++++++++++++++++++++++++++++------- > 3 files changed, 108 insertions(+), 25 deletions(-) > > diff --git a/kernel/power/power.h b/kernel/power/power.h > index de0e6b1077f23..74af2eb8d48a4 100644 > --- a/kernel/power/power.h > +++ b/kernel/power/power.h > @@ -16,7 +16,7 @@ struct swsusp_info { > unsigned long image_pages; > unsigned long pages; > unsigned long size; > -} __aligned(PAGE_SIZE); > +} __aligned(PAGE_SIZE_MAX); > > #ifdef CONFIG_HIBERNATION > /* kernel/power/snapshot.c */ > diff --git a/kernel/power/snapshot.c b/kernel/power/snapshot.c > index 405eddbda4fc5..144e92f786e35 100644 > --- a/kernel/power/snapshot.c > +++ b/kernel/power/snapshot.c > @@ -155,7 +155,7 @@ struct pbe *restore_pblist; > > struct linked_page { > struct linked_page *next; > - char data[LINKED_PAGE_DATA_SIZE]; > + char data[]; > } __packed; > > /* > diff --git a/kernel/power/swap.c b/kernel/power/swap.c > index 82b884b67152f..ffd4c864acfa2 100644 > --- a/kernel/power/swap.c > +++ b/kernel/power/swap.c > @@ -59,6 +59,7 @@ static bool clean_pages_on_decompress; > */ > > #define MAP_PAGE_ENTRIES (PAGE_SIZE / sizeof(sector_t) - 1) > +#define NEXT_SWAP_INDEX MAP_PAGE_ENTRIES > > /* > * Number of free pages that are not high. > @@ -78,8 +79,11 @@ static inline unsigned long reqd_free_pages(void) > } > > struct swap_map_page { > - sector_t entries[MAP_PAGE_ENTRIES]; > - sector_t next_swap; > + /* > + * A PAGE_SIZE structure with (PAGE_SIZE / sizeof(sector_t)) entries. > + * The last entry, [NEXT_SWAP_INDEX], is `.next_swap`. > + */ > + sector_t entries[1]; > }; > > struct swap_map_page_list { > @@ -103,8 +107,6 @@ struct swap_map_handle { > }; > > struct swsusp_header { > - char reserved[PAGE_SIZE - 20 - sizeof(sector_t) - sizeof(int) - > - sizeof(u32) - sizeof(u32)]; > u32 hw_sig; > u32 crc32; > sector_t image; > @@ -113,6 +115,7 @@ struct swsusp_header { > char sig[10]; > } __packed; > > +static char *swsusp_header_pg; > static struct swsusp_header *swsusp_header; > > /* > @@ -315,7 +318,7 @@ static int mark_swapfiles(struct swap_map_handle *handle, unsigned int flags) > { > int error; > > - hib_submit_io(REQ_OP_READ, swsusp_resume_block, swsusp_header, NULL); > + hib_submit_io(REQ_OP_READ, swsusp_resume_block, swsusp_header_pg, NULL); > if (!memcmp("SWAP-SPACE",swsusp_header->sig, 10) || > !memcmp("SWAPSPACE2",swsusp_header->sig, 10)) { > memcpy(swsusp_header->orig_sig,swsusp_header->sig, 10); > @@ -329,7 +332,7 @@ static int mark_swapfiles(struct swap_map_handle *handle, unsigned int flags) > if (flags & SF_CRC32_MODE) > swsusp_header->crc32 = handle->crc32; > error = hib_submit_io(REQ_OP_WRITE | REQ_SYNC, > - swsusp_resume_block, swsusp_header, NULL); > + swsusp_resume_block, swsusp_header_pg, NULL); > } else { > pr_err("Swap header not found!\n"); > error = -ENODEV; > @@ -466,7 +469,7 @@ static int swap_write_page(struct swap_map_handle *handle, void *buf, > offset = alloc_swapdev_block(root_swap); > if (!offset) > return -ENOSPC; > - handle->cur->next_swap = offset; > + handle->cur->entries[NEXT_SWAP_INDEX] = offset; > error = write_page(handle->cur, handle->cur_swap, hb); > if (error) > goto out; > @@ -643,8 +646,8 @@ struct cmp_data { > wait_queue_head_t done; /* compression done */ > size_t unc_len; /* uncompressed length */ > size_t cmp_len; /* compressed length */ > - unsigned char unc[UNC_SIZE]; /* uncompressed buffer */ > - unsigned char cmp[CMP_SIZE]; /* compressed buffer */ > + unsigned char *unc; /* uncompressed buffer */ > + unsigned char *cmp; /* compressed buffer */ > }; > > /* Indicates the image size after compression */ > @@ -683,6 +686,45 @@ static int compress_threadfn(void *data) > return 0; > } > > +static void free_cmp_data(struct cmp_data *data, unsigned nr_threads) > +{ > + int i; > + > + if (!data) > + return; > + > + for (i = 0; i < nr_threads; i++) { > + vfree(data[i].unc); > + vfree(data[i].cmp); > + } > + > + vfree(data); > +} > + > +static struct cmp_data *alloc_cmp_data(unsigned nr_threads) > +{ > + struct cmp_data *data = NULL; > + int i = -1; > + > + data = vzalloc(array_size(nr_threads, sizeof(*data))); > + if (!data) > + goto fail; > + > + for (i = 0; i < nr_threads; i++) { > + data[i].unc = vzalloc(UNC_SIZE); > + if (!data[i].unc) > + goto fail; > + data[i].cmp = vzalloc(CMP_SIZE); > + if (!data[i].cmp) > + goto fail; > + } > + > + return data; > +fail: > + free_cmp_data(data, nr_threads); > + return NULL; > +} > + > /** > * save_compressed_image - Save the suspend image data after compression. > * @handle: Swap map handle to use for saving the image. > @@ -724,7 +766,7 @@ static int save_compressed_image(struct swap_map_handle *handle, > goto out_clean; > } > > - data = vzalloc(array_size(nr_threads, sizeof(*data))); > + data = alloc_cmp_data(nr_threads); > if (!data) { > pr_err("Failed to allocate %s data\n", hib_comp_algo); > ret = -ENOMEM; > @@ -902,7 +944,7 @@ static int save_compressed_image(struct swap_map_handle *handle, > if (data[thr].cc) > crypto_free_comp(data[thr].cc); > } > - vfree(data); > + free_cmp_data(data, nr_threads); > } > if (page) free_page((unsigned long)page); > > @@ -1036,7 +1078,7 @@ static int get_swap_reader(struct swap_map_handle *handle, > release_swap_reader(handle); > return error; > } > - offset = tmp->map->next_swap; > + offset = tmp->map->entries[NEXT_SWAP_INDEX]; > } > handle->k = 0; > handle->cur = handle->maps->map; > @@ -1150,8 +1192,8 @@ struct dec_data { > wait_queue_head_t done; /* decompression done */ > size_t unc_len; /* uncompressed length */ > size_t cmp_len; /* compressed length */ > - unsigned char unc[UNC_SIZE]; /* uncompressed buffer */ > - unsigned char cmp[CMP_SIZE]; /* compressed buffer */ > + unsigned char *unc; /* uncompressed buffer */ > + unsigned char *cmp; /* compressed buffer */ > }; > > /* > @@ -1189,6 +1231,45 @@ static int decompress_threadfn(void *data) > return 0; > } > > +static void free_dec_data(struct dec_data *data, unsigned nr_threads) > +{ > + int i; > + > + if (!data) > + return; > + > + for (i = 0; i < nr_threads; i++) { > + vfree(data[i].unc); > + vfree(data[i].cmp); > + } > + > + vfree(data); > +} > + > +static struct dec_data *alloc_dec_data(unsigned nr_threads) > +{ > + struct dec_data *data = NULL; > + int i = -1; > + > + data = vzalloc(array_size(nr_threads, sizeof(*data))); > + if (!data) > + goto fail; > + > + for (i = 0; i < nr_threads; i++) { > + data[i].unc = vzalloc(UNC_SIZE); > + if (!data[i].unc) > + goto fail; > + data[i].cmp = vzalloc(CMP_SIZE); > + if (!data[i].cmp) > + goto fail; > + } > + > + return data; > +fail: > + free_dec_data(data, nr_threads); > + return NULL; > +} > + > /** > * load_compressed_image - Load compressed image data and decompress it. > * @handle: Swap map handle to use for loading data. > @@ -1231,7 +1312,7 @@ static int load_compressed_image(struct swap_map_handle *handle, > goto out_clean; > } > > - data = vzalloc(array_size(nr_threads, sizeof(*data))); > + data = alloc_dec_data(nr_threads); > if (!data) { > pr_err("Failed to allocate %s data\n", hib_comp_algo); > ret = -ENOMEM; > @@ -1510,7 +1591,7 @@ static int load_compressed_image(struct swap_map_handle *handle, > if (data[thr].cc) > crypto_free_comp(data[thr].cc); > } > - vfree(data); > + free_dec_data(data, nr_threads); > } > vfree(page); > > @@ -1569,9 +1650,9 @@ int swsusp_check(bool exclusive) > hib_resume_bdev_file = bdev_file_open_by_dev(swsusp_resume_device, > BLK_OPEN_READ, holder, NULL); > if (!IS_ERR(hib_resume_bdev_file)) { > - clear_page(swsusp_header); > + clear_page(swsusp_header_pg); > error = hib_submit_io(REQ_OP_READ, swsusp_resume_block, > - swsusp_header, NULL); > + swsusp_header_pg, NULL); > if (error) > goto put; > > @@ -1581,7 +1662,7 @@ int swsusp_check(bool exclusive) > /* Reset swap signature now */ > error = hib_submit_io(REQ_OP_WRITE | REQ_SYNC, > swsusp_resume_block, > - swsusp_header, NULL); > + swsusp_header_pg, NULL); > } else { > error = -EINVAL; > } > @@ -1631,12 +1712,12 @@ int swsusp_unmark(void) > int error; > > hib_submit_io(REQ_OP_READ, swsusp_resume_block, > - swsusp_header, NULL); > + swsusp_header_pg, NULL); > if (!memcmp(HIBERNATE_SIG,swsusp_header->sig, 10)) { > memcpy(swsusp_header->sig,swsusp_header->orig_sig, 10); > error = hib_submit_io(REQ_OP_WRITE | REQ_SYNC, > swsusp_resume_block, > - swsusp_header, NULL); > + swsusp_header_pg, NULL); > } else { > pr_err("Cannot find swsusp signature!\n"); > error = -ENODEV; > @@ -1653,9 +1734,11 @@ int swsusp_unmark(void) > > static int __init swsusp_header_init(void) > { > - swsusp_header = (struct swsusp_header*) __get_free_page(GFP_KERNEL); > - if (!swsusp_header) > + swsusp_header_pg = (char *)__get_free_page(GFP_KERNEL); > + if (!swsusp_header_pg) > panic("Could not allocate memory for swsusp_header\n"); > + swsusp_header = (struct swsusp_header *)(swsusp_header_pg + > + PAGE_SIZE - sizeof(struct swsusp_header)); > return 0; > } >