Commit 21367bf0 authored by Oleg Nesterov's avatar Oleg Nesterov Committed by Linus Torvalds

[PATCH] vmalloc: introduce __vmalloc_area() function

There are 3 copy-and-paste implementations of __vmalloc() in
arch/{arm,sparc64,x86_64}/kernel/module.c.

I believe the only reason is that __vmalloc() doesn't allow
to specify parameters of __get_vm_area().

This patch splits __vmalloc() into 2 functions. The new one,
__vmalloc_area(), can be used as follows:

	vm_struct *area = __get_vm_area(...);
	void *addr = __vmalloc_area(area, gfp, prot);
Signed-off-by: default avatarOleg Nesterov <oleg@tv-sign.ru>
Signed-off-by: default avatarAndrew Morton <akpm@osdl.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@osdl.org>
parent 772bb693
......@@ -27,6 +27,7 @@ extern void *vmalloc(unsigned long size);
extern void *vmalloc_exec(unsigned long size);
extern void *vmalloc_32(unsigned long size);
extern void *__vmalloc(unsigned long size, int gfp_mask, pgprot_t prot);
extern void *__vmalloc_area(struct vm_struct *area, int gfp_mask, pgprot_t prot);
extern void vfree(void *addr);
extern void *vmap(struct page **pages, unsigned int count,
......
......@@ -389,32 +389,12 @@ void *vmap(struct page **pages, unsigned int count,
EXPORT_SYMBOL(vmap);
/**
* __vmalloc - allocate virtually contiguous memory
*
* @size: allocation size
* @gfp_mask: flags for the page level allocator
* @prot: protection mask for the allocated pages
*
* 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.
*/
void *__vmalloc(unsigned long size, int gfp_mask, pgprot_t prot)
void *__vmalloc_area(struct vm_struct *area, int gfp_mask, pgprot_t prot)
{
struct vm_struct *area;
struct page **pages;
unsigned int nr_pages, array_size, i;
size = PAGE_ALIGN(size);
if (!size || (size >> PAGE_SHIFT) > num_physpages)
return NULL;
area = get_vm_area(size, VM_ALLOC);
if (!area)
return NULL;
nr_pages = size >> PAGE_SHIFT;
nr_pages = (area->size - PAGE_SIZE) >> PAGE_SHIFT;
array_size = (nr_pages * sizeof(struct page *));
area->nr_pages = nr_pages;
......@@ -439,7 +419,7 @@ void *__vmalloc(unsigned long size, int gfp_mask, pgprot_t prot)
goto fail;
}
}
if (map_vm_area(area, prot, &pages))
goto fail;
return area->addr;
......@@ -449,6 +429,32 @@ void *__vmalloc(unsigned long size, int gfp_mask, pgprot_t prot)
return NULL;
}
/**
* __vmalloc - allocate virtually contiguous memory
*
* @size: allocation size
* @gfp_mask: flags for the page level allocator
* @prot: protection mask for the allocated pages
*
* 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.
*/
void *__vmalloc(unsigned long size, int gfp_mask, pgprot_t prot)
{
struct vm_struct *area;
size = PAGE_ALIGN(size);
if (!size || (size >> PAGE_SHIFT) > num_physpages)
return NULL;
area = get_vm_area(size, VM_ALLOC);
if (!area)
return NULL;
return __vmalloc_area(area, gfp_mask, prot);
}
EXPORT_SYMBOL(__vmalloc);
/**
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment