File Index
Files and directories
Sign in
FILE

migrate.h

File preview with syntax highlighting.

linux-6.19.14/include/linux/migrate.h C
  1/* SPDX-License-Identifier: GPL-2.0 */
  2#ifndef _LINUX_MIGRATE_H
  3#define _LINUX_MIGRATE_H
  4
  5#include <linux/mm.h>
  6#include <linux/mempolicy.h>
  7#include <linux/migrate_mode.h>
  8#include <linux/hugetlb.h>
  9
 10typedef struct folio *new_folio_t(struct folio *folio, unsigned long private);
 11typedef void free_folio_t(struct folio *folio, unsigned long private);
 12
 13struct migration_target_control;
 14
 15/**
 16 * struct movable_operations - Driver page migration
 17 * @isolate_page:
 18 * The VM calls this function to prepare the page to be moved.  The page
 19 * is locked and the driver should not unlock it.  The driver should
 20 * return ``true`` if the page is movable and ``false`` if it is not
 21 * currently movable.  After this function returns, the VM uses the
 22 * page->lru field, so the driver must preserve any information which
 23 * is usually stored here.
 24 *
 25 * @migrate_page:
 26 * After isolation, the VM calls this function with the isolated
 27 * @src page.  The driver should copy the contents of the
 28 * @src page to the @dst page and set up the fields of @dst page.
 29 * Both pages are locked.
 30 * If page migration is successful, the driver should return 0.
 31 * If the driver cannot migrate the page at the moment, it can return
 32 * -EAGAIN.  The VM interprets this as a temporary migration failure and
 33 * will retry it later.  Any other error value is a permanent migration
 34 * failure and migration will not be retried.
 35 * The driver shouldn't touch the @src->lru field while in the
 36 * migrate_page() function.  It may write to @dst->lru.
 37 *
 38 * @putback_page:
 39 * If migration fails on the isolated page, the VM informs the driver
 40 * that the page is no longer a candidate for migration by calling
 41 * this function.  The driver should put the isolated page back into
 42 * its own data structure.
 43 */
 44struct movable_operations {
 45	bool (*isolate_page)(struct page *, isolate_mode_t);
 46	int (*migrate_page)(struct page *dst, struct page *src,
 47			enum migrate_mode);
 48	void (*putback_page)(struct page *);
 49};
 50
 51/* Defined in mm/debug.c: */
 52extern const char *migrate_reason_names[MR_TYPES];
 53
 54#ifdef CONFIG_MIGRATION
 55
 56void putback_movable_pages(struct list_head *l);
 57int migrate_folio(struct address_space *mapping, struct folio *dst,
 58		struct folio *src, enum migrate_mode mode);
 59int migrate_pages(struct list_head *l, new_folio_t new, free_folio_t free,
 60		  unsigned long private, enum migrate_mode mode, int reason,
 61		  unsigned int *ret_succeeded);
 62struct folio *alloc_migration_target(struct folio *src, unsigned long private);
 63bool isolate_movable_ops_page(struct page *page, isolate_mode_t mode);
 64bool isolate_folio_to_list(struct folio *folio, struct list_head *list);
 65
 66int migrate_huge_page_move_mapping(struct address_space *mapping,
 67		struct folio *dst, struct folio *src);
 68void softleaf_entry_wait_on_locked(softleaf_t entry, spinlock_t *ptl)
 69		__releases(ptl);
 70void folio_migrate_flags(struct folio *newfolio, struct folio *folio);
 71int folio_migrate_mapping(struct address_space *mapping,
 72		struct folio *newfolio, struct folio *folio, int extra_count);
 73int set_movable_ops(const struct movable_operations *ops, enum pagetype type);
 74
 75#else
 76
 77static inline void putback_movable_pages(struct list_head *l) {}
 78static inline int migrate_pages(struct list_head *l, new_folio_t new,
 79		free_folio_t free, unsigned long private,
 80		enum migrate_mode mode, int reason, unsigned int *ret_succeeded)
 81	{ return -ENOSYS; }
 82static inline struct folio *alloc_migration_target(struct folio *src,
 83		unsigned long private)
 84	{ return NULL; }
 85static inline bool isolate_movable_ops_page(struct page *page, isolate_mode_t mode)
 86	{ return false; }
 87static inline bool isolate_folio_to_list(struct folio *folio, struct list_head *list)
 88	{ return false; }
 89
 90static inline int migrate_huge_page_move_mapping(struct address_space *mapping,
 91				  struct folio *dst, struct folio *src)
 92{
 93	return -ENOSYS;
 94}
 95static inline int set_movable_ops(const struct movable_operations *ops, enum pagetype type)
 96{
 97	return -ENOSYS;
 98}
 99
