Skip to content

Commit 529ce23

Browse files
rpedgecoakpm00
authored andcommitted
mm: switch mm->get_unmapped_area() to a flag
The mm_struct contains a function pointer *get_unmapped_area(), which is set to either arch_get_unmapped_area() or arch_get_unmapped_area_topdown() during the initialization of the mm. Since the function pointer only ever points to two functions that are named the same across all arch's, a function pointer is not really required. In addition future changes will want to add versions of the functions that take additional arguments. So to save a pointers worth of bytes in mm_struct, and prevent adding additional function pointers to mm_struct in future changes, remove it and keep the information about which get_unmapped_area() to use in a flag. Add the new flag to MMF_INIT_MASK so it doesn't get clobbered on fork by mmf_init_flags(). Most MM flags get clobbered on fork. In the pre-existing behavior mm->get_unmapped_area() would get copied to the new mm in dup_mm(), so not clobbering the flag preserves the existing behavior around inheriting the topdown-ness. Introduce a helper, mm_get_unmapped_area(), to easily convert code that refers to the old function pointer to instead select and call either arch_get_unmapped_area() or arch_get_unmapped_area_topdown() based on the flag. Then drop the mm->get_unmapped_area() function pointer. Leave the get_unmapped_area() pointer in struct file_operations alone. The main purpose of this change is to reorganize in preparation for future changes, but it also converts the calls of mm->get_unmapped_area() from indirect branches into a direct ones. The stress-ng bigheap benchmark calls realloc a lot, which calls through get_unmapped_area() in the kernel. On x86, the change yielded a ~1% improvement there on a retpoline config. In testing a few x86 configs, removing the pointer unfortunately didn't result in any actual size reductions in the compiled layout of mm_struct. But depending on compiler or arch alignment requirements, the change could shrink the size of mm_struct. Link: https://lkml.kernel.org/r/[email protected] Signed-off-by: Rick Edgecombe <[email protected]> Acked-by: Dave Hansen <[email protected]> Acked-by: Liam R. Howlett <[email protected]> Reviewed-by: Kirill A. Shutemov <[email protected]> Acked-by: Alexei Starovoitov <[email protected]> Cc: Dan Williams <[email protected]> Cc: Andy Lutomirski <[email protected]> Cc: Aneesh Kumar K.V <[email protected]> Cc: Borislav Petkov (AMD) <[email protected]> Cc: Christophe Leroy <[email protected]> Cc: Deepak Gupta <[email protected]> Cc: Guo Ren <[email protected]> Cc: Helge Deller <[email protected]> Cc: H. Peter Anvin (Intel) <[email protected]> Cc: Ingo Molnar <[email protected]> Cc: "James E.J. Bottomley" <[email protected]> Cc: Kees Cook <[email protected]> Cc: Mark Brown <[email protected]> Cc: Michael Ellerman <[email protected]> Cc: Naveen N. Rao <[email protected]> Cc: Nicholas Piggin <[email protected]> Cc: Peter Zijlstra <[email protected]> Cc: Thomas Gleixner <[email protected]> Signed-off-by: Andrew Morton <[email protected]>
1 parent 5def1e0 commit 529ce23

File tree

23 files changed

+66
-57
lines changed

23 files changed

+66
-57
lines changed

arch/s390/mm/hugetlbpage.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -318,7 +318,7 @@ unsigned long hugetlb_get_unmapped_area(struct file *file, unsigned long addr,
318318
goto check_asce_limit;
319319
}
320320

321-
if (mm->get_unmapped_area == arch_get_unmapped_area)
321+
if (!test_bit(MMF_TOPDOWN, &mm->flags))
322322
addr = hugetlb_get_unmapped_area_bottomup(file, addr, len,
323323
pgoff, flags);
324324
else

