]> www.infradead.org Git - users/jedix/linux-maple.git/commitdiff
mm: introduce kv[mz]alloc helpers
authorKyle Fortin <kyle.fortin@oracle.com>
Fri, 14 Jul 2017 20:18:04 +0000 (16:18 -0400)
committerChuck Anderson <chuck.anderson@oracle.com>
Wed, 26 Jul 2017 04:45:34 +0000 (21:45 -0700)
Patch series "kvmalloc", v5.

There are many open coded kmalloc with vmalloc fallback instances in the
tree.  Most of them are not careful enough or simply do not care about
the underlying semantic of the kmalloc/page allocator which means that
a) some vmalloc fallbacks are basically unreachable because the kmalloc
part will keep retrying until it succeeds b) the page allocator can
invoke a really disruptive steps like the OOM killer to move forward
which doesn't sound appropriate when we consider that the vmalloc
fallback is available.

As it can be seen implementing kvmalloc requires quite an intimate
knowledge if the page allocator and the memory reclaim internals which
strongly suggests that a helper should be implemented in the memory
subsystem proper.

Most callers, I could find, have been converted to use the helper
instead.  This is patch 6.  There are some more relying on __GFP_REPEAT
in the networking stack which I have converted as well and Eric Dumazet
was not opposed [2] to convert them as well.

[1] http://lkml.kernel.org/r/20170130094940.13546-1-mhocko@kernel.org
[2] http://lkml.kernel.org/r/1485273626.16328.301.camel@edumazet-glaptop3.roam.corp.google.com

This patch (of 9):

Using kmalloc with the vmalloc fallback for larger allocations is a
common pattern in the kernel code.  Yet we do not have any common helper
for that and so users have invented their own helpers.  Some of them are
really creative when doing so.  Let's just add kv[mz]alloc and make sure
it is implemented properly.  This implementation makes sure to not make
a large memory pressure for > PAGE_SZE requests (__GFP_NORETRY) and also
to not warn about allocation failures.  This also rules out the OOM
killer as the vmalloc is a more approapriate fallback than a disruptive
user visible action.

This patch also changes some existing users and removes helpers which
are specific for them.  In some cases this is not possible (e.g.
ext4_kvmalloc, libcfs_kvzalloc) because those seems to be broken and
require GFP_NO{FS,IO} context which is not vmalloc compatible in general
(note that the page table allocation is GFP_KERNEL).  Those need to be
fixed separately.

While we are at it, document that __vmalloc{_node} about unsupported gfp
mask because there seems to be a lot of confusion out there.
kvmalloc_node will warn about GFP_KERNEL incompatible (which are not
superset) flags to catch new abusers.  Existing ones would have to die
slowly.

[sfr@canb.auug.org.au: f2fs fixup]
Link: http://lkml.kernel.org/r/20170320163735.332e64b7@canb.auug.org.au
Link: http://lkml.kernel.org/r/20170306103032.2540-2-mhocko@kernel.org
Signed-off-by: Michal Hocko <mhocko@suse.com>
Signed-off-by: Stephen Rothwell <sfr@canb.auug.org.au>
Reviewed-by: Andreas Dilger <adilger@dilger.ca> [ext4 part]
Acked-by: Vlastimil Babka <vbabka@suse.cz>
Cc: John Hubbard <jhubbard@nvidia.com>
Cc: David Miller <davem@davemloft.net>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Orabug: 26473178
(cherry picked from commit a7c3e901a46ff54c016d040847eda598a9e3e653)
Signed-off-by: Kyle Fortin <kyle.fortin@oracle.com>
Reviewed-by: Martin K. Petersen <martin.petersen@oracle.com>
Conflicts:

arch/x86/kvm/lapic.c
arch/x86/kvm/page_track.c
arch/x86/kvm/x86.c
fs/f2fs/f2fs.h
fs/f2fs/file.c
fs/f2fs/node.c
fs/f2fs/segment.c
fs/seq_file.c
security/apparmor/apparmorfs.c
security/apparmor/include/lib.h
security/apparmor/lib.c
security/apparmor/policy_unpack.c
virt/kvm/kvm_main.c

