[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-Id: <20190109164025.24554-3-rpenyaev@suse.de>
Date: Wed, 9 Jan 2019 17:40:12 +0100
From: Roman Penyaev <rpenyaev@...e.de>
To: unlisted-recipients:; (no To-header on input)
Cc: Roman Penyaev <rpenyaev@...e.de>,
Andrew Morton <akpm@...ux-foundation.org>,
Michal Hocko <mhocko@...e.com>,
Andrey Ryabinin <aryabinin@...tuozzo.com>,
Joe Perches <joe@...ches.com>,
"Luis R. Rodriguez" <mcgrof@...nel.org>, linux-mm@...ck.org,
linux-kernel@...r.kernel.org
Subject: [RFC PATCH 02/15] mm/vmalloc: move common logic from __vmalloc_area_node to a separate func
This one moves logic related to pages array creation to a separate
function, which will be used by vrealloc() call as well, which
implementation will follow.
Signed-off-by: Roman Penyaev <rpenyaev@...e.de>
Cc: Andrew Morton <akpm@...ux-foundation.org>
Cc: Michal Hocko <mhocko@...e.com>
Cc: Andrey Ryabinin <aryabinin@...tuozzo.com>
Cc: Joe Perches <joe@...ches.com>
Cc: "Luis R. Rodriguez" <mcgrof@...nel.org>
Cc: linux-mm@...ck.org
Cc: linux-kernel@...r.kernel.org
---
mm/vmalloc.c | 36 +++++++++++++++++++++++++++++-------
1 file changed, 29 insertions(+), 7 deletions(-)
diff --git a/mm/vmalloc.c b/mm/vmalloc.c
index 4851b4a67f55..ad6cd807f6db 100644
--- a/mm/vmalloc.c
+++ b/mm/vmalloc.c
@@ -1662,21 +1662,26 @@ EXPORT_SYMBOL(vmap);
static void *__vmalloc_node(unsigned long size, unsigned long align,
gfp_t gfp_mask, pgprot_t prot,
int node, const void *caller);
-static void *__vmalloc_area_node(struct vm_struct *area, gfp_t gfp_mask,
- pgprot_t prot, int node)
+
+static int alloc_vm_area_array(struct vm_struct *area, gfp_t gfp_mask, int node)
{
+ unsigned int nr_pages, array_size;
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 highmem_mask = (gfp_mask & (GFP_DMA | GFP_DMA32)) ?
0 :
__GFP_HIGHMEM;
+ if (WARN_ON(area->pages))
+ return -EINVAL;
+
nr_pages = get_vm_area_size(area) >> PAGE_SHIFT;
+ if (!nr_pages)
+ return -EINVAL;
+
array_size = (nr_pages * sizeof(struct page *));
- area->nr_pages = nr_pages;
/* Please note that the recursion is strictly bounded. */
if (array_size > PAGE_SIZE) {
pages = __vmalloc_node(array_size, 1, nested_gfp|highmem_mask,
@@ -1684,8 +1689,25 @@ static void *__vmalloc_area_node(struct vm_struct *area, gfp_t gfp_mask,
} else {
pages = kmalloc_node(array_size, nested_gfp, node);
}
+ if (!pages)
+ return -ENOMEM;
+
+ area->nr_pages = nr_pages;
area->pages = pages;
- if (!area->pages) {
+
+ return 0;
+}
+
+static void *__vmalloc_area_node(struct vm_struct *area, gfp_t gfp_mask,
+ pgprot_t prot, int node)
+{
+ const gfp_t alloc_mask = gfp_mask | __GFP_NOWARN;
+ const gfp_t highmem_mask = (gfp_mask & (GFP_DMA | GFP_DMA32)) ?
+ 0 :
+ __GFP_HIGHMEM;
+ unsigned int i;
+
+ if (alloc_vm_area_array(area, gfp_mask, node)) {
remove_vm_area(area->addr);
kfree(area);
return NULL;
@@ -1709,7 +1731,7 @@ static void *__vmalloc_area_node(struct vm_struct *area, gfp_t gfp_mask,
cond_resched();
}
- if (map_vm_area(area, prot, pages))
+ if (map_vm_area(area, prot, area->pages))
goto fail;
return area->addr;
--
2.19.1
Powered by blists - more mailing lists