Skip to content

Commit

Permalink
mm, vmalloc: use __GFP_HIGHMEM implicitly
Browse files Browse the repository at this point in the history
__vmalloc* allows users to provide gfp flags for the underlying
allocation.  This API is quite popular

  $ git grep "=[[:space:]]__vmalloc\|return[[:space:]]*__vmalloc" | wc -l
  77

The only problem is that many people are not aware that they really want
to give __GFP_HIGHMEM along with other flags because there is really no
reason to consume precious lowmemory on CONFIG_HIGHMEM systems for pages
which are mapped to the kernel vmalloc space.  About half of users don't
use this flag, though.  This signals that we make the API unnecessarily
too complex.

This patch simply uses __GFP_HIGHMEM implicitly when allocating pages to
be mapped to the vmalloc space.  Current users which add __GFP_HIGHMEM
are simplified and drop the flag.

Link: http://lkml.kernel.org/r/20170307141020.29107-1-mhocko@kernel.org
Signed-off-by: Michal Hocko <mhocko@suse.com>
Reviewed-by: Matthew Wilcox <mawilcox@microsoft.com>
Cc: Al Viro <viro@zeniv.linux.org.uk>
Cc: Vlastimil Babka <vbabka@suse.cz>
Cc: David Rientjes <rientjes@google.com>
Cc: Cristopher Lameter <cl@linux.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
  • Loading branch information
Michal Hocko authored and torvalds committed May 9, 2017
1 parent 54f180d commit 19809c2
Show file tree
Hide file tree
Showing 20 changed files with 31 additions and 41 deletions.
2 changes: 1 addition & 1 deletion arch/parisc/kernel/module.c
Original file line number Diff line number Diff line change
Expand Up @@ -218,7 +218,7 @@ void *module_alloc(unsigned long size)
* easier than trying to map the text, data, init_text and
* init_data correctly */
return __vmalloc_node_range(size, 1, VMALLOC_START, VMALLOC_END,
GFP_KERNEL | __GFP_HIGHMEM,
GFP_KERNEL,
PAGE_KERNEL_RWX, 0, NUMA_NO_NODE,
__builtin_return_address(0));
}
Expand Down
2 changes: 1 addition & 1 deletion arch/x86/kernel/module.c
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ void *module_alloc(unsigned long size)