arch/s390/mm/mmap.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -185,10 +185,10 @@ void arch_pick_mmap_layout(struct mm_struct *mm, struct rlimit *rlim_stack)
185185
*/
186186
if (mmap_is_legacy(rlim_stack)) {
187187
mm->mmap_base = mmap_base_legacy(random_factor);
188-
mm->get_unmapped_area = arch_get_unmapped_area;
188+
clear_bit(MMF_TOPDOWN, &mm->flags);
189189
} else {
190190
mm->mmap_base = mmap_base(random_factor, rlim_stack);
191-
mm->get_unmapped_area = arch_get_unmapped_area_topdown;
191+
set_bit(MMF_TOPDOWN, &mm->flags);
192192
}
193193
}
194194

arch/sparc/kernel/sys_sparc_64.c

Lines changed: 6 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -218,14 +218,10 @@ arch_get_unmapped_area_topdown(struct file *filp, const unsigned long addr0,
218218
unsigned long get_fb_unmapped_area(struct file *filp, unsigned long orig_addr, unsigned long len, unsigned long pgoff, unsigned long flags)
219219
{
220220
unsigned long align_goal, addr = -ENOMEM;
221-
unsigned long (*get_area)(struct file *, unsigned long,
222-
unsigned long, unsigned long, unsigned long);
223-
224-
get_area = current->mm->get_unmapped_area;
225221

226222
if (flags & MAP_FIXED) {
227223
/* Ok, don't mess with it. */
228-
return get_area(NULL, orig_addr, len, pgoff, flags);
224+
return mm_get_unmapped_area(current->mm, NULL, orig_addr, len, pgoff, flags);
229225
}
230226
flags &= ~MAP_SHARED;
231227

@@ -238,7 +234,8 @@ unsigned long get_fb_unmapped_area(struct file *filp, unsigned long orig_addr, u
238234
align_goal = (64UL * 1024);
239235

240236
do {
241-
addr = get_area(NULL, orig_addr, len + (align_goal - PAGE_SIZE), pgoff, flags);
237+
addr = mm_get_unmapped_area(current->mm, NULL, orig_addr,
238+
len + (align_goal - PAGE_SIZE), pgoff, flags);
242239
if (!(addr & ~PAGE_MASK)) {
243240
addr = (addr + (align_goal - 1UL)) & ~(align_goal - 1UL);
244241
break;
@@ -256,7 +253,7 @@ unsigned long get_fb_unmapped_area(struct file *filp, unsigned long orig_addr, u
256253
* be obtained.
257254
*/
258255
if (addr & ~PAGE_MASK)
259-
addr = get_area(NULL, orig_addr, len, pgoff, flags);
256+
addr = mm_get_unmapped_area(current->mm, NULL, orig_addr, len, pgoff, flags);
260257

261258
return addr;
262259
}
@@ -292,7 +289,7 @@ void arch_pick_mmap_layout(struct mm_struct *mm, struct rlimit *rlim_stack)
292289
gap == RLIM_INFINITY ||
293290
sysctl_legacy_va_layout) {
294291
mm->mmap_base = TASK_UNMAPPED_BASE + random_factor;
295-
mm->get_unmapped_area = arch_get_unmapped_area;
292+
clear_bit(MMF_TOPDOWN, &mm->flags);
296293
} else {
297294
/* We know it's 32-bit */
298295
unsigned long task_size = STACK_TOP32;
@@ -303,7 +300,7 @@ void arch_pick_mmap_layout(struct mm_struct *mm, struct rlimit *rlim_stack)
303300
gap = (task_size / 6 * 5);
304301

305302
mm->mmap_base = PAGE_ALIGN(task_size - gap - random_factor);
306-
mm->get_unmapped_area = arch_get_unmapped_area_topdown;
303+
set_bit(MMF_TOPDOWN, &mm->flags);
307304
}
308305
}
309306

arch/sparc/mm/hugetlbpage.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -123,7 +123,7 @@ hugetlb_get_unmapped_area(struct file *file, unsigned long addr,
123123
(!vma || addr + len <= vm_start_gap(vma)))
124124
return addr;
125125
}
126-
if (mm->get_unmapped_area == arch_get_unmapped_area)
126+
if (!test_bit(MMF_TOPDOWN, &mm->flags))
127127
return hugetlb_get_unmapped_area_bottomup(file, addr, len,
128128
pgoff, flags);
129129
else

arch/x86/kernel/cpu/sgx/driver.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -113,7 +113,7 @@ static unsigned long sgx_get_unmapped_area(struct file *file,
113113
if (flags & MAP_FIXED)
114114
return addr;
115115

116-
return current->mm->get_unmapped_area(file, addr, len, pgoff, flags);
116+
return mm_get_unmapped_area(current->mm, file, addr, len, pgoff, flags);
117117
}
118118

119119
#ifdef CONFIG_COMPAT

arch/x86/mm/hugetlbpage.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -115,7 +115,7 @@ hugetlb_get_unmapped_area(struct file *file, unsigned long addr,
115115
}
116116

117117
get_unmapped_area:
118-
if (mm->get_unmapped_area == arch_get_unmapped_area)
118+
if (!test_bit(MMF_TOPDOWN, &mm->flags))
119119
return hugetlb_get_unmapped_area_bottomup(file, addr, len,
120120
pgoff, flags);
121121
else

arch/x86/mm/mmap.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -129,9 +129,9 @@ static void arch_pick_mmap_base(unsigned long *base, unsigned long *legacy_base,
129129
void arch_pick_mmap_layout(struct mm_struct *mm, struct rlimit *rlim_stack)
130130
{
131131
if (mmap_is_legacy())
132-
mm->get_unmapped_area = arch_get_unmapped_area;
132+
clear_bit(MMF_TOPDOWN, &mm->flags);
133133
else
134-
mm->get_unmapped_area = arch_get_unmapped_area_topdown;
134+
set_bit(MMF_TOPDOWN, &mm->flags);
135135

136136
arch_pick_mmap_base(&mm->mmap_base, &mm->mmap_legacy_base,
137137
arch_rnd(mmap64_rnd_bits), task_size_64bit(0),

drivers/char/mem.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -544,7 +544,7 @@ static unsigned long get_unmapped_area_zero(struct file *file,
544544
}
545545

546546
/* Otherwise flags & MAP_PRIVATE: with no shmem object beneath it */
547-
return current->mm->get_unmapped_area(file, addr, len, pgoff, flags);
547+
return mm_get_unmapped_area(current->mm, file, addr, len, pgoff, flags);
548548
#else
549549
return -ENOSYS;
550550
#endif

drivers/dax/device.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -329,14 +329,14 @@ static unsigned long dax_get_unmapped_area(struct file *filp,
329329
if ((off + len_align) < off)
330330
goto out;
331331

332-
addr_align = current->mm->get_unmapped_area(filp, addr, len_align,
333-
pgoff, flags);
332+
addr_align = mm_get_unmapped_area(current->mm, filp, addr, len_align,
333+
pgoff, flags);
334334
if (!IS_ERR_VALUE(addr_align)) {
335335
addr_align += (off - addr_align) & (align - 1);
336336
return addr_align;
337337
}
338338
out:
339-
return current->mm->get_unmapped_area(filp, addr, len, pgoff, flags);
339+
return mm_get_unmapped_area(current->mm, filp, addr, len, pgoff, flags);
340340
}
341341

342342
static const struct address_space_operations dev_dax_aops = {

fs/hugetlbfs/inode.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -249,11 +249,11 @@ generic_hugetlb_get_unmapped_area(struct file *file, unsigned long addr,
249249
}
250250

251251
/*
252-
* Use mm->get_unmapped_area value as a hint to use topdown routine.
252+
* Use MMF_TOPDOWN flag as a hint to use topdown routine.
253253
* If architectures have special needs, they should define their own
254254
* version of hugetlb_get_unmapped_area.
255255
*/
256-
if (mm->get_unmapped_area == arch_get_unmapped_area_topdown)
256+
if (test_bit(MMF_TOPDOWN, &mm->flags))
257257
return hugetlb_get_unmapped_area_topdown(file, addr, len,
258258
pgoff, flags);
259259
return hugetlb_get_unmapped_area_bottomup(file, addr, len,

0 commit comments

Comments
 (0)