18 files changed:
arch/x86/kvm/x86.c
drivers/md/dm-stats.c
fs/ext4/mballoc.c
fs/ext4/super.c
fs/f2fs/segment.c
fs/seq_file.c
include/linux/kvm_host.h
include/linux/mm.h
include/linux/vmalloc.h
ipc/util.c
mm/nommu.c
mm/util.c
mm/vmalloc.c
security/apparmor/apparmorfs.c
security/apparmor/include/apparmor.h
security/apparmor/lib.c
security/apparmor/match.c
virt/kvm/kvm_main.c

index 03e6c1e84cf29c1abea0e31535dd656d3dc05d58..10c4ae978682cfc411d0df6cd3b3ef67f2a140c0 100644 (file)
@@ -7545,14 +7545,15 @@ int kvm_arch_create_memslot(struct kvm *kvm, struct kvm_memory_slot *slot,
                                      slot->base_gfn, level) + 1;
 
                slot->arch.rmap[i] =
-                       kvm_kvzalloc(lpages * sizeof(*slot->arch.rmap[i]));
+                       kvzalloc(lpages * sizeof(*slot->arch.rmap[i]), GFP_KERNEL);
                if (!slot->arch.rmap[i])
                        goto out_free;
                if (i == 0)
                        continue;
 
-               slot->arch.lpage_info[i - 1] = kvm_kvzalloc(lpages *
-                                       sizeof(*slot->arch.lpage_info[i - 1]));
+               slot->arch.lpage_info[i - 1] = kvzalloc(lpages *
+                                       sizeof(*slot->arch.lpage_info[i - 1]),
+                                       GFP_KERNEL);
                if (!slot->arch.lpage_info[i - 1])
                        goto out_free;
 
index 419bdd4fc8b8ef062b8b39ba61f24c1911ce9ba4..608e6fe3b24151d099763ee846afdc6fab9386a9 100644 (file)
@@ -139,12 +139,7 @@ static void *dm_kvzalloc(size_t alloc_size, int node)
        if (!claim_shared_memory(alloc_size))
                return NULL;
 
-       if (alloc_size <= KMALLOC_MAX_SIZE) {
-               p = kzalloc_node(alloc_size, GFP_KERNEL | __GFP_NORETRY | __GFP_NOMEMALLOC | __GFP_NOWARN, node);
-               if (p)
-                       return p;
-       }
-       p = vzalloc_node(alloc_size, node);
+       p = kvzalloc_node(alloc_size, GFP_KERNEL | __GFP_NOMEMALLOC, node);
        if (p)
                return p;
 
index 41260489d3bcd64106bf0414de57bae9b8781ec1..0eba2331ca479ffca78f86482f80a9bc80b88dc9 100644 (file)
@@ -2350,7 +2350,7 @@ int ext4_mb_alloc_groupinfo(struct super_block *sb, ext4_group_t ngroups)
                return 0;
 
        size = roundup_pow_of_two(sizeof(*sbi->s_group_info) * size);
-       new_groupinfo = ext4_kvzalloc(size, GFP_KERNEL);
+       new_groupinfo = kvzalloc(size, GFP_KERNEL);
        if (!new_groupinfo) {
                ext4_msg(sb, KERN_ERR, "can't allocate buddy meta group");
                return -ENOMEM;
index b63f2f073d6d1d6a051ba47b5e216304d6989cb3..c4326f16573dc72f1c687642108ed0bced6eb664 100644 (file)
@@ -1969,7 +1969,7 @@ int ext4_alloc_flex_bg_array(struct super_block *sb, ext4_group_t ngroup)
                return 0;
 
        size = roundup_pow_of_two(size * sizeof(struct flex_groups));
-       new_groups = ext4_kvzalloc(size, GFP_KERNEL);
+       new_groups = kvzalloc(size, GFP_KERNEL);
        if (!new_groups) {
                ext4_msg(sb, KERN_ERR, "not enough memory for %d flex groups",
                         size / (int) sizeof(struct flex_groups));
@@ -3968,7 +3968,7 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent)
                        goto failed_mount;
                }
        }
