Skip to content

Commit

Permalink
mm/hmm: avoid bloating arch that do not make use of HMM
Browse files Browse the repository at this point in the history
This moves all new code including new page migration helper behind kernel
Kconfig option so that there is no codee bloat for arch or user that do
not want to use HMM or any of its associated features.

arm allyesconfig (without all the patchset, then with and this patch):
   text	   data	    bss	    dec	    hex	filename
83721896	46511131	27582964	157815991	96814b7	../without/vmlinux
83722364	46511131	27582964	157816459	968168b	vmlinux

[[email protected]: struct hmm is only use by HMM mirror functionality]
  Link: http://lkml.kernel.org/r/[email protected]
[[email protected]: fix build (arm multi_v7_defconfig)]
  Link: http://lkml.kernel.org/r/[email protected]
Link: http://lkml.kernel.org/r/[email protected]
Signed-off-by: Jérôme Glisse <[email protected]>
Signed-off-by: Stephen Rothwell <[email protected]>
Cc: Dan Williams <[email protected]>
Cc: Arnd Bergmann <[email protected]>
Signed-off-by: Andrew Morton <[email protected]>
Signed-off-by: Linus Torvalds <[email protected]>
  • Loading branch information
Jérôme Glisse authored and torvalds committed Sep 9, 2017
1 parent d3df0a4 commit 6b368cd
Show file tree
Hide file tree
Showing 8 changed files with 54 additions and 32 deletions.
9 changes: 6 additions & 3 deletions include/linux/hmm.h
Original file line number Diff line number Diff line change
Expand Up @@ -501,18 +501,21 @@ void hmm_device_put(struct hmm_device *hmm_device);


/* Below are for HMM internal use only! Not to be used by device driver! */
#if IS_ENABLED(CONFIG_HMM_MIRROR)
void hmm_mm_destroy(struct mm_struct *mm);

static inline void hmm_mm_init(struct mm_struct *mm)
{
mm->hmm = NULL;
}
#else /* IS_ENABLED(CONFIG_HMM_MIRROR) */
static inline void hmm_mm_destroy(struct mm_struct *mm) {}
static inline void hmm_mm_init(struct mm_struct *mm) {}
#endif /* IS_ENABLED(CONFIG_HMM_MIRROR) */

#else /* IS_ENABLED(CONFIG_HMM) */

/* Below are for HMM internal use only! Not to be used by device driver! */
#else /* IS_ENABLED(CONFIG_HMM) */
static inline void hmm_mm_destroy(struct mm_struct *mm) {}
static inline void hmm_mm_init(struct mm_struct *mm) {}

