migrate.h 4.5 KB
Newer Older
C
Christoph Lameter 已提交
1 2 3 4
#ifndef _LINUX_MIGRATE_H
#define _LINUX_MIGRATE_H

#include <linux/mm.h>
5
#include <linux/mempolicy.h>
6
#include <linux/migrate_mode.h>
7
#include <linux/hugetlb.h>
C
Christoph Lameter 已提交
8

9 10 11
typedef struct page *new_page_t(struct page *page, unsigned long private,
				int **reason);
typedef void free_page_t(struct page *page, unsigned long private);
12

13 14 15 16 17 18
/*
 * Return values from addresss_space_operations.migratepage():
 * - negative errno on page migration failure;
 * - zero on page migration success;
 */
#define MIGRATEPAGE_SUCCESS		0
19

20 21 22 23 24 25
enum migrate_reason {
	MR_COMPACTION,
	MR_MEMORY_FAILURE,
	MR_MEMORY_HOTPLUG,
	MR_SYSCALL,		/* also applies to cpusets */
	MR_MEMPOLICY_MBIND,
26
	MR_NUMA_MISPLACED,
27 28
	MR_CMA,
	MR_TYPES
29
};
30

31 32 33
/* In mm/debug.c; also keep sync with include/trace/events/migrate.h */
extern char *migrate_reason_names[MR_TYPES];

34 35 36
static inline struct page *new_page_nodemask(struct page *page,
				int preferred_nid, nodemask_t *nodemask)
{
37
	gfp_t gfp_mask = GFP_USER | __GFP_MOVABLE | __GFP_RETRY_MAYFAIL;
38 39
	unsigned int order = 0;
	struct page *new_page = NULL;
40 41 42

	if (PageHuge(page))
		return alloc_huge_page_nodemask(page_hstate(compound_head(page)),
43
				preferred_nid, nodemask);
44

45 46 47 48 49
	if (thp_migration_supported() && PageTransHuge(page)) {
		order = HPAGE_PMD_ORDER;
		gfp_mask |= GFP_TRANSHUGE;
	}

50 51 52
	if (PageHighMem(page) || (zone_idx(page_zone(page)) == ZONE_MOVABLE))
		gfp_mask |= __GFP_HIGHMEM;

53 54 55 56 57 58 59
	new_page = __alloc_pages_nodemask(gfp_mask, order,
				preferred_nid, nodemask);

	if (new_page && PageTransHuge(page))
		prep_transhuge_page(new_page);

	return new_page;
60 61
}

62
#ifdef CONFIG_MIGRATION
63

64
extern void putback_movable_pages(struct list_head *l);
65 66 67
extern int migrate_page(struct address_space *mapping,
			struct page *newpage, struct page *page,
			enum migrate_mode mode);
68
extern int migrate_pages(struct list_head *l, new_page_t new, free_page_t free,
69
		unsigned long private, enum migrate_mode mode, int reason);
70
extern int isolate_movable_page(struct page *page, isolate_mode_t mode);
71
extern void putback_movable_page(struct page *page);
72

C
Christoph Lameter 已提交
73
extern int migrate_prep(void);
74
extern int migrate_prep_local(void);
N
Naoya Horiguchi 已提交
75 76 77
extern void migrate_page_copy(struct page *newpage, struct page *page);
extern int migrate_huge_page_move_mapping(struct address_space *mapping,
				  struct page *newpage, struct page *page);
78 79
extern int migrate_page_move_mapping(struct address_space *mapping,
		struct page *newpage, struct page *page,
80 81
		struct buffer_head *head, enum migrate_mode mode,
		int extra_count);
C
Christoph Lameter 已提交
82
#else
83

84
static inline void putback_movable_pages(struct list_head *l) {}
85 86 87
static inline int migrate_pages(struct list_head *l, new_page_t new,
		free_page_t free, unsigned long private, enum migrate_mode mode,
		int reason)
88
	{ return -ENOSYS; }
89 90
static inline int isolate_movable_page(struct page *page, isolate_mode_t mode)
	{ return -EBUSY; }
91

C
Christoph Lameter 已提交
92
static inline int migrate_prep(void) { return -ENOSYS; }
93
static inline int migrate_prep_local(void) { return -ENOSYS; }
C
Christoph Lameter 已提交
94

N
Naoya Horiguchi 已提交
95 96 97
static inline void migrate_page_copy(struct page *newpage,
				     struct page *page) {}

98
static inline int migrate_huge_page_move_mapping(struct address_space *mapping,
N
Naoya Horiguchi 已提交
99 100 101 102 103
				  struct page *newpage, struct page *page)
{
	return -ENOSYS;
}

C
Christoph Lameter 已提交
104
#endif /* CONFIG_MIGRATION */
105

106 107 108 109 110 111 112 113 114 115 116 117 118 119 120
#ifdef CONFIG_COMPACTION
extern int PageMovable(struct page *page);
extern void __SetPageMovable(struct page *page, struct address_space *mapping);
extern void __ClearPageMovable(struct page *page);
#else
static inline int PageMovable(struct page *page) { return 0; };
static inline void __SetPageMovable(struct page *page,
				struct address_space *mapping)
{
}
static inline void __ClearPageMovable(struct page *page)
{
}
#endif

121
#ifdef CONFIG_NUMA_BALANCING
122
extern bool pmd_trans_migrating(pmd_t pmd);
123 124
extern int migrate_misplaced_page(struct page *page,
				  struct vm_area_struct *vma, int node);
125
#else
126 127 128 129
static inline bool pmd_trans_migrating(pmd_t pmd)
{
	return false;
}
130 131
static inline int migrate_misplaced_page(struct page *page,
					 struct vm_area_struct *vma, int node)
132 133 134
{
	return -EAGAIN; /* can't migrate now */
}
135
#endif /* CONFIG_NUMA_BALANCING */
136

137 138 139 140 141 142 143
#if defined(CONFIG_NUMA_BALANCING) && defined(CONFIG_TRANSPARENT_HUGEPAGE)
extern int migrate_misplaced_transhuge_page(struct mm_struct *mm,
			struct vm_area_struct *vma,
			pmd_t *pmd, pmd_t entry,
			unsigned long address,
			struct page *page, int node);
#else
144 145 146 147 148 149 150 151
static inline int migrate_misplaced_transhuge_page(struct mm_struct *mm,
			struct vm_area_struct *vma,
			pmd_t *pmd, pmd_t entry,
			unsigned long address,
			struct page *page, int node)
{
	return -EAGAIN;
}
152
#endif /* CONFIG_NUMA_BALANCING && CONFIG_TRANSPARENT_HUGEPAGE*/
153

C
Christoph Lameter 已提交
154
#endif /* _LINUX_MIGRATE_H */