xref: /linux/mm/swap.h (revision 0fc8f6200d2313278fbf4539bbab74677c685531)
1014bb1deSNeilBrown /* SPDX-License-Identifier: GPL-2.0 */
2014bb1deSNeilBrown #ifndef _MM_SWAP_H
3014bb1deSNeilBrown #define _MM_SWAP_H
4014bb1deSNeilBrown 
58578e0c0SKairui Song #include <linux/atomic.h> /* for atomic_long_t */
6ddc1a5cbSHugh Dickins struct mempolicy;
7624043dbSChristoph Hellwig struct swap_iocb;
8624043dbSChristoph Hellwig 
97e05627eSKaixiong Yu extern int page_cluster;
10ddc1a5cbSHugh Dickins 
114522aed4SKairui Song #ifdef CONFIG_THP_SWAP
124522aed4SKairui Song #define SWAPFILE_CLUSTER	HPAGE_PMD_NR
134522aed4SKairui Song #define swap_entry_order(order)	(order)
144522aed4SKairui Song #else
154522aed4SKairui Song #define SWAPFILE_CLUSTER	256
164522aed4SKairui Song #define swap_entry_order(order)	0
174522aed4SKairui Song #endif
184522aed4SKairui Song 
190fcf8ef4SKairui Song extern struct swap_info_struct *swap_info[];
200fcf8ef4SKairui Song 
214522aed4SKairui Song /*
224522aed4SKairui Song  * We use this to track usage of a cluster. A cluster is a block of swap disk
234522aed4SKairui Song  * space with SWAPFILE_CLUSTER pages long and naturally aligns in disk. All
244522aed4SKairui Song  * free clusters are organized into a list. We fetch an entry from the list to
254522aed4SKairui Song  * get a free cluster.
264522aed4SKairui Song  *
274522aed4SKairui Song  * The flags field determines if a cluster is free. This is
284522aed4SKairui Song  * protected by cluster lock.
294522aed4SKairui Song  */
304522aed4SKairui Song struct swap_cluster_info {
314522aed4SKairui Song 	spinlock_t lock;	/*
324522aed4SKairui Song 				 * Protect swap_cluster_info fields
334522aed4SKairui Song 				 * other than list, and swap_info_struct->swap_map
344522aed4SKairui Song 				 * elements corresponding to the swap cluster.
354522aed4SKairui Song 				 */
364522aed4SKairui Song 	u16 count;
374522aed4SKairui Song 	u8 flags;
384522aed4SKairui Song 	u8 order;
3907adc4cfSKairui Song 	atomic_long_t __rcu *table;	/* Swap table entries, see mm/swap_table.h */
400d6af9bcSKairui Song 	unsigned int *extend_table;	/* For large swap count, protected by ci->lock */
414522aed4SKairui Song 	struct list_head list;
424522aed4SKairui Song };
434522aed4SKairui Song 
444522aed4SKairui Song /* All on-list cluster must have a non-zero flag. */
454522aed4SKairui Song enum swap_cluster_flags {
464522aed4SKairui Song 	CLUSTER_FLAG_NONE = 0, /* For temporary off-list cluster */
474522aed4SKairui Song 	CLUSTER_FLAG_FREE,
484522aed4SKairui Song 	CLUSTER_FLAG_NONFULL,
494522aed4SKairui Song 	CLUSTER_FLAG_FRAG,
504522aed4SKairui Song 	/* Clusters with flags above are allocatable */
514522aed4SKairui Song 	CLUSTER_FLAG_USABLE = CLUSTER_FLAG_FRAG,
524522aed4SKairui Song 	CLUSTER_FLAG_FULL,
534522aed4SKairui Song 	CLUSTER_FLAG_DISCARD,
544522aed4SKairui Song 	CLUSTER_FLAG_MAX,
554522aed4SKairui Song };
564522aed4SKairui Song 
57014bb1deSNeilBrown #ifdef CONFIG_SWAP
58545ebe71SKairui Song #include <linux/swapops.h> /* for swp_offset */
59014bb1deSNeilBrown #include <linux/blk_types.h> /* for bio_end_io_t */
60014bb1deSNeilBrown 
swp_cluster_offset(swp_entry_t entry)618578e0c0SKairui Song static inline unsigned int swp_cluster_offset(swp_entry_t entry)
628578e0c0SKairui Song {
638578e0c0SKairui Song 	return swp_offset(entry) % SWAPFILE_CLUSTER;
648578e0c0SKairui Song }
658578e0c0SKairui Song 
660fcf8ef4SKairui Song /*
670fcf8ef4SKairui Song  * Callers of all helpers below must ensure the entry, type, or offset is
680fcf8ef4SKairui Song  * valid, and protect the swap device with reference count or locks.
690fcf8ef4SKairui Song  */
__swap_type_to_info(int type)700fcf8ef4SKairui Song static inline struct swap_info_struct *__swap_type_to_info(int type)
710fcf8ef4SKairui Song {
720fcf8ef4SKairui Song 	struct swap_info_struct *si;
730fcf8ef4SKairui Song 
740fcf8ef4SKairui Song 	si = READ_ONCE(swap_info[type]); /* rcu_dereference() */
750fcf8ef4SKairui Song 	VM_WARN_ON_ONCE(percpu_ref_is_zero(&si->users)); /* race with swapoff */
760fcf8ef4SKairui Song 	return si;
770fcf8ef4SKairui Song }
780fcf8ef4SKairui Song 
__swap_entry_to_info(swp_entry_t entry)790fcf8ef4SKairui Song static inline struct swap_info_struct *__swap_entry_to_info(swp_entry_t entry)
800fcf8ef4SKairui Song {
810fcf8ef4SKairui Song 	return __swap_type_to_info(swp_type(entry));
820fcf8ef4SKairui Song }
830fcf8ef4SKairui Song 
__swap_offset_to_cluster(struct swap_info_struct * si,pgoff_t offset)840fcf8ef4SKairui Song static inline struct swap_cluster_info *__swap_offset_to_cluster(
854522aed4SKairui Song 		struct swap_info_struct *si, pgoff_t offset)
864522aed4SKairui Song {
870fcf8ef4SKairui Song 	VM_WARN_ON_ONCE(percpu_ref_is_zero(&si->users)); /* race with swapoff */
8845711d44SKairui Song 	VM_WARN_ON_ONCE(offset >= roundup(si->max, SWAPFILE_CLUSTER));
894522aed4SKairui Song 	return &si->cluster_info[offset / SWAPFILE_CLUSTER];
904522aed4SKairui Song }
914522aed4SKairui Song 
__swap_entry_to_cluster(swp_entry_t entry)928578e0c0SKairui Song static inline struct swap_cluster_info *__swap_entry_to_cluster(swp_entry_t entry)
938578e0c0SKairui Song {
948578e0c0SKairui Song 	return __swap_offset_to_cluster(__swap_entry_to_info(entry),
958578e0c0SKairui Song 					swp_offset(entry));
968578e0c0SKairui Song }
978578e0c0SKairui Song 
__swap_cluster_lock(struct swap_info_struct * si,unsigned long offset,bool irq)988578e0c0SKairui Song static __always_inline struct swap_cluster_info *__swap_cluster_lock(
998578e0c0SKairui Song 		struct swap_info_struct *si, unsigned long offset, bool irq)
1008578e0c0SKairui Song {
1018578e0c0SKairui Song 	struct swap_cluster_info *ci = __swap_offset_to_cluster(si, offset);
1028578e0c0SKairui Song 
1038b47299aSKairui Song 	/*
1048b47299aSKairui Song 	 * Nothing modifies swap cache in an IRQ context. All access to
1058b47299aSKairui Song 	 * swap cache is wrapped by swap_cache_* helpers, and swap cache
1068b47299aSKairui Song 	 * writeback is handled outside of IRQs. Swapin or swapout never
1078b47299aSKairui Song 	 * occurs in IRQ, and neither does in-place split or replace.
1088b47299aSKairui Song 	 *
1098b47299aSKairui Song 	 * Besides, modifying swap cache requires synchronization with
1108b47299aSKairui Song 	 * swap_map, which was never IRQ safe.
1118b47299aSKairui Song 	 */
1128b47299aSKairui Song 	VM_WARN_ON_ONCE(!in_task());
1138578e0c0SKairui Song 	VM_WARN_ON_ONCE(percpu_ref_is_zero(&si->users)); /* race with swapoff */
1148578e0c0SKairui Song 	if (irq)
1158578e0c0SKairui Song 		spin_lock_irq(&ci->lock);
1168578e0c0SKairui Song 	else
1178578e0c0SKairui Song 		spin_lock(&ci->lock);
1188578e0c0SKairui Song 	return ci;
1198578e0c0SKairui Song }
1208578e0c0SKairui Song 
1214522aed4SKairui Song /**
1224522aed4SKairui Song  * swap_cluster_lock - Lock and return the swap cluster of given offset.
1234522aed4SKairui Song  * @si: swap device the cluster belongs to.
1244522aed4SKairui Song  * @offset: the swap entry offset, pointing to a valid slot.
1254522aed4SKairui Song  *
1264522aed4SKairui Song  * Context: The caller must ensure the offset is in the valid range and
1274522aed4SKairui Song  * protect the swap device with reference count or locks.
1284522aed4SKairui Song  */
swap_cluster_lock(struct swap_info_struct * si,unsigned long offset)1294522aed4SKairui Song static inline struct swap_cluster_info *swap_cluster_lock(
1304522aed4SKairui Song 		struct swap_info_struct *si, unsigned long offset)
1314522aed4SKairui Song {
1328578e0c0SKairui Song 	return __swap_cluster_lock(si, offset, false);
1338578e0c0SKairui Song }
1344522aed4SKairui Song 
__swap_cluster_get_and_lock(const struct folio * folio,bool irq)1358578e0c0SKairui Song static inline struct swap_cluster_info *__swap_cluster_get_and_lock(
1368578e0c0SKairui Song 		const struct folio *folio, bool irq)
1378578e0c0SKairui Song {
1388578e0c0SKairui Song 	VM_WARN_ON_ONCE_FOLIO(!folio_test_locked(folio), folio);
1398578e0c0SKairui Song 	VM_WARN_ON_ONCE_FOLIO(!folio_test_swapcache(folio), folio);
1408578e0c0SKairui Song 	return __swap_cluster_lock(__swap_entry_to_info(folio->swap),
1418578e0c0SKairui Song 				   swp_offset(folio->swap), irq);
1428578e0c0SKairui Song }
1438578e0c0SKairui Song 
1448578e0c0SKairui Song /*
1458578e0c0SKairui Song  * swap_cluster_get_and_lock - Locks the cluster that holds a folio's entries.
1468578e0c0SKairui Song  * @folio: The folio.
1478578e0c0SKairui Song  *
1488578e0c0SKairui Song  * This locks and returns the swap cluster that contains a folio's swap
1498578e0c0SKairui Song  * entries. The swap entries of a folio are always in one single cluster.
1508578e0c0SKairui Song  * The folio has to be locked so its swap entries won't change and the
1518578e0c0SKairui Song  * cluster won't be freed.
1528578e0c0SKairui Song  *
1538578e0c0SKairui Song  * Context: Caller must ensure the folio is locked and in the swap cache.
1548578e0c0SKairui Song  * Return: Pointer to the swap cluster.
1558578e0c0SKairui Song  */
swap_cluster_get_and_lock(const struct folio * folio)1568578e0c0SKairui Song static inline struct swap_cluster_info *swap_cluster_get_and_lock(
1578578e0c0SKairui Song 		const struct folio *folio)
1588578e0c0SKairui Song {
1598578e0c0SKairui Song 	return __swap_cluster_get_and_lock(folio, false);
1608578e0c0SKairui Song }
1618578e0c0SKairui Song 
1628578e0c0SKairui Song /*
1638578e0c0SKairui Song  * swap_cluster_get_and_lock_irq - Locks the cluster that holds a folio's entries.
1648578e0c0SKairui Song  * @folio: The folio.
1658578e0c0SKairui Song  *
1668578e0c0SKairui Song  * Same as swap_cluster_get_and_lock but also disable IRQ.
1678578e0c0SKairui Song  *
1688578e0c0SKairui Song  * Context: Caller must ensure the folio is locked and in the swap cache.
1698578e0c0SKairui Song  * Return: Pointer to the swap cluster.
1708578e0c0SKairui Song  */
swap_cluster_get_and_lock_irq(const struct folio * folio)1718578e0c0SKairui Song static inline struct swap_cluster_info *swap_cluster_get_and_lock_irq(
1728578e0c0SKairui Song 		const struct folio *folio)
1738578e0c0SKairui Song {
1748578e0c0SKairui Song 	return __swap_cluster_get_and_lock(folio, true);
1754522aed4SKairui Song }
1764522aed4SKairui Song 
swap_cluster_unlock(struct swap_cluster_info * ci)1774522aed4SKairui Song static inline void swap_cluster_unlock(struct swap_cluster_info *ci)
1784522aed4SKairui Song {
1794522aed4SKairui Song 	spin_unlock(&ci->lock);
1804522aed4SKairui Song }
1814522aed4SKairui Song 
swap_cluster_unlock_irq(struct swap_cluster_info * ci)1828578e0c0SKairui Song static inline void swap_cluster_unlock_irq(struct swap_cluster_info *ci)
1838578e0c0SKairui Song {
1848578e0c0SKairui Song 	spin_unlock_irq(&ci->lock);
1858578e0c0SKairui Song }
1868578e0c0SKairui Song 
1870d6af9bcSKairui Song extern int swap_retry_table_alloc(swp_entry_t entry, gfp_t gfp);
1880d6af9bcSKairui Song 
18936976159SKairui Song /*
19036976159SKairui Song  * Below are the core routines for doing swap for a folio.
19136976159SKairui Song  * All helpers requires the folio to be locked, and a locked folio
19236976159SKairui Song  * in the swap cache pins the swap entries / slots allocated to the
19336976159SKairui Song  * folio, swap relies heavily on the swap cache and folio lock for
19436976159SKairui Song  * synchronization.
19536976159SKairui Song  *
19636976159SKairui Song  * folio_alloc_swap(): the entry point for a folio to be swapped
19736976159SKairui Song  * out. It allocates swap slots and pins the slots with swap cache.
198*a0f79916SKairui Song  * The slots start with a swap count of zero. The slots are pinned
199*a0f79916SKairui Song  * by swap cache reference which doesn't contribute to swap count.
20036976159SKairui Song  *
20136976159SKairui Song  * folio_dup_swap(): increases the swap count of a folio, usually
20236976159SKairui Song  * during it gets unmapped and a swap entry is installed to replace
20336976159SKairui Song  * it (e.g., swap entry in page table). A swap slot with swap
204*a0f79916SKairui Song  * count == 0 can only be increased by this helper.
20536976159SKairui Song  *
20636976159SKairui Song  * folio_put_swap(): does the opposite thing of folio_dup_swap().
20736976159SKairui Song  */
20836976159SKairui Song int folio_alloc_swap(struct folio *folio);
20936976159SKairui Song int folio_dup_swap(struct folio *folio, struct page *subpage);
21036976159SKairui Song void folio_put_swap(struct folio *folio, struct page *subpage);
21136976159SKairui Song 
212d3852f96SKairui Song /* For internal use */
2130d6af9bcSKairui Song extern void __swap_cluster_free_entries(struct swap_info_struct *si,
214d3852f96SKairui Song 					struct swap_cluster_info *ci,
2150d6af9bcSKairui Song 					unsigned int ci_off, unsigned int nr_pages);
216d3852f96SKairui Song 
217014bb1deSNeilBrown /* linux/mm/page_io.c */
218e1209d3aSNeilBrown int sio_pool_init(void);
2195169b844SNeilBrown struct swap_iocb;
220b2d1f38bSYosry Ahmed void swap_read_folio(struct folio *folio, struct swap_iocb **plug);
2215169b844SNeilBrown void __swap_read_unplug(struct swap_iocb *plug);
swap_read_unplug(struct swap_iocb * plug)2225169b844SNeilBrown static inline void swap_read_unplug(struct swap_iocb *plug)
2235169b844SNeilBrown {
2245169b844SNeilBrown 	if (unlikely(plug))
2255169b844SNeilBrown 		__swap_read_unplug(plug);
2265169b844SNeilBrown }
2272282679fSNeilBrown void swap_write_unplug(struct swap_iocb *sio);
228624043dbSChristoph Hellwig int swap_writeout(struct folio *folio, struct swap_iocb **swap_plug);
2292ba8ffceSChristoph Hellwig void __swap_writepage(struct folio *folio, struct swap_iocb **swap_plug);
230014bb1deSNeilBrown 
231014bb1deSNeilBrown /* linux/mm/swap_state.c */
232a0f3c084Srobin.kuo extern struct address_space swap_space __read_mostly;
swap_address_space(swp_entry_t entry)2338578e0c0SKairui Song static inline struct address_space *swap_address_space(swp_entry_t entry)
2348578e0c0SKairui Song {
2358578e0c0SKairui Song 	return &swap_space;
2368578e0c0SKairui Song }
237014bb1deSNeilBrown 
238545ebe71SKairui Song /*
239545ebe71SKairui Song  * Return the swap device position of the swap entry.
240545ebe71SKairui Song  */
swap_dev_pos(swp_entry_t entry)241545ebe71SKairui Song static inline loff_t swap_dev_pos(swp_entry_t entry)
242545ebe71SKairui Song {
243545ebe71SKairui Song 	return ((loff_t)swp_offset(entry)) << PAGE_SHIFT;
244545ebe71SKairui Song }
245545ebe71SKairui Song 
246ae38eb21SKairui Song /**
247ae38eb21SKairui Song  * folio_matches_swap_entry - Check if a folio matches a given swap entry.
248ae38eb21SKairui Song  * @folio: The folio.
249ae38eb21SKairui Song  * @entry: The swap entry to check against.
250ae38eb21SKairui Song  *
251ae38eb21SKairui Song  * Context: The caller should have the folio locked to ensure it's stable
252ae38eb21SKairui Song  * and nothing will move it in or out of the swap cache.
253ae38eb21SKairui Song  * Return: true or false.
254ae38eb21SKairui Song  */
folio_matches_swap_entry(const struct folio * folio,swp_entry_t entry)255ae38eb21SKairui Song static inline bool folio_matches_swap_entry(const struct folio *folio,
256ae38eb21SKairui Song 					    swp_entry_t entry)
257ae38eb21SKairui Song {
258ae38eb21SKairui Song 	swp_entry_t folio_entry = folio->swap;
259ae38eb21SKairui Song 	long nr_pages = folio_nr_pages(folio);
260ae38eb21SKairui Song 
261ae38eb21SKairui Song 	VM_WARN_ON_ONCE_FOLIO(!folio_test_locked(folio), folio);
262ae38eb21SKairui Song 	if (!folio_test_swapcache(folio))
263ae38eb21SKairui Song 		return false;
264ae38eb21SKairui Song 	VM_WARN_ON_ONCE_FOLIO(!IS_ALIGNED(folio_entry.val, nr_pages), folio);
265ae38eb21SKairui Song 	return folio_entry.val == round_down(entry.val, nr_pages);
266ae38eb21SKairui Song }
267ae38eb21SKairui Song 
268fd8d4f86SKairui Song /*
269fd8d4f86SKairui Song  * All swap cache helpers below require the caller to ensure the swap entries
27062451ae3SKevin Lourenco  * used are valid and stabilize the device by any of the following ways:
271fd8d4f86SKairui Song  * - Hold a reference by get_swap_device(): this ensures a single entry is
272fd8d4f86SKairui Song  *   valid and increases the swap device's refcount.
273fd8d4f86SKairui Song  * - Locking a folio in the swap cache: this ensures the folio's swap entries
274fd8d4f86SKairui Song  *   are valid and pinned, also implies reference to the device.
275fd8d4f86SKairui Song  * - Locking anything referencing the swap entry: e.g. PTL that protects
276fd8d4f86SKairui Song  *   swap entries in the page table, similar to locking swap cache folio.
277fd8d4f86SKairui Song  * - See the comment of get_swap_device() for more complex usage.
278fd8d4f86SKairui Song  */
2794984d746SKairui Song bool swap_cache_has_folio(swp_entry_t entry);
280f2812461SKairui Song struct folio *swap_cache_get_folio(swp_entry_t entry);
281fd8d4f86SKairui Song void *swap_cache_get_shadow(swp_entry_t entry);
282fd8d4f86SKairui Song void swap_cache_del_folio(struct folio *folio);
283d7cf0d54SKairui Song struct folio *swap_cache_alloc_folio(swp_entry_t entry, gfp_t gfp_flags,
284d7cf0d54SKairui Song 				     struct mempolicy *mpol, pgoff_t ilx,
285de85024bSKairui Song 				     bool *alloced);
2868578e0c0SKairui Song /* Below helpers require the caller to lock and pass in the swap cluster. */
287270f0951SKairui Song void __swap_cache_add_folio(struct swap_cluster_info *ci,
288270f0951SKairui Song 			    struct folio *folio, swp_entry_t entry);
2898578e0c0SKairui Song void __swap_cache_del_folio(struct swap_cluster_info *ci,
2908578e0c0SKairui Song 			    struct folio *folio, swp_entry_t entry, void *shadow);
2918578e0c0SKairui Song void __swap_cache_replace_folio(struct swap_cluster_info *ci,
2928578e0c0SKairui Song 				struct folio *old, struct folio *new);
293fd8d4f86SKairui Song 
294fd8d4f86SKairui Song void show_swap_cache_info(void);
295fd8d4f86SKairui Song void swapcache_clear(struct swap_info_struct *si, swp_entry_t entry, int nr);
2966e03492eSMatthew Wilcox (Oracle) struct folio *read_swap_cache_async(swp_entry_t entry, gfp_t gfp_mask,
2976e03492eSMatthew Wilcox (Oracle) 		struct vm_area_struct *vma, unsigned long addr,
2985169b844SNeilBrown 		struct swap_iocb **plug);
299a4575c41SMatthew Wilcox (Oracle) struct folio *swap_cluster_readahead(swp_entry_t entry, gfp_t flag,
300ddc1a5cbSHugh Dickins 		struct mempolicy *mpol, pgoff_t ilx);
30194dc8bffSMatthew Wilcox (Oracle) struct folio *swapin_readahead(swp_entry_t entry, gfp_t flag,
302014bb1deSNeilBrown 		struct vm_fault *vmf);
303f1879e8aSKairui Song struct folio *swapin_folio(swp_entry_t entry, struct folio *folio);
304f2812461SKairui Song void swap_update_readahead(struct folio *folio, struct vm_area_struct *vma,
305f2812461SKairui Song 			   unsigned long addr);
306014bb1deSNeilBrown 
folio_swap_flags(struct folio * folio)307b98c359fSMatthew Wilcox (Oracle) static inline unsigned int folio_swap_flags(struct folio *folio)
308d791ea67SNeilBrown {
3090fcf8ef4SKairui Song 	return __swap_entry_to_info(folio->swap)->flags;
310d791ea67SNeilBrown }
3119d57090eSBarry Song 
3129d57090eSBarry Song /*
3139d57090eSBarry Song  * Return the count of contiguous swap entries that share the same
3149d57090eSBarry Song  * zeromap status as the starting entry. If is_zeromap is not NULL,
3159d57090eSBarry Song  * it will return the zeromap status of the starting entry.
3169d57090eSBarry Song  */
swap_zeromap_batch(swp_entry_t entry,int max_nr,bool * is_zeromap)3179d57090eSBarry Song static inline int swap_zeromap_batch(swp_entry_t entry, int max_nr,
3189d57090eSBarry Song 		bool *is_zeromap)
3199d57090eSBarry Song {
3200fcf8ef4SKairui Song 	struct swap_info_struct *sis = __swap_entry_to_info(entry);
3219d57090eSBarry Song 	unsigned long start = swp_offset(entry);
3229d57090eSBarry Song 	unsigned long end = start + max_nr;
3239d57090eSBarry Song 	bool first_bit;
3249d57090eSBarry Song 
3259d57090eSBarry Song 	first_bit = test_bit(start, sis->zeromap);
3269d57090eSBarry Song 	if (is_zeromap)
3279d57090eSBarry Song 		*is_zeromap = first_bit;
3289d57090eSBarry Song 
3299d57090eSBarry Song 	if (max_nr <= 1)
3309d57090eSBarry Song 		return max_nr;
3319d57090eSBarry Song 	if (first_bit)
3329d57090eSBarry Song 		return find_next_zero_bit(sis->zeromap, end, start) - start;
3339d57090eSBarry Song 	else
3349d57090eSBarry Song 		return find_next_bit(sis->zeromap, end, start) - start;
3359d57090eSBarry Song }
3369d57090eSBarry Song 
non_swapcache_batch(swp_entry_t entry,int max_nr)337a05dd8aeSKairui Song static inline int non_swapcache_batch(swp_entry_t entry, int max_nr)
338a05dd8aeSKairui Song {
339a05dd8aeSKairui Song 	int i;
340a05dd8aeSKairui Song 
341a05dd8aeSKairui Song 	/*
342a05dd8aeSKairui Song 	 * While allocating a large folio and doing mTHP swapin, we need to
343a05dd8aeSKairui Song 	 * ensure all entries are not cached, otherwise, the mTHP folio will
344a05dd8aeSKairui Song 	 * be in conflict with the folio in swap cache.
345a05dd8aeSKairui Song 	 */
346a05dd8aeSKairui Song 	for (i = 0; i < max_nr; i++) {
3474984d746SKairui Song 		if (swap_cache_has_folio(entry))
348a05dd8aeSKairui Song 			return i;
3494984d746SKairui Song 		entry.val++;
350a05dd8aeSKairui Song 	}
351a05dd8aeSKairui Song 
352a05dd8aeSKairui Song 	return i;
353a05dd8aeSKairui Song }
354a05dd8aeSKairui Song 
355014bb1deSNeilBrown #else /* CONFIG_SWAP */
3565169b844SNeilBrown struct swap_iocb;
swap_cluster_lock(struct swap_info_struct * si,pgoff_t offset,bool irq)3578578e0c0SKairui Song static inline struct swap_cluster_info *swap_cluster_lock(
3588578e0c0SKairui Song 	struct swap_info_struct *si, pgoff_t offset, bool irq)
3598578e0c0SKairui Song {
3608578e0c0SKairui Song 	return NULL;
3618578e0c0SKairui Song }
3628578e0c0SKairui Song 
swap_cluster_get_and_lock(struct folio * folio)3638578e0c0SKairui Song static inline struct swap_cluster_info *swap_cluster_get_and_lock(
3648578e0c0SKairui Song 		struct folio *folio)
3658578e0c0SKairui Song {
3668578e0c0SKairui Song 	return NULL;
3678578e0c0SKairui Song }
3688578e0c0SKairui Song 
swap_cluster_get_and_lock_irq(struct folio * folio)3698578e0c0SKairui Song static inline struct swap_cluster_info *swap_cluster_get_and_lock_irq(
3708578e0c0SKairui Song 		struct folio *folio)
3718578e0c0SKairui Song {
3728578e0c0SKairui Song 	return NULL;
3738578e0c0SKairui Song }
3748578e0c0SKairui Song 
swap_cluster_unlock(struct swap_cluster_info * ci)3758578e0c0SKairui Song static inline void swap_cluster_unlock(struct swap_cluster_info *ci)
3768578e0c0SKairui Song {
3778578e0c0SKairui Song }
3788578e0c0SKairui Song 
swap_cluster_unlock_irq(struct swap_cluster_info * ci)3798578e0c0SKairui Song static inline void swap_cluster_unlock_irq(struct swap_cluster_info *ci)
3808578e0c0SKairui Song {
3818578e0c0SKairui Song }
3828578e0c0SKairui Song 
__swap_entry_to_info(swp_entry_t entry)3830fcf8ef4SKairui Song static inline struct swap_info_struct *__swap_entry_to_info(swp_entry_t entry)
3840fcf8ef4SKairui Song {
3850fcf8ef4SKairui Song 	return NULL;
3860fcf8ef4SKairui Song }
3870fcf8ef4SKairui Song 
folio_alloc_swap(struct folio * folio)38836976159SKairui Song static inline int folio_alloc_swap(struct folio *folio)
38936976159SKairui Song {
39036976159SKairui Song 	return -EINVAL;
39136976159SKairui Song }
39236976159SKairui Song 
folio_dup_swap(struct folio * folio,struct page * page)39336976159SKairui Song static inline int folio_dup_swap(struct folio *folio, struct page *page)
39436976159SKairui Song {
39536976159SKairui Song 	return -EINVAL;
39636976159SKairui Song }
39736976159SKairui Song 
folio_put_swap(struct folio * folio,struct page * page)39836976159SKairui Song static inline void folio_put_swap(struct folio *folio, struct page *page)
39936976159SKairui Song {
40036976159SKairui Song }
40136976159SKairui Song 
swap_read_folio(struct folio * folio,struct swap_iocb ** plug)402b2d1f38bSYosry Ahmed static inline void swap_read_folio(struct folio *folio, struct swap_iocb **plug)
403014bb1deSNeilBrown {
404014bb1deSNeilBrown }
40536976159SKairui Song 
swap_write_unplug(struct swap_iocb * sio)4062282679fSNeilBrown static inline void swap_write_unplug(struct swap_iocb *sio)
4072282679fSNeilBrown {
4082282679fSNeilBrown }
409014bb1deSNeilBrown 
swap_address_space(swp_entry_t entry)410014bb1deSNeilBrown static inline struct address_space *swap_address_space(swp_entry_t entry)
411014bb1deSNeilBrown {
412014bb1deSNeilBrown 	return NULL;
413014bb1deSNeilBrown }
414014bb1deSNeilBrown 
folio_matches_swap_entry(const struct folio * folio,swp_entry_t entry)415ae38eb21SKairui Song static inline bool folio_matches_swap_entry(const struct folio *folio, swp_entry_t entry)
416ae38eb21SKairui Song {
417ae38eb21SKairui Song 	return false;
418ae38eb21SKairui Song }
419ae38eb21SKairui Song 
show_swap_cache_info(void)420014bb1deSNeilBrown static inline void show_swap_cache_info(void)
421014bb1deSNeilBrown {
422014bb1deSNeilBrown }
423014bb1deSNeilBrown 
swap_cluster_readahead(swp_entry_t entry,gfp_t gfp_mask,struct mempolicy * mpol,pgoff_t ilx)424a4575c41SMatthew Wilcox (Oracle) static inline struct folio *swap_cluster_readahead(swp_entry_t entry,
425ddc1a5cbSHugh Dickins 			gfp_t gfp_mask, struct mempolicy *mpol, pgoff_t ilx)
426014bb1deSNeilBrown {
427014bb1deSNeilBrown 	return NULL;
428014bb1deSNeilBrown }
429014bb1deSNeilBrown 
swapin_readahead(swp_entry_t swp,gfp_t gfp_mask,struct vm_fault * vmf)43094dc8bffSMatthew Wilcox (Oracle) static inline struct folio *swapin_readahead(swp_entry_t swp, gfp_t gfp_mask,
431014bb1deSNeilBrown 			struct vm_fault *vmf)
432014bb1deSNeilBrown {
433014bb1deSNeilBrown 	return NULL;
434014bb1deSNeilBrown }
435014bb1deSNeilBrown 
swapin_folio(swp_entry_t entry,struct folio * folio)436f1879e8aSKairui Song static inline struct folio *swapin_folio(swp_entry_t entry, struct folio *folio)
437f1879e8aSKairui Song {
438f1879e8aSKairui Song 	return NULL;
439f1879e8aSKairui Song }
440f1879e8aSKairui Song 
swap_update_readahead(struct folio * folio,struct vm_area_struct * vma,unsigned long addr)441f2812461SKairui Song static inline void swap_update_readahead(struct folio *folio,
442f2812461SKairui Song 		struct vm_area_struct *vma, unsigned long addr)
443f2812461SKairui Song {
444f2812461SKairui Song }
445f2812461SKairui Song 
swap_writeout(struct folio * folio,struct swap_iocb ** swap_plug)446624043dbSChristoph Hellwig static inline int swap_writeout(struct folio *folio,
447624043dbSChristoph Hellwig 		struct swap_iocb **swap_plug)
448014bb1deSNeilBrown {
449014bb1deSNeilBrown 	return 0;
450014bb1deSNeilBrown }
451014bb1deSNeilBrown 
swap_retry_table_alloc(swp_entry_t entry,gfp_t gfp)4520d6af9bcSKairui Song static inline int swap_retry_table_alloc(swp_entry_t entry, gfp_t gfp)
4530d6af9bcSKairui Song {
4540d6af9bcSKairui Song 	return -EINVAL;
4550d6af9bcSKairui Song }
4560d6af9bcSKairui Song 
swap_cache_has_folio(swp_entry_t entry)4574984d746SKairui Song static inline bool swap_cache_has_folio(swp_entry_t entry)
4584984d746SKairui Song {
4594984d746SKairui Song 	return false;
4604984d746SKairui Song }
4614984d746SKairui Song 
swap_cache_get_folio(swp_entry_t entry)462f2812461SKairui Song static inline struct folio *swap_cache_get_folio(swp_entry_t entry)
463c9edc242SMatthew Wilcox (Oracle) {
464c9edc242SMatthew Wilcox (Oracle) 	return NULL;
465c9edc242SMatthew Wilcox (Oracle) }
466c9edc242SMatthew Wilcox (Oracle) 
swap_cache_get_shadow(swp_entry_t entry)467fd8d4f86SKairui Song static inline void *swap_cache_get_shadow(swp_entry_t entry)
468014bb1deSNeilBrown {
469014bb1deSNeilBrown 	return NULL;
470014bb1deSNeilBrown }
471014bb1deSNeilBrown 
swap_cache_del_folio(struct folio * folio)472fd8d4f86SKairui Song static inline void swap_cache_del_folio(struct folio *folio)
473014bb1deSNeilBrown {
474014bb1deSNeilBrown }
475014bb1deSNeilBrown 
__swap_cache_del_folio(struct swap_cluster_info * ci,struct folio * folio,swp_entry_t entry,void * shadow)4768578e0c0SKairui Song static inline void __swap_cache_del_folio(struct swap_cluster_info *ci,
4778578e0c0SKairui Song 		struct folio *folio, swp_entry_t entry, void *shadow)
478014bb1deSNeilBrown {
479014bb1deSNeilBrown }
480014bb1deSNeilBrown 
__swap_cache_replace_folio(struct swap_cluster_info * ci,struct folio * old,struct folio * new)4818578e0c0SKairui Song static inline void __swap_cache_replace_folio(struct swap_cluster_info *ci,
4828578e0c0SKairui Song 		struct folio *old, struct folio *new)
483094dc8b0SKairui Song {
484094dc8b0SKairui Song }
485094dc8b0SKairui Song 
folio_swap_flags(struct folio * folio)486b98c359fSMatthew Wilcox (Oracle) static inline unsigned int folio_swap_flags(struct folio *folio)
487d791ea67SNeilBrown {
488d791ea67SNeilBrown 	return 0;
489d791ea67SNeilBrown }
4909d57090eSBarry Song 
swap_zeromap_batch(swp_entry_t entry,int max_nr,bool * has_zeromap)4919d57090eSBarry Song static inline int swap_zeromap_batch(swp_entry_t entry, int max_nr,
4929d57090eSBarry Song 		bool *has_zeromap)
4939d57090eSBarry Song {
4949d57090eSBarry Song 	return 0;
4959d57090eSBarry Song }
4969d57090eSBarry Song 
non_swapcache_batch(swp_entry_t entry,int max_nr)497a05dd8aeSKairui Song static inline int non_swapcache_batch(swp_entry_t entry, int max_nr)
498a05dd8aeSKairui Song {
499a05dd8aeSKairui Song 	return 0;
500a05dd8aeSKairui Song }
501014bb1deSNeilBrown #endif /* CONFIG_SWAP */
502014bb1deSNeilBrown #endif /* _MM_SWAP_H */
503