unsigned long array_size;
        unsigned int nr_small_pages = size >> PAGE_SHIFT;
        unsigned int page_order;
-       struct page **pages;
-       unsigned int i;
 
        array_size = (unsigned long)nr_small_pages * sizeof(struct page *);
        gfp_mask |= __GFP_NOWARN;
 
        /* Please note that the recursion is strictly bounded. */
        if (array_size > PAGE_SIZE) {
-               pages = __vmalloc_node(array_size, 1, nested_gfp, node,
+               area->pages = __vmalloc_node(array_size, 1, nested_gfp, node,
                                        area->caller);
        } else {
-               pages = kmalloc_node(array_size, nested_gfp, node);
+               area->pages = kmalloc_node(array_size, nested_gfp, node);
        }
 
-       if (!pages) {
+       if (!area->pages) {
                free_vm_area(area);
                warn_alloc(gfp_mask, NULL,
                           "vmalloc size %lu allocation failure: "
                return NULL;
        }
 
-       area->pages = pages;
-       area->nr_pages = nr_small_pages;
+       area->nr_pages = 0;
        set_vm_area_page_order(area, page_shift - PAGE_SHIFT);
-
        page_order = vm_area_page_order(area);
 
-       /*
-        * Careful, we allocate and map page_order pages, but tracking is done
-        * per PAGE_SIZE page so as to keep the vm_struct APIs independent of
-        * the physical/mapped size.
-        */
-       for (i = 0; i < area->nr_pages; i += 1U << page_order) {
-               struct page *page;
-               int p;
-
-               /* Compound pages required for remap_vmalloc_page */
-               page = alloc_pages_node(node, gfp_mask | __GFP_COMP, page_order);
-               if (unlikely(!page)) {
-                       /* Successfully allocated i pages, free them in __vfree() */
-                       area->nr_pages = i;
-                       atomic_long_add(area->nr_pages, &nr_vmalloc_pages);
-                       warn_alloc(gfp_mask, NULL,
-                                  "vmalloc size %lu allocation failure: "
-                                  "page order %u allocation failed",
-                                  area->nr_pages * PAGE_SIZE, page_order);
-                       goto fail;
-               }
+       if (!page_order) {
+               area->nr_pages = alloc_pages_bulk_array_node(
+                       gfp_mask, node, nr_small_pages, area->pages);
+       } else {
+               /*
+                * Careful, we allocate and map page_order pages, but tracking is done
+                * per PAGE_SIZE page so as to keep the vm_struct APIs independent of
+                * the physical/mapped size.
+                */
+               while (area->nr_pages < nr_small_pages) {
+                       struct page *page;
+                       int i;
+
+                       /* Compound pages required for remap_vmalloc_page */
+                       page = alloc_pages_node(node, gfp_mask | __GFP_COMP, page_order);
+                       if (unlikely(!page))
+                               break;
 
-               for (p = 0; p < (1U << page_order); p++)
-                       area->pages[i + p] = page + p;
+                       for (i = 0; i < (1U << page_order); i++)
+                               area->pages[area->nr_pages + i] = page + i;
 
-               if (gfpflags_allow_blocking(gfp_mask))
-                       cond_resched();
+                       if (gfpflags_allow_blocking(gfp_mask))
+                               cond_resched();
+
+                       area->nr_pages += 1U << page_order;
+               }
        }
+
        atomic_long_add(area->nr_pages, &nr_vmalloc_pages);
 
-       if (vmap_pages_range(addr, addr + size, prot, pages, page_shift) < 0) {
+       /*
+        * If not enough pages were obtained to accomplish an
+        * allocation request, free them via __vfree() if any.
+        */
+       if (area->nr_pages != nr_small_pages) {
+               warn_alloc(gfp_mask, NULL,
+                       "vmalloc size %lu allocation failure: "
+                       "page order %u allocation failed",
+                       area->nr_pages * PAGE_SIZE, page_order);
+               goto fail;
+       }
+
+       if (vmap_pages_range(addr, addr + size, prot, area->pages, page_shift) < 0) {
                warn_alloc(gfp_mask, NULL,
                           "vmalloc size %lu allocation failure: "
                           "failed to map pages",