#endif /* IS_ENABLED(CONFIG_HMM) */
#endif /* LINUX_HMM_H */
22 changes: 7 additions & 15 deletions include/linux/memremap.h
Original file line number Diff line number Diff line change
Expand Up @@ -138,18 +138,6 @@ void *devm_memremap_pages(struct device *dev, struct resource *res,
struct dev_pagemap *find_dev_pagemap(resource_size_t phys);

static inline bool is_zone_device_page(const struct page *page);

static inline bool is_device_private_page(const struct page *page)
{
return is_zone_device_page(page) &&
page->pgmap->type == MEMORY_DEVICE_PRIVATE;
}

static inline bool is_device_public_page(const struct page *page)
{
return is_zone_device_page(page) &&
page->pgmap->type == MEMORY_DEVICE_PUBLIC;
}
#else
static inline void *devm_memremap_pages(struct device *dev,
struct resource *res, struct percpu_ref *ref,
Expand All @@ -168,17 +156,21 @@ static inline struct dev_pagemap *find_dev_pagemap(resource_size_t phys)
{
return NULL;
}
#endif

#if defined(CONFIG_DEVICE_PRIVATE) || defined(CONFIG_DEVICE_PUBLIC)
static inline bool is_device_private_page(const struct page *page)
{
return false;
return is_zone_device_page(page) &&
page->pgmap->type == MEMORY_DEVICE_PRIVATE;
}

static inline bool is_device_public_page(const struct page *page)
{
return false;
return is_zone_device_page(page) &&
page->pgmap->type == MEMORY_DEVICE_PUBLIC;
}
#endif
#endif /* CONFIG_DEVICE_PRIVATE || CONFIG_DEVICE_PUBLIC */

/**
* get_dev_pagemap() - take a new live reference on the dev_pagemap for @pfn
Expand Down
13 changes: 13 additions & 0 deletions include/linux/migrate.h
Original file line number Diff line number Diff line change
Expand Up @@ -265,13 +265,26 @@ struct migrate_vma_ops {
void *private);
};

#if defined(CONFIG_MIGRATE_VMA_HELPER)
int migrate_vma(const struct migrate_vma_ops *ops,
struct vm_area_struct *vma,
unsigned long start,
unsigned long end,
unsigned long *src,
unsigned long *dst,
void *private);
#else
static inline int migrate_vma(const struct migrate_vma_ops *ops,
struct vm_area_struct *vma,
unsigned long start,
unsigned long end,
unsigned long *src,
unsigned long *dst,
void *private)
{
return -EINVAL;
}
#endif /* IS_ENABLED(CONFIG_MIGRATE_VMA_HELPER) */

#endif /* CONFIG_MIGRATION */

Expand Down
26 changes: 17 additions & 9 deletions include/linux/mm.h
Original file line number Diff line number Diff line change
Expand Up @@ -800,18 +800,27 @@ static inline bool is_zone_device_page(const struct page *page)
}
#endif

#if IS_ENABLED(CONFIG_DEVICE_PRIVATE) || IS_ENABLED(CONFIG_DEVICE_PUBLIC)
#if defined(CONFIG_DEVICE_PRIVATE) || defined(CONFIG_DEVICE_PUBLIC)
void put_zone_device_private_or_public_page(struct page *page);
#else
DECLARE_STATIC_KEY_FALSE(device_private_key);
#define IS_HMM_ENABLED static_branch_unlikely(&device_private_key)
static inline bool is_device_private_page(const struct page *page);
static inline bool is_device_public_page(const struct page *page);
#else /* CONFIG_DEVICE_PRIVATE || CONFIG_DEVICE_PUBLIC */
static inline void put_zone_device_private_or_public_page(struct page *page)
{
}
#define IS_HMM_ENABLED 0
static inline bool is_device_private_page(const struct page *page)
{
return false;
}
static inline bool is_device_public_page(const struct page *page)
{
return false;
}
#endif /* CONFIG_DEVICE_PRIVATE || CONFIG_DEVICE_PUBLIC */

static inline bool is_device_private_page(const struct page *page);
static inline bool is_device_public_page(const struct page *page);

DECLARE_STATIC_KEY_FALSE(device_private_key);

static inline void get_page(struct page *page)
{
Expand All @@ -834,9 +843,8 @@ static inline void put_page(struct page *page)
* free and we need to inform the device driver through callback. See
* include/linux/memremap.h and HMM for details.
*/
if (static_branch_unlikely(&device_private_key) &&
unlikely(is_device_private_page(page) ||
is_device_public_page(page))) {
if (IS_HMM_ENABLED && unlikely(is_device_private_page(page) ||
unlikely(is_device_public_page(page)))) {
put_zone_device_private_or_public_page(page);
return;
}
Expand Down
4 changes: 4 additions & 0 deletions mm/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -702,8 +702,12 @@ config ARCH_HAS_HMM
depends on MEMORY_HOTREMOVE
depends on SPARSEMEM_VMEMMAP

config MIGRATE_VMA_HELPER
bool

config HMM
bool
select MIGRATE_VMA_HELPER

config HMM_MIRROR
bool "HMM mirror CPU page table into a device page table"
Expand Down
3 changes: 2 additions & 1 deletion mm/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ obj-y := filemap.o mempool.o oom_kill.o \
mm_init.o mmu_context.o percpu.o slab_common.o \
compaction.o vmacache.o swap_slots.o \
interval_tree.o list_lru.o workingset.o \
debug.o hmm.o $(mmu-y)
debug.o $(mmu-y)

obj-y += init-mm.o

Expand Down Expand Up @@ -104,3 +104,4 @@ obj-$(CONFIG_FRAME_VECTOR) += frame_vector.o
obj-$(CONFIG_DEBUG_PAGE_REF) += debug_page_ref.o
obj-$(CONFIG_HARDENED_USERCOPY) += usercopy.o
obj-$(CONFIG_PERCPU_STATS) += percpu-stats.o
obj-$(CONFIG_HMM) += hmm.o
7 changes: 3 additions & 4 deletions mm/hmm.c
Original file line number Diff line number Diff line change
Expand Up @@ -35,15 +35,16 @@

#define PA_SECTION_SIZE (1UL << PA_SECTION_SHIFT)


#if defined(CONFIG_DEVICE_PRIVATE) || defined(CONFIG_DEVICE_PUBLIC)
/*
* Device private memory see HMM (Documentation/vm/hmm.txt) or hmm.h
*/
DEFINE_STATIC_KEY_FALSE(device_private_key);
EXPORT_SYMBOL(device_private_key);
#endif /* CONFIG_DEVICE_PRIVATE || CONFIG_DEVICE_PUBLIC */


#ifdef CONFIG_HMM
#if IS_ENABLED(CONFIG_HMM_MIRROR)
static const struct mmu_notifier_ops hmm_mmu_notifier_ops;

/*
Expand Down Expand Up @@ -128,9 +129,7 @@ void hmm_mm_destroy(struct mm_struct *mm)
{
kfree(mm->hmm);
}
#endif /* CONFIG_HMM */

#if IS_ENABLED(CONFIG_HMM_MIRROR)
static void hmm_invalidate_range(struct hmm *hmm,
enum hmm_update_type action,
unsigned long start,
Expand Down
2 changes: 2 additions & 0 deletions mm/migrate.c
Original file line number Diff line number Diff line change
Expand Up @@ -2127,6 +2127,7 @@ int migrate_misplaced_transhuge_page(struct mm_struct *mm,

#endif /* CONFIG_NUMA */

#if defined(CONFIG_MIGRATE_VMA_HELPER)
struct migrate_vma {
struct vm_area_struct *vma;
unsigned long *dst;
Expand Down Expand Up @@ -2980,3 +2981,4 @@ int migrate_vma(const struct migrate_vma_ops *ops,
return 0;
}
EXPORT_SYMBOL(migrate_vma);
#endif /* defined(MIGRATE_VMA_HELPER) */

0 comments on commit 6b368cd

Please sign in to comment.