linux/kernel/power/swap.c

// 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);