100static inline void softleaf_entry_wait_on_locked(softleaf_t entry, spinlock_t *ptl)
101	__releases(ptl)
102{
103	WARN_ON_ONCE(1);
104
105	spin_unlock(ptl);
106}
107
108#endif /* CONFIG_MIGRATION */
109
110#ifdef CONFIG_NUMA_BALANCING
111int migrate_misplaced_folio_prepare(struct folio *folio,
112		struct vm_area_struct *vma, int node);
113int migrate_misplaced_folio(struct folio *folio, int node);
114#else
115static inline int migrate_misplaced_folio_prepare(struct folio *folio,
116		struct vm_area_struct *vma, int node)
117{
118	return -EAGAIN; /* can't migrate now */
119}
120static inline int migrate_misplaced_folio(struct folio *folio, int node)
121{
122	return -EAGAIN; /* can't migrate now */
123}
124#endif /* CONFIG_NUMA_BALANCING */
125
126#ifdef CONFIG_MIGRATION
127
128/*
129 * Watch out for PAE architecture, which has an unsigned long, and might not
130 * have enough bits to store all physical address and flags. So far we have
131 * enough room for all our flags.
132 */
133#define MIGRATE_PFN_VALID	(1UL << 0)
134#define MIGRATE_PFN_MIGRATE	(1UL << 1)
135#define MIGRATE_PFN_WRITE	(1UL << 3)
136#define MIGRATE_PFN_COMPOUND	(1UL << 4)
137#define MIGRATE_PFN_SHIFT	6
138
139static inline struct page *migrate_pfn_to_page(unsigned long mpfn)
140{
141	if (!(mpfn & MIGRATE_PFN_VALID))
142		return NULL;
143	return pfn_to_page(mpfn >> MIGRATE_PFN_SHIFT);
144}
145
146static inline unsigned long migrate_pfn(unsigned long pfn)
147{
148	return (pfn << MIGRATE_PFN_SHIFT) | MIGRATE_PFN_VALID;
149}
150
151enum migrate_vma_direction {
152	MIGRATE_VMA_SELECT_SYSTEM = 1 << 0,
153	MIGRATE_VMA_SELECT_DEVICE_PRIVATE = 1 << 1,
154	MIGRATE_VMA_SELECT_DEVICE_COHERENT = 1 << 2,
155	MIGRATE_VMA_SELECT_COMPOUND = 1 << 3,
156};
157
158struct migrate_vma {
159	struct vm_area_struct	*vma;
160	/*
161	 * Both src and dst array must be big enough for
162	 * (end - start) >> PAGE_SHIFT entries.
163	 *
164	 * The src array must not be modified by the caller after
165	 * migrate_vma_setup(), and must not change the dst array after
166	 * migrate_vma_pages() returns.
167	 */
168	unsigned long		*dst;
169	unsigned long		*src;
170	unsigned long		cpages;
171	unsigned long		npages;
172	unsigned long		start;
173	unsigned long		end;
174
175	/*
176	 * Set to the owner value also stored in page_pgmap(page)->owner
177	 * for migrating out of device private memory. The flags also need to
178	 * be set to MIGRATE_VMA_SELECT_DEVICE_PRIVATE.
179	 * The caller should always set this field when using mmu notifier
180	 * callbacks to avoid device MMU invalidations for device private
181	 * pages that are not being migrated.
182	 */
183	void			*pgmap_owner;
184	unsigned long		flags;
185
186	/*
187	 * Set to vmf->page if this is being called to migrate a page as part of
188	 * a migrate_to_ram() callback.
189	 */
190	struct page		*fault_page;
191};
192
193int migrate_vma_setup(struct migrate_vma *args);
194void migrate_vma_pages(struct migrate_vma *migrate);
195void migrate_vma_finalize(struct migrate_vma *migrate);
196int migrate_device_range(unsigned long *src_pfns, unsigned long start,
197			unsigned long npages);
198int migrate_device_pfns(unsigned long *src_pfns, unsigned long npages);
199void migrate_device_pages(unsigned long *src_pfns, unsigned long *dst_pfns,
200			unsigned long npages);
201void migrate_device_finalize(unsigned long *src_pfns,
202			unsigned long *dst_pfns, unsigned long npages);
203
204#endif /* CONFIG_MIGRATION */
205
206#endif /* _LINUX_MIGRATE_H */
~/ Read-only file preview.