p = __vmalloc_node_range(size, MODULE_ALIGN,
MODULES_VADDR + get_module_load_offset(),
MODULES_END, GFP_KERNEL | __GFP_HIGHMEM,
MODULES_END, GFP_KERNEL,
PAGE_KERNEL_EXEC, 0, NUMA_NO_NODE,
__builtin_return_address(0));
if (p && (kasan_module_alloc(p, size) < 0)) {
Expand Down
2 changes: 1 addition & 1 deletion drivers/block/drbd/drbd_bitmap.c
Original file line number Diff line number Diff line change
Expand Up @@ -409,7 +409,7 @@ static struct page **bm_realloc_pages(struct drbd_bitmap *b, unsigned long want)
new_pages = kzalloc(bytes, GFP_NOIO | __GFP_NOWARN);
if (!new_pages) {
new_pages = __vmalloc(bytes,
GFP_NOIO | __GFP_HIGHMEM | __GFP_ZERO,
GFP_NOIO | __GFP_ZERO,
PAGE_KERNEL);
if (!new_pages)
return NULL;
Expand Down
4 changes: 2 additions & 2 deletions drivers/gpu/drm/etnaviv/etnaviv_dump.c
Original file line number Diff line number Diff line change
Expand Up @@ -161,8 +161,8 @@ void etnaviv_core_dump(struct etnaviv_gpu *gpu)
file_size += sizeof(*iter.hdr) * n_obj;

/* Allocate the file in vmalloc memory, it's likely to be big */
iter.start = __vmalloc(file_size, GFP_KERNEL | __GFP_HIGHMEM |
__GFP_NOWARN | __GFP_NORETRY, PAGE_KERNEL);
iter.start = __vmalloc(file_size, GFP_KERNEL | __GFP_NOWARN | __GFP_NORETRY,
PAGE_KERNEL);
if (!iter.start) {
dev_warn(gpu->dev, "failed to allocate devcoredump file\n");
return;
Expand Down
2 changes: 1 addition & 1 deletion drivers/md/dm-bufio.c
Original file line number Diff line number Diff line change
Expand Up @@ -406,7 +406,7 @@ static void *alloc_buffer_data(struct dm_bufio_client *c, gfp_t gfp_mask,
if (gfp_mask & __GFP_NORETRY)
noio_flag = memalloc_noio_save();

ptr = __vmalloc(c->block_size, gfp_mask | __GFP_HIGHMEM, PAGE_KERNEL);
ptr = __vmalloc(c->block_size, gfp_mask, PAGE_KERNEL);

if (gfp_mask & __GFP_NORETRY)
memalloc_noio_restore(noio_flag);
Expand Down
3 changes: 1 addition & 2 deletions fs/btrfs/free-space-tree.c
Original file line number Diff line number Diff line change
Expand Up @@ -167,8 +167,7 @@ static u8 *alloc_bitmap(u32 bitmap_size)
if (mem)
return mem;

return __vmalloc(bitmap_size, GFP_NOFS | __GFP_HIGHMEM | __GFP_ZERO,
PAGE_KERNEL);
return __vmalloc(bitmap_size, GFP_NOFS | __GFP_ZERO, PAGE_KERNEL);
}

int convert_free_space_to_bitmaps(struct btrfs_trans_handle *trans,
Expand Down
2 changes: 1 addition & 1 deletion fs/file.c
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ static void *alloc_fdmem(size_t size)
if (data != NULL)
return data;
}
return __vmalloc(size, GFP_KERNEL_ACCOUNT | __GFP_HIGHMEM, PAGE_KERNEL);
return __vmalloc(size, GFP_KERNEL_ACCOUNT, PAGE_KERNEL);
}

static void __free_fdtable(struct fdtable *fdt)
Expand Down
2 changes: 1 addition & 1 deletion fs/xfs/kmem.c
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ kmem_zalloc_large(size_t size, xfs_km_flags_t flags)
nofs_flag = memalloc_nofs_save();

lflags = kmem_flags_convert(flags);
ptr = __vmalloc(size, lflags | __GFP_HIGHMEM | __GFP_ZERO, PAGE_KERNEL);
ptr = __vmalloc(size, lflags | __GFP_ZERO, PAGE_KERNEL);

if (flags & KM_NOFS)
memalloc_nofs_restore(nofs_flag);
Expand Down
9 changes: 3 additions & 6 deletions include/drm/drm_mem_util.h
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,7 @@ static __inline__ void *drm_calloc_large(size_t nmemb, size_t size)
if (size * nmemb <= PAGE_SIZE)
return kcalloc(nmemb, size, GFP_KERNEL);

return __vmalloc(size * nmemb,
GFP_KERNEL | __GFP_HIGHMEM | __GFP_ZERO, PAGE_KERNEL);
return vzalloc(size * nmemb);
}

/* Modeled after cairo's malloc_ab, it's like calloc but without the zeroing. */
Expand All @@ -50,8 +49,7 @@ static __inline__ void *drm_malloc_ab(size_t nmemb, size_t size)
if (size * nmemb <= PAGE_SIZE)
return kmalloc(nmemb * size, GFP_KERNEL);

return __vmalloc(size * nmemb,
GFP_KERNEL | __GFP_HIGHMEM, PAGE_KERNEL);
return vmalloc(size * nmemb);
}

static __inline__ void *drm_malloc_gfp(size_t nmemb, size_t size, gfp_t gfp)
Expand All @@ -69,8 +67,7 @@ static __inline__ void *drm_malloc_gfp(size_t nmemb, size_t size, gfp_t gfp)
return ptr;
}

return __vmalloc(size * nmemb,
gfp | __GFP_HIGHMEM, PAGE_KERNEL);
return __vmalloc(size * nmemb, gfp, PAGE_KERNEL);
}

