// SPDX-License-Identifier: GPL-2.0-only /* * linux/kernel/power/swap.c * * This file provides functions for reading the suspend image from * and writing it to a swap partition. * * Copyright (C) 1998,2001-2005 Pavel Machek <[email protected]> * Copyright (C) 2006 Rafael J. Wysocki <[email protected]> * Copyright (C) 2010-2012 Bojan Smojver <[email protected]> */ #define pr_fmt(fmt) … #include <linux/module.h> #include <linux/file.h> #include <linux/delay.h> #include <linux/bitops.h> #include <linux/device.h> #include <linux/bio.h> #include <linux/blkdev.h> #include <linux/swap.h> #include <linux/swapops.h> #include <linux/pm.h> #include <linux/slab.h> #include <linux/vmalloc.h> #include <linux/cpumask.h> #include <linux/atomic.h> #include <linux/kthread.h> #include <linux/crc32.h> #include <linux/ktime.h> #include "power.h" #define HIBERNATE_SIG … u32 swsusp_hardware_signature; /* * When reading an {un,}compressed image, we may restore pages in place, * in which case some architectures need these pages cleaning before they * can be executed. We don't know which pages these may be, so clean the lot. */ static bool clean_pages_on_read; static bool clean_pages_on_decompress; /* * The swap map is a data structure used for keeping track of each page * written to a swap partition. It consists of many swap_map_page * structures that contain each an array of MAP_PAGE_ENTRIES swap entries. * These structures are stored on the swap and linked together with the * help of the .next_swap member. * * The swap map is created during suspend. The swap map pages are * allocated and populated one at a time, so we only need one memory * page to set up the entire structure. * * During resume we pick up all swap_map_page structures into a list. */ #define MAP_PAGE_ENTRIES … /* * Number of free pages that are not high. */ static inline unsigned long low_free_pages(void) { … } /* * Number of pages required to be kept free while writing the image. Always * half of all available low pages before the writing starts. */ static inline unsigned long reqd_free_pages(void) { … } struct swap_map_page { … }; struct swap_map_page_list { … }; /* * The swap_map_handle structure is used for handling swap in * a file-alike way */ struct swap_map_handle { … }; struct swsusp_header { … } __packed; static struct swsusp_header *swsusp_header; /* * The following functions are used for tracing the allocated * swap pages, so that they can be freed in case of an error. */ struct swsusp_extent { … }; static struct rb_root swsusp_extents = …; static int swsusp_extents_insert(unsigned long swap_offset) { … } /* * alloc_swapdev_block - allocate a swap page and register that it has * been allocated, so that it can be freed in case of an error. */ sector_t alloc_swapdev_block(int swap) { … } /* * free_all_swap_pages - free swap pages allocated for saving image data. * It also frees the extents used to register which swap entries had been * allocated. */ void free_all_swap_pages(int swap) { … } int swsusp_swap_in_use(void) { … } /* * General things */ static unsigned short root_swap = …; static struct file *hib_resume_bdev_file; struct hib_bio_batch { … }; static void hib_init_batch(struct hib_bio_batch *hb) { … } static void hib_finish_batch(struct hib_bio_batch *hb) { … } static void hib_end_io(struct bio *bio) { … } static int hib_submit_io(blk_opf_t opf, pgoff_t page_off, void *addr, struct hib_bio_batch *hb) { … } static int hib_wait_io(struct hib_bio_batch *hb) { … } /* * Saving part */ static int mark_swapfiles(struct swap_map_handle *handle, unsigned int flags) { … } /* * Hold the swsusp_header flag. This is used in software_resume() in * 'kernel/power/hibernate' to check if the image is compressed and query * for the compression algorithm support(if so). */ unsigned int swsusp_header_flags; /** * swsusp_swap_check - check if the resume device is a swap device * and get its index (if so) * * This is called before saving image */ static int swsusp_swap_check(void) { … } /** * write_page - Write one page to given swap location. * @buf: Address we're writing. * @offset: Offset of the swap page we're writing to. * @hb: bio completion batch */ static int write_page(void *buf, sector_t offset, struct hib_bio_batch *hb) { … } static void release_swap_writer(struct swap_map_handle *handle) { … } static int get_swap_writer(struct swap_map_handle *handle) { … } static int swap_write_page(struct swap_map_handle *handle, void *buf, struct hib_bio_batch *hb) { … } static int flush_swap_writer(struct swap_map_handle *handle) { … } static int swap_writer_finish(struct swap_map_handle *handle, unsigned int flags, int error) { … } /* * Bytes we need for compressed data in worst case. We assume(limitation) * this is the worst of all the compression algorithms. */ #define bytes_worst_compress(x) … /* We need to remember how much compressed data we need to read. */ #define CMP_HEADER … /* Number of pages/bytes we'll compress at one time. */ #define UNC_PAGES … #define UNC_SIZE … /* Number of pages we need for compressed data (worst case). */ #define CMP_PAGES … #define CMP_SIZE … /* Maximum number of threads for compression/decompression. */ #define CMP_THREADS … /* Minimum/maximum number of pages for read buffering. */ #define CMP_MIN_RD_PAGES … #define CMP_MAX_RD_PAGES … /** * save_image - save the suspend image data */ static int save_image(struct swap_map_handle *handle, struct snapshot_handle *snapshot, unsigned int nr_to_write) { … } /* * Structure used for CRC32. */ struct crc_data { … }; /* * CRC32 update function that runs in its own thread. */ static int crc32_threadfn(void *data) { … } /* * Structure used for data compression. */ struct cmp_data { … }; /* Indicates the image size after compression */ static atomic_t compressed_size = …; /* * Compression function that runs in its own thread. */ static int compress_threadfn(void *data) { … } /** * save_compressed_image - Save the suspend image data after compression. * @handle: Swap map handle to use for saving the image. * @snapshot: Image to read data from. * @nr_to_write: Number of pages to save. */ static int save_compressed_image(struct swap_map_handle *handle, struct snapshot_handle *snapshot, unsigned int nr_to_write) { … } /** * enough_swap - Make sure we have enough swap to save the image. * * Returns TRUE or FALSE after checking the total amount of swap * space available from the resume partition. */ static int enough_swap(unsigned int nr_pages) { … } /** * swsusp_write - Write entire image and metadata. * @flags: flags to pass to the "boot" kernel in the image header * * It is important _NOT_ to umount filesystems at this point. We want * them synced (in case something goes wrong) but we DO not want to mark * filesystem clean: it is not. (And it does not matter, if we resume * correctly, we'll mark system clean, anyway.) */ int swsusp_write(unsigned int flags) { … } /* * The following functions allow us to read data using a swap map * in a file-like way. */ static void release_swap_reader(struct swap_map_handle *handle) { … } static int get_swap_reader(struct swap_map_handle *handle, unsigned int *flags_p) { … } static int swap_read_page(struct swap_map_handle *handle, void *buf, struct hib_bio_batch *hb) { … } static int swap_reader_finish(struct swap_map_handle *handle) { … } /** * load_image - load the image using the swap map handle * @handle and the snapshot handle @snapshot * (assume there are @nr_pages pages to load) */ static int load_image(struct swap_map_handle *handle, struct snapshot_handle *snapshot, unsigned int nr_to_read) { … } /* * Structure used for data decompression. */ struct dec_data { … }; /* * Decompression function that runs in its own thread. */ static int decompress_threadfn(void *data) { … } /** * load_compressed_image - Load compressed image data and decompress it. * @handle: Swap map handle to use for loading data. * @snapshot: Image to copy uncompressed data into. * @nr_to_read: Number of pages to load. */ static int load_compressed_image(struct swap_map_handle *handle, struct snapshot_handle *snapshot, unsigned int nr_to_read) { … } /** * swsusp_read - read the hibernation image. * @flags_p: flags passed by the "frozen" kernel in the image header should * be written into this memory location */ int swsusp_read(unsigned int *flags_p) { … } static void *swsusp_holder; /** * swsusp_check - Open the resume device and check for the swsusp signature. * @exclusive: Open the resume device exclusively. */ int swsusp_check(bool exclusive) { … } /** * swsusp_close - close resume device. */ void swsusp_close(void) { … } /** * swsusp_unmark - Unmark swsusp signature in the resume device */ #ifdef CONFIG_SUSPEND int swsusp_unmark(void) { … } #endif static int __init swsusp_header_init(void) { … } core_initcall(swsusp_header_init);