#include <linux/blkdev.h>
#include <linux/mm.h>
#include <linux/sched/mm.h>
#include <linux/sched/task.h>
#include <linux/hugetlb.h>
#include <linux/mman.h>
#include <linux/slab.h>
#include <linux/kernel_stat.h>
#include <linux/swap.h>
#include <linux/vmalloc.h>
#include <linux/pagemap.h>
#include <linux/namei.h>
#include <linux/shmem_fs.h>
#include <linux/blk-cgroup.h>
#include <linux/random.h>
#include <linux/writeback.h>
#include <linux/proc_fs.h>
#include <linux/seq_file.h>
#include <linux/init.h>
#include <linux/ksm.h>
#include <linux/rmap.h>
#include <linux/security.h>
#include <linux/backing-dev.h>
#include <linux/mutex.h>
#include <linux/capability.h>
#include <linux/syscalls.h>
#include <linux/memcontrol.h>
#include <linux/poll.h>
#include <linux/oom.h>
#include <linux/swapfile.h>
#include <linux/export.h>
#include <linux/swap_slots.h>
#include <linux/sort.h>
#include <linux/completion.h>
#include <linux/suspend.h>
#include <linux/zswap.h>
#include <linux/plist.h>
#include <asm/tlbflush.h>
#include <linux/swapops.h>
#include <linux/swap_cgroup.h>
#include "internal.h"
#include "swap.h"
static bool swap_count_continued(struct swap_info_struct *, pgoff_t,
unsigned char);
static void free_swap_count_continuations(struct swap_info_struct *);
static DEFINE_SPINLOCK(swap_lock);
static unsigned int nr_swapfiles;
atomic_long_t nr_swap_pages;
EXPORT_SYMBOL_GPL(…);
long total_swap_pages;
static int least_priority = …;
unsigned long swapfile_maximum_size;
#ifdef CONFIG_MIGRATION
bool swap_migration_ad_supported;
#endif
static const char Bad_file[] = …;
static const char Unused_file[] = …;
static const char Bad_offset[] = …;
static const char Unused_offset[] = …;
static PLIST_HEAD(swap_active_head);
static struct plist_head *swap_avail_heads;
static DEFINE_SPINLOCK(swap_avail_lock);
static struct swap_info_struct *swap_info[MAX_SWAPFILES];
static DEFINE_MUTEX(swapon_mutex);
static DECLARE_WAIT_QUEUE_HEAD(proc_poll_wait);
static atomic_t proc_poll_event = …;
atomic_t nr_rotate_swap = …;
static struct swap_info_struct *swap_type_to_swap_info(int type)
{ … }
static inline unsigned char swap_count(unsigned char ent)
{ … }
#define TTRS_ANYWAY …
#define TTRS_UNMAPPED …
#define TTRS_FULL …
static int __try_to_reclaim_swap(struct swap_info_struct *si,
unsigned long offset, unsigned long flags)
{ … }
static inline struct swap_extent *first_se(struct swap_info_struct *sis)
{ … }
static inline struct swap_extent *next_se(struct swap_extent *se)
{ … }
static int discard_swap(struct swap_info_struct *si)
{ … }
static struct swap_extent *
offset_to_swap_extent(struct swap_info_struct *sis, unsigned long offset)
{ … }
sector_t swap_folio_sector(struct folio *folio)
{ … }
static void discard_swap_cluster(struct swap_info_struct *si,
pgoff_t start_page, pgoff_t nr_pages)
{ … }
#ifdef CONFIG_THP_SWAP
#define SWAPFILE_CLUSTER …
#define swap_entry_order(order) …
#else
#define SWAPFILE_CLUSTER …
#define swap_entry_order …
#endif
#define LATENCY_LIMIT …
static inline void cluster_set_flag(struct swap_cluster_info *info,
unsigned int flag)
{ … }
static inline unsigned int cluster_count(struct swap_cluster_info *info)
{ … }
static inline void cluster_set_count(struct swap_cluster_info *info,
unsigned int c)
{ … }
static inline void cluster_set_count_flag(struct swap_cluster_info *info,
unsigned int c, unsigned int f)
{ … }
static inline unsigned int cluster_next(struct swap_cluster_info *info)
{ … }
static inline void cluster_set_next(struct swap_cluster_info *info,
unsigned int n)
{ … }
static inline void cluster_set_next_flag(struct swap_cluster_info *info,
unsigned int n, unsigned int f)
{ … }
static inline bool cluster_is_free(struct swap_cluster_info *info)
{ … }
static inline bool cluster_is_null(struct swap_cluster_info *info)
{ … }
static inline void cluster_set_null(struct swap_cluster_info *info)
{ … }
static inline struct swap_cluster_info *lock_cluster(struct swap_info_struct *si,
unsigned long offset)
{ … }
static inline void unlock_cluster(struct swap_cluster_info *ci)
{ … }
static inline struct swap_cluster_info *lock_cluster_or_swap_info(
struct swap_info_struct *si, unsigned long offset)
{ … }
static inline void unlock_cluster_or_swap_info(struct swap_info_struct *si,
struct swap_cluster_info *ci)
{ … }
static inline bool cluster_list_empty(struct swap_cluster_list *list)
{ … }
static inline unsigned int cluster_list_first(struct swap_cluster_list *list)
{ … }
static void cluster_list_init(struct swap_cluster_list *list)
{ … }
static void cluster_list_add_tail(struct swap_cluster_list *list,
struct swap_cluster_info *ci,
unsigned int idx)
{ … }
static unsigned int cluster_list_del_first(struct swap_cluster_list *list,
struct swap_cluster_info *ci)
{ … }
static void swap_cluster_schedule_discard(struct swap_info_struct *si,
unsigned int idx)
{ … }
static void __free_cluster(struct swap_info_struct *si, unsigned long idx)
{ … }
static void swap_do_scheduled_discard(struct swap_info_struct *si)
{ … }
static void swap_discard_work(struct work_struct *work)
{ … }
static void swap_users_ref_free(struct percpu_ref *ref)
{ … }
static void alloc_cluster(struct swap_info_struct *si, unsigned long idx)
{ … }
static void free_cluster(struct swap_info_struct *si, unsigned long idx)
{ … }
static void add_cluster_info_page(struct swap_info_struct *p,
struct swap_cluster_info *cluster_info, unsigned long page_nr,
unsigned long count)
{ … }
static void inc_cluster_info_page(struct swap_info_struct *p,
struct swap_cluster_info *cluster_info, unsigned long page_nr)
{ … }
static void dec_cluster_info_page(struct swap_info_struct *p,
struct swap_cluster_info *cluster_info, unsigned long page_nr)
{ … }
static bool
scan_swap_map_ssd_cluster_conflict(struct swap_info_struct *si,
unsigned long offset, int order)
{ … }
static inline bool swap_range_empty(char *swap_map, unsigned int start,
unsigned int nr_pages)
{ … }
static bool scan_swap_map_try_ssd_cluster(struct swap_info_struct *si,
unsigned long *offset, unsigned long *scan_base, int order)
{ … }
static void __del_from_avail_list(struct swap_info_struct *p)
{ … }
static void del_from_avail_list(struct swap_info_struct *p)
{ … }
static void swap_range_alloc(struct swap_info_struct *si, unsigned long offset,
unsigned int nr_entries)
{ … }
static void add_to_avail_list(struct swap_info_struct *p)
{ … }
static void swap_range_free(struct swap_info_struct *si, unsigned long offset,
unsigned int nr_entries)
{ … }
static void set_cluster_next(struct swap_info_struct *si, unsigned long next)
{ … }
static bool swap_offset_available_and_locked(struct swap_info_struct *si,
unsigned long offset)
{ … }
static int scan_swap_map_slots(struct swap_info_struct *si,
unsigned char usage, int nr,
swp_entry_t slots[], int order)
{ … }
static void swap_free_cluster(struct swap_info_struct *si, unsigned long idx)
{ … }
int get_swap_pages(int n_goal, swp_entry_t swp_entries[], int entry_order)
{ … }
static struct swap_info_struct *_swap_info_get(swp_entry_t entry)
{ … }
static struct swap_info_struct *swap_info_get_cont(swp_entry_t entry,
struct swap_info_struct *q)
{ … }
static unsigned char __swap_entry_free_locked(struct swap_info_struct *p,
unsigned long offset,
unsigned char usage)
{ … }
struct swap_info_struct *get_swap_device(swp_entry_t entry)
{ … }
static unsigned char __swap_entry_free(struct swap_info_struct *p,
swp_entry_t entry)
{ … }
static void swap_entry_free(struct swap_info_struct *p, swp_entry_t entry)
{ … }
static void cluster_swap_free_nr(struct swap_info_struct *sis,
unsigned long offset, int nr_pages)
{ … }
void swap_free_nr(swp_entry_t entry, int nr_pages)
{ … }
void put_swap_folio(struct folio *folio, swp_entry_t entry)
{ … }
static int swp_entry_cmp(const void *ent1, const void *ent2)
{ … }
void swapcache_free_entries(swp_entry_t *entries, int n)
{ … }
int __swap_count(swp_entry_t entry)
{ … }
int swap_swapcount(struct swap_info_struct *si, swp_entry_t entry)
{ … }
int swp_swapcount(swp_entry_t entry)
{ … }
static bool swap_page_trans_huge_swapped(struct swap_info_struct *si,
swp_entry_t entry, int order)
{ … }
static bool folio_swapped(struct folio *folio)
{ … }
bool folio_free_swap(struct folio *folio)
{ … }
void free_swap_and_cache_nr(swp_entry_t entry, int nr)
{ … }
#ifdef CONFIG_HIBERNATION
swp_entry_t get_swap_page_of_type(int type)
{ … }
int swap_type_of(dev_t device, sector_t offset)
{ … }
int find_first_swap(dev_t *device)
{ … }
sector_t swapdev_block(int type, pgoff_t offset)
{ … }
unsigned int count_swap_pages(int type, int free)
{ … }
#endif
static inline int pte_same_as_swp(pte_t pte, pte_t swp_pte)
{ … }
static int unuse_pte(struct vm_area_struct *vma, pmd_t *pmd,
unsigned long addr, swp_entry_t entry, struct folio *folio)
{ … }
static int unuse_pte_range(struct vm_area_struct *vma, pmd_t *pmd,
unsigned long addr, unsigned long end,
unsigned int type)
{ … }
static inline int unuse_pmd_range(struct vm_area_struct *vma, pud_t *pud,
unsigned long addr, unsigned long end,
unsigned int type)
{ … }
static inline int unuse_pud_range(struct vm_area_struct *vma, p4d_t *p4d,
unsigned long addr, unsigned long end,
unsigned int type)
{ … }
static inline int unuse_p4d_range(struct vm_area_struct *vma, pgd_t *pgd,
unsigned long addr, unsigned long end,
unsigned int type)
{ … }
static int unuse_vma(struct vm_area_struct *vma, unsigned int type)
{ … }
static int unuse_mm(struct mm_struct *mm, unsigned int type)
{ … }
static unsigned int find_next_to_unuse(struct swap_info_struct *si,
unsigned int prev)
{ … }
static int try_to_unuse(unsigned int type)
{ … }
static void drain_mmlist(void)
{ … }
static void destroy_swap_extents(struct swap_info_struct *sis)
{ … }
int
add_swap_extent(struct swap_info_struct *sis, unsigned long start_page,
unsigned long nr_pages, sector_t start_block)
{ … }
EXPORT_SYMBOL_GPL(…);
static int setup_swap_extents(struct swap_info_struct *sis, sector_t *span)
{ … }
static int swap_node(struct swap_info_struct *p)
{ … }
static void setup_swap_info(struct swap_info_struct *p, int prio,
unsigned char *swap_map,
struct swap_cluster_info *cluster_info)
{ … }
static void _enable_swap_info(struct swap_info_struct *p)
{ … }
static void enable_swap_info(struct swap_info_struct *p, int prio,
unsigned char *swap_map,
struct swap_cluster_info *cluster_info)
{ … }
static void reinsert_swap_info(struct swap_info_struct *p)
{ … }
static bool __has_usable_swap(void)
{ … }
bool has_usable_swap(void)
{ … }
SYSCALL_DEFINE1(swapoff, const char __user *, specialfile)
{ … }
#ifdef CONFIG_PROC_FS
static __poll_t swaps_poll(struct file *file, poll_table *wait)
{ … }
static void *swap_start(struct seq_file *swap, loff_t *pos)
{ … }
static void *swap_next(struct seq_file *swap, void *v, loff_t *pos)
{ … }
static void swap_stop(struct seq_file *swap, void *v)
{ … }
static int swap_show(struct seq_file *swap, void *v)
{ … }
static const struct seq_operations swaps_op = …;
static int swaps_open(struct inode *inode, struct file *file)
{ … }
static const struct proc_ops swaps_proc_ops = …;
static int __init procswaps_init(void)
{ … }
__initcall(procswaps_init);
#endif
#ifdef MAX_SWAPFILES_CHECK
static int __init max_swapfiles_check(void)
{ … }
late_initcall(max_swapfiles_check);
#endif
static struct swap_info_struct *alloc_swap_info(void)
{ … }
static int claim_swapfile(struct swap_info_struct *p, struct inode *inode)
{ … }
unsigned long generic_max_swapfile_size(void)
{ … }
__weak unsigned long arch_max_swapfile_size(void)
{ … }
static unsigned long read_swap_header(struct swap_info_struct *p,
union swap_header *swap_header,
struct inode *inode)
{ … }
#define SWAP_CLUSTER_INFO_COLS …
#define SWAP_CLUSTER_SPACE_COLS …
#define SWAP_CLUSTER_COLS …
static int setup_swap_map_and_extents(struct swap_info_struct *p,
union swap_header *swap_header,
unsigned char *swap_map,
struct swap_cluster_info *cluster_info,
unsigned long maxpages,
sector_t *span)
{ … }
SYSCALL_DEFINE2(swapon, const char __user *, specialfile, int, swap_flags)
{ … }
void si_swapinfo(struct sysinfo *val)
{ … }
static int __swap_duplicate(swp_entry_t entry, unsigned char usage)
{ … }
void swap_shmem_alloc(swp_entry_t entry)
{ … }
int swap_duplicate(swp_entry_t entry)
{ … }
int swapcache_prepare(swp_entry_t entry)
{ … }
void swapcache_clear(struct swap_info_struct *si, swp_entry_t entry)
{ … }
struct swap_info_struct *swp_swap_info(swp_entry_t entry)
{ … }
struct address_space *swapcache_mapping(struct folio *folio)
{ … }
EXPORT_SYMBOL_GPL(…);
pgoff_t __folio_swap_cache_index(struct folio *folio)
{ … }
EXPORT_SYMBOL_GPL(…);
int add_swap_count_continuation(swp_entry_t entry, gfp_t gfp_mask)
{ … }
static bool swap_count_continued(struct swap_info_struct *si,
pgoff_t offset, unsigned char count)
{ … }
static void free_swap_count_continuations(struct swap_info_struct *si)
{ … }
#if defined(CONFIG_MEMCG) && defined(CONFIG_BLK_CGROUP)
void __folio_throttle_swaprate(struct folio *folio, gfp_t gfp)
{ … }
#endif
static int __init swapfile_init(void)
{ … }
subsys_initcall(swapfile_init);