-       sbi->s_group_desc = ext4_kvmalloc(db_count *
+       sbi->s_group_desc = kvmalloc(db_count *
                                          sizeof(struct buffer_head *),
                                          GFP_KERNEL);
        if (sbi->s_group_desc == NULL) {
index f939660941bbc7a69fc24d84023e7561134f687b..e68f13e3a935978a626627bb35bc20d4dd18ca11 100644 (file)
@@ -1843,12 +1843,13 @@ static int build_sit_info(struct f2fs_sb_info *sbi)
 
        SM_I(sbi)->sit_info = sit_i;
 
-       sit_i->sentries = vzalloc(MAIN_SEGS(sbi) * sizeof(struct seg_entry));
+       sit_i->sentries = kvzalloc(MAIN_SEGS(sbi) * sizeof(struct seg_entry),
+                                       GFP_KERNEL);
        if (!sit_i->sentries)
                return -ENOMEM;
 
        bitmap_size = f2fs_bitmap_size(MAIN_SEGS(sbi));
-       sit_i->dirty_sentries_bitmap = kzalloc(bitmap_size, GFP_KERNEL);
+       sit_i->dirty_sentries_bitmap = kvzalloc(bitmap_size, GFP_KERNEL);
        if (!sit_i->dirty_sentries_bitmap)
                return -ENOMEM;
 
@@ -1867,8 +1868,8 @@ static int build_sit_info(struct f2fs_sb_info *sbi)
                return -ENOMEM;
 
        if (sbi->segs_per_sec > 1) {
-               sit_i->sec_entries = vzalloc(MAIN_SECS(sbi) *
-                                       sizeof(struct sec_entry));
+               sit_i->sec_entries = kvzalloc(MAIN_SECS(sbi) *
+                                       sizeof(struct sec_entry), GFP_KERNEL);
                if (!sit_i->sec_entries)
                        return -ENOMEM;
        }
@@ -1913,12 +1914,12 @@ static int build_free_segmap(struct f2fs_sb_info *sbi)
        SM_I(sbi)->free_info = free_i;
 
        bitmap_size = f2fs_bitmap_size(MAIN_SEGS(sbi));
-       free_i->free_segmap = kmalloc(bitmap_size, GFP_KERNEL);
+       free_i->free_segmap = kvmalloc(bitmap_size, GFP_KERNEL);
        if (!free_i->free_segmap)
                return -ENOMEM;
 
        sec_bitmap_size = f2fs_bitmap_size(MAIN_SECS(sbi));
-       free_i->free_secmap = kmalloc(sec_bitmap_size, GFP_KERNEL);
+       free_i->free_secmap = kvmalloc(sec_bitmap_size, GFP_KERNEL);
        if (!free_i->free_secmap)
                return -ENOMEM;
 
@@ -2054,7 +2055,7 @@ static int init_victim_secmap(struct f2fs_sb_info *sbi)
        struct dirty_seglist_info *dirty_i = DIRTY_I(sbi);
        unsigned int bitmap_size = f2fs_bitmap_size(MAIN_SECS(sbi));
 
-       dirty_i->victim_secmap = kzalloc(bitmap_size, GFP_KERNEL);
+       dirty_i->victim_secmap = kvzalloc(bitmap_size, GFP_KERNEL);
        if (!dirty_i->victim_secmap)
                return -ENOMEM;
        return 0;
@@ -2076,7 +2077,7 @@ static int build_dirty_segmap(struct f2fs_sb_info *sbi)
        bitmap_size = f2fs_bitmap_size(MAIN_SEGS(sbi));
 
        for (i = 0; i < NR_DIRTY_TYPE; i++) {
-               dirty_i->dirty_segmap[i] = kzalloc(bitmap_size, GFP_KERNEL);
+               dirty_i->dirty_segmap[i] = kvzalloc(bitmap_size, GFP_KERNEL);
                if (!dirty_i->dirty_segmap[i])
                        return -ENOMEM;
        }
@@ -2181,7 +2182,7 @@ static void discard_dirty_segmap(struct f2fs_sb_info *sbi,
        struct dirty_seglist_info *dirty_i = DIRTY_I(sbi);
 
        mutex_lock(&dirty_i->seglist_lock);
-       kfree(dirty_i->dirty_segmap[dirty_type]);
+       kvfree(dirty_i->dirty_segmap[dirty_type]);
        dirty_i->nr_dirty[dirty_type] = 0;
        mutex_unlock(&dirty_i->seglist_lock);
 }
@@ -2189,7 +2190,7 @@ static void discard_dirty_segmap(struct f2fs_sb_info *sbi,
 static void destroy_victim_secmap(struct f2fs_sb_info *sbi)
 {
        struct dirty_seglist_info *dirty_i = DIRTY_I(sbi);
-       kfree(dirty_i->victim_secmap);
+       kvfree(dirty_i->victim_secmap);
 }
 
 static void destroy_dirty_segmap(struct f2fs_sb_info *sbi)
@@ -2228,8 +2229,8 @@ static void destroy_free_segmap(struct f2fs_sb_info *sbi)
        if (!free_i)
                return;
        SM_I(sbi)->free_info = NULL;
-       kfree(free_i->free_segmap);
-       kfree(free_i->free_secmap);
+       kvfree(free_i->free_segmap);
+       kvfree(free_i->free_secmap);
        kfree(free_i);
 }
 
@@ -2249,9 +2250,9 @@ static void destroy_sit_info(struct f2fs_sb_info *sbi)
        }
        kfree(sit_i->tmp_map);
 
-       vfree(sit_i->sentries);
-       vfree(sit_i->sec_entries);
-       kfree(sit_i->dirty_sentries_bitmap);
+       kvfree(sit_i->sentries);
+       kvfree(sit_i->sec_entries);
+       kvfree(sit_i->dirty_sentries_bitmap);
 
        SM_I(sbi)->sit_info = NULL;
        kfree(sit_i->sit_bitmap);
index 52b492721603db1e37a8fb424a7f112a4932da2f..f6b5dac4101188fcb2afa6a0d8b209c7a4fbb72f 100644 (file)
@@ -23,16 +23,7 @@ static void seq_set_overflow(struct seq_file *m)
 
 static void *seq_buf_alloc(unsigned long size)
 {
-       void *buf;
-
-       /*
-        * __GFP_NORETRY to avoid oom-killings with high-order allocations -
-        * it's better to fall back to vmalloc() than to kill things.
-        */
-       buf = kmalloc(size, GFP_KERNEL | __GFP_NORETRY | __GFP_NOWARN);
-       if (!buf && size > PAGE_SIZE)
-               buf = vmalloc(size);
-       return buf;
+       return kvmalloc(size, GFP_KERNEL);
 }
 
 /**
index 29a57a5b7cee0eb3deace75421117bcc1758a171..d4e9e88a4f333108be6bb43737012ad335659b14 100644 (file)
@@ -668,8 +668,6 @@ void kvm_arch_check_processor_compat(void *rtn);
 int kvm_arch_vcpu_runnable(struct kvm_vcpu *vcpu);
 int kvm_arch_vcpu_should_kick(struct kvm_vcpu *vcpu);
 
-void *kvm_kvzalloc(unsigned long size);
-
 #ifndef __KVM_HAVE_ARCH_VM_ALLOC
 static inline struct kvm *kvm_arch_alloc_vm(void)
 {
index 3c56b36ebd9d5ff83bba4a9bf40b488e51e0d28f..83f72c5bceff984ca001fbda466e06cc0ea40d1d 100644 (file)
@@ -422,6 +422,20 @@ static inline int is_vmalloc_or_module_addr(const void *x)
 }
 #endif
 
+extern void *kvmalloc_node(size_t size, gfp_t flags, int node);
+static inline void *kvmalloc(size_t size, gfp_t flags)
+{
+       return kvmalloc_node(size, flags, NUMA_NO_NODE);
+}
+static inline void *kvzalloc_node(size_t size, gfp_t flags, int node)
+{
+       return kvmalloc_node(size, flags | __GFP_ZERO, node);
+}
+static inline void *kvzalloc(size_t size, gfp_t flags)
+{
+       return kvmalloc(size, flags | __GFP_ZERO);
+}
+
 extern void kvfree(const void *addr);
 
 static inline void compound_lock(struct page *page)
index 0ec598381f9766182db52f246afc2f0a5f28b36f..d5543f61483f7eb98ac6442554aa5ca613878edb 100644 (file)
@@ -79,6 +79,7 @@ extern void *__vmalloc_node_range(unsigned long size, unsigned long align,
                        unsigned long start, unsigned long end, gfp_t gfp_mask,
                        pgprot_t prot, unsigned long vm_flags, int node,
                        const void *caller);
+extern void *__vmalloc_node_flags(unsigned long size, int node, gfp_t flags);
 
 extern void vfree(const void *addr);
 
index c917e9fd10b139e1370bc06f6ff83cc1af957034..0a7dc460c53090ea0d076b588d139a041d16b4f9 100644 (file)
@@ -403,12 +403,7 @@ void ipc_rmid(struct ipc_ids *ids, struct kern_ipc_perm *ipcp)
  */
 void *ipc_alloc(int size)
 {
-       void *out;
-       if (size > PAGE_SIZE)
-               out = vmalloc(size);
-       else
-               out = kmalloc(size, GFP_KERNEL);
-       return out;
+       return kvmalloc(size, GFP_KERNEL);
 }
 
 /**
index e544508e2a4bc3e3dfa6190abdd3faf0616c95f2..cc5fe1804a9955c7f8f9dc90bb3523445ace6b67 100644 (file)
@@ -287,6 +287,11 @@ void *__vmalloc(unsigned long size, gfp_t gfp_mask, pgprot_t prot)
 }
 EXPORT_SYMBOL(__vmalloc);
 
+void *__vmalloc_node_flags(unsigned long size, int node, gfp_t flags)
+{
+       return __vmalloc(size, flags, PAGE_KERNEL);
+}
+
 void *vmalloc_user(unsigned long size)
 {
        void *ret;
index 68ff8a5361e79a30233fe9ecc4b26b09e614e1b8..1c0a050d0a08ef84d0ee6df26cbeb8a7346b05e8 100644 (file)
--- a/mm/util.c
+++ b/mm/util.c
@@ -316,6 +316,51 @@ unsigned long vm_mmap(struct file *file, unsigned long addr,
 }
 EXPORT_SYMBOL(vm_mmap);
 
+/**
+ * kvmalloc_node - attempt to allocate physically contiguous memory, but upon
+ * failure, fall back to non-contiguous (vmalloc) allocation.
+ * @size: size of the request.
+ * @flags: gfp mask for the allocation - must be compatible (superset) with GFP_KERNEL.
+ * @node: numa node to allocate from
+ *
+ * Uses kmalloc to get the memory but if the allocation fails then falls back
+ * to the vmalloc allocator. Use kvfree for freeing the memory.
+ *
+ * Reclaim modifiers - __GFP_NORETRY, __GFP_REPEAT and __GFP_NOFAIL are not supported
+ *
+ * Any use of gfp flags outside of GFP_KERNEL should be consulted with mm people.
+ */
+void *kvmalloc_node(size_t size, gfp_t flags, int node)
+{
+       gfp_t kmalloc_flags = flags;
+       void *ret;
+
+       /*
+        * vmalloc uses GFP_KERNEL for some internal allocations (e.g page tables)
+        * so the given set of flags has to be compatible.
+        */
+       WARN_ON_ONCE((flags & GFP_KERNEL) != GFP_KERNEL);
+
+       /*
+        * Make sure that larger requests are not too disruptive - no OOM
+        * killer and no allocation failure warnings as we have a fallback
+        */
+       if (size > PAGE_SIZE)
+               kmalloc_flags |= __GFP_NORETRY | __GFP_NOWARN;
+
+       ret = kmalloc_node(size, kmalloc_flags, node);
+
+       /*
+        * It doesn't really make sense to fallback to vmalloc for sub page
+        * requests
+        */
+       if (ret || size <= PAGE_SIZE)
+               return ret;
+
+       return __vmalloc_node_flags(size, node, flags | __GFP_HIGHMEM);
+}
+EXPORT_SYMBOL(kvmalloc_node);
+
 void kvfree(const void *addr)
 {
        if (is_vmalloc_addr(addr))
index a0cc9a4f9137c27124f3a767840f1c7428cc6806..de367e5ff59c69a0d00df852539fd2a529ca57c5 100644 (file)
@@ -1745,6 +1745,13 @@ fail:
  *     Allocate enough pages to cover @size from the page level
  *     allocator with @gfp_mask flags.  Map them into contiguous
  *     kernel virtual space, using a pagetable protection of @prot.
+ *
+ *     Reclaim modifiers in @gfp_mask - __GFP_NORETRY, __GFP_REPEAT
+ *     and __GFP_NOFAIL are not supported
+ *
+ *     Any use of gfp flags outside of GFP_KERNEL should be consulted
+ *     with mm people.
+ *
  */
 static void *__vmalloc_node(unsigned long size, unsigned long align,
                            gfp_t gfp_mask, pgprot_t prot,
@@ -1761,7 +1768,7 @@ void *__vmalloc(unsigned long size, gfp_t gfp_mask, pgprot_t prot)
 }
 EXPORT_SYMBOL(__vmalloc);
 
-static inline void *__vmalloc_node_flags(unsigned long size,
+void *__vmalloc_node_flags(unsigned long size,
                                        int node, gfp_t flags)
 {
        return __vmalloc_node(size, 1, flags, PAGE_KERNEL,
index ad4fa49ad1db23a70dfa16751a9c7f8ec006e854..16f7e6b9e4090dc65617121420729ca1278f35b3 100644 (file)
@@ -100,7 +100,7 @@ static char *aa_simple_write_to_buffer(int op, const char __user *userbuf,
                return ERR_PTR(-EACCES);
 
        /* freed by caller to simple_write_to_buffer */
-       data = kvmalloc(alloc_size);
+       data = kvmalloc(alloc_size, GFP_KERNEL);
        if (data == NULL)
                return ERR_PTR(-ENOMEM);
 
index e4ea6266386662c2c88445743ff2e107b665230a..92a14993784fdb60e344c2d370b10d1b8f4df7c5 100644 (file)
@@ -65,17 +65,6 @@ extern int apparmor_initialized __initdata;
 /* fn's in lib */
 char *aa_split_fqname(char *args, char **ns_name);
 void aa_info_message(const char *str);
-void *__aa_kvmalloc(size_t size, gfp_t flags);
-
-static inline void *kvmalloc(size_t size)
-{
-       return __aa_kvmalloc(size, 0);
-}
-
-static inline void *kvzalloc(size_t size)
-{
-       return __aa_kvmalloc(size, __GFP_ZERO);
-}
 
 /* returns 0 if kref not incremented */
 static inline int kref_get_not0(struct kref *kref)
index c1827e068454cf992c510fd7f6bc9cbbda67a500..b86f15cbbffd50a9b2cf99c914c0555a2c90816d 100644 (file)
@@ -75,32 +75,3 @@ void aa_info_message(const char *str)
        }
        printk(KERN_INFO "AppArmor: %s\n", str);
 }
-
-/**
- * __aa_kvmalloc - do allocation preferring kmalloc but falling back to vmalloc
- * @size: how many bytes of memory are required
- * @flags: the type of memory to allocate (see kmalloc).
- *
- * Return: allocated buffer or NULL if failed
- *
- * It is possible that policy being loaded from the user is larger than
- * what can be allocated by kmalloc, in those cases fall back to vmalloc.
- */
-void *__aa_kvmalloc(size_t size, gfp_t flags)
-{
-       void *buffer = NULL;
-
-       if (size == 0)
-               return NULL;
-
-       /* do not attempt kmalloc if we need more than 16 pages at once */
-       if (size <= (16*PAGE_SIZE))
-               buffer = kmalloc(size, flags | GFP_NOIO | __GFP_NOWARN);
-       if (!buffer) {
-               if (flags & __GFP_ZERO)
-                       buffer = vzalloc(size);
-               else
-                       buffer = vmalloc(size);
-       }
-       return buffer;
-}
index 727eb4200d5c922d8818a6f0a84ace38fd759306..4096e200ae9a83a4ff1813d24899b776f844ec42 100644 (file)
@@ -59,7 +59,7 @@ static struct table_header *unpack_table(char *blob, size_t bsize)
        if (bsize < tsize)
                goto out;
 
-       table = kvzalloc(tsize);
+       table = kvzalloc(tsize, GFP_KERNEL);
        if (table) {
                *table = th;
                if (th.td_flags == YYTD_DATA8)
index d93deb5ce4f27733d72a4cdb8b375b261430b244..adf531bcbb5f6dec34a3fb6d86e97d1394c908e4 100644 (file)
@@ -482,7 +482,7 @@ static struct kvm *kvm_create_vm(unsigned long type)
        BUILD_BUG_ON(KVM_MEM_SLOTS_NUM > SHRT_MAX);
 
        r = -ENOMEM;
-       kvm->memslots = kvm_kvzalloc(sizeof(struct kvm_memslots));
+       kvm->memslots = kvzalloc(sizeof(struct kvm_memslots), GFP_KERNEL);
        if (!kvm->memslots)
                goto out_err_no_srcu;
 
@@ -529,18 +529,6 @@ out_err_no_disable:
        return ERR_PTR(r);
 }
 
-/*
- * Avoid using vmalloc for a small buffer.
- * Should not be used when the size is statically known.
- */
-void *kvm_kvzalloc(unsigned long size)
-{
-       if (size > PAGE_SIZE)
-               return vzalloc(size);
-       else
-               return kzalloc(size, GFP_KERNEL);
-}
-
 static void kvm_destroy_dirty_bitmap(struct kvm_memory_slot *memslot)
 {
        if (!memslot->dirty_bitmap)
@@ -648,7 +636,7 @@ static int kvm_create_dirty_bitmap(struct kvm_memory_slot *memslot)
 {
        unsigned long dirty_bytes = 2 * kvm_dirty_bitmap_bytes(memslot);
 
-       memslot->dirty_bitmap = kvm_kvzalloc(dirty_bytes);
+       memslot->dirty_bitmap = kvzalloc(dirty_bytes, GFP_KERNEL);
        if (!memslot->dirty_bitmap)
                return -ENOMEM;
 
@@ -865,7 +853,7 @@ int __kvm_set_memory_region(struct kvm *kvm,
                        goto out_free;
        }
 
-       slots = kvm_kvzalloc(sizeof(struct kvm_memslots));
+       slots = kvzalloc(sizeof(struct kvm_memslots), GFP_KERNEL);
        if (!slots)
                goto out_free;
        memcpy(slots, kvm->memslots, sizeof(struct kvm_memslots));