static __inline void drm_free_large(void *ptr)
Expand Down
9 changes: 3 additions & 6 deletions kernel/bpf/core.c
Original file line number Diff line number Diff line change
Expand Up @@ -76,8 +76,7 @@ void *bpf_internal_load_pointer_neg_helper(const struct sk_buff *skb, int k, uns

struct bpf_prog *bpf_prog_alloc(unsigned int size, gfp_t gfp_extra_flags)
{
gfp_t gfp_flags = GFP_KERNEL | __GFP_HIGHMEM | __GFP_ZERO |
gfp_extra_flags;
gfp_t gfp_flags = GFP_KERNEL | __GFP_ZERO | gfp_extra_flags;
struct bpf_prog_aux *aux;
struct bpf_prog *fp;

Expand Down Expand Up @@ -107,8 +106,7 @@ EXPORT_SYMBOL_GPL(bpf_prog_alloc);
struct bpf_prog *bpf_prog_realloc(struct bpf_prog *fp_old, unsigned int size,
gfp_t gfp_extra_flags)
{
gfp_t gfp_flags = GFP_KERNEL | __GFP_HIGHMEM | __GFP_ZERO |
gfp_extra_flags;
gfp_t gfp_flags = GFP_KERNEL | __GFP_ZERO | gfp_extra_flags;
struct bpf_prog *fp;
u32 pages, delta;
int ret;
Expand Down Expand Up @@ -655,8 +653,7 @@ static int bpf_jit_blind_insn(const struct bpf_insn *from,
static struct bpf_prog *bpf_prog_clone_create(struct bpf_prog *fp_other,
gfp_t gfp_extra_flags)
{
gfp_t gfp_flags = GFP_KERNEL | __GFP_HIGHMEM | __GFP_ZERO |
gfp_extra_flags;
gfp_t gfp_flags = GFP_KERNEL | __GFP_ZERO | gfp_extra_flags;
struct bpf_prog *fp;

fp = __vmalloc(fp_other->pages * PAGE_SIZE, gfp_flags, PAGE_KERNEL);
Expand Down
3 changes: 1 addition & 2 deletions kernel/bpf/syscall.c
Original file line number Diff line number Diff line change
Expand Up @@ -67,8 +67,7 @@ void *bpf_map_area_alloc(size_t size)
return area;
}

return __vmalloc(size, GFP_KERNEL | __GFP_HIGHMEM | flags,
PAGE_KERNEL);
return __vmalloc(size, GFP_KERNEL | flags, PAGE_KERNEL);
}

void bpf_map_area_free(void *area)
Expand Down
2 changes: 1 addition & 1 deletion kernel/fork.c
Original file line number Diff line number Diff line change
Expand Up @@ -221,7 +221,7 @@ static unsigned long *alloc_thread_stack_node(struct task_struct *tsk, int node)

stack = __vmalloc_node_range(THREAD_SIZE, THREAD_SIZE,
VMALLOC_START, VMALLOC_END,
THREADINFO_GFP | __GFP_HIGHMEM,
THREADINFO_GFP,
PAGE_KERNEL,
0, node, __builtin_return_address(0));

Expand Down
2 changes: 1 addition & 1 deletion kernel/groups.c
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ struct group_info *groups_alloc(int gidsetsize)
len = sizeof(struct group_info) + sizeof(kgid_t) * gidsetsize;
gi = kmalloc(len, GFP_KERNEL_ACCOUNT|__GFP_NOWARN|__GFP_NORETRY);
if (!gi)
gi = __vmalloc(len, GFP_KERNEL_ACCOUNT|__GFP_HIGHMEM, PAGE_KERNEL);
gi = __vmalloc(len, GFP_KERNEL_ACCOUNT, PAGE_KERNEL);
if (!gi)
return NULL;

Expand Down
2 changes: 1 addition & 1 deletion kernel/module.c
Original file line number Diff line number Diff line change
Expand Up @@ -2864,7 +2864,7 @@ static int copy_module_from_user(const void __user *umod, unsigned long len,

/* Suck in entire file: we'll want most of it. */
info->hdr = __vmalloc(info->len,
GFP_KERNEL | __GFP_HIGHMEM | __GFP_NOWARN, PAGE_KERNEL);
GFP_KERNEL | __GFP_NOWARN, PAGE_KERNEL);
if (!info->hdr)
return -ENOMEM;

Expand Down
2 changes: 1 addition & 1 deletion mm/kasan/kasan.c
Original file line number Diff line number Diff line change
Expand Up @@ -691,7 +691,7 @@ int kasan_module_alloc(void *addr, size_t size)

ret = __vmalloc_node_range(shadow_size, 1, shadow_start,
shadow_start + shadow_size,
GFP_KERNEL | __GFP_HIGHMEM | __GFP_ZERO,
GFP_KERNEL | __GFP_ZERO,
PAGE_KERNEL, VM_NO_GUARD, NUMA_NO_NODE,
__builtin_return_address(0));

Expand Down
3 changes: 1 addition & 2 deletions mm/nommu.c
Original file line number Diff line number Diff line change
Expand Up @@ -246,8 +246,7 @@ void *vmalloc_user(unsigned long size)
{
void *ret;

ret = __vmalloc(size, GFP_KERNEL | __GFP_HIGHMEM | __GFP_ZERO,
PAGE_KERNEL);
ret = __vmalloc(size, GFP_KERNEL | __GFP_ZERO, PAGE_KERNEL);
if (ret) {
struct vm_area_struct *vma;

Expand Down
2 changes: 1 addition & 1 deletion mm/util.c
Original file line number Diff line number Diff line change
Expand Up @@ -382,7 +382,7 @@ void *kvmalloc_node(size_t size, gfp_t flags, int node)
if (ret || size <= PAGE_SIZE)
return ret;

return __vmalloc_node_flags(size, node, flags | __GFP_HIGHMEM);
return __vmalloc_node_flags(size, node, flags);
}
EXPORT_SYMBOL(kvmalloc_node);

Expand Down
14 changes: 7 additions & 7 deletions mm/vmalloc.c
Original file line number Diff line number Diff line change
Expand Up @@ -1655,7 +1655,7 @@ static void *__vmalloc_area_node(struct vm_struct *area, gfp_t gfp_mask,
struct page **pages;
unsigned int nr_pages, array_size, i;
const gfp_t nested_gfp = (gfp_mask & GFP_RECLAIM_MASK) | __GFP_ZERO;
const gfp_t alloc_mask = gfp_mask | __GFP_NOWARN;
const gfp_t alloc_mask = gfp_mask | __GFP_HIGHMEM | __GFP_NOWARN;

nr_pages = get_vm_area_size(area) >> PAGE_SHIFT;
array_size = (nr_pages * sizeof(struct page *));
Expand Down Expand Up @@ -1818,7 +1818,7 @@ EXPORT_SYMBOL(__vmalloc);
void *vmalloc(unsigned long size)
{
return __vmalloc_node_flags(size, NUMA_NO_NODE,
GFP_KERNEL | __GFP_HIGHMEM);
GFP_KERNEL);
}
EXPORT_SYMBOL(vmalloc);

Expand All @@ -1835,7 +1835,7 @@ EXPORT_SYMBOL(vmalloc);
void *vzalloc(unsigned long size)
{
return __vmalloc_node_flags(size, NUMA_NO_NODE,
GFP_KERNEL | __GFP_HIGHMEM | __GFP_ZERO);
GFP_KERNEL | __GFP_ZERO);
}
EXPORT_SYMBOL(vzalloc);

Expand All @@ -1852,7 +1852,7 @@ void *vmalloc_user(unsigned long size)
void *ret;

ret = __vmalloc_node(size, SHMLBA,
GFP_KERNEL | __GFP_HIGHMEM | __GFP_ZERO,
GFP_KERNEL | __GFP_ZERO,
PAGE_KERNEL, NUMA_NO_NODE,
__builtin_return_address(0));
if (ret) {
Expand All @@ -1876,7 +1876,7 @@ EXPORT_SYMBOL(vmalloc_user);
*/
void *vmalloc_node(unsigned long size, int node)
{
return __vmalloc_node(size, 1, GFP_KERNEL | __GFP_HIGHMEM, PAGE_KERNEL,
return __vmalloc_node(size, 1, GFP_KERNEL, PAGE_KERNEL,
node, __builtin_return_address(0));
}
EXPORT_SYMBOL(vmalloc_node);
Expand All @@ -1896,7 +1896,7 @@ EXPORT_SYMBOL(vmalloc_node);
void *vzalloc_node(unsigned long size, int node)
{
return __vmalloc_node_flags(size, node,
GFP_KERNEL | __GFP_HIGHMEM | __GFP_ZERO);
GFP_KERNEL | __GFP_ZERO);
}
EXPORT_SYMBOL(vzalloc_node);

Expand All @@ -1918,7 +1918,7 @@ EXPORT_SYMBOL(vzalloc_node);

void *vmalloc_exec(unsigned long size)
{
return __vmalloc_node(size, 1, GFP_KERNEL | __GFP_HIGHMEM, PAGE_KERNEL_EXEC,
return __vmalloc_node(size, 1, GFP_KERNEL, PAGE_KERNEL_EXEC,
NUMA_NO_NODE, __builtin_return_address(0));
}

Expand Down
2 changes: 1 addition & 1 deletion net/ceph/ceph_common.c
Original file line number Diff line number Diff line change
Expand Up @@ -187,7 +187,7 @@ void *ceph_kvmalloc(size_t size, gfp_t flags)
return ptr;
}

return __vmalloc(size, flags | __GFP_HIGHMEM, PAGE_KERNEL);
return __vmalloc(size, flags, PAGE_KERNEL);
}


Expand Down
3 changes: 1 addition & 2 deletions net/netfilter/x_tables.c
Original file line number Diff line number Diff line change
Expand Up @@ -998,8 +998,7 @@ struct xt_table_info *xt_alloc_table_info(unsigned int size)
if (sz <= (PAGE_SIZE << PAGE_ALLOC_COSTLY_ORDER))
info = kmalloc(sz, GFP_KERNEL | __GFP_NOWARN | __GFP_NORETRY);
if (!info) {
info = __vmalloc(sz, GFP_KERNEL | __GFP_NOWARN |
__GFP_NORETRY | __GFP_HIGHMEM,
info = __vmalloc(sz, GFP_KERNEL | __GFP_NOWARN | __GFP_NORETRY,
PAGE_KERNEL);
if (!info)
return NULL;
Expand Down

0 comments on commit 19809c2

Please sign in to comment.