void bpf_map_put_with_uref(struct bpf_map *map);
 void bpf_map_put(struct bpf_map *map);
 int bpf_map_precharge_memlock(u32 pages);
+void *bpf_map_area_alloc(size_t size);
+void bpf_map_area_free(void *base);
 
 extern int sysctl_unprivileged_bpf_disabled;
 
 
  */
 #include <linux/bpf.h>
 #include <linux/err.h>
-#include <linux/vmalloc.h>
 #include <linux/slab.h>
 #include <linux/mm.h>
 #include <linux/filter.h>
        if (array_size >= U32_MAX - PAGE_SIZE)
                return ERR_PTR(-ENOMEM);
 
-
        /* allocate all map elements and zero-initialize them */
-       array = kzalloc(array_size, GFP_USER | __GFP_NOWARN);
-       if (!array) {
-               array = vzalloc(array_size);
-               if (!array)
-                       return ERR_PTR(-ENOMEM);
-       }
+       array = bpf_map_area_alloc(array_size);
+       if (!array)
+               return ERR_PTR(-ENOMEM);
 
        /* copy mandatory map attributes */
        array->map.map_type = attr->map_type;
 
        if (array_size >= U32_MAX - PAGE_SIZE ||
            elem_size > PCPU_MIN_UNIT_SIZE || bpf_array_alloc_percpu(array)) {
-               kvfree(array);
+               bpf_map_area_free(array);
                return ERR_PTR(-ENOMEM);
        }
 out:
        if (array->map.map_type == BPF_MAP_TYPE_PERCPU_ARRAY)
                bpf_array_free_percpu(array);
 
-       kvfree(array);
+       bpf_map_area_free(array);
 }
 
 static const struct bpf_map_ops array_ops = {
        /* make sure it's empty */
        for (i = 0; i < array->map.max_entries; i++)
                BUG_ON(array->ptrs[i] != NULL);
-       kvfree(array);
+
+       bpf_map_area_free(array);
 }
 
 static void *fd_array_map_lookup_elem(struct bpf_map *map, void *key)
 
 #include <linux/bpf.h>
 #include <linux/jhash.h>
 #include <linux/filter.h>
-#include <linux/vmalloc.h>
 #include "percpu_freelist.h"
 #include "bpf_lru_list.h"
 
                free_percpu(pptr);
        }
 free_elems:
-       vfree(htab->elems);
+       bpf_map_area_free(htab->elems);
 }
 
 static struct htab_elem *prealloc_lru_pop(struct bpf_htab *htab, void *key,
 {
        int err = -ENOMEM, i;
 
-       htab->elems = vzalloc(htab->elem_size * htab->map.max_entries);
+       htab->elems = bpf_map_area_alloc(htab->elem_size *
+                                        htab->map.max_entries);
        if (!htab->elems)
                return -ENOMEM;
 
                goto free_htab;
 
        err = -ENOMEM;
-       htab->buckets = kmalloc_array(htab->n_buckets, sizeof(struct bucket),
-                                     GFP_USER | __GFP_NOWARN);
-
-       if (!htab->buckets) {
-               htab->buckets = vmalloc(htab->n_buckets * sizeof(struct bucket));
-               if (!htab->buckets)
-                       goto free_htab;
-       }
+       htab->buckets = bpf_map_area_alloc(htab->n_buckets *
+                                          sizeof(struct bucket));
+       if (!htab->buckets)
+               goto free_htab;
 
        for (i = 0; i < htab->n_buckets; i++) {
                INIT_HLIST_HEAD(&htab->buckets[i].head);
 free_extra_elems:
        free_percpu(htab->extra_elems);
 free_buckets:
-       kvfree(htab->buckets);
+       bpf_map_area_free(htab->buckets);
 free_htab:
        kfree(htab);
        return ERR_PTR(err);
                prealloc_destroy(htab);
 
        free_percpu(htab->extra_elems);
-       kvfree(htab->buckets);
+       bpf_map_area_free(htab->buckets);
        kfree(htab);
 }
 
 
 #include <linux/bpf.h>
 #include <linux/jhash.h>
 #include <linux/filter.h>
-#include <linux/vmalloc.h>
 #include <linux/stacktrace.h>
 #include <linux/perf_event.h>
 #include "percpu_freelist.h"
        u32 elem_size = sizeof(struct stack_map_bucket) + smap->map.value_size;
        int err;
 
-       smap->elems = vzalloc(elem_size * smap->map.max_entries);
+       smap->elems = bpf_map_area_alloc(elem_size * smap->map.max_entries);
        if (!smap->elems)
                return -ENOMEM;
 
        return 0;
 
 free_elems:
-       vfree(smap->elems);
+       bpf_map_area_free(smap->elems);
        return err;
 }
 
        if (cost >= U32_MAX - PAGE_SIZE)
                return ERR_PTR(-E2BIG);
 
-       smap = kzalloc(cost, GFP_USER | __GFP_NOWARN);
-       if (!smap) {
-               smap = vzalloc(cost);
-               if (!smap)
-                       return ERR_PTR(-ENOMEM);
-       }
+       smap = bpf_map_area_alloc(cost);
+       if (!smap)
+               return ERR_PTR(-ENOMEM);
 
        err = -E2BIG;
        cost += n_buckets * (value_size + sizeof(struct stack_map_bucket));
 put_buffers:
        put_callchain_buffers();
 free_smap:
-       kvfree(smap);
+       bpf_map_area_free(smap);
        return ERR_PTR(err);
 }
 
        /* wait for bpf programs to complete before freeing stack map */
        synchronize_rcu();
 
-       vfree(smap->elems);
+       bpf_map_area_free(smap->elems);
        pcpu_freelist_destroy(&smap->freelist);
-       kvfree(smap);
+       bpf_map_area_free(smap);
        put_callchain_buffers();
 }
 
 
 #include <linux/bpf.h>
 #include <linux/syscalls.h>
 #include <linux/slab.h>
+#include <linux/vmalloc.h>
+#include <linux/mmzone.h>
 #include <linux/anon_inodes.h>
 #include <linux/file.h>
 #include <linux/license.h>
        list_add(&tl->list_node, &bpf_map_types);
 }
 
+void *bpf_map_area_alloc(size_t size)
+{
+       /* We definitely need __GFP_NORETRY, so OOM killer doesn't
+        * trigger under memory pressure as we really just want to
+        * fail instead.
+        */
+       const gfp_t flags = __GFP_NOWARN | __GFP_NORETRY | __GFP_ZERO;
+       void *area;
+
+       if (size <= (PAGE_SIZE << PAGE_ALLOC_COSTLY_ORDER)) {
+               area = kmalloc(size, GFP_USER | flags);
+               if (area != NULL)
+                       return area;
+       }
+
+       return __vmalloc(size, GFP_KERNEL | __GFP_HIGHMEM | flags,
+                        PAGE_KERNEL);
+}
+
+void bpf_map_area_free(void *area)
+{
+       kvfree(area);
+}
+
 int bpf_map_precharge_memlock(u32 pages)
 {
        struct user_struct *user = get_current_user();